From 0cca0c495c7dc29d134a10d7eed5de1f377c99bf Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 5 Aug 2005 12:06:08 +0000 Subject: [PATCH 1/1] Initial import. --- Lugaru.sln | 21 + Lugaru.vcproj | 360 + Source/Carbon Include.h | 6 + Source/Carbon.r | 1 + Source/CarbonStdCLib.h | 54 + Source/Constants.h | 328 + Source/DRIVER.CC | 202 + Source/Frustum.cpp | 155 + Source/Frustum.h | 13 + Source/Game.h | 270 + Source/GameDraw.cpp | 3970 ++++++++++ Source/GameInitDispose.cpp | 2019 +++++ Source/GameTick.cpp | 11579 +++++++++++++++++++++++++++++ Source/Globals.cpp | 250 + Source/Lights.cpp | 125 + Source/Lights.h | 21 + Source/LinkedList.h | 294 + Source/MD5.CC | 544 ++ Source/MacInput.cpp | 803 ++ Source/MacInput.h | 123 + Source/Models.cpp | 1529 ++++ Source/Models.h | 130 + Source/MoreFilesX.c | 2770 +++++++ Source/MoreFilesX.h | 1827 +++++ Source/Objects.cpp | 777 ++ Source/Objects.h | 77 + Source/OpenGL_Full_Screen.cpp | 1770 +++++ Source/OpenGL_Windows.cpp | 1876 +++++ Source/Person.cpp | 7983 ++++++++++++++++++++ Source/Person.h | 366 + Source/PhysicsMath.h | 738 ++ Source/Pointer.h | 70 + Source/Quaternions.cpp | 508 ++ Source/Quaternions.h | 466 ++ Source/Random.c | 40 + Source/Random.h | 18 + Source/Skeleton.cpp | 1712 +++++ Source/Skeleton.h | 206 + Source/Skybox.cpp | 358 + Source/Skybox.h | 21 + Source/Sprites.cpp | 443 ++ Source/Sprites.h | 68 + Source/TGALoader.cpp | 267 + Source/TGALoader.h | 40 + Source/Terrain.cpp | 1540 ++++ Source/Terrain.h | 113 + Source/Text.cpp | 261 + Source/Text.h | 30 + Source/Weapons.cpp | 1343 ++++ Source/Weapons.h | 93 + Source/WinDefs.cpp | 108 + Source/WinDefs.h | 102 + Source/WinInput.cpp | 989 +++ Source/WinInput.h | 136 + Source/binio.h | 92 + Source/fmod.h | 17 + Source/fmod_errors.h | 32 + Source/fmod_header.h | 1219 +++ Source/fmoddyn.h | 543 ++ Source/gl.h | 49 + Source/logger/Copy of logger.cpp | 448 ++ Source/logger/Copy of logger.h | 186 + Source/logger/logger.cpp | 337 + Source/logger/logger.h | 182 + Source/md5.h | 110 + Source/mmgr.cpp | 1751 +++++ Source/mmgr.h | 165 + Source/nommgr.h | 60 + Source/nsp_network.c | 720 ++ Source/pack.c | 53 + Source/pack_private.c | 72 + Source/pack_private.h | 14 + Source/private.c | 181 + Source/private.h | 134 + Source/res/Lugaru.aps | Bin 0 -> 61168 bytes Source/res/Lugaru.png | Bin 0 -> 30618 bytes Source/res/Lugaru.psd | Bin 0 -> 114265 bytes Source/res/Lugaru.rc | 72 + Source/res/Untitled-1.jpg | Bin 0 -> 13267 bytes Source/res/icon1.ico | Bin 0 -> 2998 bytes Source/res/icon2.ico | Bin 0 -> 2166 bytes Source/res/lugaru.ico | Bin 0 -> 25214 bytes Source/res/resource.h | 16 + Source/unpack.c | 53 + Source/unpack_private.c | 21 + Source/unpack_private.h | 14 + Source/wincompat.h | 81 + 87 files changed, 56535 insertions(+) create mode 100644 Lugaru.sln create mode 100644 Lugaru.vcproj create mode 100644 Source/Carbon Include.h create mode 100644 Source/Carbon.r create mode 100644 Source/CarbonStdCLib.h create mode 100644 Source/Constants.h create mode 100644 Source/DRIVER.CC create mode 100644 Source/Frustum.cpp create mode 100644 Source/Frustum.h create mode 100644 Source/Game.h create mode 100644 Source/GameDraw.cpp create mode 100644 Source/GameInitDispose.cpp create mode 100644 Source/GameTick.cpp create mode 100644 Source/Globals.cpp create mode 100644 Source/Lights.cpp create mode 100644 Source/Lights.h create mode 100644 Source/LinkedList.h create mode 100644 Source/MD5.CC create mode 100644 Source/MacInput.cpp create mode 100644 Source/MacInput.h create mode 100644 Source/Models.cpp create mode 100644 Source/Models.h create mode 100644 Source/MoreFilesX.c create mode 100644 Source/MoreFilesX.h create mode 100644 Source/Objects.cpp create mode 100644 Source/Objects.h create mode 100644 Source/OpenGL_Full_Screen.cpp create mode 100644 Source/OpenGL_Windows.cpp create mode 100644 Source/Person.cpp create mode 100644 Source/Person.h create mode 100644 Source/PhysicsMath.h create mode 100644 Source/Pointer.h create mode 100644 Source/Quaternions.cpp create mode 100644 Source/Quaternions.h create mode 100644 Source/Random.c create mode 100644 Source/Random.h create mode 100644 Source/Skeleton.cpp create mode 100644 Source/Skeleton.h create mode 100644 Source/Skybox.cpp create mode 100644 Source/Skybox.h create mode 100644 Source/Sprites.cpp create mode 100644 Source/Sprites.h create mode 100644 Source/TGALoader.cpp create mode 100644 Source/TGALoader.h create mode 100644 Source/Terrain.cpp create mode 100644 Source/Terrain.h create mode 100644 Source/Text.cpp create mode 100644 Source/Text.h create mode 100644 Source/Weapons.cpp create mode 100644 Source/Weapons.h create mode 100644 Source/WinDefs.cpp create mode 100644 Source/WinDefs.h create mode 100644 Source/WinInput.cpp create mode 100644 Source/WinInput.h create mode 100644 Source/binio.h create mode 100644 Source/fmod.h create mode 100644 Source/fmod_errors.h create mode 100644 Source/fmod_header.h create mode 100644 Source/fmoddyn.h create mode 100644 Source/gl.h create mode 100644 Source/logger/Copy of logger.cpp create mode 100644 Source/logger/Copy of logger.h create mode 100644 Source/logger/logger.cpp create mode 100644 Source/logger/logger.h create mode 100644 Source/md5.h create mode 100644 Source/mmgr.cpp create mode 100644 Source/mmgr.h create mode 100644 Source/nommgr.h create mode 100644 Source/nsp_network.c create mode 100644 Source/pack.c create mode 100644 Source/pack_private.c create mode 100644 Source/pack_private.h create mode 100644 Source/private.c create mode 100644 Source/private.h create mode 100644 Source/res/Lugaru.aps create mode 100644 Source/res/Lugaru.png create mode 100644 Source/res/Lugaru.psd create mode 100644 Source/res/Lugaru.rc create mode 100644 Source/res/Untitled-1.jpg create mode 100644 Source/res/icon1.ico create mode 100644 Source/res/icon2.ico create mode 100644 Source/res/lugaru.ico create mode 100644 Source/res/resource.h create mode 100644 Source/unpack.c create mode 100644 Source/unpack_private.c create mode 100644 Source/unpack_private.h create mode 100644 Source/wincompat.h diff --git a/Lugaru.sln b/Lugaru.sln new file mode 100644 index 0000000..cd2144e --- /dev/null +++ b/Lugaru.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Lugaru", "Lugaru.vcproj", "{71D87E45-76A7-497F-9176-DA2600007A65}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {71D87E45-76A7-497F-9176-DA2600007A65}.Debug.ActiveCfg = Debug|Win32 + {71D87E45-76A7-497F-9176-DA2600007A65}.Debug.Build.0 = Debug|Win32 + {71D87E45-76A7-497F-9176-DA2600007A65}.Release.ActiveCfg = Release|Win32 + {71D87E45-76A7-497F-9176-DA2600007A65}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/Lugaru.vcproj b/Lugaru.vcproj new file mode 100644 index 0000000..7661834 --- /dev/null +++ b/Lugaru.vcproj @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Carbon Include.h b/Source/Carbon Include.h new file mode 100644 index 0000000..5fee235 --- /dev/null +++ b/Source/Carbon Include.h @@ -0,0 +1,6 @@ +// Carbon Include.h + +// Put Carbon specific stuff here to maintain 9/Carbon buildability... + + +#define TARGET_API_MAC_CARBON 1 \ No newline at end of file diff --git a/Source/Carbon.r b/Source/Carbon.r new file mode 100644 index 0000000..ca7d3dd --- /dev/null +++ b/Source/Carbon.r @@ -0,0 +1 @@ +/* * Permit this Carbon application to launch on OS X * * Copyright © 1997-2001 Metrowerks Corporation * * Questions and comments to: * * */ /*----------------------------carb ¥ Carbon on OS X launch information --------------------------*/ type 'carb' { }; resource 'carb'(0) { }; \ No newline at end of file diff --git a/Source/CarbonStdCLib.h b/Source/CarbonStdCLib.h new file mode 100644 index 0000000..aa67ef0 --- /dev/null +++ b/Source/CarbonStdCLib.h @@ -0,0 +1,54 @@ +/************************************************************ + + CarbonStdCLib.h + Assorted helper functions associated with CarbonStdClib.o. + + Copyright Apple Computer,Inc. 2001 + All rights reserved + + * Warning: This interface is NOT a part of the ANSI C standard. + * This header file is not POSIX compliant. + * For portable code, don't use this interface. + +************************************************************/ + + +#ifndef __CARBONSTDCLIB__ +#define __CARBONSTDCLIB__ + +#ifndef __CONDITIONALMACROS__ +#include +#endif + +#if defined (__powerc) || defined (powerc) || defined (__CFM68K__) + #pragma import on +#endif + +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if !(CALL_NOT_IN_CARBON || __MPWINTERNAL__) + +extern void InitCarbonStdCLib( void ) ; +extern void TermCarbonStdCLib( void ) ; + +extern void ConvertUnixPathToHFSPath(const char *unixPath, char *hfsPath) ; +extern void ConvertHFSPathToUnixPath(const char *hfsPath, char *unixPath) ; + +/* BSD functions */ + +int bsd_chdir(const char *path) ; +int bsd_chmod(const char *path , int mode) ; + +#endif + +#if __cplusplus +} +#endif /* __cplusplus */ + +#if defined (__powerc) || defined (powerc) || defined (__CFM68K__) + #pragma import off +#endif + +#endif /* __CARBONSTDCLIB__ */ diff --git a/Source/Constants.h b/Source/Constants.h new file mode 100644 index 0000000..e063d36 --- /dev/null +++ b/Source/Constants.h @@ -0,0 +1,328 @@ +#ifndef _CONSTANTS_H_ +#define _CONSTANTS_H_ + +#define awardklutz 0 +#define awardflawless 1 +#define awardalldead 2 +#define awardnodead 3 +#define awardstealth 4 +#define awardswordsman 5 +#define awardkungfu 6 +#define awardknifefighter 7 +#define awardcoward 8 +#define awardevasion 9 +#define awardacrobat 10 +#define awardlongrange 11 +#define awardbrutal 12 +#define awardhyper 13 +#define awardaikido 14 +#define awardrambo 15 +#define awardfast 16 +#define awardrealfast 17 +#define awarddamnfast 18 +#define awardstrategy 19 +#define awardbojutsu 20 + +#define mapkilleveryone 0 +#define mapgosomewhere 1 +#define mapkillsomeone 2 +#define mapkillmost 3 + +#define wpkeepwalking 0 +#define wppause 1 + +#define typeactive 0 +#define typesitting 1 +#define typesittingwall 2 +#define typesleeping 3 +#define typedead1 4 +#define typedead2 5 +#define typedead3 6 +#define typedead4 7 + +#define tracheotomy 1 +#define backstab 2 +#define spinecrusher 3 +#define ninja 4 +#define style 5 +#define cannon 6 +#define aimbonus 7 +#define deepimpact 8 +#define touchofdeath 9 +#define swordreversebonus 10 +#define staffreversebonus 11 +#define reverseko 12 +#define solidhit 13 +#define twoxcombo 14 +#define threexcombo 15 +#define fourxcombo 16 +#define megacombo 17 +#define Reversal 18 +#define Stabbonus 19 +#define Slicebonus 20 +#define Bullseyebonus 21 +#define Slashbonus 22 +#define Wolfbonus 23 +#define FinishedBonus 24 +#define TackleBonus 25 +#define AboveBonus 26 + +#define boneconnect 0 +#define constraint 1 +#define muscle 2 + +#define head 0 +#define neck 1 +#define leftshoulder 2 +#define leftelbow 3 +#define leftwrist 4 +#define lefthand 5 +#define rightshoulder 6 +#define rightelbow 7 +#define rightwrist 8 +#define righthand 9 +#define abdomen 10 +#define lefthip 11 +#define righthip 12 +#define groin 13 +#define leftknee 14 +#define leftankle 15 +#define leftfoot 16 +#define rightknee 17 +#define rightankle 18 +#define rightfoot 19 + +#define max_joints 50 +#define max_frames 50 +#define max_muscles 100 + +#define animation_count 140 + +#define runanim 0 +#define bounceidleanim 1 +#define stopanim 2 +#define jumpupanim 3 +#define jumpdownanim 4 +#define landanim 5 +#define climbanim 6 +#define hanganim 7 +#define spinkickanim 8 +#define tempanim 9 +#define getupfromfrontanim 10 +#define getupfrombackanim 11 +#define crouchanim 12 +#define sneakanim 13 +#define rollanim 14 +#define flipanim 15 +#define spinkickreversedanim 16 +#define spinkickreversalanim 17 +#define lowkickanim 18 +#define sweepanim 19 +#define sweepreversedanim 20 +#define sweepreversalanim 21 +#define rabbitkickanim 22 +#define rabbitkickreversedanim 23 +#define rabbitkickreversalanim 24 +#define upunchanim 25 +#define staggerbackhighanim 26 +#define upunchreversedanim 27 +#define upunchreversalanim 28 +#define hurtidleanim 29 +#define backhandspringanim 30 +#define fightidleanim 31 +#define walkanim 32 +#define fightsidestep 33 +#define killanim 34 +#define sneakattackanim 35 +#define sneakattackedanim 36 +#define drawrightanim 37 +#define knifeslashstartanim 38 +#define crouchstabanim 39 +#define crouchdrawrightanim 40 +#define knifefollowanim 41 +#define knifefollowedanim 42 +#define knifethrowanim 43 +#define removeknifeanim 44 +#define crouchremoveknifeanim 45 +#define jumpreversedanim 46 +#define jumpreversalanim 47 +#define landhardanim 48 +#define staggerbackhardanim 49 +#define dropkickanim 50 +#define winduppunchanim 51 +#define winduppunchblockedanim 52 +#define blockhighleftanim 53 +#define blockhighleftstrikeanim 54 +#define walljumpfrontanim 55 +#define walljumpbackanim 56 +#define walljumpleftanim 57 +#define walljumprightanim 58 +#define backflipanim 59 +#define leftflipanim 60 +#define rightflipanim 61 +#define walljumprightkickanim 62 +#define walljumpleftkickanim 63 +#define knifefightidleanim 64 +#define knifesneakattackanim 65 +#define knifesneakattackedanim 66 +#define swordstabanim 67 +#define swordslashleftanim 68 +#define swordslashrightanim 69 +#define swordfightidleanim 70 +#define swordsneakattackanim 71 +#define swordsneakattackedanim 72 +#define drawleftanim 73 +#define swordslashanim 74 +#define swordgroundstabanim 75 +#define dodgebackanim 76 +#define swordslashreversedanim 77 +#define swordslashreversalanim 78 +#define knifeslashreversedanim 79 +#define knifeslashreversalanim 80 +#define swordfightidlebothanim 81 +#define swordslashparryanim 82 +#define sworddisarmanim 83 +#define swordslashparriedanim 84 +#define wolfidle 85 +#define wolffightidle 86 +#define wolfswordidle 87 +#define wolfhurtidle 88 +#define wolfcrouchanim 89 +#define wolfsneakanim 90 +#define wolfrunanim 91 +#define wolfstopanim 92 +#define wolfclawanim 93 +#define wolflandanim 94 +#define wolflandhardanim 95 +#define wolfrunninganim 96 +#define rabbitrunninganim 97 +#define frontflipanim 98 +#define rabbittackleanim 99 +#define rabbittacklinganim 100 +#define rabbittackledfrontanim 101 +#define rabbittackledbackanim 102 +#define rabbittacklereversal 103 +#define rabbittacklereversed 104 +#define wolftackleanim 105 +#define wolftacklinganim 106 +#define wolftackledfrontanim 107 +#define wolftackledbacanim 108 +#define wolftacklereversal 109 +#define wolftacklereversed 110 +#define wolfslapanim 111 +#define wolfbashanim 112 +#define staffhitanim 113 +#define staffgroundsmashanim 114 +#define staffspinhitanim 115 +#define staffhitreversedanim 116 +#define staffhitreversalanim 117 +#define staffspinhitreversedanim 118 +#define staffspinhitreversalanim 119 +#define sleepanim 120 +#define sitanim 121 +#define talkidleanim 122 +#define sitwallanim 123 +#define dead1anim 124 +#define dead2anim 125 +#define dead3anim 126 +#define dead4anim 127 + +#define max_dialogues 20 +#define max_dialoguelength 20 + +#define max_model_vertex 3000 // maximum number of vertexs +#define max_textured_triangle 3000 // maximum number of texture-filled triangles in a model + +#define stream_music1desert 0 +#define stream_music1grass 1 +#define stream_music1snow 2 +#define stream_music2 3 +#define stream_music3 4 +#define stream_music4 5 +#define stream_menumusic 6 +#define stream_desertambient 7 +#define stream_firesound 8 +#define stream_wind 9 + +//#define music1desert 0 +//#define music1grass 1 +//#define music1snow 2 +//#define music2 3 +//#define music3 4 +//#define music4 5 +//#define menumusic 6 +//#define desertambient 7 +//#define firesound 8 +//#define wind 9 +#define footstepsound 10 +#define footstepsound2 11 +#define footstepsound3 12 +#define footstepsound4 13 +#define jumpsound 14 +#define landsound 15 +#define whooshsound 16 +#define hawksound 17 +#define landsound1 18 +#define landsound2 19 +#define breaksound 20 +#define lowwhooshsound 21 +#define heavyimpactsound 22 +#define firestartsound 23 +#define fireendsound 24 +#define breaksound2 25 +#define knifedrawsound 26 +#define knifesheathesound 27 +#define knifeswishsound 28 +#define knifeslicesound 29 +#define skidsound 30 +#define snowskidsound 31 +#define bushrustle 32 +#define midwhooshsound 33 +#define highwhooshsound 34 +#define movewhooshsound 35 +#define thudsound 36 +#define whooshhitsound 37 +#define clank1sound 38 +#define clank2sound 39 +#define clank3sound 40 +#define clank4sound 41 +#define consolefailsound 42 +#define consolesuccesssound 43 +#define swordslicesound 44 +#define metalhitsound 45 +#define clawslicesound 46 +#define splattersound 47 +#define growlsound 48 +#define growl2sound 49 +#define barksound 50 +#define snarlsound 51 +#define snarl2sound 52 +#define barkgrowlsound 53 +#define bark2sound 54 +#define bark3sound 55 +#define rabbitattacksound 56 +#define rabbitattack2sound 57 +#define rabbitattack3sound 58 +#define rabbitattack4sound 59 +#define rabbitpainsound 60 +#define rabbitpain1sound 61 +#define rabbitpain2sound 62 +#define rabbitchitter 63 +#define rabbitchitter2 64 +#define fleshstabsound 65 +#define fleshstabremovesound 66 +#define swordstaffsound 67 +#define staffbodysound 68 +#define staffheadsound 69 +#define alarmsound 70 +#define staffbreaksound 71 + +#define normalmode 0 +#define motionblurmode 1 +#define radialzoommode 2 +#define realmotionblurmode 3 +#define doublevisionmode 4 +#define glowmode 5 + +#define maxplayers 10 +#endif \ No newline at end of file diff --git a/Source/DRIVER.CC b/Source/DRIVER.CC new file mode 100644 index 0000000..df96e35 --- /dev/null +++ b/Source/DRIVER.CC @@ -0,0 +1,202 @@ +// DRIVER.CC - test driver for the C++/object oriented translation and +// modification of MD5. + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + + MDDRIVER.C - test driver for MD2, MD4 and MD5 + + Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +#include +#include +#include +#include + +#include "md5.h" + + +// Length of test block, number of test blocks. + +#define TEST_BLOCK_LEN 1000 +#define TEST_BLOCK_COUNT 1000 + +static void MD5_timeTrial (void); +static void MD5_testSuite (void); +static void MD5_file (char *); +static void MD5_filter (void); +static void MD5_string (unsigned char *string); +static char *MD5_usage (void); + +// Main driver. +/* +int main (int argc, char *argv[]){ + + int i; + + MD5_testSuite(); + + if (argc > 1) + for (i = 1; i < argc; i++) + if (argv[i][0] == '-' && argv[i][1] == 's') + MD5_string ( (unsigned char *) argv[i] + 2); + else if (strcmp (argv[i], "-t") == 0) + MD5_timeTrial (); + else if (strcmp (argv[i], "-x") == 0) + MD5_testSuite (); + else if (strcmp (argv[i], "-h") == 0) + cout << MD5_usage()<< flush; + else if (strcmp (argv[i], "-help")==0) + cout << MD5_usage()<< flush; + else if (argv[i][0] == '-'){ + cerr << argv[i] << " is an unknown option.\n" << MD5_usage()<< flush; + exit (1); + } + else + MD5_file (argv[i]); + else + MD5_filter (); + + return (0); +} +*/ + +// Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. + +static void MD5_timeTrial () +{ + MD5 context; + time_t endTime, startTime; + unsigned char block[TEST_BLOCK_LEN]; + unsigned int i; + + + cout << "MD5 time trial. Digesting "<< TEST_BLOCK_LEN << " "; + cout << TEST_BLOCK_COUNT << "-byte blocks ..."; + + // Initialize block + for (i = 0; i < TEST_BLOCK_LEN; i++) + block[i] = (unsigned char)(i & 0xff); + + // Start timer + time (&startTime); + + // Digest blocks + for (i = 0; i < TEST_BLOCK_COUNT; i++) + context.update (block, TEST_BLOCK_LEN); + + context.finalize(); + + // Stop timer + time (&endTime); + + cout << " done" << endl; + + cout << "Digest = " << context << endl; + + cout << "Time = "<< (long)(endTime-startTime) << " seconds" << endl; + + cout << "Speed = "; + cout << (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime); + cout << "bytes/second" < + +#include "gl.h" + + +void FRUSTUM:: + GetFrustum() { + static float projmatrix[16]; + static float mvmatrix[16]; + static float clip[16]; + static 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]; +} + +int FRUSTUM:: + CubeInFrustum(float x, float y, float z, float size) { + static int c, c2; + + 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) { + static int c, c2; + + 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) { + static int c2; + + 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; +} \ No newline at end of file diff --git a/Source/Frustum.h b/Source/Frustum.h new file mode 100644 index 0000000..d748af5 --- /dev/null +++ b/Source/Frustum.h @@ -0,0 +1,13 @@ +#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 \ No newline at end of file diff --git a/Source/Game.h b/Source/Game.h new file mode 100644 index 0000000..65cbaf1 --- /dev/null +++ b/Source/Game.h @@ -0,0 +1,270 @@ +#ifndef _GAME_H_ +#define _GAME_H_ + +#ifndef WIN32 +#include +#include "Quicktime.h" +#endif +//Jordan included glut.h +//#include + +#include "TGALoader.h" +#ifdef WIN32 +#include "WinInput.h" +#else +#include "Macinput.h" +#endif +#include "Terrain.h" +#include "Skybox.h" +#include "Skeleton.h" +#include "Models.h" +#include "Lights.h" +#include "Person.h" +#include "Constants.h" +#include "fmod.h" +#include "Sprites.h" +//#include +#include "Text.h" +#include "Objects.h" +//#include +#include "Weapons.h" +#include "binio.h" +#include +#include "gl.h" + +extern GLuint rabbittexture; + + +class Game +{ +public: + + typedef std::map TextureList; + typedef std::map GLTextureList; + typedef TextureList::iterator TexIter; + static TextureList textures; + + GLuint terraintexture; + GLuint terraintexture2; + GLuint terraintexture3; + GLuint screentexture; + GLuint screentexture2; + GLuint logotexture; + GLuint loadscreentexture; + GLuint Maparrowtexture; + GLuint Mapboxtexture; + GLuint Mapcircletexture; + GLuint cursortexture; + GLuint Mainmenuitems[10]; + + int nummenuitems; + int startx[100]; + int starty[100]; + int endx[100]; + int endy[100]; + float selectedlong[100]; + float offsetx[100]; + float offsety[100]; + float movex[100]; + float movey[100]; + float transition; + int anim; + int selected; + int loaddistrib; + int keyselect; + int indemo; + int registered; + + bool won; + + bool entername; + + char menustring[100][256]; + char registrationname[256]; + float registrationnumber; + + int newdetail; + int newscreenwidth; + int newscreenheight; + + bool gameon; + float deltah,deltav; + int mousecoordh,mousecoordv; + int oldmousecoordh,oldmousecoordv; + float rotation,rotation2; + SkyBox skybox; + bool cameramode; + bool cameratogglekeydown; + bool chattogglekeydown; + int olddrawmode; + int drawmode; + bool drawmodetogglekeydown; + bool explodetogglekeydown; + bool detailtogglekeydown; + bool firstload; + bool oldbutton; + + float leveltime; + float loadtime; + + Model hawk; + XYZ hawkcoords; + XYZ realhawkcoords; + GLuint hawktexture; + float hawkrotation; + float hawkcalldelay; + + Model eye; + Model iris; + Model cornea; + + bool stealthloading; + + int campaignnumlevels; + char campaignmapname[50][256]; + char campaigndescription[50][256]; + int campaignchoosenext[50]; + int campaignnumnext[50]; + int campaignnextlevel[50][10]; + int campaignchoicesmade; + int campaignchoices[5000]; + int campaignlocationx[50]; + int campaignlocationy[50]; + int campaignchoicenum; + int campaignchoicewhich[10]; + int whichchoice; + + int numlevelspassed; + int levelorder[5000]; + int levelvisible[50]; + int levelhighlight[50]; + + bool minimap; + + int musictype,oldmusictype,oldoldmusictype; + bool realthreat; + + Model rabbit; + XYZ rabbitcoords; + + XYZ mapcenter; + float mapradius; + + Text text; + float fps; + + XYZ cameraloc; + float cameradist; + + bool envtogglekeydown; + bool slomotogglekeydown; + bool texturesizetogglekeydown; + bool freezetogglekeydown; + int drawtoggle; + + bool editorenabled; + int editortype; + float editorsize; + float editorrotation; + float editorrotation2; + + float brightness; + + int quit; + int tryquit; + + XYZ pathpoint[30]; + int numpathpoints; + int numpathpointconnect[30]; + int pathpointconnect[30][30]; + int pathpointselected; + + int endgame; + bool scoreadded; + int numchallengelevels; + + bool console; + int archiveselected; + char consoletext[15][256]; + int consolechars[15]; + bool chatting; + char displaytext[15][256]; + int displaychars[15]; + float displaytime[15]; + float displayblinkdelay; + bool displayblink; + int displayselected; + bool consolekeydown; + bool consoletogglekeydown; + float consoleblinkdelay; + bool consoleblink; + int consoleselected; + int togglekey[140]; + float togglekeydelay[140]; + bool registernow; + bool autocam; + + unsigned short crouchkey,jumpkey,forwardkey,chatkey,backkey,leftkey,rightkey,drawkey,throwkey,attackkey; + bool oldattackkey; + + long long MD5_string (char *string); + static void LoadTexture(char *fileName, GLuint *textureid,int mipmap, bool hasalpha); + static void LoadTextureSave(char *fileName, GLuint *textureid,int mipmap,GLubyte *array, int *skinsize); + void LoadSave(char *fileName, GLuint *textureid,bool mipmap,GLubyte *array, int *skinsize); + bool AddClothes(char *fileName, GLuint *textureid,bool mipmap,GLubyte *array, int *skinsize); + void InitGame(); + void LoadStuff(); + void LoadingScreen(); + void FadeLoadingScreen(float howmuch); + void Dispose(); + int DrawGLScene(GLvoid); + void Tick(); + void TickOnce(); + void TickOnceAfter(); + void SetUpLighting(); + void Loadlevel(int which); + void Loadlevel(char *name); + void LoadSounds(); + void Setenvironment(int which); + GLvoid ReSizeGLScene(float fov, float near); + int findPathDist(int start,int end); + int checkcollide(XYZ startpoint, XYZ endpoint); + int checkcollide(XYZ startpoint, XYZ endpoint, int what); + int loading; + float talkdelay; + + int numboundaries; + XYZ boundary[360]; + + int whichlevel; + int oldenvironment; + int targetlevel; + float changedelay; + + float musicvolume[4]; + float oldmusicvolume[4]; + int musicselected; + int change; + Game(); + ~Game() { + for(int i=0;i<10;i++){ + if(Mainmenuitems[i])glDeleteTextures( 1, (const unsigned long *)&Mainmenuitems[i] ); + } + glDeleteTextures( 1, (const unsigned long *)&cursortexture ); + glDeleteTextures( 1, (const unsigned long *)&Maparrowtexture ); + glDeleteTextures( 1, (const unsigned long *)&Mapboxtexture ); + glDeleteTextures( 1, (const unsigned long *)&Mapcircletexture ); + glDeleteTextures( 1, (const unsigned long *)&terraintexture ); + glDeleteTextures( 1, (const unsigned long *)&terraintexture2 ); + if(screentexture>0)glDeleteTextures( 1, (const unsigned long *)&screentexture ); + if(screentexture2>0)glDeleteTextures( 1, (const unsigned long *)&screentexture2 ); + glDeleteTextures( 1, (const unsigned long *)&hawktexture ); + glDeleteTextures( 1, (const unsigned long *)&logotexture ); + glDeleteTextures( 1, (const unsigned long *)&loadscreentexture ); + + Dispose(); + } + +}; + +#endif \ No newline at end of file diff --git a/Source/GameDraw.cpp b/Source/GameDraw.cpp new file mode 100644 index 0000000..e3cd41b --- /dev/null +++ b/Source/GameDraw.cpp @@ -0,0 +1,3970 @@ +#include "Game.h" + +using namespace std; + +extern XYZ viewer; +extern int environment; +extern float texscale; +extern Light light; +extern Terrain terrain; +extern Sprites sprites; +extern float multiplier; +extern float sps; +extern float viewdistance; +extern float fadestart; +extern float screenwidth,screenheight; +#ifdef WIN32 +extern HDC hDC; +#else +extern AGLContext gaglContext; +#endif +extern int kTextureSize; +extern FRUSTUM frustum; +extern Light light; +extern Objects objects; +extern int detail; +extern float usermousesensitivity; +extern bool osx; +extern float camerashake; +extern Weapons weapons; +extern Person player[maxplayers]; +extern int slomo; +extern float slomodelay; +extern bool ismotionblur; +extern float woozy; +extern float blackout; +extern bool damageeffects; +extern float volume; +extern int numplayers; +extern bool texttoggle; +extern float blurness; +extern float targetblurness; +extern float playerdist; +extern bool cellophane; +extern bool freeze; +extern float flashamount,flashr,flashg,flashb; +extern int flashdelay; +extern int netstate; +extern float motionbluramount; +extern bool isclient; +extern bool alwaysblur; +extern int test; +extern bool tilt2weird; +extern bool tiltweird; +extern bool midweird; +extern bool proportionweird; +extern bool vertexweird[6]; +extern bool velocityblur; +extern bool buttons[3]; +extern bool debugmode; +extern int mainmenu; +extern int oldmainmenu; +extern int bloodtoggle; +extern int difficulty; +extern bool decals; +// MODIFIED GWC +//extern int texdetail; +extern float texdetail; +extern bool musictoggle; +extern int bonus; +extern float bonusvalue; +extern float bonustotal; +extern float bonustime; +extern int oldbonus; +extern float startbonustotal; +extern float bonusnum[100]; +extern int tutoriallevel; +extern float smoketex; +extern float tutorialstagetime; +extern float tutorialmaxtime; +extern int tutorialstage; +extern bool againbonus; +extern float damagedealt; +extern float damagetaken; +extern bool invertmouse; + +extern int numhotspots; +extern int winhotspot; +extern int killhotspot; +extern XYZ hotspot[40]; +extern int hotspottype[40]; +extern float hotspotsize[40]; +extern char hotspottext[40][256]; +extern int currenthotspot; + +extern int numaccounts; +extern int accountactive; +extern int accountdifficulty[10]; +extern int accountprogress[10]; +extern float accountpoints[10]; +extern float accounthighscore[10][50]; +extern float accountfasttime[10][50]; +extern bool accountunlocked[10][60]; +extern char accountname[10][256]; + +extern int numfalls; +extern int numflipfail; +extern int numseen; +extern int numstaffattack; +extern int numswordattack; +extern int numknifeattack; +extern int numunarmedattack; +extern int numescaped; +extern int numflipped; +extern int numwallflipped; +extern int numthrowkill; +extern int numafterkill; +extern int numreversals; +extern int numattacks; +extern int maxalarmed; +extern int numresponded; + +extern bool campaign; +extern bool winfreeze; + +extern float menupulse; + +extern bool gamestart; + +extern int numdialogues; +extern int numdialogueboxes[max_dialogues]; +extern int dialoguetype[max_dialogues]; +extern int dialogueboxlocation[max_dialogues][max_dialoguelength]; +extern float dialogueboxcolor[max_dialogues][max_dialoguelength][3]; +extern int dialogueboxsound[max_dialogues][max_dialoguelength]; +extern char dialoguetext[max_dialogues][max_dialoguelength][128]; +extern char dialoguename[max_dialogues][max_dialoguelength][64]; +extern XYZ dialoguecamera[max_dialogues][max_dialoguelength]; +extern XYZ participantlocation[max_dialogues][10]; +extern int participantfocus[max_dialogues][max_dialoguelength]; +extern int participantaction[max_dialogues][max_dialoguelength]; +extern float participantrotation[max_dialogues][10]; +extern XYZ participantfacing[max_dialogues][max_dialoguelength][10]; +extern float dialoguecamerarotation[max_dialogues][max_dialoguelength]; +extern float dialoguecamerarotation2[max_dialogues][max_dialoguelength]; +extern int indialogue; +extern int whichdialogue; +extern int directing; +extern float dialoguetime; +extern int dialoguegonethrough[20]; + +extern int accountcampaignchoicesmade[10]; +extern int accountcampaignchoices[10][5000]; + +extern float accountcampaignhighscore[10]; +extern float accountcampaignfasttime[10]; +extern float accountcampaignscore[10]; +extern float accountcampaigntime[10]; + +extern bool gamestarted; + +extern FSOUND_SAMPLE *samp[100]; +extern int channels[100]; +extern "C" void PlaySoundEx(int channel, FSOUND_SAMPLE *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused); + +/*********************> DrawGLScene() <*****/ +long long Game::MD5_string (char *string){ + char temp[256]=""; + char temp2[256]=""; + long long num=90814; + + sprintf (temp, "%s",string); + + int i=0; + while (i<256&&temp[i]!='\0'){ + if(temp[i]%3==0)num+=temp[i]*124; + else if(temp[i]%3==1)num-=temp[i]*temp[i]; + else num*=temp[i]; + i++; + } + + num=abs(num); + if(num==0)num+=1452; + + while(num<5000000000000000){ + num*=1.85421521; + } + + while(num>9900000000000000){ + num/=1.235421521; + } + + return num; + + //return 1111111111111111; +} + +int Game::DrawGLScene(GLvoid) +{ + static float texcoordwidth,texcoordheight; + static float texviewwidth, texviewheight; + static int i,j,k,l; + static GLubyte color; + static float newbrightness; + static float changespeed; + static XYZ checkpoint; + static float tempmult; + float tutorialopac; + static char string[256]=""; + static char string2[256]=""; + static char string3[256]=""; + + static float lastcheck; + + lastcheck+=multiplier; + + glColorMask( 1.0, 1.0, 1.0, 1.0 ); + if(!registered)debugmode=0; + + + if(freeze||winfreeze||(mainmenu&&gameon)||(!gameon&&gamestarted)){ + tempmult=multiplier; + multiplier=0; + } + + if(!mainmenu){ + if(editorenabled){ + numboundaries=mapradius*2; + if(numboundaries>360)numboundaries=360; + for(i=0;i200)&&velocityblur&&!cameramode){ + drawmode=motionblurmode; + motionbluramount=200/(findLengthfast(&player[0].velocity)); + changed=1; + } + if(player[0].damage-player[0].superpermanentdamage>(player[0].damagetolerance-player[0].superpermanentdamage)*1/2&&damageeffects&&!cameramode){ + drawmode=doublevisionmode; + changed=1; + } + } + + if(slomo&&!loading){ + if(ismotionblur) + drawmode=motionblurmode; + motionbluramount=.2; + slomodelay-=multiplier; + if(slomodelay<0)slomo=0; + camerashake=0; + changed=1; + } + if((!changed&&!slomo)||loading){ + drawmode=normalmode; + if(ismotionblur&&(/*fps>100||*/alwaysblur)){ + if(olddrawmode!=realmotionblurmode)change=1; + else change=0; + drawmode=realmotionblurmode; + } + else if(olddrawmode==realmotionblurmode)change=2; + else change=0; + } + + if(freeze||winfreeze||(mainmenu&&gameon)||(!gameon&&gamestarted))drawmode=normalmode; + if((freeze||winfreeze)&&ismotionblur&&!mainmenu)drawmode=radialzoommode; + + if(winfreeze||mainmenu)drawmode=normalmode; + + //drawmode=glowmode; + if(drawmode==glowmode){ + RGBColor color2; + color2.red=0; + color2.green=0; + color2.blue=0; +#ifndef WIN32 + DSpContext_FadeGamma(NULL,200,&color2); +#endif + } + + if(drawtoggle!=2)drawtoggle=1-drawtoggle; + + if(!texcoordwidth){ + + texviewwidth=kTextureSize; + if(texviewwidth>screenwidth)texviewwidth=screenwidth; + texviewheight=kTextureSize; + if(texviewheight>screenheight)texviewheight=screenheight; + + texcoordwidth=screenwidth/kTextureSize; + texcoordheight=screenheight/kTextureSize; + if(texcoordwidth>1)texcoordwidth=1; + if(texcoordheight>1)texcoordheight=1; + } + + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + + /*if(environment==desertenvironment)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, (float)(abs(Random()%100))/50 ); + else glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0); + */ + if(abs(blurness-targetblurness)2){ + blurness=targetblurness; + targetblurness=(float)(abs(Random()%100))/40; + } + if(blurnesstargetblurness)blurness-=multiplier*5; + + //glFinish(); + static XYZ terrainlight; + static float distance; + //if(drawmode==normalmode)ReSizeGLScene(90,.1); + if(drawmode==normalmode)ReSizeGLScene(90,.1f); + if(drawmode!=normalmode)glViewport(0,0,texviewwidth,texviewheight); + glDepthFunc(GL_LEQUAL); + glDepthMask(1); + glAlphaFunc(GL_GREATER, 0.0001f); + glEnable(GL_ALPHA_TEST); + glClearColor(0.25f, 0.25f, 0.25f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_MODELVIEW); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glLoadIdentity (); + if(!cameramode&&!freeze&&!winfreeze){ + glRotatef(float(Random()%100)/10*camerashake/*+(woozy*woozy)/10*/,0,0,1); + glRotatef(rotation2+sin(woozy/2)*(player[0].damage/player[0].damagetolerance)*5,1,0,0); + glRotatef(rotation+sin(woozy)*(player[0].damage/player[0].damagetolerance)*5,0,1,0); + } + if(cameramode||freeze||winfreeze){ + //glRotatef(float(Random()%100)/10*camerashake/*+(woozy*woozy)/10*/,0,0,1); + glRotatef(rotation2,1,0,0); + glRotatef(rotation,0,1,0); + } + + if(environment==desertenvironment){ + glRotatef((float)(abs(Random()%100))/3000-1,1,0,0); + glRotatef((float)(abs(Random()%100))/3000-1,0,1,0); + //glRotatef(blurness/40-1,1,0,0); + //glRotatef(blurness/40-1,0,1,0); + } + SetUpLight(&light,0); + glPushMatrix(); + if(environment==desertenvironment&&detail==2)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness+.4 ); + if(environment==desertenvironment){ + glRotatef((float)(abs(Random()%100))/1000,1,0,0); + glRotatef((float)(abs(Random()%100))/1000,0,1,0); + } + skybox.draw(); + glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0); + glPopMatrix(); + glTranslatef(-viewer.x,-viewer.y,-viewer.z); + frustum.GetFrustum(); + + //Make Shadow + static XYZ point; + static float size,opacity,rotation; + rotation=0; + for(k=0;k=typesleeping)&&player[k].playerdetail) + if(frustum.SphereInFrustum(player[k].coords.x,player[k].coords.y,player[k].coords.z,player[k].scale*5)&&player[k].occluded<25) + for(i=0;i=1)glDisable(GL_BLEND); + if(distance>=.5){ + checkpoint=DoRotation(player[k].skeleton.joints[abs(Random()%player[k].skeleton.num_joints)].position,0,player[k].rotation,0)*player[k].scale+player[k].coords; + checkpoint.y+=1; + if(!player[k].occluded==0)i=checkcollide(viewer,checkpoint,player[k].lastoccluded); + if(i==-1||player[k].occluded==0)i=checkcollide(viewer,checkpoint); + if(i!=-1){ + player[k].occluded+=1; + player[k].lastoccluded=i; + } + else player[k].occluded=0; + if(player[k].occluded<25)player[k].DrawSkeleton(); + } + } + } + } + + if(!cameramode&&musictype==stream_music2)playerdist=findDistancefastflat(&player[0].coords,&viewer); + else playerdist=-100; + glPushMatrix(); + glCullFace(GL_BACK); + glEnable(GL_TEXTURE_2D); + objects.Draw(); + glPopMatrix(); + + glPushMatrix(); + if(frustum.SphereInFrustum(realhawkcoords.x+hawk.boundingspherecenter.x,realhawkcoords.y+hawk.boundingspherecenter.y,realhawkcoords.z+hawk.boundingspherecenter.z,2)){ + glAlphaFunc(GL_GREATER, 0.0001f); + glDepthMask(1); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + glTranslatef(hawkcoords.x,hawkcoords.y,hawkcoords.z); + glRotatef(hawkrotation,0,1,0); + glTranslatef(25,0,0); + distance=findDistancefast(&viewer,&realhawkcoords)*1.2; + glColor4f(light.color[0],light.color[1],light.color[2],(viewdistance*viewdistance-(distance-(viewdistance*viewdistance*fadestart))*(1/(1-fadestart)))/viewdistance/viewdistance); + if((viewdistance*viewdistance-(distance-(viewdistance*viewdistance*fadestart))*(1/(1-fadestart)))/viewdistance/viewdistance>1)glColor4f(light.color[0],light.color[1],light.color[2],1); + if((viewdistance*viewdistance-(distance-(viewdistance*viewdistance*fadestart))*(1/(1-fadestart)))/viewdistance/viewdistance>0) + hawk.drawdifftex(hawktexture); + } + glPopMatrix(); + + //if(cellophane){ + /*glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glDepthMask(1); + for(k=0;k=1)glDisable(GL_BLEND); + if(distance>0){ + checkpoint=DoRotation(player[k].skeleton.joints[abs(Random()%player[k].skeleton.num_joints)].position,0,player[k].rotation,0)*player[k].scale+player[k].coords; + checkpoint.y+=1; + if(checkcollide(viewer,checkpoint)){ + player[k].occluded+=1; + } + else player[k].occluded=0; + if(player[k].occluded<25)player[k].DrawSkeleton(); + } + }*/ + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glDepthMask(1); + for(k=0;k=1)glDisable(GL_BLEND); + if(distance>=.5){ + checkpoint=DoRotation(player[k].skeleton.joints[abs(Random()%player[k].skeleton.num_joints)].position,0,player[k].rotation,0)*player[k].scale+player[k].coords; + checkpoint.y+=1; + if(!player[k].occluded==0)i=checkcollide(viewer,checkpoint,player[k].lastoccluded); + if(i==-1||player[k].occluded==0)i=checkcollide(viewer,checkpoint); + if(i!=-1){ + player[k].occluded+=1; + player[k].lastoccluded=i; + } + else player[k].occluded=0; + if(player[k].occluded<25)player[k].DrawSkeleton(); + } + } + } + //} + + glPushMatrix(); + glEnable(GL_TEXTURE_2D); + weapons.Draw(); + glPopMatrix(); + glCullFace(GL_BACK); + + glDisable(GL_COLOR_MATERIAL); + + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + + glDepthMask(0); + + sprites.Draw(); + + if(editorenabled){ + glEnable(GL_BLEND); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_COLOR_MATERIAL); + glColor4f(1,1,0,1); + + for(k=0;k1){ + glBegin(GL_LINE_LOOP); + for(i=0;i1){ + glColor4f(0,1,0,1); + for(k=0;k0&&bonustime<1&&!winfreeze&&indialogue==-1/*bonustime<4*/){ + if(bonus==tracheotomy)sprintf (string, "Tracheotomy!"); + else if(bonus==backstab)sprintf (string, "Backstabber!"); + else if(bonus==spinecrusher)sprintf (string, "Spinecrusher!"); + else if(bonus==ninja)sprintf (string, "Ninja Bonus!"); + else if(bonus==style)sprintf (string, "Style Bonus!"); + else if(bonus==cannon)sprintf (string, "Leg Cannon!"); + else if(bonus==aimbonus)sprintf (string, "Nice Aim!"); + else if(bonus==deepimpact)sprintf (string, "Heavy Impact!"); + else if(bonus==touchofdeath)sprintf (string, "Touch of Death!"); + else if(bonus==swordreversebonus)sprintf (string, "Sword Disarm!"); + else if(bonus==staffreversebonus)sprintf (string, "Staff Disarm!"); + else if(bonus==reverseko)sprintf (string, "Reversal KO!"); + else if(bonus==solidhit)sprintf (string, "Solid Hit!"); + else if(bonus==twoxcombo)sprintf (string, "2X Combo!"); + else if(bonus==threexcombo)sprintf (string, "3X Combo!"); + else if(bonus==fourxcombo)sprintf (string, "4X COMBO!"); + else if(bonus==megacombo)sprintf (string, "MEGA COMBO!"); + else if(bonus==Reversal)sprintf (string, "Reversal!"); + else if(bonus==Stabbonus)sprintf (string, "Punctured!"); + else if(bonus==Slicebonus)sprintf (string, "Sliced!"); + else if(bonus==Bullseyebonus)sprintf (string, "Bullseye!"); + else if(bonus==Slashbonus)sprintf (string, "Slashed!"); + else if(bonus==Wolfbonus)sprintf (string, "WOLF SLAYER!"); + else if(bonus==FinishedBonus)sprintf (string, "SLAIN!"); + else if(bonus==TackleBonus)sprintf (string, "Tackle!"); + else if(bonus==AboveBonus)sprintf (string, "Death from Above!"); + else sprintf (string, "Excellent!"); + + glColor4f(0,0,0,1-bonustime); + text.glPrintOutline(1024/2-10*strlen(string)-4,768/16-4+768*4/5,string,1,2.5,1024,768); + glColor4f(1,0,0,1-bonustime); + text.glPrint(1024/2-10*strlen(string),768/16+768*4/5,string,1,2,1024,768); + + sprintf (string, "%d",(int)bonusvalue); + glColor4f(0,0,0,1-bonustime); + text.glPrintOutline(1024/2-10*strlen(string)-4,768/16-4-20+768*4/5,string,1,2.5*.8,1024,768); + glColor4f(1,0,0,1-bonustime); + text.glPrint(1024/2-10*strlen(string),768/16-20+768*4/5,string,1,2*.8,1024,768); + glColor4f(.5,.5,.5,1); + } + + if(tutoriallevel==1){ + tutorialopac=tutorialmaxtime-tutorialstagetime; + if(tutorialopac>1)tutorialopac=1; + if(tutorialopac<0)tutorialopac=0; + + sprintf (string, " "); + sprintf (string2, " "); + sprintf (string3, " "); + if(tutorialstage==0){ + sprintf (string, " "); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==1){ + sprintf (string, "Welcome to the Lugaru training level!"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==2){ + sprintf (string, "BASIC MOVEMENT:"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==3){ + sprintf (string, "You can move the mouse to rotate the camera."); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==4){ + sprintf (string, "Try using the %s, %s, %s and %s keys to move around.",KeyToChar(forwardkey),KeyToChar(leftkey),KeyToChar(backkey),KeyToChar(rightkey)); + sprintf (string2, "All movement is relative to the camera."); + sprintf (string3, " "); + } + if(tutorialstage==5){ + sprintf (string, "Please press %s to jump.",KeyToChar(jumpkey)); + sprintf (string2, "You can hold it longer to jump higher."); + sprintf (string3, " "); + } + if(tutorialstage==6){ + sprintf (string, "You can press %s to crouch.",KeyToChar(crouchkey)); + sprintf (string2, "You can jump higher from a crouching position."); + sprintf (string3, " "); + } + if(tutorialstage==7){ + sprintf (string, "While running, you can press %s to roll.",KeyToChar(crouchkey)); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==8){ + sprintf (string, "While crouching, you can sneak around silently"); + sprintf (string2, "using the movement keys."); + sprintf (string3, " "); + } + if(tutorialstage==9){ + sprintf (string, "Release the crouch key while sneaking and hold the movement keys"); + sprintf (string2, "to run animal-style."); + sprintf (string3, " "); + } + if(tutorialstage==10){ + sprintf (string, "ADVANCED MOVEMENT:"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==11){ + sprintf (string, "When you jump at a wall, you can hold %s again",KeyToChar(jumpkey)); + sprintf (string2, "during impact to perform a walljump."); + sprintf (string3, "Be sure to use the movement keys to press against the wall"); + } + if(tutorialstage==12){ + sprintf (string, "While in the air, you can press crouch to flip.",KeyToChar(jumpkey)); + sprintf (string2, "Walljumps and flips confuse enemies and give you more control."); + sprintf (string3, " "); + } + if(tutorialstage==13){ + sprintf (string, "BASIC COMBAT:"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==14){ + sprintf (string, "There is now an imaginary enemy"); + sprintf (string2, "in the middle of the training area."); + sprintf (string3, " "); + } + if(tutorialstage==15){ + if(attackkey==MAC_MOUSEBUTTON1)sprintf (string, "Click to attack when you are near an enemy."); + else sprintf (string, "Press %s to attack when you are near an enemy.",KeyToChar(attackkey)); + sprintf (string2, "You can punch by standing still near an enemy and attacking."); + sprintf (string3, " "); + } + if(tutorialstage==16){ + sprintf (string, "If you are close, you will perform a weak punch."); + sprintf (string2, "The weak punch is excellent for starting attack combinations."); + sprintf (string3, " "); + } + if(tutorialstage==17){ + sprintf (string, "Attacking while running results in a spin kick."); + sprintf (string2, "This is one of your most powerful ground attacks."); + sprintf (string3, " "); + } + if(tutorialstage==18){ + sprintf (string, "Sweep the enemy's legs out by attacking while crouched."); + sprintf (string2, "This is a very fast attack, and easy to follow up."); + sprintf (string3, " "); + } + if(tutorialstage==19){ + sprintf (string, "When an enemy is on the ground, you can deal some extra"); + sprintf (string2, "damage by running up and drop-kicking him."); + sprintf (string3, "(Try knocking them down with a sweep first)"); + } + if(tutorialstage==20){ + sprintf (string, "Your most powerful individual attack is the rabbit kick."); + if(attackkey==MAC_MOUSEBUTTON1)sprintf (string2, "Run at the enemy while holding the mouse button, and press"); + else sprintf (string2, "Run at the enemy while holding %s, and press", KeyToChar(attackkey)); + sprintf (string3, "the jump key (%s) to attack.",KeyToChar(jumpkey)); + } + if(tutorialstage==21){ + sprintf (string, "This attack is devastating if timed correctly."); + sprintf (string2, "Even if timed incorrectly, it will knock the enemy over."); + if(againbonus)sprintf (string3, "Try rabbit-kicking the imaginary enemy again."); + else sprintf (string3, "Try rabbit-kicking the imaginary enemy."); + } + if(tutorialstage==22){ + sprintf (string, "If you sneak behind an enemy unnoticed, you can kill"); + sprintf (string2, "him instantly. Move close behind this enemy"); + sprintf (string3, "and attack."); + } + if(tutorialstage==23){ + sprintf (string, "Another important attack is the wall kick. When an enemy"); + sprintf (string2, "is near a wall, perform a walljump nearby and hold"); + sprintf (string3, "the attack key during impact with the wall."); + } + if(tutorialstage==24){ + sprintf (string, "You can tackle enemies by running at them animal-style"); + if(attackkey==MAC_MOUSEBUTTON1)sprintf (string2, "and pressing jump (%s) or attack(mouse button).",KeyToChar(jumpkey)); + else sprintf (string2, "and pressing jump (%s) or attack(%s).",KeyToChar(jumpkey),KeyToChar(attackkey)); + sprintf (string3, "This is especially useful when they are running away."); + } + if(tutorialstage==25){ + sprintf (string, "Dodge by pressing back and attack. Dodging is essential"); + sprintf (string2, "against enemies with swords or other long weapons."); + sprintf (string3, " "); + } + if(tutorialstage==26){ + sprintf (string, "REVERSALS AND COUNTER-REVERSALS"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==27){ + sprintf (string, "The enemy can now reverse your attacks."); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==28){ + sprintf (string, "If you attack, you will notice that the enemy now sometimes"); + sprintf (string2, "catches your attack and uses it against you. Hold"); + sprintf (string3, "crouch (%s) after attacking to escape from reversals.",KeyToChar(crouchkey)); + } + if(tutorialstage==29){ + sprintf (string, "Try escaping from two more reversals in a row."); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==30){ + sprintf (string, "Good!"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==31){ + sprintf (string, "To reverse an attack, you must tap crouch (%s) during the",KeyToChar(crouchkey)); + sprintf (string2, "enemy's attack. You must also be close to the enemy;"); + sprintf (string3, "this is especially important against armed opponents."); + } + if(tutorialstage==32){ + sprintf (string, "The enemy can attack in %d seconds.", (int)(tutorialmaxtime-tutorialstagetime)); + sprintf (string2, "This imaginary opponents attacks will be highlighted"); + sprintf (string3, "to make this easier."); + } + if(tutorialstage==33){ + sprintf (string, "Reverse three enemy attacks!"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==34){ + sprintf (string, "Reverse two more enemy attacks!"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==35){ + sprintf (string, "Reverse one more enemy attack!"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==36){ + sprintf (string, "Excellent!"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==37){ + sprintf (string, "Now spar with the enemy for %d more seconds.", (int)(tutorialmaxtime-tutorialstagetime)); + sprintf (string2, "Damage dealt: %d",(int)damagedealt); + sprintf (string3, "Damage taken: %d.",(int)damagetaken); + } + if(tutorialstage==38){ + sprintf (string, "WEAPONS:"); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==39){ + sprintf (string, "There is now an imaginary knife"); + sprintf (string2, "in the center of the training area."); + sprintf (string3, " "); + } + if(tutorialstage==40){ + sprintf (string, "Stand, roll or handspring over the knife"); + sprintf (string2, "while pressing %s to pick it up.",KeyToChar(throwkey)); + sprintf (string3, "You can crouch and press the same key to drop it again."); + } + if(tutorialstage==41){ + sprintf (string, "You can equip and unequip weapons using the %s key.",KeyToChar(drawkey)); + sprintf (string2, "Sometimes it is best to keep them unequipped to"); + sprintf (string3, "prevent enemies from taking them. "); + } + if(tutorialstage==42){ + sprintf (string, "The knife is the smallest weapon and the least encumbering."); + sprintf (string2, "You can equip or unequip it while standing, crouching,"); + sprintf (string3, "running or flipping."); + } + if(tutorialstage==43){ + sprintf (string, "You perform weapon attacks the same way as unarmed attacks,"); + sprintf (string2, "but sharp weapons cause permanent damage, instead of the"); + sprintf (string3, "temporary trauma from blunt weapons, fists and feet."); + } + if(tutorialstage==44){ + sprintf (string, "The enemy now has your knife!"); + sprintf (string2, "Please reverse two of his knife attacks."); + sprintf (string3, " "); + } + if(tutorialstage==45){ + sprintf (string, "Please reverse one more of his knife attacks."); + sprintf (string2, " "); + sprintf (string3, " "); + } + if(tutorialstage==46){ + sprintf (string, "Now he has a sword!"); + sprintf (string2, "The sword has longer reach than your arms, so you"); + sprintf (string3, "must move close to reverse the sword slash."); + } + if(tutorialstage==47){ + sprintf (string, "Long weapons like the sword and staff are also useful for defense;"); + sprintf (string2, "you can parry enemy weapon attacks by pressing the attack key"); + sprintf (string3, "at the right time. Please try parrying the enemy's attacks!"); + } + if(tutorialstage==48){ + sprintf (string, "The staff is like the sword, but has two main attacks."); + sprintf (string2, "The standing smash is fast and effective, and the running"); + sprintf (string3, "spin smash is slower and more powerful."); + } + if(tutorialstage==49){ + sprintf (string, "When facing an enemy, you can throw the knife with %s.",KeyToChar(throwkey)); + sprintf (string2, "It is possible to throw the knife while flipping,"); + sprintf (string3, "but it is very inaccurate."); + } + if(tutorialstage==50){ + sprintf (string, "You now know everything you can learn from training."); + sprintf (string2, "Everything else you must learn from experience!"); + sprintf (string3, " "); + } + if(tutorialstage==51){ + sprintf (string, "Walk out of the training area to return to the main menu."); + sprintf (string2, " "); + sprintf (string3, " "); + } + + glColor4f(0,0,0,tutorialopac); + text.glPrintOutline(screenwidth/2-7.6*strlen(string)*screenwidth/1024-4,screenheight/16-4+screenheight*4/5,string,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight); + text.glPrintOutline(screenwidth/2-7.6*strlen(string2)*screenwidth/1024-4,screenheight/16-4+screenheight*4/5-20*screenwidth/1024,string2,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight); + text.glPrintOutline(screenwidth/2-7.6*strlen(string3)*screenwidth/1024-4,screenheight/16-4+screenheight*4/5-40*screenwidth/1024,string3,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight); + glColor4f(1,1,1,tutorialopac); + text.glPrint(screenwidth/2-7.6*strlen(string)*screenwidth/1024,screenheight/16+screenheight*4/5,string,1,1.5*screenwidth/1024,screenwidth,screenheight); + text.glPrint(screenwidth/2-7.6*strlen(string2)*screenwidth/1024,screenheight/16+screenheight*4/5-20*screenwidth/1024,string2,1,1.5*screenwidth/1024,screenwidth,screenheight); + text.glPrint(screenwidth/2-7.6*strlen(string3)*screenwidth/1024,screenheight/16+screenheight*4/5-40*screenwidth/1024,string3,1,1.5*screenwidth/1024,screenwidth,screenheight); + + sprintf (string, "Press 'tab' to skip to the next item.",KeyToChar(jumpkey)); + sprintf (string2, "Press escape at any time to"); + sprintf (string3, "pause or exit the tutorial."); + + glColor4f(0,0,0,1); + text.glPrintOutline(screenwidth/2-7.6*strlen(string)*screenwidth/1024*.8-4,0-4+screenheight*1/10,string,1,1.5*1.25*screenwidth/1024*.8,screenwidth,screenheight); + text.glPrintOutline(screenwidth/2-7.6*strlen(string2)*screenwidth/1024*.8-4,0-4+screenheight*1/10-20*.8*screenwidth/1024,string2,1,1.5*1.25*screenwidth/1024*.8,screenwidth,screenheight); + text.glPrintOutline(screenwidth/2-7.6*strlen(string3)*screenwidth/1024*.8-4,0-4+screenheight*1/10-40*.8*screenwidth/1024,string3,1,1.5*1.25*screenwidth/1024*.8,screenwidth,screenheight); + glColor4f(0.5,0.5,0.5,1); + text.glPrint(screenwidth/2-7.6*strlen(string)*screenwidth/1024*.8,0+screenheight*1/10,string,1,1.5*screenwidth/1024*.8,screenwidth,screenheight); + text.glPrint(screenwidth/2-7.6*strlen(string2)*screenwidth/1024*.8,0+screenheight*1/10-20*.8*screenwidth/1024,string2,1,1.5*screenwidth/1024*.8,screenwidth,screenheight); + text.glPrint(screenwidth/2-7.6*strlen(string3)*screenwidth/1024*.8,0+screenheight*1/10-40*.8*screenwidth/1024,string3,1,1.5*screenwidth/1024*.8,screenwidth,screenheight); + } + //Hot spots + + if(numhotspots&&(bonustime>=1||bonus<=0||bonustime<0)&&!tutoriallevel){ + int closest=-1; + float closestdist=-1; + float distance=0; + closest=currenthotspot; + for(i=0;i=0)||(hotspottype[i]<=40&&hotspottype[i]>=20))){ + closestdist=distance; + closest=i; + } + } + } + if(closest!=-1) + currenthotspot=closest; + if(currenthotspot!=-1){ + if(hotspottype[closest]<=10){ + if(findDistancefast(&player[0].coords,&hotspot[closest])1)tutorialopac=1; + if(tutorialopac<0)tutorialopac=0; + + sprintf (string, "%s", hotspottext[closest]); + + int lastline; + int line=0; + bool done=0; + lastline=0; + i=0; + while(!done){ + if(string[i]=='\n'||string[i]>'z'||string[i]<' '||string[i]=='\0'){ + glColor4f(0,0,0,tutorialopac); + text.glPrintOutline(screenwidth/2-7.6*(i-lastline)*screenwidth/1024-4,screenheight/16-4+screenheight*4/5-20*screenwidth/1024*line,string,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight,lastline,i); + glColor4f(1,1,1,tutorialopac); + text.glPrint(screenwidth/2-7.6*(i-lastline)*screenwidth/1024,screenheight/16+screenheight*4/5-20*screenwidth/1024*line,string,1,1.5*screenwidth/1024,screenwidth,screenheight,lastline,i); + lastline=i+1; + line++; + if(string[i]=='\0')done=1; + } + if(i>=255)done=1; + i++; + } + } + else if (hotspottype[closest]>=20&&dialoguegonethrough[hotspottype[closest]-20]==0){ + whichdialogue=hotspottype[closest]-20; + for(j=0;j2)if(tempname[tempnum-2]=='e'&&tempname[tempnum-1]=='r')goodchar=0; + //if(tempnum>2)if(tempname[tempnum]=='r'&&tempname[0]=='a')goodchar=0; + if(goodchar)tempnum++; + else tempname[tempnum]='\0'; + } + + sprintf (string, "%s: ", tempname); + + if(dialogueboxcolor[whichdialogue][indialogue][0]+dialogueboxcolor[whichdialogue][indialogue][1]+dialogueboxcolor[whichdialogue][indialogue][2]<1.5){ + glColor4f(0,0,0,tutorialopac); + text.glPrintOutline(startx-2*7.6*strlen(string)*screenwidth/1024-4,starty-4,string,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight); + glColor4f(0.7,0.7,0.7,tutorialopac); + text.glPrint(startx-2*7.6*strlen(string)*screenwidth/1024,starty,string,1,1.5*screenwidth/1024,screenwidth,screenheight); + } + else + { + glColor4f(0,0,0,tutorialopac); + text.glPrintOutline(startx-2*7.6*strlen(string)*screenwidth/1024-4,starty-4,string,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight); + + } + + tempnum=0; + for(i=0;i<(int)strlen(dialoguetext[whichdialogue][indialogue])+1;i++){ + tempname[tempnum]=dialoguetext[whichdialogue][indialogue][i]; + if(dialoguetext[whichdialogue][indialogue][i]!='#')tempnum++; + } + + + sprintf (string, "%s", tempname); + + + int lastline; + int line=0; + bool done=0; + lastline=0; + i=0; + while(!done){ + if(string[i]=='\n'||string[i]>'z'||string[i]<' '||string[i]=='\0'){ + if(dialogueboxcolor[whichdialogue][indialogue][0]+dialogueboxcolor[whichdialogue][indialogue][1]+dialogueboxcolor[whichdialogue][indialogue][2]<1.5){ + glColor4f(0,0,0,tutorialopac); + text.glPrintOutline(startx/*-7.6*(i-lastline)*screenwidth/1024*/-4,starty-4-20*screenwidth/1024*line,string,1,1.5*1.25*screenwidth/1024,screenwidth,screenheight,lastline,i); + glColor4f(1,1,1,tutorialopac); + text.glPrint(startx/*-7.6*(i-lastline)*screenwidth/1024*/,starty-20*screenwidth/1024*line,string,1,1.5*screenwidth/1024,screenwidth,screenheight,lastline,i); + } + else + { + glColor4f(0,0,0,tutorialopac); + text.glPrint(startx/*-7.6*(i-lastline)*screenwidth/1024*/,starty-20*screenwidth/1024*line,string,1,1.5*screenwidth/1024,screenwidth,screenheight,lastline,i); + } + lastline=i+1; + line++; + if(string[i]=='\0')done=1; + } + if(i>=255)done=1; + i++; + } + } + + if(!tutoriallevel&&!winfreeze&&indialogue==-1&&!mainmenu){ + if(campaign){ + if(!scoreadded)sprintf (string, "Score: %d", (int)accountcampaignscore[accountactive]+(int)bonustotal);//(int)bonustotal); + if(scoreadded)sprintf (string, "Score: %d", (int)accountcampaignscore[accountactive]);//(int)bonustotal); + } + if(!campaign)sprintf (string, "Score: %d", (int)bonustotal); + glColor4f(0,0,0,1); + text.glPrintOutline(1024/40-4,768/16-4+768*14/16,string,1,1.5*1.25,1024,768); + glColor4f(1,0,0,1); + text.glPrint(1024/40,768/16+768*14/16,string,1,1.5,1024,768); + } + + glColor4f(.5,.5,.5,1); + + + if((texttoggle||editorenabled)&&debugmode&&!mainmenu){ + sprintf (string, "The framespersecond is %d.",(int)(fps)); + text.glPrint(10,30,string,0,.8,1024,768); + + sprintf (string, "Name: %s", registrationname); + text.glPrint(10,260,string,0,.8,1024,768); + + + if(editorenabled)sprintf (string, "Map editor enabled."); + if(!editorenabled)sprintf (string, "Map editor Disabled."); + text.glPrint(10,60,string,0,.8,1024,768); + if(editorenabled){ + sprintf (string, "Object size: %f",editorsize); + text.glPrint(10,75,string,0,.8,1024,768); + if(editorrotation>=0)sprintf (string, "Object rotation: %f",editorrotation); + else sprintf (string, "Object rotation: Random"); + text.glPrint(10,90,string,0,.8,1024,768); + if(editorrotation2>=0)sprintf (string, "Object rotation2: %f",editorrotation2); + else sprintf (string, "Object rotation2: Random"); + text.glPrint(10,105,string,0,.8,1024,768); + sprintf (string, "Object type: %d",editortype); + text.glPrint(10,120,string,0,.8,1024,768); + if(editortype==boxtype)sprintf (string, "(box)"); + if(editortype==treetrunktype)sprintf (string, "(tree)"); + if(editortype==walltype)sprintf (string, "(wall)"); + if(editortype==weirdtype)sprintf (string, "(weird)"); + if(editortype==spiketype)sprintf (string, "(spike)"); + if(editortype==rocktype)sprintf (string, "(rock)"); + if(editortype==bushtype)sprintf (string, "(bush)"); + if(editortype==tunneltype)sprintf (string, "(tunnel)"); + if(editortype==chimneytype)sprintf (string, "(chimney)"); + if(editortype==platformtype)sprintf (string, "(platform)"); + if(editortype==cooltype)sprintf (string, "(cool)"); + if(editortype==firetype)sprintf (string, "(fire)"); + text.glPrint(130,120,string,0,.8,1024,768); + + sprintf (string, "Numplayers: %d",numplayers); + text.glPrint(10,155,string,0,.8,1024,768); + sprintf (string, "Player %d: numwaypoints: %d",numplayers,player[numplayers-1].numwaypoints); + text.glPrint(10,140,string,0,.8,1024,768); + } + /*sprintf (string, "Coords are: %f %f %f",player[0].coords.x,player[0].coords.y,player[0].coords.z); + text.glPrint(10,200,string,0,.8,1024,768);*/ + sprintf (string, "Difficulty: %d",difficulty); + text.glPrint(10,240,string,0,.8,1024,768); + /* + sprintf (string, "lasthotspot: %d",hotspottype[numhotspots-1]); + text.glPrint(10,240,string,0,.8,1024,768); + sprintf (string, "killhotspot: %d",killhotspot); + text.glPrint(10,220,string,0,.8,1024,768); + sprintf (string, "winhotspot: %d",winhotspot); + text.glPrint(10,200,string,0,.8,1024,768);*/ + + } + } + + if(drawmode==glowmode){ + 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,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,.5); + 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((((blackout&&damageeffects)||(player[0].bloodloss>0&&damageeffects&&player[0].blooddimamount>0)||player[0].dead)&&!cameramode)||console){ + 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,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); + if(player[0].dead)blackout+=multiplier*3; + if(player[0].dead==1)blackout=.4f; + if(player[0].dead==2&&blackout>.6)blackout=.6; + glColor4f(0,0,0,blackout); + if(!player[0].dead){ + if((player[0].bloodloss/player[0].damagetolerance*(sin(woozy)/4+.5))*.3<.3){ + glColor4f(0,0,0,player[0].blooddimamount*player[0].bloodloss/player[0].damagetolerance*(sin(woozy)/4+.5)*.3); + blackout=player[0].blooddimamount*player[0].bloodloss/player[0].damagetolerance*(sin(woozy)/4+.5)*.3; + } + else { + glColor4f(0,0,0,player[0].blooddimamount*.3); + blackout=player[0].blooddimamount*.3; + } + } + if(console)glColor4f(.7,0,0,.2); + 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(flashamount>0&&damageeffects){ + if(flashamount>1)flashamount=1; + if(flashdelay<=0)flashamount-=multiplier; + flashdelay--; + 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(!console){ + displaytime[0]=0; + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + if(chatting){ + sprintf (string, " ]"); + text.glPrint(10,30+screenheight-330,string,0,1,screenwidth,screenheight); + if(displayblink){ + sprintf (string, "_"); + text.glPrint(30+(float)(displayselected)*10,30+(screenheight-330),string,0,1,screenwidth,screenheight); + } + } + for(i=0;i<15;i++){ + if((i!=0||chatting)&&displaytime[i]<4) + for(j=0;jmaxdistance){ + whichclosest=i; + maxdistance=tempdist; + } + } + for(i=0;imaxdistance){ + whichclosest=i; + maxdistance=tempdist; + } + } + } + radius=fast_sqrt(maxdistance); + + radius=110; + + glScalef(.25/radius*256*terrain.scale*.4,.25/radius*256*terrain.scale*.4,1); + glPushMatrix(); + glScalef(1/(1/radius*256*terrain.scale*.4),1/(1/radius*256*terrain.scale*.4),1); + /*float startx,starty,endx,endy; + glBegin(GL_QUADS); + glTexCoord2f(1-(center.x-radius)/terrain.scale/256,(center.z-radius)/terrain.scale/256); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1-(center.x+radius)/terrain.scale/256,(center.z-radius)/terrain.scale/256); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1-(center.x+radius)/terrain.scale/256,(center.z+radius)/terrain.scale/256); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(1-(center.x-radius)/terrain.scale/256,(center.z+radius)/terrain.scale/256); + glVertex3f(-1, 1, 0.0f); + glEnd();*/ + glPopMatrix(); + glRotatef(player[0].lookrotation*-1+180,0,0,1); + glTranslatef(-(center.x/terrain.scale/256*-2+1),(center.z/terrain.scale/256*-2+1),0); + for(i=0;itypesleeping)glColor4f(0,0,0,opac*(1-distcheck/mapviewdist)); + else if(player[i].dead)glColor4f(.3,.3,.3,opac*(1-distcheck/mapviewdist)); + else if(player[i].aitype==attacktypecutoff)glColor4f(1,0,0,opac*(1-distcheck/mapviewdist)); + else if(player[i].aitype==passivetype)glColor4f(0,1,0,opac*(1-distcheck/mapviewdist)); + else glColor4f(1,1,0,1); + glTranslatef(player[i].coords.x/terrain.scale/256*-2+1,player[i].coords.z/terrain.scale/256*2-1,0); + glRotatef(player[i].rotation+180,0,0,1); + glScalef(.005,.005,.005); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + /*glBegin(GL_TRIANGLES); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(0, 1, 0.0f); + glEnd();*/ + glPopMatrix(); + } + } + /*glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd();*/ + glPopMatrix(); + 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); + } + + /*if(loading){ + loading=2; + drawmode=normalmode; + }*/ + + + if(loading&&!stealthloading&&(!campaign||player[0].dead)){ + 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,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,.7); + 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); + + //logo + glDisable(GL_DEPTH_TEST); + glColor3f (1.0, 1.0, 1.0); // no coloring + + glEnable(GL_TEXTURE_2D); + /*glBindTexture( GL_TEXTURE_2D, logotexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + 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((float)screenwidth/2,(float)screenwidth/2,1); + glTranslatef(1.8,1.25,0); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glColor4f(1,1,1,1); + glPushMatrix(); + glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + 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);*/ + + //Minimap + + if(loading!=4){ + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + sprintf (string, "Loading..."); + text.glPrint(1024/2-90,768/2,string,1,2,1024,768); + } + loading=2; + //if(ismotionblur)drawmode=motionblurmode; + drawmode=normalmode; + } + + if(winfreeze&&!campaign){ + 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,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,.4); + 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); + + //logo + glDisable(GL_DEPTH_TEST); + glColor3f (1.0, 1.0, 1.0); // no coloring + + glEnable(GL_TEXTURE_2D); + /*glBindTexture( GL_TEXTURE_2D, logotexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + 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((float)screenwidth/2,(float)screenwidth/2,1); + glTranslatef(1.8,1.25,0); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glColor4f(1,1,1,1); + glPushMatrix(); + glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + 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);*/ + + //Awards + int numawards; + int awards[30]; + numawards=0; + + if(damagetaken==0&&player[0].bloodloss==0){ + awards[numawards]=awardflawless; + numawards++; + } + bool alldead; + alldead=1; + if(numplayers>1) + for(i=1;i1) + for(i=1;i0){ + awards[numawards]=awardbojutsu; + numawards++; + } + if(numattacks==numswordattack&&numattacks>0){ + awards[numawards]=awardswordsman; + numawards++; + } + if(numattacks==numknifeattack&&numattacks>0){ + awards[numawards]=awardknifefighter; + numawards++; + } + if(numattacks==numunarmedattack&&numthrowkill==0&&weapons.numweapons>0){ + awards[numawards]=awardkungfu; + numawards++; + } + if(numescaped>0){ + awards[numawards]=awardevasion; + numawards++; + } + if(numflipfail==0&&numflipped+numwallflipped*2>20){ + awards[numawards]=awardacrobat; + numawards++; + } + if(numthrowkill==numplayers-1){ + awards[numawards]=awardlongrange; + numawards++; + } + alldead=1; + if(numplayers>1) + for(i=1;i0&&alldead){ + awards[numawards]=awardbrutal; + numawards++; + } + if(numreversals>((float)numattacks)*.8&&numreversals>3){ + awards[numawards]=awardaikido; + numawards++; + } + if(maxalarmed==1&&numplayers>2){ + awards[numawards]=awardstrategy; + numawards++; + } + if(numflipfail>3){ + awards[numawards]=awardklutz; + numawards++; + } + + + //Win Screen Won Victory + + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + sprintf (string, "Level Cleared!"); + text.glPrintOutlined(1024/2-strlen(string)*10,768*7/8,string,1,2,1024,768); + + sprintf (string, "Score: %d",(int)(bonustotal-startbonustotal)); + text.glPrintOutlined(1024/30,768*6/8,string,1,2,1024,768); + + if(!campaign)sprintf (string, "Press Escape to return to menu or Space to continue"); + if(campaign)sprintf (string, "Press Escape or Space to continue"); + text.glPrintOutlined(640/2-strlen(string)*5,480*1/16,string,1,1,640,480); + + char temp[255]; + + for(i=0;i<255;i++)string[i]='\0'; + sprintf (temp, "Time: %d:",(int)(((int)leveltime-(int)(leveltime)%60)/60)); + strcat(string,temp); + if((int)(leveltime)%60<10)strcat(string,"0"); + sprintf (temp, "%d",(int)(leveltime)%60); + strcat(string,temp); + text.glPrintOutlined(1024/30,768*6/8-40,string,1,2,1024,768); + + for(i=0;i1)crosseyedness=1; + if(crosseyedness<0)crosseyedness=0; + glColor4f(1,1,1,1); + glDisable(GL_BLEND); + glPushMatrix(); + glScalef(1,1,1); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + if(crosseyedness){ + glColor4f(1,1,1,.5); + glEnable(GL_BLEND); + glPushMatrix(); + glTranslatef(.015*crosseyedness,0,0); + glScalef(1,1,1); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + } + } + if(drawmode==glowmode){ + glColor4f(.5,.5,.5,.5); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glPushMatrix(); + glTranslatef(.01,0,0); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glPushMatrix(); + glTranslatef(-.01,0,0); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glPushMatrix(); + glTranslatef(.0,.01,0); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glPushMatrix(); + glTranslatef(0,-.01,0); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + } + if(drawmode==radialzoommode){ + for(i=0;i<3;i++){ + //glRotatef((float)i*.1,0,0,1); + glColor4f(1,1,1,1/((float)i+1)); + glPushMatrix(); + glScalef(1+(float)i*.01,1+(float)i*.01,1); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(texcoordwidth,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(texcoordwidth,texcoordheight); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,texcoordheight); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + } + } + 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); + } + + if(console){ + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + if(console){ + int offset; + offset=0; + if(consoleselected>=60)offset=consoleselected-60; + sprintf (string, " ]"); + text.glPrint(10,30,string,0,1,1024,768); + if(consoleblink){ + sprintf (string, "_"); + text.glPrint(30+(float)(consoleselected)*10-offset*10,30,string,0,1,1024,768); + } + for(i=0;i<15;i++){ + for(j=0;j2)texdetail=2; + if(mainmenu!=oldmainmenu&&oldmainmenu!=0){ + if(mainmenu==1){ + LoadTexture(":Data:Textures:Newgame.png",&Mainmenuitems[1],0,0); + LoadTexture(":Data:Textures:Quit.png",&Mainmenuitems[3],0,0); + /*if(oldmainmenu==1||oldmainmenu==0){ + LoadTexture(":Data:Textures:World.png",&Mainmenuitems[7],0,0); + LoadTexture(":Data:Textures:Options.png",&Mainmenuitems[2],0,0); + LoadTexture(":Data:Textures:Lugaru.png",&Mainmenuitems[0],0,0); + loaddistrib=0; + }*/ + } + if(mainmenu==2){ + LoadTexture(":Data:Textures:Resume.png",&Mainmenuitems[1],0,0); + LoadTexture(":Data:Textures:Endgame.png",&Mainmenuitems[3],0,0); + /*if(oldmainmenu==2||oldmainmenu==0){ + LoadTexture(":Data:Textures:World.png",&Mainmenuitems[7],0,0); + LoadTexture(":Data:Textures:Options.png",&Mainmenuitems[2],0,0); + LoadTexture(":Data:Textures:Lugaru.png",&Mainmenuitems[0],0,0); + loaddistrib=0; + }*/ + } + } + if(lastcheck>.5||oldmainmenu!=mainmenu){ + if(mainmenu==5){ + // ifstream ipstream(":Data:Campaigns:main.txt"); + ifstream ipstream("./Data/Campaigns/main.txt"); + //campaignnumlevels=0; + //accountcampaignchoicesmade[accountactive]=0; + ipstream.ignore(256,':'); + ipstream >> campaignnumlevels; + for(i=0;i> campaignmapname[i]; + ipstream.ignore(256,':'); + ipstream >> campaigndescription[i]; + for(j=0;j<256;j++){ + if(campaigndescription[i][j]=='_')campaigndescription[i][j]=' '; + } + ipstream.ignore(256,':'); + ipstream >> campaignchoosenext[i]; + ipstream.ignore(256,':'); + ipstream >> campaignnumnext[i]; + if(campaignnumnext[i]) + for(j=0;j> campaignnextlevel[i][j]; + campaignnextlevel[i][j]-=1; + } + ipstream.ignore(256,':'); + ipstream >> campaignlocationx[i]; + //campaignlocationx[i]-=30; + ipstream.ignore(256,':'); + ipstream >> campaignlocationy[i]; + //campaignlocationy[i]+=30; + } + ipstream.close(); + + for(i=0;iaccountcampaignhighscore[accountactive])accountcampaignhighscore[accountactive]=accountcampaignscore[accountactive]; + if(accountcampaignfasttime[accountactive]==0||accountcampaigntime[accountactive](float)newscreenheight*1.61||(float)newscreenwidth<(float)newscreenheight*1.59)sprintf (menustring[0], "Resolution: %d*%d",(int)newscreenwidth,(int)newscreenheight); + else sprintf (menustring[0], "Resolution: %d*%d (widescreen)",(int)newscreenwidth,(int)newscreenheight); + startx[0]=10+20; + starty[0]=440; + endx[0]=startx[0]+strlen(menustring[0])*10; + endy[0]=starty[0]+20; + movex[0]=0; + movey[0]=0; + + if(newdetail==2)sprintf (menustring[1], "Detail: High"); + else if(newdetail==1)sprintf (menustring[1], "Detail: Medium"); + else sprintf (menustring[1], "Detail: Low"); + startx[1]=10+60; + starty[1]=405; + endx[1]=startx[1]+strlen(menustring[1])*10; + endy[1]=starty[1]+20; + movex[1]=0; + movey[1]=0; + + if(bloodtoggle==2)sprintf (menustring[2], "Blood: On, high detail (slower)"); + if(bloodtoggle==1)sprintf (menustring[2], "Blood: On, low detail"); + if(bloodtoggle==0)sprintf (menustring[2], "Blood: Off"); + startx[2]=10+70; + starty[2]=370; + endx[2]=startx[2]+strlen(menustring[2])*10; + endy[2]=starty[2]+20; + movex[2]=0; + movey[2]=0; + + if(difficulty==2)sprintf (menustring[3], "Difficulty: Insane"); + if(difficulty==1)sprintf (menustring[3], "Difficulty: Difficult"); + if(difficulty==0)sprintf (menustring[3], "Difficulty: Easier"); + startx[3]=10+20-1000; + starty[3]=335-1000; + endx[3]=startx[3]+strlen(menustring[3])*10; + endy[3]=starty[3]+20; + movex[3]=0; + movey[3]=0; + + if(ismotionblur==1)sprintf (menustring[4], "Blur Effects: Enabled (less compatible)"); + if(ismotionblur==0)sprintf (menustring[4], "Blur Effects: Disabled (more compatible)"); + startx[4]=10; + starty[4]=335; + endx[4]=startx[4]+strlen(menustring[4])*10; + endy[4]=starty[4]+20; + movex[4]=0; + movey[4]=0; + + if(decals==1)sprintf (menustring[5], "Decals: Enabled (slower)"); + if(decals==0)sprintf (menustring[5], "Decals: Disabled"); + startx[5]=10+60; + starty[5]=300; + endx[5]=startx[5]+strlen(menustring[5])*10; + endy[5]=starty[5]+20; + movex[5]=0; + movey[5]=0; + + if(musictoggle==1)sprintf (menustring[6], "Music: Enabled"); + if(musictoggle==0)sprintf (menustring[6], "Music: Disabled"); + startx[6]=10+70; + starty[6]=265; + endx[6]=startx[6]+strlen(menustring[6])*10; + endy[6]=starty[6]+20; + movex[6]=0; + movey[6]=0; + + if(invertmouse==1)sprintf (menustring[9], "Invert mouse: Yes"); + if(invertmouse==0)sprintf (menustring[9], "Invert mouse: No"); + startx[9]=10; + starty[9]=230; + endx[9]=startx[9]+strlen(menustring[9])*10; + endy[9]=starty[9]+20; + movex[9]=0; + movey[9]=0; + + sprintf (menustring[10], "Mouse Speed: %d", (int)(usermousesensitivity*5)); + startx[10]=20; + starty[10]=195; + endx[10]=startx[10]+strlen(menustring[10])*10; + endy[10]=starty[10]+20; + movex[10]=0; + movey[10]=0; + + sprintf (menustring[11], "Volume: %d%", (int)(volume*100)); + startx[11]=10+60; + starty[11]=155; + endx[11]=startx[11]+strlen(menustring[11])*10; + endy[11]=starty[11]+20; + movex[11]=0; + movey[11]=0; + + sprintf (menustring[7], "-Configure Controls-"); + startx[7]=10+15; + starty[7]=100; + endx[7]=startx[7]+strlen(menustring[7])*10; + endy[7]=starty[7]+20; + movex[7]=0; + movey[7]=0; + + if(newdetail==detail&&newscreenheight==(int)screenheight&&newscreenwidth==(int)screenwidth)sprintf (menustring[8], "Back"); + else sprintf (menustring[8], "Back (some changes take effect next time Lugaru is opened)"); + startx[8]=10; + endx[8]=startx[8]+strlen(menustring[8])*10; + starty[8]=10; + endy[8]=starty[8]+20; + movex[8]=0; + movey[8]=0; + } + + if(mainmenu==4){ + nummenuitems=10; + if(keyselect!=0)sprintf (menustring[0], "Forwards: %s",KeyToChar(forwardkey)); + else sprintf (menustring[0], "Forwards: _"); + startx[0]=10; + starty[0]=400; + endx[0]=startx[0]+strlen(menustring[0])*10; + endy[0]=starty[0]+20; + movex[0]=0; + movey[0]=0; + + if(keyselect!=1)sprintf (menustring[1], "Back: %s",KeyToChar(backkey)); + else sprintf (menustring[1], "Back: _"); + startx[1]=10+40; + starty[1]=360; + endx[1]=startx[1]+strlen(menustring[1])*10; + endy[1]=starty[1]+20; + movex[1]=0; + movey[1]=0; + + if(keyselect!=2)sprintf (menustring[2], "Left: %s",KeyToChar(leftkey)); + else sprintf (menustring[2], "Left: _"); + startx[2]=10+40; + starty[2]=320; + endx[2]=startx[2]+strlen(menustring[2])*10; + endy[2]=starty[2]+20; + movex[2]=0; + movey[2]=0; + + if(keyselect!=3)sprintf (menustring[3], "Right: %s",KeyToChar(rightkey)); + else sprintf (menustring[3], "Right: _"); + startx[3]=10+30; + starty[3]=280; + endx[3]=startx[3]+strlen(menustring[3])*10; + endy[3]=starty[3]+20; + movex[3]=0; + movey[3]=0; + + if(keyselect!=4)sprintf (menustring[4], "Crouch: %s",KeyToChar(crouchkey)); + else sprintf (menustring[4], "Crouch: _"); + startx[4]=10+20; + starty[4]=240; + endx[4]=startx[4]+strlen(menustring[4])*10; + endy[4]=starty[4]+20; + movex[4]=0; + movey[4]=0; + + if(keyselect!=5)sprintf (menustring[5], "Jump: %s",KeyToChar(jumpkey)); + else sprintf (menustring[5], "Jump: _"); + startx[5]=10+40; + starty[5]=200; + endx[5]=startx[5]+strlen(menustring[5])*10; + endy[5]=starty[5]+20; + movex[5]=0; + movey[5]=0; + + if(keyselect!=6)sprintf (menustring[6], "Draw: %s",KeyToChar(drawkey)); + else sprintf (menustring[6], "Draw: _"); + startx[6]=10+40; + starty[6]=160; + endx[6]=startx[6]+strlen(menustring[6])*10; + endy[6]=starty[6]+20; + movex[6]=0; + movey[6]=0; + + if(keyselect!=7)sprintf (menustring[7], "Throw: %s",KeyToChar(throwkey)); + else sprintf (menustring[7], "Throw: _"); + startx[7]=10+30; + starty[7]=120; + endx[7]=startx[7]+strlen(menustring[7])*10; + endy[7]=starty[7]+20; + movex[7]=0; + movey[7]=0; + + if(keyselect!=8)sprintf (menustring[8], "Attack: %s",KeyToChar(attackkey)); + else sprintf (menustring[8], "Attack: _"); + startx[8]=10+20; + starty[8]=80; + endx[8]=startx[8]+strlen(menustring[8])*10; + endy[8]=starty[8]+20; + movex[8]=0; + movey[8]=0; + + + + sprintf (menustring[9], "Back"); + startx[9]=10; + endx[9]=startx[9]+strlen(menustring[9])*10; + starty[9]=10; + endy[9]=starty[9]+20; + movex[9]=0; + movey[9]=0; + } + if(mainmenu==5){ + nummenuitems=7+accountcampaignchoicesmade[accountactive]+campaignchoicenum; + + sprintf (menustring[0], "%s",accountname[accountactive]); + startx[0]=5; + starty[0]=400; + endx[0]=startx[0]+strlen(menustring[0])*10; + endy[0]=starty[0]+20; + movex[0]=0; + movey[0]=0; + + sprintf (menustring[1], "Tutorial"); + startx[1]=5; + starty[1]=300; + endx[1]=startx[1]+strlen(menustring[1])*10; + endy[1]=starty[1]+20; + movex[1]=0; + movey[1]=0; + + sprintf (menustring[2], "Challenge"); + startx[2]=5; + starty[2]=240; + endx[2]=startx[2]+strlen(menustring[2])*10; + endy[2]=starty[2]+20; + movex[2]=0; + movey[2]=0; + + sprintf (menustring[3], "Delete User"); + startx[3]=400; + starty[3]=10; + endx[3]=startx[3]+strlen(menustring[3])*10; + endy[3]=starty[3]+20; + movex[3]=0; + movey[3]=0; + + sprintf (menustring[4], "Main Menu"); + startx[4]=5; + starty[4]=10; + endx[4]=startx[4]+strlen(menustring[4])*10; + endy[4]=starty[4]+20; + movex[4]=0; + movey[4]=0; + + sprintf (menustring[5], "Change User"); + startx[5]=5; + endx[5]=startx[5]+strlen(menustring[5])*10; + starty[5]=180; + endy[5]=starty[5]+20; + movex[5]=0; + movey[5]=0; + + //World + + sprintf (menustring[6], "World"); + startx[6]=30+120; + starty[6]=30+480-400-50; + endx[6]=startx[6]+400; + endy[6]=30+480-50; + movex[6]=0; + movey[6]=0; + + if(accountcampaignchoicesmade[accountactive]) + for(i=0;i0) + for(i=accountcampaignchoicesmade[accountactive];istartx[i]&&(mousecoordh/screenwidth*640)starty[i]&&480-(mousecoordv/screenheight*480)startx[i]&&(mousecoordh/screenwidth*640)starty[i]&&480-(mousecoordv/screenheight*480)0) + for(i=0;i1)selectedlong[i]=1; + if(selected!=i)selectedlong[i]-=multiplier*5; + if(selectedlong[i]<0)selectedlong[i]=0; + //if(i>=4)selectedlong[i]=.3; + if(i>=4&&(mainmenu==1||mainmenu==2))selectedlong[i]=0; + } + + if(nummenuitems>0) + for(i=0;i=4&&(mainmenu==1||mainmenu==2)){ + offsetx[i]=(startx[i]+endx[i]+movex[i]*transition)/2-(640+190)/2; + offsety[i]=(starty[i]+endy[i]+movey[i]*transition)/2-(336+150)/2; + offsetx[i]*=.06f; + offsety[i]*=.06f; + } + } + + if(mainmenu==1||mainmenu==2){ + glClear(GL_DEPTH_BUFFER_BIT); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.001f); + glEnable(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,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 + glTranslatef(screenwidth/2,screenheight/2,0); + glPushMatrix(); + glScalef((float)screenwidth/2,(float)screenheight/2,1); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + glColor4f(0,0,0,1.0); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glDisable(GL_TEXTURE_2D); + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glEnable(GL_BLEND); + glColor4f(0.4,0.4,0.4,1.0); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, Mainmenuitems[4]); + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glPopMatrix(); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); + + 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 + glLoadIdentity(); // Reset The Modelview Matrix + glPushMatrix(); + glDisable(GL_TEXTURE_2D); + glColor4f(1,0,0,1); + /*glPushMatrix(); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + if(anim!=1)glVertex3f(190, 150, 0.0f); + if(anim==1)glVertex3f(190+movex[4]*transition, 150, 0.0f); + glTexCoord2f(1,0); + glVertex3f(640, 150, 0.0f); + glTexCoord2f(1,1); + glVertex3f(640, 336, 0.0f); + glTexCoord2f(0,1); + if(anim!=1)glVertex3f(190, 336, 0.0f); + if(anim==1)glVertex3f(190+movex[4]*transition, 336, 0.0f); + glEnd(); + glPopMatrix();*/ + glPopMatrix(); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + } + + 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 + glLoadIdentity(); // Reset The Modelview Matrix + glEnable(GL_TEXTURE_2D); + if(nummenuitems>0) + { + for(j=0;j0) + { + glColor4f(1,1,1,(1-((float)i)/10-(1-selectedlong[j]))*.25); + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(startx[j]-((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, starty[j]-((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glTexCoord2f(1,0); + glVertex3f(endx[j]+((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, starty[j]-((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glTexCoord2f(1,1); + glVertex3f(endx[j]+((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, endy[j]+((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glTexCoord2f(0,1); + glVertex3f(startx[j]-((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, endy[j]+((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glEnd(); + glPopMatrix(); + } + } + } + if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==11||mainmenu==12||mainmenu==13||mainmenu==14||mainmenu==15||mainmenu==16||mainmenu==17) + { + if(mainmenu!=5||j<6) + { + glColor4f(1,0,0,1); + if(mainmenu==12&&j==4)glColor4f(1,(sin(menupulse)+1)/2,(sin(menupulse)+1)/2,1); + if(mainmenu==9&&j>accountprogress[accountactive]&&jaccountprogress[accountactive]&&j0){ + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); + if((mainmenu!=7||j!=0||!entername)&&(mainmenu!=13||j!=1)&&(mainmenu!=14||j!=1))text.glPrint(startx[j],starty[j],menustring[j],0,1,640,480); + else + { + if(displayblink){ + sprintf (string, "_"); + text.glPrint(startx[j]+(float)(displayselected)*10,starty[j],string,0,1,640,480); + } + k=0; + for(l=0;l0) + { + glColor4f(1,0,0,(1-((float)i)/10-(1-selectedlong[j]))*.25); + if(mainmenu==12&&j==4)glColor4f(1,(sin(menupulse)+1)/2,(sin(menupulse)+1)/2,(1-((float)i)/10-(1-selectedlong[j]))*.25); + if(mainmenu==9&&j>accountprogress[accountactive]&&jaccountprogress[accountactive]&&j6&&j=6+accountcampaignchoicesmade[accountactive]){ + linestart.x=(startx[6+accountcampaignchoicesmade[accountactive]]+endx[6+accountcampaignchoicesmade[accountactive]])/2; + linestart.y=(starty[6+accountcampaignchoicesmade[accountactive]]+endy[6+accountcampaignchoicesmade[accountactive]])/2; + } + lineend.x=(startx[j+1]+endx[j+1])/2; + lineend.y=(starty[j+1]+endy[j+1])/2; + offset=lineend-linestart; + fac=offset; + Normalise(&fac); + offset=DoRotation(offset,0,0,90); + Normalise(&offset); + glDisable(GL_TEXTURE_2D); + + if(j<6+accountcampaignchoicesmade[accountactive]){ + glColor4f(0.5,0,0,1); + startsize=.5; + endsize=.5; + } + if(j>=6+accountcampaignchoicesmade[accountactive]){ + glColor4f(1,0,0,1); + endsize=1; + startsize=.5; + } + + linestart+=fac*4*startsize; + lineend-=fac*4*endsize; + + if(!(j>7+accountcampaignchoicesmade[accountactive]+campaignchoicenum)){ + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(linestart.x-offset.x*startsize, linestart.y-offset.y*startsize, 0.0f); + glTexCoord2f(1,0); + glVertex3f(linestart.x+offset.x*startsize, linestart.y+offset.y*startsize, 0.0f); + glTexCoord2f(1,1); + glVertex3f(lineend.x+offset.x*endsize, lineend.y+offset.y*endsize, 0.0f); + glTexCoord2f(0,1); + glVertex3f(lineend.x-offset.x*endsize, lineend.y-offset.y*endsize, 0.0f); + glEnd(); + glPopMatrix(); + } + glEnable(GL_TEXTURE_2D); + } + + + if(j==6)glBindTexture( GL_TEXTURE_2D, Mainmenuitems[7]); + else glBindTexture( GL_TEXTURE_2D, Mapcircletexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + if(j-7=accountcampaignchoicesmade[accountactive])glColor4f(1,0,0,1); + if(j==6)glColor4f(1,1,1,1); + XYZ midpoint; + float itemsize; + itemsize=abs(startx[j]-endx[j])/2; + midpoint=0; + midpoint.x=(startx[j]+endx[j])/2; + midpoint.y=(starty[j]+endy[j])/2; + if(j>6&&(j-7accountcampaignchoicesmade[accountactive]+campaignchoicenum)) + { + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(midpoint.x-itemsize+movex[j]*transition, midpoint.y-itemsize+movey[j]*transition, 0.0f); + glTexCoord2f(1,0); + glVertex3f(midpoint.x+itemsize+movex[j]*transition, midpoint.y-itemsize+movey[j]*transition, 0.0f); + glTexCoord2f(1,1); + glVertex3f(midpoint.x+itemsize+movex[j]*transition, midpoint.y+itemsize+movey[j]*transition, 0.0f); + glTexCoord2f(0,1); + glVertex3f(midpoint.x-itemsize+movex[j]*transition, midpoint.y+itemsize+movey[j]*transition, 0.0f); + glEnd(); + glPopMatrix(); + glEnable(GL_BLEND); + //glDisable(GL_ALPHA_TEST); + if(j<4)glBlendFunc(GL_SRC_ALPHA,GL_ONE); + for(i=0;i<10;i++) + { + if(1-((float)i)/10-(1-selectedlong[j])>0) + { + glColor4f(1,0,0,(1-((float)i)/10-(1-selectedlong[j]))*.25); + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(midpoint.x-itemsize-((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, midpoint.y-itemsize-((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glTexCoord2f(1,0); + glVertex3f(midpoint.x+itemsize+((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, midpoint.y-itemsize-((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glTexCoord2f(1,1); + glVertex3f(midpoint.x+itemsize+((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, midpoint.y+itemsize+((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glTexCoord2f(0,1); + glVertex3f(midpoint.x-itemsize-((float)i)*1/2+offsetx[j]*((float)i)/2+movex[j]*transition, midpoint.y+itemsize+((float)i)*1/2+offsety[j]*((float)i)/2+movey[j]*transition, 0.0f); + glEnd(); + glPopMatrix(); + } + } + } + glPopMatrix(); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + + if(j-7>=accountcampaignchoicesmade[accountactive]){ + //glColor4f(0,0,0,1); + //text.glPrintOutline(startx[j]+10-1.5,starty[j]-4-1.5,menustring[j],0,0.6*1.25,640,480); + //glColor4f(1,0,0,1); + //text.glPrint(startx[j]+10,starty[j]-4,menustring[j],0,0.6,640,480); + text.glPrintOutlined(0.9,0,0,startx[j]+10,starty[j]-4,menustring[j],0,0.6,640,480); + glDisable(GL_DEPTH_TEST); + } + } + } + } + } + } + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPopMatrix(); + + if(mainmenu==1||mainmenu==2) + if(transition<.1||transition>.9){ + glClear(GL_DEPTH_BUFFER_BIT); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.001f); + glEnable(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 + glLoadIdentity(); // Reset The Modelview Matrix + glPushMatrix(); + glDisable(GL_TEXTURE_2D); + if(transition<.1)glColor4f(1,0,0,1-(transition*10)); + if(transition>.9)glColor4f(1,0,0,1-((1-transition)*10)); + /*glPushMatrix(); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(190, 150, 0.0f); + glTexCoord2f(1,0); + glVertex3f(640, 150, 0.0f); + glTexCoord2f(1,1); + glVertex3f(640, 336, 0.0f); + glTexCoord2f(0,1); + glVertex3f(190, 336, 0.0f); + glEnd(); + glPopMatrix();*/ + glPopMatrix(); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); + } + + 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 + glTranslatef(screenwidth/2,screenheight/2,0); + glPushMatrix(); + glScalef((float)screenwidth/2,(float)screenheight/2,1); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glPopMatrix(); + glPushMatrix(); + glTranslatef(mousecoordh-screenwidth/2,mousecoordv*-1+screenheight/2,0); + glScalef((float)screenwidth/64,(float)screenwidth/64,1); + glTranslatef(1,-1,0); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1,1,1,1); + glBindTexture( GL_TEXTURE_2D, cursortexture); + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glPopMatrix(); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glPopMatrix(); + + + if(flashamount>0) + { + if(flashamount>1)flashamount=1; + if(flashdelay<=0)flashamount-=multiplier; + flashdelay--; + if(flashamount<0)flashamount=0; + 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,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(freeze||winfreeze||(mainmenu&&gameon)||(!gameon&&gamestarted)||(!gameon&&gamestarted)){ + tempmult=multiplier; + multiplier=0; + } + + + //glFlush(); + if(drawmode!=motionblurmode||mainmenu){ +#ifdef WIN32 + if(drawmode!=motionblurmode) SwapBuffers( hDC); +#else + if(drawmode!=motionblurmode)aglSwapBuffers(gaglContext); // send swap command +#endif // send swap command + } + + //myassert(glGetError() == GL_NO_ERROR); + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + //glFlush(); + + weapons.DoStuff(); + + if(drawtoggle==2)drawtoggle=0; + + if(freeze||winfreeze||(mainmenu&&gameon)||(!gameon&&gamestarted)){ + multiplier=tempmult; + } + //Jordan fixed your warning! + return 0; +} diff --git a/Source/GameInitDispose.cpp b/Source/GameInitDispose.cpp new file mode 100644 index 0000000..d966a35 --- /dev/null +++ b/Source/GameInitDispose.cpp @@ -0,0 +1,2019 @@ +#include "Game.h" +extern float screenwidth,screenheight; +extern float viewdistance; +extern XYZ viewer; +extern XYZ lightlocation; +extern float lightambient[3],lightbrightness[3]; +extern float fadestart; +extern float texscale; +extern float gravity; +extern Light light; +extern Animation animation[animation_count]; +extern Skeleton testskeleton; +extern int numsounds; +extern FSOUND_SAMPLE *samp[100]; +extern int channels[100]; +extern Terrain terrain; +extern Sprites sprites; +extern int kTextureSize; +extern float texdetail; +extern float realtexdetail; +extern float terraindetail; +extern float volume; +extern Objects objects; +extern int detail; +extern bool cellophane; +extern GLubyte bloodText[512*512*3]; +extern GLubyte wolfbloodText[512*512*3]; +extern bool ismotionblur; +extern bool trilinear; +#ifdef WIN32 +extern HDC hDC; +#else +extern AGLContext gaglContext; +#endif +extern bool osx; +extern bool musictoggle; +extern Weapons weapons; +extern Person player[maxplayers]; +extern int numplayers; +extern int environment; +extern bool ambientsound; +extern float multiplier; +extern int newnetmessages; +extern int netdatanew; +extern float mapinfo; +extern bool stillloading; +extern TGAImageRec texture; +extern short vRefNum; +extern long dirID; +extern int mainmenu; +extern int oldmainmenu; +extern bool visibleloading; +extern int loadscreencolor; +extern float flashamount,flashr,flashg,flashb; +extern int flashdelay; +extern int whichjointstartarray[26]; +extern int whichjointendarray[26]; +extern int difficulty; +extern float tintr,tintg,tintb; +extern float slomospeed; +extern char mapname[256]; +extern bool gamestarted; + +extern int numaccounts; +extern int accountactive; +extern int accountdifficulty[10]; +extern int accountprogress[10]; +extern float accountpoints[10]; +extern float accounthighscore[10][50]; +extern float accountfasttime[10][50]; +extern bool accountunlocked[10][60]; +extern char accountname[10][256]; + +extern int numdialogues; +extern int numdialogueboxes[20]; +extern int dialoguetype[20]; +extern int dialogueboxlocation[20][20]; +extern float dialogueboxcolor[20][20][3]; +extern int dialogueboxsound[20][20]; +extern char dialoguetext[20][20][128]; +extern char dialoguename[20][20][64]; +extern XYZ dialoguecamera[20][20]; +extern float dialoguecamerarotation[20][20]; +extern float dialoguecamerarotation2[20][20]; +extern int indialogue; +extern int whichdialogue; +extern float dialoguetime; + +extern float accountcampaignhighscore[10]; +extern float accountcampaignfasttime[10]; +extern float accountcampaignscore[10]; +extern float accountcampaigntime[10]; + +extern int accountcampaignchoicesmade[10]; +extern int accountcampaignchoices[10][5000]; + +extern FSOUND_STREAM * strm[10]; + +extern "C" void PlaySoundEx(int channel, FSOUND_SAMPLE *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused); +extern "C" void PlayStreamEx(int chan, FSOUND_STREAM *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused); + +Game::TextureList Game::textures; + +void Game::Dispose() +{ + int i,j; + + LOGFUNC; + + if(endgame==2){ + accountcampaignchoicesmade[accountactive]=0; + accountcampaignscore[accountactive]=0; + accountcampaigntime[accountactive]=0; + endgame=0; + } + + + sprintf (mapname, ":Data:Users"); + + FILE *tfile; + tfile=fopen( mapname, "wb" ); + if (tfile) + { + fpackf(tfile, "Bi", numaccounts); + fpackf(tfile, "Bi", accountactive); + if(numaccounts>0) + { + for(i=0;i0) + { + for(j=0;j<(int)strlen(accountname[i]);j++) + { + fpackf(tfile, "Bb", accountname[i][j]); + } + } + } + } + + fclose(tfile); + } + + TexIter it = textures.begin(); + for (; it != textures.end(); ++it) + { + if (glIsTexture(it->second)) + glDeleteTextures(1, &it->second); + } + textures.clear(); + + LOG("Shutting down sound system..."); + + FSOUND_StopSound(FSOUND_ALL); + +#define streamcount 20 +#define samplecount 100 + + for (i=0; i < samplecount; ++i) + { + FSOUND_Sample_Free(samp[i]); + } + + for (i=0; i < streamcount; ++i) + { + FSOUND_Stream_Close(strm[i]); + } + + FSOUND_Close(); + if (texture.data) + { + free(texture.data); + } + texture.data = 0; +} + + +//void Game::LoadSounds(); +void Game::LoadSounds() +{ + LOGFUNC; + + LOG(std::string("Loading sounds...")); + + FSOUND_3D_SetDopplerFactor(0); + + FSOUND_SetSFXMasterVolume((int)(volume*255)); + + samp[footstepsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepsnow1.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound], 4.0f, 1000.0f); + + samp[footstepsound2] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepsnow2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound2], 4.0f, 1000.0f); + + samp[footstepsound3] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepstone1.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound3], 4.0f, 1000.0f); + + samp[footstepsound4] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepstone2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound4], 4.0f, 1000.0f); + + samp[landsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:land.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[landsound], 4.0f, 1000.0f); + + samp[jumpsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:jump.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[jumpsound], 4.0f, 1000.0f); + + samp[hawksound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:hawk.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[hawksound], 40.0f, 10000.0f); + + samp[whooshsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:whoosh.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[whooshsound], 4.0f, 1000.0f); + FSOUND_Sample_SetMode(samp[whooshsound], FSOUND_LOOP_NORMAL); + + samp[landsound1] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:land1.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[landsound1], 4.0f, 1000.0f); + + + + samp[landsound2] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:land2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[landsound2], 4.0f, 1000.0f); + + samp[breaksound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:broken.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[breaksound], 8.0f, 2000.0f); + + samp[lowwhooshsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:Lowwhoosh.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[lowwhooshsound], 8.0f, 2000.0f); + + samp[midwhooshsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:midwhoosh.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[midwhooshsound], 8.0f, 2000.0f); + + samp[highwhooshsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:highwhoosh.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[highwhooshsound], 8.0f, 2000.0f); + + samp[movewhooshsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:movewhoosh.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[movewhooshsound], 8.0f, 2000.0f); + + samp[heavyimpactsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:heavyimpact.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[heavyimpactsound], 8.0f, 2000.0f); + + samp[whooshhitsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:Whooshhit.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[whooshhitsound], 8.0f, 2000.0f); + + samp[thudsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:thud.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[thudsound], 8.0f, 2000.0f); + + samp[alarmsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:alarm.ogg", FSOUND_2D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[alarmsound], 8.0f, 2000.0f); + + samp[breaksound2] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:break.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[breaksound2], 8.0f, 2000.0f); + + samp[knifedrawsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:knifedraw.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[knifedrawsound], 8.0f, 2000.0f); + + samp[knifesheathesound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:knifesheathe.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[knifesheathesound], 8.0f, 2000.0f); + + samp[fleshstabsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:Fleshstab.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[fleshstabsound], 8.0f, 2000.0f); + + samp[fleshstabremovesound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:Fleshstabremove.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[fleshstabremovesound], 8.0f, 2000.0f); + + samp[knifeswishsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:knifeswish.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[knifeswishsound], 8.0f, 2000.0f); + + samp[knifeslicesound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:knifeslice.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[knifeslicesound], 8.0f, 2000.0f); + + samp[swordslicesound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:swordslice.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[swordslicesound], 8.0f, 2000.0f); + + samp[skidsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:skid.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[skidsound], 8.0f, 2000.0f); + + samp[snowskidsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:snowskid.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[snowskidsound], 8.0f, 2000.0f); + + samp[bushrustle] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:bushrustle.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[bushrustle], 4.0f, 1000.0f); + + samp[clank1sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:clank1.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[clank1sound], 8.0f, 2000.0f); + + samp[clank2sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:clank2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[clank2sound], 8.0f, 2000.0f); + + samp[clank3sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:clank3.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[clank3sound], 8.0f, 2000.0f); + + samp[clank4sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:clank4.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[clank4sound], 8.0f, 2000.0f); + + samp[consolesuccesssound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:consolesuccess.ogg", FSOUND_2D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[consolesuccesssound], 4.0f, 1000.0f); + + samp[consolefailsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:consolefail.ogg", FSOUND_2D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[consolefailsound], 4.0f, 1000.0f); + + samp[metalhitsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:MetalHit.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[metalhitsound], 8.0f, 2000.0f); + + samp[clawslicesound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:clawslice.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[clawslicesound], 8.0f, 2000.0f); + + samp[splattersound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:splatter.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[splattersound], 8.0f, 2000.0f); + + samp[growlsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:Growl.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[growlsound], 1000.0f, 2000.0f); + + samp[growl2sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:Growl2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[growl2sound], 1000.0f, 2000.0f); + + samp[barksound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:bark.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[barksound], 1000.0f, 2000.0f); + + samp[bark2sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:bark2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[bark2sound], 1000.0f, 2000.0f); + + samp[bark3sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:bark3.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[bark3sound], 1000.0f, 2000.0f); + + samp[snarlsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:snarl.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[snarlsound], 1000.0f, 2000.0f); + + + samp[snarl2sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:snarl2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[snarl2sound], 1000.0f, 2000.0f); + + samp[barkgrowlsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:barkgrowl.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[barkgrowlsound], 1000.0f, 2000.0f); + + samp[rabbitattacksound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitattack.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitattacksound], 1000.0f, 2000.0f); + + samp[rabbitattack2sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitattack2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitattack2sound], 1000.0f, 2000.0f); + + samp[rabbitattack3sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitattack3.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitattack3sound], 1000.0f, 2000.0f); + + samp[rabbitattack4sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitattack4.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitattack4sound], 1000.0f, 2000.0f); + + samp[rabbitpainsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitpain.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitpainsound], 1000.0f, 2000.0f); + + samp[rabbitpain1sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitpain2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitpain1sound], 1000.0f, 2000.0f); + + /*samp[rabbitpain2sound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitpain2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitpain2sound], 1000.0f, 2000.0f); + */ + samp[rabbitchitter] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitchitter.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitchitter], 1000.0f, 2000.0f); + + samp[rabbitchitter2] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:rabbitchitter2.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[rabbitchitter2], 1000.0f, 2000.0f); + + samp[swordstaffsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:swordstaff.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[swordstaffsound], 8.0f, 2000.0f); + + samp[staffbodysound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:staffbody.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[staffbodysound], 8.0f, 2000.0f); + + samp[staffheadsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:staffhead.ogg", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[staffheadsound], 8.0f, 2000.0f); + + samp[staffbreaksound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:staffbreak.wav", FSOUND_HW3D, 0); if(visibleloading){LoadingScreen(); loadscreencolor=5;} + FSOUND_Sample_SetMinMaxDistance(samp[staffbreaksound], 8.0f, 2000.0f); + + + +} + +void Game::LoadTexture(char *fileName, GLuint *textureid,int mipmap, bool hasalpha) +{ + GLuint type; + + LOGFUNC; + + LOG(std::string("Loading texture...") + fileName); + + unsigned char fileNamep[256]; + CopyCStringToPascal(fileName,fileNamep); + //Load Image + upload_image( fileNamep ,hasalpha); + +// std::string fname(fileName); +// std::transform(fname.begin(), fname.end(), tolower); +// TexIter it = textures.find(fname); + + //Is it valid? + if(1==1) + //if(textures.end() == it) + { + //Alpha channel? + if ( texture.bpp == 24 ) + type = GL_RGB; + else + type = GL_RGBA; + + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + if(!*textureid)glGenTextures( 1, textureid ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glBindTexture( GL_TEXTURE_2D, *textureid); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + if(trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + if(!trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); + if(!mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.sizeX, texture.sizeY, 0, + // GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, texture.data); + + //gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, texture.data ); + + gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data ); + +// textures.insert(std::make_pair(fname, *textureid)); + } +// else +// { +// *textureid = it->second; +// } +} + +void Game::LoadTextureSave(char *fileName, GLuint *textureid,int mipmap,GLubyte *array, int *skinsize) +{ + GLuint type; + int i; + int bytesPerPixel; + + LOGFUNC; + + LOG(std::string("Loading texture (S)...") + fileName); + + //Load Image + unsigned char fileNamep[256]; + CopyCStringToPascal(fileName,fileNamep); + //Load Image + upload_image( fileNamep ,0); + //LoadTGA( fileName ); + +// std::string fname(fileName); +// std::transform(fname.begin(), fname.end(), tolower); +// TexIter it = textures.find(fname); + + //Is it valid? + if(1==1) + //if(textures.end() == it) + { + bytesPerPixel=texture.bpp/8; + + //Alpha channel? + if ( texture.bpp == 24 ) + type = GL_RGB; + else + type = GL_RGBA; + + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + if(!*textureid)glGenTextures( 1, textureid ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glBindTexture( GL_TEXTURE_2D, *textureid); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + if(trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + if(!trilinear)if(mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); + if(!mipmap)glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + int tempnum=0; + for(i=0;i<(int)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){ + if((i+1)%4||type==GL_RGB){ + array[tempnum]=texture.data[i]; + tempnum++; + } + } + + *skinsize=texture.sizeX; + + gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, GL_RGB, GL_UNSIGNED_BYTE, array ); + +// textures.insert(std::make_pair(fname, *textureid)); + } +// else +// { +// *textureid = it->second; +// } +} + +void Game::LoadSave(char *fileName, GLuint *textureid,bool mipmap,GLubyte *array, int *skinsize) +{ + int i; + int bytesPerPixel; + + LOGFUNC; + + LOG(std::string("Loading (S)...") + fileName); + + //Load Image + float temptexdetail=texdetail; + texdetail=1; + //upload_image( fileName ); + //LoadTGA( fileName ); + //Load Image + unsigned char fileNamep[256]; + CopyCStringToPascal(fileName,fileNamep); + //Load Image + upload_image( fileNamep ,0); + texdetail=temptexdetail; + + //Is it valid? + if(1==1){ + bytesPerPixel=texture.bpp/8; + + int tempnum=0; + for(i=0;i<(int)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){ + if((i+1)%4||bytesPerPixel==3){ + array[tempnum]=texture.data[i]; + tempnum++; + } + } + } +} + +bool Game::AddClothes(char *fileName, GLuint *textureid,bool mipmap,GLubyte *array, int *skinsize) +{ + int i; + int bytesPerPixel; + + LOGFUNC; + + //upload_image( fileName ); + //LoadTGA( fileName ); + //Load Image + unsigned char fileNamep[256]; + CopyCStringToPascal(fileName,fileNamep); + //Load Image + bool opened; + opened=upload_image( fileNamep ,1); + + float alphanum; + //Is it valid? + if(opened){ + if(tintr>1)tintr=1; + if(tintg>1)tintg=1; + if(tintb>1)tintb=1; + + if(tintr<0)tintr=0; + if(tintg<0)tintg=0; + if(tintb<0)tintb=0; + + bytesPerPixel=texture.bpp/8; + + int tempnum=0; + alphanum=255; + for(i=0;i<(int)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){ + if(bytesPerPixel==3)alphanum=255; + else if((i+1)%4==0)alphanum=texture.data[i]; + //alphanum/=2; + if((i+1)%4||bytesPerPixel==3){ + if((i%4)==0)texture.data[i]*=tintr; + if((i%4)==1)texture.data[i]*=tintg; + if((i%4)==2)texture.data[i]*=tintb; + array[tempnum]=(float)array[tempnum]*(1-alphanum/255)+(float)texture.data[i]*(alphanum/255); + tempnum++; + } + } + } + else return 0; + return 1; +} + + +//***************> ResizeGLScene() <******/ +GLvoid Game::ReSizeGLScene(float fov, float pnear) +{ + if (screenheight==0) + { + screenheight=1; + } + + glViewport(0,0,screenwidth,screenheight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(fov,(GLfloat)screenwidth/(GLfloat)screenheight,pnear,viewdistance); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void Game::LoadingScreen() +{ + static float loadprogress,minprogress,maxprogress; + static AbsoluteTime time = {0,0}; + static AbsoluteTime frametime = {0,0}; + AbsoluteTime currTime = UpTime (); + double deltaTime = (float) AbsoluteDeltaToDuration (currTime, frametime); + + if (0 > deltaTime) // if negative microseconds + deltaTime /= -1000000.0; + else // else milliseconds + deltaTime /= 1000.0; + + multiplier=deltaTime; + if(multiplier<.001)multiplier=.001; + if(multiplier>10)multiplier=10; + if(multiplier>.05){ + frametime = currTime; // reset for next time interval + + float size=1; + glLoadIdentity(); + //Clear to black + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + loadtime+=multiplier*4; + + loadprogress=loadtime; + if(loadprogress>100)loadprogress=100; + + //loadprogress=abs(Random()%100); + + //Background + + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, loadscreentexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + 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 + glTranslatef(screenwidth/2,screenheight/2,0); + glScalef((float)screenwidth/2,(float)screenheight/2,1); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,1); + //glColor4f(1,1,1,1); + /*if(loadscreencolor==0)glColor4f(1,1,1,1); + if(loadscreencolor==1)glColor4f(1,0,0,1); + if(loadscreencolor==2)glColor4f(0,1,0,1); + if(loadscreencolor==3)glColor4f(0,0,1,1); + if(loadscreencolor==4)glColor4f(1,1,0,1); + if(loadscreencolor==5)glColor4f(1,0,1,1); + */ + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(.1-loadprogress/100,0+loadprogress/100+.3); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(.1-loadprogress/100,0+loadprogress/100+.3); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(.1-loadprogress/100,1+loadprogress/100+.3); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(.1-loadprogress/100,1+loadprogress/100+.3); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + glEnable(GL_BLEND); + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(.4+loadprogress/100,0+loadprogress/100); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(.4+loadprogress/100,0+loadprogress/100); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(.4+loadprogress/100,1+loadprogress/100); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(.4+loadprogress/100,1+loadprogress/100); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + 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 + glDisable(GL_BLEND); + glDepthMask(1); + + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, loadscreentexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + 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 + glTranslatef(screenwidth/2,screenheight/2,0); + glScalef((float)screenwidth/2*(1.5-(loadprogress)/200),(float)screenheight/2*(1.5-(loadprogress)/200),1); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glEnable(GL_BLEND); + //glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,1); + glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,1); + /*if(loadscreencolor==0)glColor4f(1,1,1,1); + if(loadscreencolor==1)glColor4f(1,0,0,1); + if(loadscreencolor==2)glColor4f(0,1,0,1); + if(loadscreencolor==3)glColor4f(0,0,1,1); + if(loadscreencolor==4)glColor4f(1,1,0,1); + if(loadscreencolor==5)glColor4f(1,0,1,1); + */ + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0+.5,0+.5); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1+.5,0+.5); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1+.5,1+.5); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0+.5,1+.5); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + 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 + glDisable(GL_BLEND); + glDepthMask(1); + + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, loadscreentexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + 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 + glTranslatef(screenwidth/2,screenheight/2,0); + glScalef((float)screenwidth/2*(100+loadprogress)/100,(float)screenheight/2*(100+loadprogress)/100,1); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glEnable(GL_BLEND); + glColor4f(loadprogress/100,loadprogress/100,loadprogress/100,.4); + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0+.2,0+.8); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1+.2,0+.8); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1+.2,1+.8); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0+.2,1+.8); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + 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 + glDisable(GL_BLEND); + glDepthMask(1); + + //Text + /* + glEnable(GL_TEXTURE_2D); + static char string[256]=""; + sprintf (string, "LOADING... %d%",(int)loadprogress); + glColor4f(1,1,1,.2); + text.glPrint(280-280*loadprogress/100/2/4,125-125*loadprogress/100/2/4,string,1,1+loadprogress/100,640,480); + glColor4f(1.2-loadprogress/100,1.2-loadprogress/100,1.2-loadprogress/100,1); + text.glPrint(280,125,string,1,1,640,480); + */ + + if(flashamount>0){ + if(flashamount>1)flashamount=1; + if(flashdelay<=0)flashamount-=multiplier; + flashdelay--; + if(flashamount<0)flashamount=0; + 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,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); + } + +#ifdef WIN32 + SwapBuffers( hDC); +#else + aglSwapBuffers(gaglContext); +#endif + + loadscreencolor=0; + } +} + +void Game::FadeLoadingScreen(float howmuch) +{ + static float loadprogress,minprogress,maxprogress; + + float size=1; + glLoadIdentity(); + //Clear to black + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + loadprogress=howmuch; + + //loadprogress=abs(Random()%100); + + //Background + + //glEnable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_2D); + //glBindTexture( GL_TEXTURE_2D, loadscreentexture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + 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 + glTranslatef(screenwidth/2,screenheight/2,0); + glScalef((float)screenwidth/2,(float)screenheight/2,1); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + glColor4f(loadprogress/100,0,0,1); + /*if(loadscreencolor==0)glColor4f(1,1,1,1); + if(loadscreencolor==1)glColor4f(1,0,0,1); + if(loadscreencolor==2)glColor4f(0,1,0,1); + if(loadscreencolor==3)glColor4f(0,0,1,1); + if(loadscreencolor==4)glColor4f(1,1,0,1); + if(loadscreencolor==5)glColor4f(1,0,1,1); + */ + glPushMatrix(); + //glScalef(.25,.25,.25); + glBegin(GL_QUADS); + glTexCoord2f(0,0); + glVertex3f(-1, -1, 0.0f); + glTexCoord2f(1,0); + glVertex3f(1, -1, 0.0f); + glTexCoord2f(1,1); + glVertex3f(1, 1, 0.0f); + glTexCoord2f(0,1); + glVertex3f(-1, 1, 0.0f); + glEnd(); + glPopMatrix(); + 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 + glDisable(GL_BLEND); + glDepthMask(1); + //Text + /* + glEnable(GL_TEXTURE_2D); + static char string[256]=""; + sprintf (string, "LOADING... %d%",(int)loadprogress); + glColor4f(1,1,1,.2); + text.glPrint(280-280*loadprogress/100/2/4,125-125*loadprogress/100/2/4,string,1,1+loadprogress/100,640,480); + glColor4f(1.2-loadprogress/100,1.2-loadprogress/100,1.2-loadprogress/100,1); + text.glPrint(280,125,string,1,1,640,480); + */ +#ifdef WIN32 + SwapBuffers( hDC); +#else + aglSwapBuffers(gaglContext); // send swap command +#endif + + loadscreencolor=0; +} + + +void Game::InitGame() +{ +#ifndef WIN32 + ProcessSerialNumber PSN; + ProcessInfoRec pinfo; + FSSpec pspec; + OSStatus err; + /* set up process serial number */ + PSN.highLongOfPSN = 0; + PSN.lowLongOfPSN = kCurrentProcess; + /* set up info block */ + pinfo.processInfoLength = sizeof(pinfo); + pinfo.processName = NULL; + pinfo.processAppSpec = &pspec; + /* grab the vrefnum and directory */ + err = GetProcessInformation(&PSN, &pinfo); + if (err == noErr) { + vRefNum = pspec.vRefNum; + dirID = pspec.parID; + } +#endif + + LOGFUNC; + + autocam=0; + + int i,j; + + numchallengelevels=14; + + registered=0; + + /*char tempstring[256]; + sprintf (tempstring, "%s", registrationname); + long num1; + long num2; + long num3; + long num4; + long long longnum; + longnum = MD5_string ( tempstring); + //longnum = 1111111111111111; + num1 = longnum/100000000; + num2 = longnum%100000000; + sprintf (tempstring, "%d-%d-%d-%d", num1/10000, num1%10000, num2/10000, num2%10000); + */ + + FILE *tfile; + tfile=fopen( ":Data:Sounds:flame.ogg", "rb" ); + if(tfile) + { + long num1; + long num2; + long long longnum; + long long longnuma; + long num1a; + long num2a; + + int numchars; + funpackf(tfile, "Bb", ®istered); + if(registered) + { + funpackf(tfile, "Bi", &numchars); + if(numchars>0) + { + for(j=0;j2)registered=1; + else registered=0; + } + } + fclose(tfile); + } + else registered=0; + + accountactive=-1; + + sprintf (mapname, ":Data:Users"); + tfile=fopen( mapname, "rb" ); + if(tfile) + { + funpackf(tfile, "Bi", &numaccounts); + funpackf(tfile, "Bi", &accountactive); + if(numaccounts>0) + { + for(i=0;i= 10) + { + accountcampaignchoices[i][j] = 0; + } + } + funpackf(tfile, "Bf", &accountpoints[i]); + for(j=0;j<50;j++) + { + funpackf(tfile, "Bf", &accounthighscore[i][j]); + funpackf(tfile, "Bf", &accountfasttime[i][j]); + } + for(j=0;j<60;j++) + { + funpackf(tfile, "Bb", &accountunlocked[i][j]); + } + int temp; + funpackf(tfile, "Bi", &temp); + if(temp>0) + { + for(j=0;j2)texdetail=2; + LoadTexture(":Data:Textures:Lugaru.png",&Mainmenuitems[0],0,0); + LoadTexture(":Data:Textures:Newgame.png",&Mainmenuitems[1],0,0); + LoadTexture(":Data:Textures:Options.png",&Mainmenuitems[2],0,0); + LoadTexture(":Data:Textures:Quit.png",&Mainmenuitems[3],0,0); + LoadTexture(":Data:Textures:World.png",&Mainmenuitems[7],0,0); + LoadTexture(":Data:Textures:Eyelid.png",&Mainmenuitems[4],0,1); + //LoadTexture(":Data:Textures:Eye.jpg",&Mainmenuitems[5],0,1); + texdetail=temptexdetail; + + loaddistrib=0; + anim=0; + + FadeLoadingScreen(95); + + + gameon=0; + mainmenu=1; + + stillloading=0; + firstload=0; + oldmainmenu=0; + + newdetail=detail; + newscreenwidth=screenwidth; + newscreenheight=screenheight; + + + + /* + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + */ +} + + +void Game::LoadStuff() +{ + static float temptexdetail; + static float viewdistdetail; + static int i,j,texsize; + float megascale =1; + + LOGFUNC; + + visibleloading=1; + + /*musicvolume[3]=512; + PlaySoundEx( music4, samp[music4], NULL, TRUE); + FSOUND_SetPaused(channels[music4], FALSE); + FSOUND_SetVolume(channels[music4], 512); + */ + loadtime=0; + + stillloading=1; + + //texture.data = ( GLubyte* )malloc( 1024*1024*4 ); + + newnetmessages=0; + + for(i=0;i4)texdetail=4; + LoadTexture(":Data:Textures:shadow.png",&terrain.shadowtexture,0,1); + + LoadTexture(":Data:Textures:blood.png",&terrain.bloodtexture,0,1); + + LoadTexture(":Data:Textures:break.png",&terrain.breaktexture,0,1); + + LoadTexture(":Data:Textures:blood.png",&terrain.bloodtexture2,0,1); + + + LoadTexture(":Data:Textures:footprint.png",&terrain.footprinttexture,0,1); + + LoadTexture(":Data:Textures:bodyprint.png",&terrain.bodyprinttexture,0,1); + + /*LoadTexture(":Data:Textures:cloud.png",&sprites.cloudtexture,1); + + LoadTexture(":Data:Textures:cloudimpact.png",&sprites.cloudimpacttexture,1); + + LoadTexture(":Data:Textures:bloodparticle.png",&sprites.bloodtexture,1); + + LoadTexture(":Data:Textures:snowflake.png",&sprites.snowflaketexture,1); + + LoadTexture(":Data:Textures:flame.png",&sprites.flametexture,1); + + LoadTexture(":Data:Textures:smoke.png",&sprites.smoketexture,1); + //texdetail=temptexdetail; + LoadTexture(":Data:Textures:shine.png",&sprites.shinetexture,1);*/ + + + + LoadTexture(":Data:Textures:hawk.png",&hawktexture,0,1); + + LoadTexture(":Data:Textures:logo.png",&logotexture,0,1); + + + //LoadTexture(":Data:Textures:box.jpg",&objects.boxtextureptr,1,0); + + + LoadTexture(":Data:Textures:cloud.png",&sprites.cloudtexture,1,1); + LoadTexture(":Data:Textures:cloudimpact.png",&sprites.cloudimpacttexture,1,1); + LoadTexture(":Data:Textures:bloodparticle.png",&sprites.bloodtexture,1,1); + LoadTexture(":Data:Textures:snowflake.png",&sprites.snowflaketexture,1,1); + LoadTexture(":Data:Textures:flame.png",&sprites.flametexture,1,1); + LoadTexture(":Data:Textures:bloodflame.png",&sprites.bloodflametexture,1,1); + LoadTexture(":Data:Textures:smoke.png",&sprites.smoketexture,1,1); + LoadTexture(":Data:Textures:shine.png",&sprites.shinetexture,1,0); + LoadTexture(":Data:Textures:splinter.png",&sprites.splintertexture,1,1); + LoadTexture(":Data:Textures:leaf.png",&sprites.leaftexture,1,1); + LoadTexture(":Data:Textures:tooth.png",&sprites.toothtexture,1,1); + + rotation=0; + rotation2=0; + ReSizeGLScene(90,.01); + + viewer=0; + + + + + if(detail)kTextureSize=1024; + if(detail==1)kTextureSize=512; + if(detail==0)kTextureSize=256; + + + //drawmode=motionblurmode; + + //Set up distant light + light.color[0]=.95; + light.color[1]=.95; + light.color[2]=1; + light.ambient[0]=.2; + light.ambient[1]=.2; + light.ambient[2]=.24; + light.location.x=1; + light.location.y=1; + light.location.z=-.2; + Normalise(&light.location); + + LoadingScreen(); + + SetUpLighting(); + + + fadestart=.6; + gravity=-10; + + texscale=.2/megascale/viewdistdetail; + terrain.scale=3*megascale*terraindetail*viewdistdetail; + + viewer.x=terrain.size/2*terrain.scale; + viewer.z=terrain.size/2*terrain.scale; + + hawk.load((char *)":Data:Models:hawk.solid",1); + hawk.Scale(.03,.03,.03); + hawk.Rotate(90,1,1); + hawk.CalculateNormals(0); + hawk.ScaleNormals(-1,-1,-1); + hawkcoords.x=terrain.size/2*terrain.scale-5-7; + hawkcoords.z=terrain.size/2*terrain.scale-5-7; + hawkcoords.y=terrain.getHeight(hawkcoords.x,hawkcoords.z)+25; + + + eye.load((char *)":Data:Models:eye.solid",1); + eye.Scale(.03,.03,.03); + eye.CalculateNormals(0); + + cornea.load((char *)":Data:Models:cornea.solid",1); + cornea.Scale(.03,.03,.03); + cornea.CalculateNormals(0); + + iris.load((char *)":Data:Models:iris.solid",1); + iris.Scale(.03,.03,.03); + iris.CalculateNormals(0); + + LoadSave(":Data:Textures:Bloodfur.png",0,1,&bloodText[0],0); + LoadSave(":Data:Textures:Wolfbloodfur.png",0,1,&wolfbloodText[0],0); + + oldenvironment=-4; + + gameon=1; + mainmenu=0; + + firstload=0; + //if(targetlevel!=7) + Loadlevel(targetlevel); + + + rabbitcoords=player[0].coords; + rabbitcoords.y=terrain.getHeight(rabbitcoords.x,rabbitcoords.z); + + animation[runanim].Load((char *)":Data:Animations:Run",middleheight,neutral); + + animation[bounceidleanim].Load((char *)":Data:Animations:Idle",middleheight,neutral); + animation[stopanim].Load((char *)":Data:Animations:Stop",middleheight,neutral); + + animation[jumpupanim].Load((char *)":Data:Animations:JumpUp",highheight,neutral); + animation[jumpdownanim].Load((char *)":Data:Animations:JumpDown",highheight,neutral); + + animation[landanim].Load((char *)":Data:Animations:Landing",lowheight,neutral); + animation[landhardanim].Load((char *)":Data:Animations:Landhard",lowheight,neutral); + animation[climbanim].Load((char *)":Data:Animations:Climb",lowheight,neutral); + animation[hanganim].Load((char *)":Data:Animations:Hangon",lowheight,neutral); + animation[spinkickanim].Load((char *)":Data:Animations:SpinKick",middleheight,normalattack); + + animation[getupfromfrontanim].Load((char *)":Data:Animations:GetUpFromFront",lowheight,neutral); + animation[getupfrombackanim].Load((char *)":Data:Animations:GetUpFromBack",lowheight,neutral); + animation[crouchanim].Load((char *)":Data:Animations:Crouch",lowheight,neutral); + animation[sneakanim].Load((char *)":Data:Animations:Sneak",lowheight,neutral); + animation[rollanim].Load((char *)":Data:Animations:Roll",lowheight,neutral); + animation[flipanim].Load((char *)":Data:Animations:Flip",highheight,neutral); + animation[frontflipanim].Load((char *)":Data:Animations:Flip",highheight,neutral); + animation[spinkickreversedanim].Load((char *)":Data:Animations:SpinKickCaught",middleheight,reversed); + + animation[spinkickreversalanim].Load((char *)":Data:Animations:SpinKickCatch",middleheight,reversal); + animation[lowkickanim].Load((char *)":Data:Animations:lowkick",middleheight,normalattack); + animation[sweepanim].Load((char *)":Data:Animations:sweep",lowheight,normalattack); + animation[sweepreversedanim].Load((char *)":Data:Animations:SweepCaught",lowheight,reversed); + animation[sweepreversalanim].Load((char *)":Data:Animations:SweepCatch",middleheight,reversal); + animation[rabbitkickanim].Load((char *)":Data:Animations:RabbitKick",middleheight,normalattack); + animation[rabbitkickreversedanim].Load((char *)":Data:Animations:RabbitKickCaught",middleheight,reversed); + animation[rabbitkickreversalanim].Load((char *)":Data:Animations:RabbitKickCatch",lowheight,reversal); + animation[upunchanim].Load((char *)":Data:Animations:Upunch",middleheight,normalattack); + animation[staggerbackhighanim].Load((char *)":Data:Animations:Staggerbackhigh",middleheight,neutral); + animation[upunchreversedanim].Load((char *)":Data:Animations:UpunchCaught",middleheight,reversed); + + animation[upunchreversalanim].Load((char *)":Data:Animations:UpunchCatch",middleheight,reversal); + animation[hurtidleanim].Load((char *)":Data:Animations:Hurtidle",middleheight,neutral); + animation[backhandspringanim].Load((char *)":Data:Animations:Backhandspring",middleheight,neutral); + animation[fightidleanim].Load((char *)":Data:Animations:Fightidle",middleheight,neutral); + animation[walkanim].Load((char *)":Data:Animations:Walk",middleheight,neutral); + + animation[fightsidestep].Load((char *)":Data:Animations:Fightsidestep",middleheight,neutral); + animation[killanim].Load((char *)":Data:Animations:Kill",middleheight,normalattack); + animation[sneakattackanim].Load((char *)":Data:Animations:Sneakattack",middleheight,reversal); + animation[sneakattackedanim].Load((char *)":Data:Animations:Sneakattacked",middleheight,reversed); + animation[drawrightanim].Load((char *)":Data:Animations:drawright",middleheight,neutral); + animation[knifeslashstartanim].Load((char *)":Data:Animations:slashstart",middleheight,normalattack); + animation[crouchdrawrightanim].Load((char *)":Data:Animations:crouchdrawright",lowheight,neutral); + animation[crouchstabanim].Load((char *)":Data:Animations:crouchstab",lowheight,normalattack); + + animation[knifefollowanim].Load((char *)":Data:Animations:slashfollow",middleheight,reversal); + animation[knifefollowedanim].Load((char *)":Data:Animations:slashfollowed",middleheight,reversed); + animation[knifethrowanim].Load((char *)":Data:Animations:knifethrow",middleheight,normalattack); + animation[removeknifeanim].Load((char *)":Data:Animations:removeknife",middleheight,neutral); + animation[crouchremoveknifeanim].Load((char *)":Data:Animations:crouchremoveknife",lowheight,neutral); + animation[jumpreversedanim].Load((char *)":Data:Animations:JumpCaught",middleheight,reversed); + animation[jumpreversalanim].Load((char *)":Data:Animations:JumpCatch",middleheight,reversal); + animation[staggerbackhardanim].Load((char *)":Data:Animations:Staggerbackhard",middleheight,neutral); + + animation[dropkickanim].Load((char *)":Data:Animations:Dropkick",middleheight,normalattack); + animation[winduppunchanim].Load((char *)":Data:Animations:Winduppunch",middleheight,normalattack); + animation[winduppunchblockedanim].Load((char *)":Data:Animations:Winduppunchblocked",middleheight,normalattack); + animation[blockhighleftanim].Load((char *)":Data:Animations:Blockhighleft",middleheight,normalattack); + animation[blockhighleftstrikeanim].Load((char *)":Data:Animations:Blockhighleftstrike",middleheight,normalattack); + animation[backflipanim].Load((char *)":Data:Animations:Backflip",highheight,neutral); + animation[walljumpbackanim].Load((char *)":Data:Animations:Walljumpback",highheight,neutral); + animation[walljumpfrontanim].Load((char *)":Data:Animations:Walljumpfront",highheight,neutral); + animation[rightflipanim].Load((char *)":Data:Animations:Rightflip",highheight,neutral); + animation[walljumprightanim].Load((char *)":Data:Animations:Walljumpright",highheight,neutral); + animation[leftflipanim].Load((char *)":Data:Animations:Leftflip",highheight,neutral); + animation[walljumpleftanim].Load((char *)":Data:Animations:Walljumpleft",highheight,neutral); + animation[walljumprightkickanim].Load((char *)":Data:Animations:Walljumprightkick",highheight,neutral); + animation[walljumpleftkickanim].Load((char *)":Data:Animations:Walljumpleftkick",highheight,neutral); + animation[knifefightidleanim].Load((char *)":Data:Animations:Knifefightidle",middleheight,neutral); + animation[knifesneakattackanim].Load((char *)":Data:Animations:Knifesneakattack",middleheight,reversal); + animation[knifesneakattackedanim].Load((char *)":Data:Animations:Knifesneakattacked",middleheight,reversed); + animation[swordfightidleanim].Load((char *)":Data:Animations:swordfightidle",middleheight,neutral); + animation[drawleftanim].Load((char *)":Data:Animations:drawleft",middleheight,neutral); + animation[swordslashanim].Load((char *)":Data:Animations:swordslash",middleheight,normalattack); + animation[swordgroundstabanim].Load((char *)":Data:Animations:swordgroundstab",lowheight,normalattack); + animation[dodgebackanim].Load((char *)":Data:Animations:dodgeback",middleheight,neutral); + animation[swordsneakattackanim].Load((char *)":Data:Animations:Swordsneakattack",middleheight,reversal); + animation[swordsneakattackedanim].Load((char *)":Data:Animations:Swordsneakattacked",middleheight,reversed); + animation[swordslashreversedanim].Load((char *)":Data:Animations:swordslashCaught",middleheight,reversed); + animation[swordslashreversalanim].Load((char *)":Data:Animations:swordslashCatch",middleheight,reversal); + animation[knifeslashreversedanim].Load((char *)":Data:Animations:knifeslashCaught",middleheight,reversed); + animation[knifeslashreversalanim].Load((char *)":Data:Animations:knifeslashCatch",middleheight,reversal); + animation[swordfightidlebothanim].Load((char *)":Data:Animations:swordfightidleboth",middleheight,neutral); + animation[swordslashparryanim].Load((char *)":Data:Animations:sworduprightparry",middleheight,normalattack); + animation[swordslashparriedanim].Load((char *)":Data:Animations:swordslashparried",middleheight,normalattack); + animation[wolfidle].Load((char *)":Data:Animations:Wolfidle",middleheight,neutral); + animation[wolfcrouchanim].Load((char *)":Data:Animations:Wolfcrouch",lowheight,neutral); + animation[wolflandanim].Load((char *)":Data:Animations:Wolflanding",lowheight,neutral); + animation[wolflandhardanim].Load((char *)":Data:Animations:Wolflandhard",lowheight,neutral); + animation[wolfrunanim].Load((char *)":Data:Animations:Wolfrun",middleheight,neutral); + animation[wolfrunninganim].Load((char *)":Data:Animations:Wolfrunning",middleheight,neutral); + animation[rabbitrunninganim].Load((char *)":Data:Animations:Rabbitrunning",middleheight,neutral); + animation[wolfstopanim].Load((char *)":Data:Animations:Wolfstop",middleheight,neutral); + animation[rabbittackleanim].Load((char *)":Data:Animations:Rabbittackle",middleheight,neutral); + animation[rabbittacklinganim].Load((char *)":Data:Animations:Rabbittackling",middleheight,reversal); + animation[rabbittackledbackanim].Load((char *)":Data:Animations:Rabbittackledback",middleheight,reversed); + animation[rabbittackledfrontanim].Load((char *)":Data:Animations:Rabbittackledfront",middleheight,reversed); + animation[wolfslapanim].Load((char *)":Data:Animations:Wolfslap",middleheight,normalattack); + animation[staffhitanim].Load((char *)":Data:Animations:StaffHit",middleheight,normalattack); + animation[staffgroundsmashanim].Load((char *)":Data:Animations:StaffGroundSmash",lowheight,normalattack); + animation[staffspinhitanim].Load((char *)":Data:Animations:Spinwhack",middleheight,normalattack); + animation[staffhitreversedanim].Load((char *)":Data:Animations:StaffHitCaught",middleheight,reversed); + animation[staffhitreversalanim].Load((char *)":Data:Animations:StaffHitCatch",middleheight,reversal); + animation[staffspinhitreversedanim].Load((char *)":Data:Animations:SpinWhackCaught",middleheight,reversed); + animation[staffspinhitreversalanim].Load((char *)":Data:Animations:SpinWhackCatch",middleheight,reversal); + + animation[sitanim].Load((char *)":Data:Animations:Sit",lowheight,neutral); + animation[sleepanim].Load((char *)":Data:Animations:Sleep",lowheight,neutral); + animation[talkidleanim].Load((char *)":Data:Animations:TalkIdle",middleheight,neutral); + + animation[sitwallanim].Load((char *)":Data:Animations:Dying",lowheight,neutral); + animation[dead1anim].Load((char *)":Data:Animations:Dead1",lowheight,neutral); + animation[dead2anim].Load((char *)":Data:Animations:Dead2",lowheight,neutral); + animation[dead3anim].Load((char *)":Data:Animations:Dead3",lowheight,neutral); + animation[dead4anim].Load((char *)":Data:Animations:Dead4",lowheight,neutral); + //Fix knife stab, too lazy to do it manually + XYZ moveamount; + moveamount=0; + moveamount.z=2; + for(i=0;i +#include +#include "Game.h" + +using namespace std; + +extern float multiplier; +extern XYZ viewer; +extern int environment; +extern float texscale; +extern Terrain terrain; +extern FSOUND_SAMPLE *samp[100]; +extern int channels[100]; +extern Sprites sprites; +extern int kTextureSize; +extern float screenwidth,screenheight; +extern float gravity; +extern int detail; +extern float texdetail; +extern Objects objects; +extern int slomo; +extern float slomodelay; +extern bool floatjump; +extern float volume; +extern Animation animation[animation_count]; +extern Light light; +extern float texdetail; +extern GLubyte bloodText[512*512*3]; +extern GLubyte wolfbloodText[512*512*3]; +extern float terraindetail; +extern float camerashake; +extern float woozy; +extern float blackout; +extern bool cellophane; +extern bool musictoggle; +extern int difficulty; +extern Weapons weapons; +extern Person player[maxplayers]; +extern int numplayers; +extern int bloodtoggle; +extern bool invertmouse; +extern float windvar; +extern float precipdelay; +extern XYZ viewerfacing; +extern bool ambientsound; +extern bool mousejump; +extern float viewdistance; +extern bool freeze; +extern bool autoslomo; +extern int newnetmessages; +extern char netmessages[256]; +extern bool keyboardfrozen; +extern int netdatanew; +extern bool loadingstuff; +extern char mapname[256]; +extern XYZ windvector; +extern bool buttons[3]; +extern bool debugmode; +static int music1; +extern int mainmenu; +extern int oldmainmenu; +extern bool visibleloading; +extern int loadscreencolor; +extern float flashamount,flashr,flashg,flashb; +extern int flashdelay; +extern XYZ envsound[30]; +extern float envsoundvol[30]; +extern int numenvsounds; +extern float envsoundlife[30]; +extern float usermousesensitivity; +extern bool ismotionblur; +extern bool foliage; +extern bool trilinear; +extern bool damageeffects; +extern bool showpoints; +extern bool texttoggle; +extern bool alwaysblur; +extern float gamespeed; +extern bool decals; +extern bool vblsync; +extern bool immediate; +extern bool velocityblur; +extern int bonus; +extern int oldbonus; +extern float bonusvalue; +extern float bonustotal; +extern float bonustime; +extern float startbonustotal; +extern float tintr,tintg,tintb; +extern float bonusnum[100]; +extern bool skyboxtexture; +extern float skyboxr; +extern float skyboxg; +extern float skyboxb; +extern float skyboxlightr; +extern float skyboxlightg; +extern float skyboxlightb; +extern float fadestart; +extern float slomospeed; +extern float slomofreq; +extern int tutoriallevel; +extern float smoketex; +extern float tutorialstagetime; +extern int tutorialstage; +extern float tutorialmaxtime; +extern float tutorialsuccess; +extern bool againbonus; +extern bool reversaltrain; +extern bool canattack; +extern bool cananger; +extern float damagedealt; +extern float damagetaken; +extern int maptype; +extern int editoractive; +extern int editorpathtype; +extern bool oldbuttons[3]; + +extern float hostiletime; + +extern bool gamestarted; + +extern int numhotspots; +extern int winhotspot; +extern int windialogue; +extern int killhotspot; +extern XYZ hotspot[40]; +extern int hotspottype[40]; +extern float hotspotsize[40]; +extern char hotspottext[40][256]; +extern int currenthotspot; + +extern int kBitsPerPixel; +extern int hostile; + +extern int numaccounts; +extern int accountactive; +extern int accountdifficulty[10]; +extern int accountprogress[10]; +extern float accountpoints[10]; +extern float accounthighscore[10][50]; +extern float accountfasttime[10][50]; +extern bool accountunlocked[10][60]; +extern char accountname[10][256]; + +extern bool stillloading; +extern bool winfreeze; + +extern int numfalls; +extern int numflipfail; +extern int numseen; +extern int numstaffattack; +extern int numswordattack; +extern int numknifeattack; +extern int numunarmedattack; +extern int numescaped; +extern int numflipped; +extern int numwallflipped; +extern int numthrowkill; +extern int numafterkill; +extern int numreversals; +extern int numattacks; +extern int maxalarmed; +extern int numresponded; + +extern int numdialogues; +extern int numdialogueboxes[max_dialogues]; +extern int dialoguetype[max_dialogues]; +extern int dialogueboxlocation[max_dialogues][max_dialoguelength]; +extern float dialogueboxcolor[max_dialogues][max_dialoguelength][3]; +extern int dialogueboxsound[max_dialogues][max_dialoguelength]; +extern char dialoguetext[max_dialogues][max_dialoguelength][128]; +extern char dialoguename[max_dialogues][max_dialoguelength][64]; +extern XYZ dialoguecamera[max_dialogues][max_dialoguelength]; +extern XYZ participantlocation[max_dialogues][10]; +extern int participantfocus[max_dialogues][max_dialoguelength]; +extern int participantaction[max_dialogues][max_dialoguelength]; +extern float participantrotation[max_dialogues][10]; +extern XYZ participantfacing[max_dialogues][max_dialoguelength][10]; +extern float dialoguecamerarotation[max_dialogues][max_dialoguelength]; +extern float dialoguecamerarotation2[max_dialogues][max_dialoguelength]; +extern int indialogue; +extern int whichdialogue; +extern int directing; +extern float dialoguetime; +extern int dialoguegonethrough[20]; + +extern bool campaign; + +extern float oldgamespeed; + +extern float accountcampaignhighscore[10]; +extern float accountcampaignfasttime[10]; +extern float accountcampaignscore[10]; +extern float accountcampaigntime[10]; + +extern int accountcampaignchoicesmade[10]; +extern int accountcampaignchoices[10][5000]; +/********************> Tick() <*****/ +extern FSOUND_STREAM * strm[10]; +extern "C" void PlaySoundEx(int channel, FSOUND_SAMPLE *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused); +extern "C" void PlayStreamEx(int chan, FSOUND_STREAM *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused); + +extern void ScreenShot(const char * fname); +void Screenshot (void) +{ + char temp[1024]; + time_t t = time(NULL); + struct tm *tme = localtime(&t); + sprintf(temp, "Screenshots\\Screenshot_%04d_%02d_%02d--%02d_%02d_%02d.png", tme->tm_year + 1900, tme->tm_mon + 1, tme->tm_mday, tme->tm_hour, tme->tm_min, tme->tm_sec); + + mkdir("Screenshots"); + ScreenShot(temp/*"Screenshots\\Screenshot.png"*/); + + /*FSSpec MAC_file; + GraphicsExportComponent QT_exporter; + OSErr MAC_error_code; + CGrafPtr MAC_currentPort; + GDHandle MAC_currentDevice; + unsigned char* MAC_pixels; + Rect MAC_picture_rectangle; + GWorldPtr MAC_offscreen_graphics_port; + + static int numscreenshots=0; + + // Make an FSSpec + static char buf[256]; + if(numscreenshots==0){ + buf[0]=26; + buf[1]=':'; + buf[2]='S'; + buf[3]='c'; + buf[4]='r'; + buf[5]='e'; + buf[6]='e'; + buf[7]='n'; + buf[8]='s'; + buf[9]='h'; + buf[10]='o'; + buf[11]='t'; + buf[12]='s'; + buf[13]=':'; + buf[14]='S'; + buf[15]='c'; + buf[16]='r'; + buf[17]='e'; + buf[18]='e'; + buf[19]='n'; + buf[20]='s'; + buf[21]='h'; + buf[22]='o'; + buf[23]='t'; + buf[24]='0'; + buf[25]='0'; + buf[26]='0'; + } + + FInfo *fndrInfo; + FSMakeFSSpec(0, 0, (unsigned char*)buf, &MAC_file); + while(!FSpGetFInfo (&MAC_file, fndrInfo)){ + FSMakeFSSpec(0, 0, (unsigned char*)buf, &MAC_file); + if(!FSpGetFInfo (&MAC_file, fndrInfo)){ + numscreenshots++; + buf[26]++; + if(buf[26]==':'){ + buf[26]='0'; + buf[25]++; + if(buf[25]==':'){ + buf[25]='0'; + buf[24]++; + if(buf[24]==':'){ + buf[24]='9'; + buf[25]='9'; + buf[26]='9'; + } + } + } + } + } + + + // Get the GWorld + GWorldPtr MAC_gWorld = (CGrafPtr) FrontWindow(); + //assert(MAC_gWorld != NULL); + + // Allocate memory for loading image + MAC_pixels = new unsigned char[(int)(screenheight * screenwidth * 4)]; + if (MAC_pixels == NULL) { + //UTIL_Error("Could not create Texture data."); + return; + } + + // Get GWorld + ::GetGWorld(&MAC_currentPort, &MAC_currentDevice); + + // Make a picture Rectangle + MAC_picture_rectangle.left = 0; + MAC_picture_rectangle.right = screenwidth; + MAC_picture_rectangle.top = 0; + MAC_picture_rectangle.bottom = screenheight; + + // Create new offscreen GWorld + MAC_error_code = ::QTNewGWorldFromPtr (&MAC_offscreen_graphics_port, k32ARGBPixelFormat, &MAC_picture_rectangle, NULL, NULL, 0, (char *) MAC_pixels, screenwidth * 4); + if (MAC_error_code) { + ::SetGWorld(MAC_currentPort, MAC_currentDevice); + delete MAC_pixels; + //UTIL_Error("Could not create offscreen GWorld. "); + return; + + } + + // Copy OpenGL Context to new GWorld + glReadBuffer(GL_FRONT); + glReadPixels(0,0,screenwidth,screenheight,GL_RGBA,GL_UNSIGNED_BYTE,MAC_pixels); + + // Swizzle texture + for (unsigned long byte = 0; byte < screenheight * screenwidth * 4; byte+=4) { + unsigned char temp = MAC_pixels[byte+0]; + MAC_pixels[byte+0] = MAC_pixels[byte+3]; + MAC_pixels[byte+3] = MAC_pixels[byte+2]; + MAC_pixels[byte+2] = MAC_pixels[byte+1]; + MAC_pixels[byte+1] = temp; + } + + // Flip the image :( This could probably be optimized + int vert; + int src_index; + int dst_index; + unsigned char temp; + for (int horz = 0; horz < screenwidth; ++horz) + for (vert = 0; vert < screenheight / 2; ++vert) { + src_index = (screenwidth * vert + horz) * 4; + dst_index = (screenwidth * (screenheight - vert - 1) + horz) * 4; + + temp=MAC_pixels[src_index+0]; + MAC_pixels[src_index+0]=MAC_pixels[dst_index+0]; + MAC_pixels[dst_index+0]=temp; + + temp=MAC_pixels[src_index+1]; + MAC_pixels[src_index+1]=MAC_pixels[dst_index+1]; + MAC_pixels[dst_index+1]=temp; + + temp=MAC_pixels[src_index+2]; + MAC_pixels[src_index+2]=MAC_pixels[dst_index+2]; + MAC_pixels[dst_index+2]=temp; + + temp=MAC_pixels[src_index+3]; + MAC_pixels[src_index+3]=MAC_pixels[dst_index+3]; + MAC_pixels[dst_index+3]=temp; + } + + + + // Export the Gworld + MAC_error_code = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeBMP, &QT_exporter); + if (MAC_error_code) { + //UTIL_Warning("Unable to export screenshot."); + ::SetGWorld(MAC_currentPort, MAC_currentDevice); + ::DisposeGWorld(MAC_offscreen_graphics_port); + delete MAC_pixels; + return; + } + + MAC_error_code = GraphicsExportSetInputGWorld(QT_exporter,MAC_offscreen_graphics_port); + if (MAC_error_code) { + ::CloseComponent(QT_exporter); + ::SetGWorld(MAC_currentPort, MAC_currentDevice); + ::DisposeGWorld(MAC_offscreen_graphics_port); + delete MAC_pixels; + //UTIL_Warning("Unable to export screenshot."); + return; + } + + MAC_error_code = GraphicsExportSetOutputFile(QT_exporter,&MAC_file); + if (MAC_error_code) { + ::CloseComponent(QT_exporter); + ::SetGWorld(MAC_currentPort, MAC_currentDevice); + ::DisposeGWorld(MAC_offscreen_graphics_port); + delete MAC_pixels; + //UTIL_Warning("Unable to export screenshot."); + return; + } + + MAC_error_code = GraphicsExportDoExport(QT_exporter,NULL); + if (MAC_error_code) { + ::CloseComponent(QT_exporter); + ::SetGWorld(MAC_currentPort, MAC_currentDevice); + ::DisposeGWorld(MAC_offscreen_graphics_port); + delete MAC_pixels; + //UTIL_Warning("Unable to export screenshot."); + return; + } + + ::CloseComponent(QT_exporter); + ::SetGWorld(MAC_currentPort, MAC_currentDevice); + ::DisposeGWorld(MAC_offscreen_graphics_port); + + delete MAC_pixels;*/ +} + + + +void Game::SetUpLighting(){ + if(environment==snowyenvironment){ + light.color[0]=.65; + light.color[1]=.65; + light.color[2]=.7; + light.ambient[0]=.4; + light.ambient[1]=.4; + light.ambient[2]=.44; + } + if(environment==desertenvironment){ + light.color[0]=.95; + light.color[1]=.95; + light.color[2]=.95; + light.ambient[0]=.4; + light.ambient[1]=.35; + light.ambient[2]=.3; + } + + if(environment==grassyenvironment){ + light.color[0]=.95; + light.color[1]=.95; + light.color[2]=1; + light.ambient[0]=.4; + light.ambient[1]=.4; + light.ambient[2]=.44; + } + if(!skyboxtexture){ + light.color[0]=1; + light.color[1]=1; + light.color[2]=1; + light.ambient[0]=.4; + light.ambient[1]=.4; + light.ambient[2]=.4; + } + float average; + average=(skyboxlightr+skyboxlightg+skyboxlightb)/3; + light.color[0]*=(skyboxlightr+average)/2; + light.color[1]*=(skyboxlightg+average)/2; + light.color[2]*=(skyboxlightb+average)/2; + light.ambient[0]=light.ambient[0]*(skyboxlightr+average)/2*1; + light.ambient[1]=light.ambient[1]*(skyboxlightg+average)/2*1; + light.ambient[2]=light.ambient[2]*(skyboxlightb+average)/2*1; + /* + light.ambient[0]=0; + light.ambient[1]=0; + light.ambient[2]=0; */ +} + +int Game::findPathDist(int start,int end){ + int i,j,k,smallestcount,count,connected; + int last,last2,last3,last4; + int closest; + + smallestcount=1000; + for(i=0;i<50;i++){ + count=0; + last=start; + last2=-1; + last3=-1; + last4=-1; + while(last!=end&&count<30){ + closest=-1; + for(j=0;jendpoint.x)minx=endpoint.x; + miny=startpoint.y; + if(miny>endpoint.y)miny=endpoint.y; + minz=startpoint.z; + if(minz>endpoint.z)minz=endpoint.z; + + maxx=startpoint.x; + if(maxxminx-objects.model[i].boundingsphereradius&&objects.position[i].xminy-objects.model[i].boundingsphereradius&&objects.position[i].yminz-objects.model[i].boundingsphereradius&&objects.position[i].zendpoint.x)minx=endpoint.x; + miny=startpoint.y; + if(miny>endpoint.y)miny=endpoint.y; + minz=startpoint.z; + if(minz>endpoint.z)minz=endpoint.z; + + maxx=startpoint.x; + if(maxxminx-objects.model[what].boundingsphereradius&&objects.position[what].xminy-objects.model[what].boundingsphereradius&&objects.position[what].yminz-objects.model[what].boundingsphereradius&&objects.position[what].z1)texdetail=4; + skybox.load( ":Data:Textures:Skybox(snow):Front.jpg", + ":Data:Textures:Skybox(snow):Left.jpg", + ":Data:Textures:Skybox(snow):Back.jpg", + ":Data:Textures:Skybox(snow):Right.jpg", + ":Data:Textures:Skybox(snow):Up.jpg", + ":Data:Textures:Skybox(snow):Down.jpg", + ":Data:Textures:Skybox(snow):Cloud.jpg", + ":Data:Textures:Skybox(snow):Reflect.jpg"); + + + + + texdetail=temptexdetail; + } + if(environment==desertenvironment){ + windvector=0; + windvector.z=2; + LoadTexture(":Data:Textures:deserttree.png",&objects.treetextureptr,0,1); + LoadTexture(":Data:Textures:bushdesert.png",&objects.bushtextureptr,0,1); + LoadTexture(":Data:Textures:boulderdesert.jpg",&objects.rocktextureptr,1,0); + LoadTexture(":Data:Textures:desertbox.jpg",&objects.boxtextureptr,1,0); + + + if(ambientsound){ + //PlaySoundEx( desertambient, samp[desertambient], NULL, TRUE); + PlayStreamEx( stream_desertambient, strm[stream_desertambient], NULL, TRUE); + FSOUND_SetPaused(channels[stream_desertambient], FALSE); + FSOUND_SetVolume(channels[stream_desertambient], 256); + } + + FSOUND_Sample_Free(samp[footstepsound]); + FSOUND_Sample_Free(samp[footstepsound2]); + FSOUND_Sample_Free(samp[footstepsound3]); + FSOUND_Sample_Free(samp[footstepsound4]); + samp[footstepsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepsnow1.ogg", FSOUND_HW3D, 0); + samp[footstepsound2] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepsnow2.ogg", FSOUND_HW3D, 0); + samp[footstepsound3] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepsnow1.ogg", FSOUND_HW3D, 0); + samp[footstepsound4] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepsnow2.ogg", FSOUND_HW3D, 0); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound], 4.0f, 1000.0f); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound2], 4.0f, 1000.0f); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound3], 4.0f, 1000.0f); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound4], 4.0f, 1000.0f); + + LoadTexture(":Data:Textures:sand.jpg",&terraintexture,1,0); + + LoadTexture(":Data:Textures:sandslope.jpg",&terraintexture2,1,0); + + //LoadTexture(":Data:Textures:detailgrain.png",&terraintexture3,1); + + + + temptexdetail=texdetail; + if(texdetail>1)texdetail=4; + skybox.load( ":Data:Textures:Skybox(sand):Front.jpg", + ":Data:Textures:Skybox(sand):Left.jpg", + ":Data:Textures:Skybox(sand):Back.jpg", + ":Data:Textures:Skybox(sand):Right.jpg", + ":Data:Textures:Skybox(sand):Up.jpg", + ":Data:Textures:Skybox(sand):Down.jpg", + ":Data:Textures:Skybox(sand):Cloud.jpg", + ":Data:Textures:Skybox(sand):Reflect.jpg"); + + + + + texdetail=temptexdetail; + } + if(environment==grassyenvironment){ + windvector=0; + windvector.z=2; + LoadTexture(":Data:Textures:tree.png",&objects.treetextureptr,0,1); + LoadTexture(":Data:Textures:bush.png",&objects.bushtextureptr,0,1); + LoadTexture(":Data:Textures:boulder.jpg",&objects.rocktextureptr,1,0); + LoadTexture(":Data:Textures:grassbox.jpg",&objects.boxtextureptr,1,0); + + if(ambientsound){ + PlayStreamEx( stream_wind, strm[stream_wind], NULL, TRUE); + FSOUND_SetPaused(channels[stream_wind], FALSE); + FSOUND_SetVolume(channels[stream_wind], 100); + } + + FSOUND_Sample_Free(samp[footstepsound]); + FSOUND_Sample_Free(samp[footstepsound2]); + FSOUND_Sample_Free(samp[footstepsound3]); + FSOUND_Sample_Free(samp[footstepsound4]); + samp[footstepsound] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepgrass1.ogg", FSOUND_HW3D, 0); + samp[footstepsound2] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepgrass2.ogg", FSOUND_HW3D, 0); + samp[footstepsound3] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepstone1.ogg", FSOUND_HW3D, 0); + samp[footstepsound4] = FSOUND_Sample_Load(FSOUND_FREE, ":Data:Sounds:footstepstone2.ogg", FSOUND_HW3D, 0); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound], 4.0f, 1000.0f); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound2], 4.0f, 1000.0f); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound3], 4.0f, 1000.0f); + FSOUND_Sample_SetMinMaxDistance(samp[footstepsound4], 4.0f, 1000.0f); + + LoadTexture(":Data:Textures:grassdirt.jpg",&terraintexture,1,0); + + LoadTexture(":Data:Textures:mossrock.jpg",&terraintexture2,1,0); + + //LoadTexture(":Data:Textures:detail.png",&terraintexture3,1); + + + + temptexdetail=texdetail; + if(texdetail>1)texdetail=4; + skybox.load( ":Data:Textures:Skybox(grass):Front.jpg", + ":Data:Textures:Skybox(grass):Left.jpg", + ":Data:Textures:Skybox(grass):Back.jpg", + ":Data:Textures:Skybox(grass):Right.jpg", + ":Data:Textures:Skybox(grass):Up.jpg", + ":Data:Textures:Skybox(grass):Down.jpg", + ":Data:Textures:Skybox(grass):Cloud.jpg", + ":Data:Textures:Skybox(grass):Reflect.jpg"); + + + + texdetail=temptexdetail; + } + temptexdetail=texdetail; + texdetail=1; + terrain.load(":Data:Textures:heightmap.png"); + + texdetail=temptexdetail; +} + + +void Game::Loadlevel(int which){ + stealthloading=0; + + if(which==0)Loadlevel((char *)":Data:Maps:map1"); + else if(which==1)Loadlevel((char *)":Data:Maps:map2"); + else if(which==2)Loadlevel((char *)":Data:Maps:map3"); + else if(which==3)Loadlevel((char *)":Data:Maps:map4"); + else if(which==4)Loadlevel((char *)":Data:Maps:map5"); + else if(which==5)Loadlevel((char *)":Data:Maps:map6"); + else if(which==6)Loadlevel((char *)":Data:Maps:map7"); + else if(which==7)Loadlevel((char *)":Data:Maps:map8"); + else if(which==8)Loadlevel((char *)":Data:Maps:map9"); + else if(which==9)Loadlevel((char *)":Data:Maps:map10"); + else if(which==10)Loadlevel((char *)":Data:Maps:map11"); + else if(which==11)Loadlevel((char *)":Data:Maps:map12"); + else if(which==12)Loadlevel((char *)":Data:Maps:map13"); + else if(which==13)Loadlevel((char *)":Data:Maps:map14"); + else if(which==14)Loadlevel((char *)":Data:Maps:map15"); + else if(which==15)Loadlevel((char *)":Data:Maps:map16"); + else if(which==-1){tutoriallevel=-1;Loadlevel((char *)":Data:Maps:tutorial");} + else Loadlevel((char *)":Data:Maps:mapsave"); + + whichlevel=which; +} + +/*char * Game::MD5_string (unsigned char *string){ +char temp[50]; +char temp2[100]; + +strcpy(temp2,(const char *)string); +strcat((char *)temp2,(const char *)"Lugaru"); +sprintf (temp, "%d",strlen((char *)temp2)); +strcat((char *)temp2,temp); + +MD5 context; +unsigned int len = strlen ( (char *)temp2); + +context.update ((unsigned char *)temp2, len); +context.finalize (); + +return context.hex_digest(); +}*/ + + + +void Game::Loadlevel(char *name){ + int i,j,k,l,m; + static int oldlevel; + int templength; + float lamefloat; + int lameint; + + float headprop,legprop,armprop,bodyprop; + + LOGFUNC; + + LOG(std::string("Loading level...") + name); + + if(!gameon)visibleloading=1; + + if(stealthloading)visibleloading=0; + + if(!stillloading)loadtime=0; + gamestarted=1; + + numenvsounds=0; + //visibleloading=1; + if(tutoriallevel!=-1)tutoriallevel=0; + else tutoriallevel=1; + + if(tutoriallevel==1)tutorialstage=0; + if(tutorialstage==0){ + tutorialstagetime=0; + tutorialmaxtime=1; + } + loadingstuff=1; + if(!firstload){ + oldlevel=50; + } + FSOUND_SetPaused(channels[whooshsound], TRUE); + FSOUND_SetPaused(channels[stream_firesound], TRUE); + + int mapvers; + FILE *tfile; + tfile=fopen( name, "rb" ); + if(tfile) + { + FSOUND_SetPaused(channels[stream_firesound], TRUE); + + + scoreadded=0; + windialogue=0; + + hostiletime=0; + + won=0; + + //campaign=0; + animation[bounceidleanim].Load((char *)":Data:Animations:Idle",middleheight,neutral); + + numdialogues=0; + + for(i=0;i<20;i++) + { + dialoguegonethrough[i]=0; + } + + indialogue=-1; + cameramode=0; + + damagedealt=0; + damagetaken=0; + + if(accountactive!=-1)difficulty=accountdifficulty[accountactive]; + + if(difficulty!=2)minimap=1; + else minimap=0; + + numhotspots=0; + currenthotspot=-1; + bonustime=1; + + skyboxtexture=1; + skyboxr=1; + skyboxg=1; + skyboxb=1; + + freeze=0; + winfreeze=0; + + for(i=0;i<100;i++) + { + bonusnum[i]=0; + } + + numfalls=0; + numflipfail=0; + numseen=0; + numstaffattack=0; + numswordattack=0; + numknifeattack=0; + numunarmedattack=0; + numescaped=0; + numflipped=0; + numwallflipped=0; + numthrowkill=0; + numafterkill=0; + numreversals=0; + numattacks=0; + maxalarmed=0; + numresponded=0; + + bonustotal=startbonustotal; + bonus=0; + gameon=1; + changedelay=0; + if(console) + { + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + freeze=0; + console=0; + } + + if(!stealthloading) + { + terrain.numdecals=0; + sprites.numsprites=0; + for(i=0;i=15)funpackf(tfile, "Bi", &indemo); + else indemo=0; + if(mapvers>=5)funpackf(tfile, "Bi", &maptype); + else maptype=mapkilleveryone; + if(mapvers>=6)funpackf(tfile, "Bi", &hostile); + else hostile=1; + if(mapvers>=4)funpackf(tfile, "Bf Bf", &viewdistance, &fadestart); + else + { + viewdistance=100; + fadestart=.6; + } + if(mapvers>=2)funpackf(tfile, "Bb Bf Bf Bf", &skyboxtexture, &skyboxr, &skyboxg, &skyboxb); + else + { + skyboxtexture=1; + skyboxr=1; + skyboxg=1; + skyboxb=1; + } + if(mapvers>=10)funpackf(tfile, "Bf Bf Bf", &skyboxlightr, &skyboxlightg, &skyboxlightb); + else + { + skyboxlightr=skyboxr; + skyboxlightg=skyboxg; + skyboxlightb=skyboxb; + } + if(!stealthloading)funpackf(tfile, "Bf Bf Bf Bf Bf Bi", &player[0].coords.x,&player[0].coords.y,&player[0].coords.z,&player[0].rotation,&player[0].targetrotation, &player[0].num_weapons); + if(stealthloading)funpackf(tfile, "Bf Bf Bf Bf Bf Bi", &lamefloat,&lamefloat,&lamefloat,&lamefloat,&lamefloat, &player[0].num_weapons); + player[0].originalcoords=player[0].coords; + if(player[0].num_weapons>0&&player[0].num_weapons<5) + { + for(j=0;j=9) + { + funpackf(tfile, "Bi Bi", &player[0].whichskin, &player[0].creature); + } + else + { + player[0].whichskin=0; + player[0].creature=rabbittype; + } + + for(i=0;i=8) + { + funpackf(tfile, "Bi", &numdialogues); + if(numdialogues) + { + for(k=0;k128||templength<=0)templength=128; + for(m=0;m64||templength<=0)templength=64; + for(m=0;m=7) + { + funpackf(tfile, "Bi", &numhotspots); + if(numhotspots) + { + for(i=0;imaxdistance) + { + whichclosest=i; + maxdistance=tempdist; + } + } + objects.radius=fast_sqrt(maxdistance); + } + + if(visibleloading){loadscreencolor=4; LoadingScreen();} + //mapcenter=objects.center; + //mapradius=objects.radius; + + funpackf(tfile, "Bi", &numplayers); + int howmanyremoved=0; + bool removeanother=0; + if(numplayers>1&&numplayers=5)funpackf(tfile, "Bi", &player[i-howmanyremoved].howactive); + else player[i-howmanyremoved].howactive=typeactive; + if(mapvers>=3)funpackf(tfile, "Bf",&player[i-howmanyremoved].scale); + else player[i-howmanyremoved].scale=-1; + if(mapvers>=11)funpackf(tfile, "Bb",&player[i-howmanyremoved].immobile); + else player[i-howmanyremoved].immobile=0; + if(mapvers>=12)funpackf(tfile, "Bf",&player[i-howmanyremoved].rotation); + else player[i-howmanyremoved].rotation=0; + player[i-howmanyremoved].targetrotation=player[i-howmanyremoved].rotation; + if(player[i-howmanyremoved].num_weapons<0||player[i-howmanyremoved].num_weapons>5){ + removeanother=1; + howmanyremoved++; + } + if(!removeanother) + { + if(player[i-howmanyremoved].num_weapons>0&&player[i-howmanyremoved].num_weapons<5) + { + for(j=0;j=5)funpackf(tfile, "Bi", &player[i-howmanyremoved].waypointtype[j]); + else player[i-howmanyremoved].waypointtype[j] = wpkeepwalking; + } + + funpackf(tfile, "Bi", &player[i-howmanyremoved].waypoint); + if(player[i-howmanyremoved].waypoint>player[i-howmanyremoved].numwaypoints-1)player[i-howmanyremoved].waypoint=0; + + funpackf(tfile, "Bf Bf Bf", &player[i-howmanyremoved].armorhead, &player[i-howmanyremoved].armorhigh, &player[i-howmanyremoved].armorlow); + funpackf(tfile, "Bf Bf Bf", &player[i-howmanyremoved].protectionhead, &player[i-howmanyremoved].protectionhigh, &player[i-howmanyremoved].protectionlow); + funpackf(tfile, "Bf Bf Bf", &player[i-howmanyremoved].metalhead, &player[i-howmanyremoved].metalhigh, &player[i-howmanyremoved].metallow); + funpackf(tfile, "Bf Bf", &player[i-howmanyremoved].power, &player[i-howmanyremoved].speedmult); + + if(mapvers>=4)funpackf(tfile, "Bf Bf Bf Bf", &headprop, &bodyprop, &armprop, &legprop); + else + { + headprop=1; + bodyprop=1; + armprop=1; + legprop=1; + } + if(player[i-howmanyremoved].creature==wolftype) + { + player[i-howmanyremoved].proportionhead=1.1*headprop; + player[i-howmanyremoved].proportionbody=1.1*bodyprop; + player[i-howmanyremoved].proportionarms=1.1*armprop; + player[i-howmanyremoved].proportionlegs=1.1*legprop; + } + + if(player[i-howmanyremoved].creature==rabbittype) + { + player[i-howmanyremoved].proportionhead=1.2*headprop; + player[i-howmanyremoved].proportionbody=1.05*bodyprop; + player[i-howmanyremoved].proportionarms=1.00*armprop; + player[i-howmanyremoved].proportionlegs=1.1*legprop; + player[i-howmanyremoved].proportionlegs.y=1.05*legprop; + } + + funpackf(tfile, "Bi", &player[i-howmanyremoved].numclothes); + if(player[i-howmanyremoved].numclothes) + { + for(k=0;k30||numpathpoints<0) + numpathpoints=0; + if(numpathpoints) + { + for(j=0;jmaxplayers-1)numplayers=maxplayers-1; + for(i=0;i20) + FSOUND_StopSound(i); + } +*/ + LOG("Starting background music..."); + + FSOUND_StopSound(FSOUND_ALL); + if(environment==snowyenvironment) + { + if(ambientsound) + { + PlayStreamEx(stream_wind, strm[stream_wind], NULL, TRUE); + FSOUND_SetPaused(channels[stream_wind], FALSE); + FSOUND_SetVolume(channels[stream_wind], 256); + } + } + else if(environment==desertenvironment) + { + if(ambientsound) + { + //PlaySoundEx(desertambient, + // samp[desertambient], NULL, TRUE); + PlayStreamEx(stream_desertambient, + strm[stream_desertambient], NULL, TRUE); + FSOUND_SetPaused(channels[stream_desertambient], FALSE); + FSOUND_SetVolume(channels[stream_desertambient], 256); + } + } + else if(environment==grassyenvironment) + { + if(ambientsound) + { + //PlaySoundEx(wind, samp[wind], NULL, TRUE); + PlayStreamEx(stream_wind, strm[stream_wind], NULL, TRUE); + FSOUND_SetPaused(channels[stream_wind], FALSE); + FSOUND_SetVolume(channels[stream_wind], 100); + } + } + oldmusicvolume[0]=0; + oldmusicvolume[1]=0; + oldmusicvolume[2]=0; + oldmusicvolume[3]=0; + + + /*LoadTexture(":Data:Textures:cloud.png",&sprites.cloudtexture,1,1); + LoadTexture(":Data:Textures:cloudimpact.png",&sprites.cloudimpacttexture,1,1); + LoadTexture(":Data:Textures:bloodparticle.png",&sprites.bloodtexture,1,1); + LoadTexture(":Data:Textures:snowflake.png",&sprites.snowflaketexture,1,1); + LoadTexture(":Data:Textures:flame.png",&sprites.flametexture,1,1); + LoadTexture(":Data:Textures:bloodflame.png",&sprites.bloodflametexture,1,1); + LoadTexture(":Data:Textures:smoke.png",&sprites.smoketexture,1,1); + LoadTexture(":Data:Textures:shine.png",&sprites.shinetexture,1,0); + */ + + if(!firstload) + { + firstload=1; + } + } + leveltime=0; + loadingstuff=0; + visibleloading=0; +} + +void Game::Tick() +{ + static int i,k,j,l,m; + static XYZ facing,flatfacing,absflatfacing; + static XYZ rotatetarget; + static bool oldkey; + static float oldtargetrotation; + static int target, numgood; + static XYZ tempcoords1,tempcoords2; + static XYZ test; + static XYZ test2; + static XYZ lowpoint,lowpointtarget,lowpoint2,lowpointtarget2,lowpoint3,lowpointtarget3,lowpoint4,lowpointtarget4,lowpoint5,lowpointtarget5,lowpoint6,lowpointtarget6,lowpoint7,lowpointtarget7,colpoint,colpoint2; + static int whichhit; + static bool donesomething; + static bool oldjumpkeydown; + + int templength; + + float headprop,bodyprop,armprop,legprop; + + if(newnetmessages){ + newnetmessages=0; + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + + for(k=14;k>=2;k--){ + for(j=0;j<255;j++){ + consoletext[k][j]=consoletext[k-1][j]; + } + consolechars[k]=consolechars[k-1]; + } + for(k=14;k>=2;k--){ + for(j=0;j<255;j++){ + displaytext[k][j]=displaytext[k-1][j]; + } + displaychars[k]=displaychars[k-1]; + displaytime[k]=displaytime[k-1]; + } + for(j=0;j<255;j++){ + consoletext[1][j]=' '; + displaytext[1][j]=' '; + } + sprintf (consoletext[1], netmessages); + sprintf (displaytext[1], netmessages); + consolechars[1]=255; + displaychars[1]=255; + displaytime[1]=0; + } + + for(i=0;i<15;i++){ + displaytime[i]+=multiplier; + } + + static unsigned char theKeyMap[16]; + GetKeys( theKeyMap ); + + keyboardfrozen=0; + + + static bool mainmenutogglekeydown; + if(!console){ + if(mainmenu&&endgame==1)mainmenu=10; + if(IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)&&!mainmenutogglekeydown&&(mainmenu==7&&entername)){ + for(j=0;j<255;j++){ + displaytext[0][j]=' '; + } + displaychars[0]=0; + displayselected=0; + entername=0; + mainmenutogglekeydown=1; + } + if((IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)||(mainmenu==0&&((IsKeyDown(theKeyMap, jumpkey)||IsKeyDown(theKeyMap, MAC_SPACE_KEY)||(campaign)))&&!oldjumpkeydown&&campaign&&winfreeze))&&!mainmenutogglekeydown&&(!mainmenu||gameon||mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||(mainmenu==7&&!entername)||mainmenu==9||mainmenu==11||(mainmenu==12&&!tryquit)||mainmenu==13||mainmenu==14||mainmenu==15||mainmenu==16||mainmenu==17||mainmenu==10)){ + selected=-1; + if(mainmenu==1||mainmenu==2||mainmenu==0){ + if(mainmenu==0&&!winfreeze)mainmenu=2; + else if(mainmenu==0&&winfreeze&&(campaignchoosenext[campaignchoicewhich[whichchoice]])==1)mainmenu=100; + else if(mainmenu==0&&winfreeze){ + /* if(campaignchoosenext[campaignchoicewhich[whichchoice]]==2) + stealthloading=1; + else stealthloading=0; + + if(!stealthloading){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + + startbonustotal=0; + + for(i=0;i2)newdetail=detail; + if(newdetail<0)newdetail=detail; + if(newscreenwidth>3000)newscreenwidth=screenwidth; + if(newscreenwidth<0)newscreenwidth=screenwidth; + if(newscreenheight>3000)newscreenheight=screenheight; + if(newscreenheight<0)newscreenheight=screenheight; + + //ofstream opstream(":Data:config.txt"); + ofstream opstream("./Data/config.txt"); + opstream << "Screenwidth:\n"; + opstream << newscreenwidth; + opstream << "\nScreenheight:\n"; + opstream << newscreenheight; + opstream << "\nMouse sensitivity:\n"; + opstream << usermousesensitivity; + opstream << "\nBlur(0,1):\n"; + opstream << ismotionblur; + opstream << "\nOverall Detail(0,1,2) higher=better:\n"; + opstream << newdetail; + opstream << "\nFloating jump:\n"; + opstream << floatjump; + opstream << "\nMouse jump:\n"; + opstream << mousejump; + opstream << "\nAmbient sound:\n"; + opstream << ambientsound; + opstream << "\nBlood (0,1,2):\n"; + opstream << bloodtoggle; + opstream << "\nAuto slomo:\n"; + opstream << autoslomo; + opstream << "\nFoliage:\n"; + opstream << foliage; + opstream << "\nMusic:\n"; + opstream << musictoggle; + opstream << "\nTrilinear:\n"; + opstream << trilinear; + opstream << "\nDecals(shadows,blood puddles,etc):\n"; + opstream << decals; + opstream << "\nInvert mouse:\n"; + opstream << invertmouse; + opstream << "\nGamespeed:\n"; + if(oldgamespeed==0)oldgamespeed=1; + opstream << oldgamespeed; + opstream << "\nDifficulty(0,1,2) higher=harder:\n"; + opstream << difficulty; + opstream << "\nDamage effects(blackout, doublevision):\n"; + opstream << damageeffects; + opstream << "\nText:\n"; + opstream << texttoggle; + opstream << "\nDebug:\n"; + opstream << debugmode; + opstream << "\nVBL Sync:\n"; + opstream << vblsync; + opstream << "\nShow Points:\n"; + opstream << showpoints; + opstream << "\nAlways Blur:\n"; + opstream << alwaysblur; + opstream << "\nImmediate mode (turn on on G5):\n"; + opstream << immediate; + opstream << "\nVelocity blur:\n"; + opstream << velocityblur; + opstream << "\nVolume:\n"; + opstream << volume; + opstream << "\nForward key:\n"; + opstream << KeyToChar(forwardkey); + opstream << "\nBack key:\n"; + opstream << KeyToChar(backkey); + opstream << "\nLeft key:\n"; + opstream << KeyToChar(leftkey); + opstream << "\nRight key:\n"; + opstream << KeyToChar(rightkey); + opstream << "\nJump key:\n"; + opstream << KeyToChar(jumpkey); + opstream << "\nCrouch key:\n"; + opstream << KeyToChar(crouchkey); + opstream << "\nDraw key:\n"; + opstream << KeyToChar(drawkey); + opstream << "\nThrow key:\n"; + opstream << KeyToChar(throwkey); + opstream << "\nAttack key:\n"; + opstream << KeyToChar(attackkey); + opstream << "\nChat key:\n"; + opstream << KeyToChar(chatkey); + opstream.close(); + } + if(mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==9||mainmenu==12||mainmenu==13||mainmenu==14||mainmenu==10||mainmenu==11||mainmenu==100){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + if(mainmenu==3&&gameon)mainmenu=2; + if(mainmenu==3&&!gameon)mainmenu=1; + if(mainmenu==5&&gameon)mainmenu=2; + if(mainmenu==5&&!gameon)mainmenu=1; + if(mainmenu==4)mainmenu=3; + if(mainmenu==6)mainmenu=5; + if(mainmenu==7)mainmenu=1; + if(mainmenu==9)mainmenu=5; + if(mainmenu==11)mainmenu=5; + if(mainmenu==12)mainmenu=5; + if(mainmenu==13)mainmenu=12; + if(mainmenu==14)mainmenu=13; + if(mainmenu==10)mainmenu=5; + if(mainmenu==100){ + mainmenu=5; + gameon=0; + winfreeze=0; + } + mainmenutogglekeydown=1; + } + if(!IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)){ + mainmenutogglekeydown=0; + } + } + + /*static bool minimaptogglekeydown; + if(IsKeyDown(theKeyMap, MAC_TAB_KEY)&&!minimaptogglekeydown){ + minimap=1-minimap; + minimaptogglekeydown=1; + } + if(!IsKeyDown(theKeyMap, MAC_TAB_KEY)){ + minimaptogglekeydown=0; + } + */ + + static bool minimaptogglekeydown; + if(IsKeyDown(theKeyMap, MAC_TAB_KEY)&&!minimaptogglekeydown&&tutoriallevel){ + if(tutorialstage!=51) + tutorialstagetime=tutorialmaxtime; + PlaySoundEx( consolefailsound, samp[consolefailsound], NULL, TRUE); + FSOUND_SetVolume(channels[consolefailsound], 128); + FSOUND_SetPaused(channels[consolefailsound], FALSE); + minimaptogglekeydown=1; + } + if(!IsKeyDown(theKeyMap, MAC_TAB_KEY)){ + minimaptogglekeydown=0; + } + + if(mainmenu){ + //menu buttons + if(mainmenu==1||mainmenu==2){ + if(Button()&&!oldbutton&&selected==1){ + if(!gameon){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + //new game + if(accountactive!=-1)mainmenu=5; + else mainmenu=7; + /* + startbonustotal=0; + + loading=2; + loadtime=0; + if(firstload)TickOnceAfter(); + if(!firstload)LoadStuff(); + else { + Loadlevel(0); + } + mainmenu=0; + gameon=1; + FSOUND_SetPaused(channels[music3], TRUE); */ + } + else + { + //resume + mainmenu=0; + FSOUND_SetPaused(channels[stream_music3], TRUE); + FSOUND_SetPaused(channels[music1], FALSE); + } + } + + if(Button()&&!oldbutton&&selected==2){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + //options + + mainmenu=3; + + if(newdetail>2)newdetail=detail; + if(newdetail<0)newdetail=detail; + if(newscreenwidth>3000)newscreenwidth=screenwidth; + if(newscreenwidth<0)newscreenwidth=screenwidth; + if(newscreenheight>3000)newscreenheight=screenheight; + if(newscreenheight<0)newscreenheight=screenheight; + } + + if(Button()&&!oldbutton&&selected==3){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + if(!gameon){ + //quit + tryquit=1; + if(registered)FSOUND_SetPaused(channels[stream_music3], TRUE); + } + else{ + //end game + gameon=0; + mainmenu=1; + } + } + if(Button())oldbutton=1; + else oldbutton=0; + } + + if(mainmenu==3){ + if(Button()&&!oldbutton&&selected!=-1){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + } + if(Button()&&!oldbutton&&selected==0){ + int whichres; + whichres=-1; + if(newscreenwidth==640&&newscreenheight==480)whichres=0; + if(newscreenwidth==800&&newscreenheight==600)whichres=1; + if(newscreenwidth==1024&&newscreenheight==768)whichres=2; + if(newscreenwidth==1280&&newscreenheight==1024)whichres=3; + if(newscreenwidth==1600&&newscreenheight==1200)whichres=4; + if(newscreenwidth==840&&newscreenheight==524)whichres=5; + if(newscreenwidth==1024&&newscreenheight==640)whichres=6; + if(newscreenwidth==1344&&newscreenheight==840)whichres=7; + + if(whichres==-1||whichres==7){ + newscreenwidth=640; + newscreenheight=480; + } + if(whichres==0){ + newscreenwidth=800; + newscreenheight=600; + } + if(whichres==1){ + newscreenwidth=1024; + newscreenheight=768; + } + if(whichres==2){ + newscreenwidth=1280; + newscreenheight=1024; + } + if(whichres==3){ + newscreenwidth=1600; + newscreenheight=1200; + } + if(whichres==4){ + newscreenwidth=840; + newscreenheight=524; + } + if(whichres==5){ + newscreenwidth=1024; + newscreenheight=640; + } + if(whichres==6){ + newscreenwidth=1344; + newscreenheight=840; + } + } + if(Button()&&!oldbutton&&selected==1){ + newdetail++; + if(newdetail>2)newdetail=0; + } + if(Button()&&!oldbutton&&selected==2){ + bloodtoggle++; + if(bloodtoggle>2)bloodtoggle=0; + } + if(Button()&&!oldbutton&&selected==3){ + difficulty++; + if(difficulty>2)difficulty=0; + } + if(Button()&&!oldbutton&&selected==4){ + ismotionblur=1-ismotionblur; + } + if(Button()&&!oldbutton&&selected==5){ + decals=1-decals; + } + if(Button()&&!oldbutton&&selected==6){ + musictoggle=1-musictoggle; + + if(!musictoggle){ + FSOUND_SetPaused(channels[music1], TRUE); + FSOUND_SetPaused(channels[stream_music2], TRUE); + FSOUND_SetPaused(channels[stream_music3], TRUE); + + for(i=0;i<4;i++){ + oldmusicvolume[i]=0; + musicvolume[i]=0; + } + } + + if(musictoggle){ + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + FSOUND_SetVolume(channels[stream_music3], 256); + } + } + if(Button()&&!oldbutton&&selected==9){ + invertmouse=1-invertmouse; + } + if(Button()&&!oldbutton&&selected==10){ + usermousesensitivity+=.2; + if(usermousesensitivity>2)usermousesensitivity=.2; + } + if(Button()&&!oldbutton&&selected==11){ + volume+=.1f; + if(volume>1.0001f)volume=0; + FSOUND_SetSFXMasterVolume((int)(volume*255)); + } + if(Button()&&!oldbutton&&selected==7){ + /*float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + */ + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + //options + + mainmenu=4; + keyselect=-1; + } + if(Button()&&!oldbutton&&selected==8){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + if(newdetail>2)newdetail=detail; + if(newdetail<0)newdetail=detail; + if(newscreenwidth>3000)newscreenwidth=screenwidth; + if(newscreenwidth<0)newscreenwidth=screenwidth; + if(newscreenheight>3000)newscreenheight=screenheight; + if(newscreenheight<0)newscreenheight=screenheight; + + + //ofstream opstream(":Data:config.txt"); + ofstream opstream("./Data/config.txt"); + opstream << "Screenwidth:\n"; + opstream << newscreenwidth; + opstream << "\nScreenheight:\n"; + opstream << newscreenheight; + opstream << "\nMouse sensitivity:\n"; + opstream << usermousesensitivity; + opstream << "\nBlur(0,1):\n"; + opstream << ismotionblur; + opstream << "\nOverall Detail(0,1,2) higher=better:\n"; + opstream << newdetail; + opstream << "\nFloating jump:\n"; + opstream << floatjump; + opstream << "\nMouse jump:\n"; + opstream << mousejump; + opstream << "\nAmbient sound:\n"; + opstream << ambientsound; + opstream << "\nBlood (0,1,2):\n"; + opstream << bloodtoggle; + opstream << "\nAuto slomo:\n"; + opstream << autoslomo; + opstream << "\nFoliage:\n"; + opstream << foliage; + opstream << "\nMusic:\n"; + opstream << musictoggle; + opstream << "\nTrilinear:\n"; + opstream << trilinear; + opstream << "\nDecals(shadows,blood puddles,etc):\n"; + opstream << decals; + opstream << "\nInvert mouse:\n"; + opstream << invertmouse; + opstream << "\nGamespeed:\n"; + if(oldgamespeed==0)oldgamespeed=1; + opstream << oldgamespeed; + opstream << "\nDifficulty(0,1,2) higher=harder:\n"; + opstream << difficulty; + opstream << "\nDamage effects(blackout, doublevision):\n"; + opstream << damageeffects; + opstream << "\nText:\n"; + opstream << texttoggle; + opstream << "\nDebug:\n"; + opstream << debugmode; + opstream << "\nVBL Sync:\n"; + opstream << vblsync; + opstream << "\nShow Points:\n"; + opstream << showpoints; + opstream << "\nAlways Blur:\n"; + opstream << alwaysblur; + opstream << "\nImmediate mode (turn on on G5):\n"; + opstream << immediate; + opstream << "\nVelocity blur:\n"; + opstream << velocityblur; + opstream << "\nVolume:\n"; + opstream << volume; + opstream << "\nForward key:\n"; + opstream << KeyToChar(forwardkey); + opstream << "\nBack key:\n"; + opstream << KeyToChar(backkey); + opstream << "\nLeft key:\n"; + opstream << KeyToChar(leftkey); + opstream << "\nRight key:\n"; + opstream << KeyToChar(rightkey); + opstream << "\nJump key:\n"; + opstream << KeyToChar(jumpkey); + opstream << "\nCrouch key:\n"; + opstream << KeyToChar(crouchkey); + opstream << "\nDraw key:\n"; + opstream << KeyToChar(drawkey); + opstream << "\nThrow key:\n"; + opstream << KeyToChar(throwkey); + opstream << "\nAttack key:\n"; + opstream << KeyToChar(attackkey); + opstream << "\nChat key:\n"; + opstream << KeyToChar(chatkey); + opstream.close(); + + if(mainmenu==3&&gameon)mainmenu=2; + if(mainmenu==3&&!gameon)mainmenu=1; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + if(mainmenu==4){ + if(Button()&&!oldbutton&&selected!=-1&&keyselect==-1){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + } + if(Button()&&!oldbutton&&selected<9&&keyselect==-1){ + keyselect=selected; + oldbuttons[0]=1; + oldbuttons[1]=1; + oldbuttons[2]=1; + } + if(keyselect!=-1){ + for(i=0;i<3;i++) + if(!buttons[i]&&!oldbutton&&!Button())oldbuttons[i]=0; + for(i=0;i<140;i++){ + if((IsKeyDown(theKeyMap, i)||(buttons[0]&&!oldbuttons[0]&&!oldbutton)||(buttons[1]&&!oldbuttons[1]&&!oldbutton))&&keyselect!=-1){ + if(i!=MAC_ESCAPE_KEY&&(strcmp(KeyToChar(i),"unknown")||(buttons[0]&&!oldbuttons[0]&&!oldbutton)||(buttons[1]&&!oldbuttons[1]&&!oldbutton))){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + int keynum; + keynum=i; + if(buttons[0]&&!oldbuttons[0])keynum=MAC_MOUSEBUTTON1; + if(buttons[1]&&!oldbuttons[1])keynum=MAC_MOUSEBUTTON2; + + + + if(keyselect==0)forwardkey=keynum; + if(keyselect==1)backkey=keynum; + if(keyselect==2)leftkey=keynum; + if(keyselect==3)rightkey=keynum; + if(keyselect==4)crouchkey=keynum; + if(keyselect==5)jumpkey=keynum; + if(keyselect==6)drawkey=keynum; + if(keyselect==7)throwkey=keynum; + if(keyselect==8)attackkey=keynum; + keyselect=-1; + } + } + }} + if(Button()&&!oldbutton&&selected==9){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=3; + + if(newdetail>2)newdetail=detail; + if(newdetail<0)newdetail=detail; + if(newscreenwidth>3000)newscreenwidth=screenwidth; + if(newscreenwidth<0)newscreenwidth=screenwidth; + if(newscreenheight>3000)newscreenheight=screenheight; + if(newscreenheight<0)newscreenheight=screenheight; + } + } + + if(mainmenu==5){ + if(accountcampaignchoicesmade[accountactive]>8&&!registered){ + FSOUND_SetFrequency(FSOUND_ALL, 0.001); + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + FSOUND_SetVolume(channels[stream_music3], 256); + + gameon=0; + mainmenu=12; + accountcampaignchoicesmade[accountactive]=0; + accountcampaignscore[accountactive]=0; + accountcampaigntime[accountactive]=0; + + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + + if(endgame==2){ + accountcampaignchoicesmade[accountactive]=0; + accountcampaignscore[accountactive]=0; + accountcampaigntime[accountactive]=0; + endgame=0; + } + + if(Button()&&!oldbutton&&selected==1){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + startbonustotal=0; + + loading=2; + loadtime=0; + targetlevel=-1; + if(firstload)TickOnceAfter(); + if(!firstload)LoadStuff(); + else { + Loadlevel(-1); + } + + mainmenu=0; + gameon=1; + FSOUND_SetPaused(channels[stream_music3], TRUE); + } + if(Button()&&!oldbutton&&selected-7>=accountcampaignchoicesmade[accountactive]){//selected>=7&&(selected-7<=campaignnumchoices)){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + startbonustotal=0; + + loading=2; + loadtime=0; + targetlevel=7; + if(firstload)TickOnceAfter(); + if(!firstload)LoadStuff(); + //else { + for(i=0;i<255;i++){ + mapname[i]='\0'; + } + mapname[0]=':'; + mapname[1]='D'; + mapname[2]='a'; + mapname[3]='t'; + mapname[4]='a'; + mapname[5]=':'; + mapname[6]='M'; + mapname[7]='a'; + mapname[8]='p'; + mapname[9]='s'; + mapname[10]=':'; + strcat(mapname,campaignmapname[campaignchoicewhich[selected-7-accountcampaignchoicesmade[accountactive]]]); + whichchoice=selected-7-accountcampaignchoicesmade[accountactive]; + visibleloading=1; + stillloading=1; + Loadlevel(mapname); + //Loadlevel(campaignmapname[levelorder[selected-7]]); + //} + campaign=1; + mainmenu=0; + gameon=1; + FSOUND_SetPaused(channels[stream_music3], TRUE); + } + if(Button()&&!oldbutton&&selected==4){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + if(mainmenu==5&&gameon)mainmenu=2; + if(mainmenu==5&&!gameon)mainmenu=1; + } + if(Button()&&!oldbutton&&selected==5){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=7; + } + if(Button()&&!oldbutton&&selected==3){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=6; + } + if(Button()&&!oldbutton&&selected==2){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=9; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + if(mainmenu==9){ + if(Button()&&!oldbutton&&selected=0&&selected<=accountprogress[accountactive]){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + startbonustotal=0; + + loading=2; + loadtime=0; + targetlevel=selected; + if(firstload)TickOnceAfter(); + if(!firstload)LoadStuff(); + else { + Loadlevel(selected); + } + campaign=0; + + mainmenu=0; + gameon=1; + FSOUND_SetPaused(channels[stream_music3], TRUE); + } + if(Button()&&!oldbutton&&selected==numchallengelevels){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=5; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + if(mainmenu==11){ + if(Button()&&!oldbutton&&selected=0&&selected<=accountprogress[accountactive]){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + startbonustotal=0; + + loading=2; + loadtime=0; + targetlevel=selected; + if(firstload)TickOnceAfter(); + if(!firstload)LoadStuff(); + else { + Loadlevel(selected); + } + campaign=0; + + mainmenu=0; + gameon=1; + FSOUND_SetPaused(channels[stream_music3], TRUE); + } + if(Button()&&!oldbutton&&selected==numchallengelevels){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=5; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + if(mainmenu==10){ + endgame=2; + if(Button()&&!oldbutton&&selected==3){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=5; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + + if(mainmenu==15||mainmenu==16){ + if(Button()&&!oldbutton&&selected==1){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + if(mainmenu==15)mainmenu=5; + else mainmenu=12; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + + if(mainmenu==12){ + endgame=2; + if(Button()&&!oldbutton&&selected==3){ + if(tryquit)quit=1; + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=5; + } + + if(Button()&&!oldbutton&&selected==4){ + registernow=1; + quit=1; + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + + + if(Button()&&!oldbutton&&selected==5){ + tryquit=0; + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + mainmenu=13; + } + if(Button())oldbutton=1; + else oldbutton=0; + } + if(mainmenu==6){ + if(Button()&&!oldbutton&&selected!=-1){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + } + if(Button()&&!oldbutton&&selected==1){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + + for(i=accountactive;i0&&selected2)newdetail=detail; + if(newdetail<0)newdetail=detail; + if(newscreenwidth>3000)newscreenwidth=screenwidth; + if(newscreenwidth<0)newscreenwidth=screenwidth; + if(newscreenheight>3000)newscreenheight=screenheight; + if(newscreenheight<0)newscreenheight=screenheight; + + //ofstream opstream(":Data:config.txt"); + ofstream opstream("./Data/config.txt"); + opstream << "Screenwidth:\n"; + opstream << newscreenwidth; + opstream << "\nScreenheight:\n"; + opstream << newscreenheight; + opstream << "\nMouse sensitivity:\n"; + opstream << usermousesensitivity; + opstream << "\nBlur(0,1):\n"; + opstream << ismotionblur; + opstream << "\nOverall Detail(0,1,2) higher=better:\n"; + opstream << newdetail; + opstream << "\nFloating jump:\n"; + opstream << floatjump; + opstream << "\nMouse jump:\n"; + opstream << mousejump; + opstream << "\nAmbient sound:\n"; + opstream << ambientsound; + opstream << "\nBlood (0,1,2):\n"; + opstream << bloodtoggle; + opstream << "\nAuto slomo:\n"; + opstream << autoslomo; + opstream << "\nFoliage:\n"; + opstream << foliage; + opstream << "\nMusic:\n"; + opstream << musictoggle; + opstream << "\nTrilinear:\n"; + opstream << trilinear; + opstream << "\nDecals(shadows,blood puddles,etc):\n"; + opstream << decals; + opstream << "\nInvert mouse:\n"; + opstream << invertmouse; + opstream << "\nGamespeed:\n"; + if(oldgamespeed==0)oldgamespeed=1; + opstream << oldgamespeed; + opstream << "\nDifficulty(0,1,2) higher=harder:\n"; + opstream << difficulty; + opstream << "\nDamage effects(blackout, doublevision):\n"; + opstream << damageeffects; + opstream << "\nText:\n"; + opstream << texttoggle; + opstream << "\nDebug:\n"; + opstream << debugmode; + opstream << "\nVBL Sync:\n"; + opstream << vblsync; + opstream << "\nShow Points:\n"; + opstream << showpoints; + opstream << "\nAlways Blur:\n"; + opstream << alwaysblur; + opstream << "\nImmediate mode (turn on on G5):\n"; + opstream << immediate; + opstream << "\nVelocity blur:\n"; + opstream << velocityblur; + opstream << "\nVolume:\n"; + opstream << volume; + opstream << "\nForward key:\n"; + opstream << KeyToChar(forwardkey); + opstream << "\nBack key:\n"; + opstream << KeyToChar(backkey); + opstream << "\nLeft key:\n"; + opstream << KeyToChar(leftkey); + opstream << "\nRight key:\n"; + opstream << KeyToChar(rightkey); + opstream << "\nJump key:\n"; + opstream << KeyToChar(jumpkey); + opstream << "\nCrouch key:\n"; + opstream << KeyToChar(crouchkey); + opstream << "\nDraw key:\n"; + opstream << KeyToChar(drawkey); + opstream << "\nThrow key:\n"; + opstream << KeyToChar(throwkey); + opstream << "\nAttack key:\n"; + opstream << KeyToChar(attackkey); + opstream << "\nChat key:\n"; + opstream << KeyToChar(chatkey); + opstream.close(); + } + } + + if(mainmenu==1||mainmenu==2){ + if(loaddistrib>4)transition+=multiplier/8; + if(transition>1){ + transition=0; + anim++; + if(anim>4)anim=0; + loaddistrib=0; + } + } + FSOUND_SetFrequency(channels[stream_music3], 22050); + + if(entername||mainmenu==13||mainmenu==14){ + for(i=0;i<140;i++){ + if(IsKeyDown(theKeyMap, i)){ + togglekeydelay[i]+=multiplier; + if(togglekeydelay[i]>.4){ + togglekey[i]=0; + togglekeydelay[i]=.36; + } + if(!togglekey[i]){ + if(KeyToSingleChar(i)!='\0'&&displaychars[0]<60){ + for(j=255;j>=displayselected+1;j--){ + displaytext[0][j]=displaytext[0][j-1]; + } + displaytext[0][displayselected]=KeyToSingleChar(i); + if(IsKeyDown(theKeyMap, MAC_SHIFT_KEY))displaytext[0][displayselected]=Shift(displaytext[0][displayselected]); + displayselected++; + displaychars[0]++; + } + if(i==MAC_DELETE_KEY&&displayselected!=0){ + for(j=displayselected-1;j<255;j++){ + displaytext[0][j]=displaytext[0][j+1]; + } + displaytext[0][255]=' '; + displayselected--; + displaychars[0]--; + } + if(i==MAC_ARROW_LEFT_KEY&&displayselected!=0){ + displayselected--; + } + if(i==MAC_ARROW_RIGHT_KEY&&displayselected999)numchars+=4; + else if(num1/10000>99)numchars+=3; + else if(num1/10000>9)numchars+=2; + else numchars+=1; + if(num1%10000>999)numchars+=4; + else if(num1%10000>99)numchars+=3; + else if(num1%10000>9)numchars+=2; + else numchars+=1; + if(num2/10000>999)numchars+=4; + else if(num2/10000>99)numchars+=3; + else if(num2/10000>9)numchars+=2; + else numchars+=1; + if(num2%10000>999)numchars+=4; + else if(num2%10000>99)numchars+=3; + else if(num2%10000>9)numchars+=2; + else numchars+=1; + + //numchars=12; + + for(j=0;j0) + { + for(j=0;j.4){ + togglekey[i]=0; + togglekeydelay[i]=.36; + } + if(!togglekey[i]){ + if(KeyToSingleChar(i)!='\0'&&displaychars[0]<60){ + for(j=255;j>=displayselected+1;j--){ + displaytext[0][j]=displaytext[0][j-1]; + } + displaytext[0][displayselected]=KeyToSingleChar(i); + if(IsKeyDown(theKeyMap, MAC_SHIFT_KEY))displaytext[0][displayselected]=Shift(displaytext[0][displayselected]); + displayselected++; + displaychars[0]++; + } + if(i==MAC_DELETE_KEY&&displayselected!=0){ + for(j=displayselected-1;j<255;j++){ + displaytext[0][j]=displaytext[0][j+1]; + } + displaytext[0][255]=' '; + displayselected--; + displaychars[0]--; + } + if(i==MAC_ARROW_LEFT_KEY&&displayselected!=0){ + displayselected--; + } + if(i==MAC_ARROW_RIGHT_KEY&&displayselected.4){ + togglekey[i]=0; + togglekeydelay[i]=.36; + } + if(!togglekey[i]){ + if(KeyToSingleChar(i)!='\0'&&consolechars[0]<255){ + for(j=255;j>=consoleselected+1;j--){ + consoletext[0][j]=consoletext[0][j-1]; + } + consoletext[0][consoleselected]=KeyToSingleChar(i); + if(IsKeyDown(theKeyMap, MAC_SHIFT_KEY))consoletext[0][consoleselected]=Shift(consoletext[0][consoleselected]); + consoleselected++; + consolechars[0]++; + } + else if(i==MAC_ENTER_KEY){ + for(j=255;j>=consoleselected+1;j--){ + consoletext[0][j]=consoletext[0][j-1]; + } + consoletext[0][consoleselected]='\n'; + consoleselected++; + consolechars[0]++; + } + if(i==MAC_DELETE_KEY&&consoleselected!=0){ + for(j=consoleselected-1;j<255;j++){ + consoletext[0][j]=consoletext[0][j+1]; + } + consoletext[0][255]=' '; + consoleselected--; + consolechars[0]--; + } + if(i==MAC_ARROW_UP_KEY){ + if(archiveselected<14)archiveselected++; + for(j=0;j<255;j++){ + consolechars[0]=consolechars[archiveselected]; + consoletext[0][j]=consoletext[archiveselected][j]; + consoleselected=consolechars[0]; + } + } + if(i==MAC_ARROW_DOWN_KEY){ + if(archiveselected>0)archiveselected--; + for(j=0;j<255;j++){ + consolechars[0]=consolechars[archiveselected]; + consoletext[0][j]=consoletext[archiveselected][j]; + consoleselected=consolechars[0]; + } + } + if(i==MAC_ARROW_LEFT_KEY&&consoleselected!=0){ + consoleselected--; + } + if(i==MAC_ARROW_RIGHT_KEY&&consoleselected32)numchars=32; + for(j=5;j0){ + for(k=14;k>=1;k--){ + for(j=0;j<255;j++){ + consoletext[k][j]=consoletext[k-1][j]; + } + consolechars[k]=consolechars[k-1]; + } + for(j=0;j<255;j++){ + consoletext[0][j]=' '; + } + if(v!=-4994)sprintf (consoletext[0], "Error #%d!!!",v); + else sprintf (consoletext[0], "Could not open connection"); + + consolechars[0]=255; + consoleselected=0; + } + } + else + { + donesomething=1; + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + + if(consolechars[0]>0){ + for(k=14;k>=1;k--){ + for(j=0;j<255;j++){ + consoletext[k][j]=consoletext[k-1][j]; + } + consolechars[k]=consolechars[k-1]; + } + for(j=0;j<255;j++){ + consoletext[0][j]=' '; + } + sprintf (consoletext[0], "Connected to %s",theIPAddress); + + consolechars[0]=255; + consoleselected=0; + } + } + } + + if(Compare(consoletext[0],"host ",0,4)){ + unsigned char gameNameStr[32], playerNameStr[32]; + char gameName[32];//, playerName[32]; + NMUInt32 port; + int players; + int v; + + port = 25710; + players =4; + + strcpy(gameName, "Host's game"); + strcpy(playerName, "Host"); + GameC2PStr( gameName, gameNameStr ); + GameC2PStr( playerName, playerNameStr ); + + v=NetworkStartServer( (NMUInt16)port, players, gameNameStr, playerNameStr ); + if(v) + { + if(consolechars[0]>0){ + for(k=14;k>=1;k--){ + for(j=0;j<255;j++){ + consoletext[k][j]=consoletext[k-1][j]; + } + consolechars[k]=consolechars[k-1]; + } + for(j=0;j<255;j++){ + consoletext[0][j]=' '; + } + sprintf (consoletext[0], "Error #%d!!!",v); + + consolechars[0]=255; + consoleselected=0; + } + } + else + { + donesomething=1; + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + + if(consolechars[0]>0){ + for(k=14;k>=1;k--){ + for(j=0;j<255;j++){ + consoletext[k][j]=consoletext[k-1][j]; + } + consolechars[k]=consolechars[k-1]; + } + for(j=0;j<255;j++){ + consoletext[0][j]=' '; + } + sprintf (consoletext[0], "Game hosted"); + + consolechars[0]=255; + consoleselected=0; + } + } + } + */ + if(Compare(consoletext[0],"save ",0,4)){ + mapname[0]=':'; + mapname[1]='D'; + mapname[2]='a'; + mapname[3]='t'; + mapname[4]='a'; + mapname[5]=':'; + mapname[6]='M'; + mapname[7]='a'; + mapname[8]='p'; + mapname[9]='s'; + mapname[10]=':'; + for(j=5;j0&&player[0].num_weapons<5) + for(j=0;j1&&numplayers0&&player[j].num_weapons<5) + for(k=0;k0&&player[0].num_weapons<5) + for(j=0;j1&&numplayers0&&player[j].num_weapons<5) + for(k=0;k0&&player[0].num_weapons<5) + for(j=0;j1&&numplayers0&&player[j].num_weapons<5) + for(k=0;k1) + for(i=1;i1) + for(i=1;i> numdialogueboxes[numdialogues]; + for(i=0;i> dialogueboxlocation[numdialogues][i]; + ipstream.ignore(256,':'); + ipstream >> dialogueboxcolor[numdialogues][i][0]; + ipstream >> dialogueboxcolor[numdialogues][i][1]; + ipstream >> dialogueboxcolor[numdialogues][i][2]; + ipstream.ignore(256,':'); + ipstream.getline(dialoguename[numdialogues][i],64); + ipstream.ignore(256,':'); + ipstream.ignore(256,' '); + ipstream.getline(dialoguetext[numdialogues][i],128); + for(j=0;j<128;j++){ + if(dialoguetext[numdialogues][i][j]=='\\')dialoguetext[numdialogues][i][j]='\n'; + } + ipstream.ignore(256,':'); + ipstream >> dialogueboxsound[numdialogues][i]; + } + + for(i=0;i> numdialogueboxes[whichdi]; + for(i=0;i> dialogueboxlocation[whichdi][i]; + ipstream.ignore(256,':'); + ipstream >> dialogueboxcolor[whichdi][i][0]; + ipstream >> dialogueboxcolor[whichdi][i][1]; + ipstream >> dialogueboxcolor[whichdi][i][2]; + ipstream.ignore(256,':'); + ipstream.getline(dialoguename[whichdi][i],64); + ipstream.ignore(256,':'); + ipstream.ignore(256,' '); + ipstream.getline(dialoguetext[whichdi][i],128); + for(j=0;j<128;j++){ + if(dialoguetext[whichdi][i][j]=='\\')dialoguetext[whichdi][i][j]='\n'; + } + ipstream.ignore(256,':'); + ipstream >> dialogueboxsound[whichdi][i]; + } + + ipstream.close(); + + donesomething=1; + } + + if(Compare(consoletext[0],"fixtype ",0,7)){ + int startpoint; + int alldone; + int whichdi; + + alldone=0; + startpoint=8; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + dialoguetype[0]=atoi(mapname); + + startpoint=j+1; + + donesomething=1; + } + + + if(Compare(consoletext[0],"fixrotation ",0,11)){ + participantrotation[whichdialogue][participantfocus[whichdialogue][indialogue]]=player[participantfocus[whichdialogue][indialogue]].rotation; + + donesomething=1; + } + + if(Compare(consoletext[0],"ddialogue ",0,9)){ + numdialogues--; + if(numdialogues<0)numdialogues=0; + + donesomething=1; + } + + if(Compare(consoletext[0],"immobile ",0,8)){ + player[0].immobile=1; + donesomething=1; + } + + if(Compare(consoletext[0],"mobile ",0,6)){ + player[0].immobile=0; + donesomething=1; + } + + if(Compare(consoletext[0],"play ",0,4)){ + int startpoint; + int alldone; + + alldone=0; + startpoint=5; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + startpoint=j+1; + + whichdialogue=atoi(mapname); + + if(numdialogues>whichdialogue){ + for(i=0;i0)player[i].immobile=1; + } + donesomething=1; + } + + + if(Compare(consoletext[0],"default ",0,7)||Compare(consoletext[0],"Default ",0,7)){ + player[0].armorhead=1; + player[0].armorhigh=1; + player[0].armorlow=1; + player[0].protectionhead=1; + player[0].protectionhigh=1; + player[0].protectionlow=1; + player[0].metalhead=1; + player[0].metalhigh=1; + player[0].metallow=1; + player[0].power=1; + player[0].speedmult=1; + player[0].scale=1; + + if(player[0].creature==wolftype){ + player[0].proportionhead=1.1; + player[0].proportionbody=1.1; + player[0].proportionarms=1.1; + player[0].proportionlegs=1.1; + } + + if(player[0].creature==rabbittype){ + player[0].proportionhead=1.2; + player[0].proportionbody=1.05; + player[0].proportionarms=1.00; + player[0].proportionlegs=1.1; + player[0].proportionlegs.y=1.05; + } + + player[0].numclothes=0; + if(player[0].whichskin==0){ + LoadTextureSave(":Data:Textures:Fur3.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==1){ + LoadTextureSave(":Data:Textures:Fur.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==2){ + LoadTextureSave(":Data:Textures:Fur2.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==3){ + LoadTextureSave(":Data:Textures:Lynx.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==4){ + LoadTextureSave(":Data:Textures:Otter.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==5){ + LoadTextureSave(":Data:Textures:Opal.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==6){ + LoadTextureSave(":Data:Textures:Sable.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==7){ + LoadTextureSave(":Data:Textures:Chocolate.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==8){ + LoadTextureSave(":Data:Textures:BW2.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + else if(player[0].whichskin==9){ + LoadTextureSave(":Data:Textures:WB2.jpg",&player[0].skeleton.drawmodel.textureptr,1,&player[0].skeleton.skinText[0],&player[0].skeleton.skinsize); + } + + editoractive=typeactive; + player[0].immobile=0; + + + + donesomething=1; + } + + if(Compare(consoletext[0],"tint ",0,4)||Compare(consoletext[0],"Tint ",0,4)){ + int startpoint; + int alldone; + alldone=0; + startpoint=5; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + tintr=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + tintg=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + tintb=atof(mapname); + + donesomething=1; + } + + if(Compare(consoletext[0],"sky tint ",0,8)||Compare(consoletext[0],"Sky Tint ",0,8)){ + int startpoint; + int alldone; + alldone=0; + startpoint=9; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + skyboxr=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + skyboxg=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + skyboxb=atof(mapname); + + skyboxlightr=skyboxr; + skyboxlightg=skyboxg; + skyboxlightb=skyboxb; + + SetUpLighting(); + + //if(skyboxtexture){ + terrain.DoShadows(); + objects.DoShadows(); + /*} + else terrain.DoLighting(); + */ + donesomething=1; + } + + if(Compare(consoletext[0],"sky light ",0,9)||Compare(consoletext[0],"Sky Light ",0,9)){ + int startpoint; + int alldone; + alldone=0; + startpoint=10; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + skyboxlightr=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + skyboxlightg=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + skyboxlightb=atof(mapname); + + SetUpLighting(); + + //if(skyboxtexture){ + terrain.DoShadows(); + objects.DoShadows(); + /*} + else terrain.DoLighting(); + */ + donesomething=1; + } + + if(Compare(consoletext[0],"skybox ",0,6)||Compare(consoletext[0],"Skybox ",0,6)){ + skyboxtexture=1-skyboxtexture; + + SetUpLighting(); + //if(skyboxtexture){ + terrain.DoShadows(); + objects.DoShadows(); + /*} + else terrain.DoLighting(); + */ + donesomething=1; + } + + if(Compare(consoletext[0],"protection ",0,10)||Compare(consoletext[0],"Protection ",0,10)){ + int startpoint; + int alldone; + alldone=0; + startpoint=11; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + player[0].protectionhead=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + player[0].protectionhigh=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + player[0].protectionlow=atof(mapname); + + donesomething=1; + } + + if(Compare(consoletext[0],"armor ",0,5)||Compare(consoletext[0],"Armor ",0,5)){ + int startpoint; + int alldone; + alldone=0; + startpoint=6; + j=startpoint; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + player[0].armorhead=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + player[0].armorhigh=atof(mapname); + + j++; + startpoint=j; + while(consoletext[0][j]!='\0'&&consoletext[0][j]!=' '&&!alldone&&j<255){ + mapname[j-startpoint]=consoletext[0][j]; + j++; + if(consoletext[0][j]=='\0')alldone=1; + } + mapname[j-startpoint]='\0'; + + player[0].armorlow=atof(mapname); + + donesomething=1; + } + + if(Compare(consoletext[0],"protectionreset ",0,15)||Compare(consoletext[0],"Protectionreset ",0,15)){ + for(i=0;i1) + for(i=1;i1) + for(i=1;i1) + for(i=1;i1) + for(i=1;i0){ + for(k=14;k>=1;k--){ + for(j=0;j<255;j++){ + consoletext[k][j]=consoletext[k-1][j]; + } + consolechars[k]=consolechars[k-1]; + } + for(j=0;j<255;j++){ + consoletext[0][j]=' '; + } + consolechars[0]=0; + consoleselected=0; + + if(!donesomething){ + PlaySoundEx( consolefailsound, samp[consolefailsound], NULL, TRUE); + FSOUND_SetVolume(channels[consolefailsound], 256); + FSOUND_SetPaused(channels[consolefailsound], FALSE); + } + } + } + } + togglekey[i]=1; + } + else { + togglekey[i]=0; + togglekeydelay[i]=0; + } + } + + consoleblinkdelay-=multiplier; + if(consoleblinkdelay<=0){ + consoleblinkdelay=.3; + consoleblink=1-consoleblink; + } + } + + if(IsKeyDown(theKeyMap, MAC_Q_KEY)&&IsKeyDown(theKeyMap, MAC_COMMAND_KEY)){ + tryquit=1; + if(mainmenu==3){ + if(newdetail>2)newdetail=detail; + if(newdetail<0)newdetail=detail; + if(newscreenwidth>3000)newscreenwidth=screenwidth; + if(newscreenwidth<0)newscreenwidth=screenwidth; + if(newscreenheight>3000)newscreenheight=screenheight; + if(newscreenheight<0)newscreenheight=screenheight; + + //ofstream opstream(":Data:config.txt"); + ofstream opstream("./Data/config.txt"); + opstream << "Screenwidth:\n"; + opstream << newscreenwidth; + opstream << "\nScreenheight:\n"; + opstream << newscreenheight; + opstream << "\nMouse sensitivity:\n"; + opstream << usermousesensitivity; + opstream << "\nBlur(0,1):\n"; + opstream << ismotionblur; + opstream << "\nOverall Detail(0,1,2) higher=better:\n"; + opstream << newdetail; + opstream << "\nFloating jump:\n"; + opstream << floatjump; + opstream << "\nMouse jump:\n"; + opstream << mousejump; + opstream << "\nAmbient sound:\n"; + opstream << ambientsound; + opstream << "\nBlood (0,1,2):\n"; + opstream << bloodtoggle; + opstream << "\nAuto slomo:\n"; + opstream << autoslomo; + opstream << "\nFoliage:\n"; + opstream << foliage; + opstream << "\nMusic:\n"; + opstream << musictoggle; + opstream << "\nTrilinear:\n"; + opstream << trilinear; + opstream << "\nDecals(shadows,blood puddles,etc):\n"; + opstream << decals; + opstream << "\nInvert mouse:\n"; + opstream << invertmouse; + opstream << "\nGamespeed:\n"; + if(oldgamespeed==0)oldgamespeed=1; + opstream << oldgamespeed; + opstream << "\nDifficulty(0,1,2) higher=harder:\n"; + opstream << difficulty; + opstream << "\nDamage effects(blackout, doublevision):\n"; + opstream << damageeffects; + opstream << "\nText:\n"; + opstream << texttoggle; + opstream << "\nDebug:\n"; + opstream << debugmode; + opstream << "\nVBL Sync:\n"; + opstream << vblsync; + opstream << "\nShow Points:\n"; + opstream << showpoints; + opstream << "\nAlways Blur:\n"; + opstream << alwaysblur; + opstream << "\nImmediate mode (turn on on G5):\n"; + opstream << immediate; + opstream << "\nVelocity blur:\n"; + opstream << velocityblur; + opstream << "\nVolume:\n"; + opstream << volume; + opstream << "\nForward key:\n"; + opstream << KeyToChar(forwardkey); + opstream << "\nBack key:\n"; + opstream << KeyToChar(backkey); + opstream << "\nLeft key:\n"; + opstream << KeyToChar(leftkey); + opstream << "\nRight key:\n"; + opstream << KeyToChar(rightkey); + opstream << "\nJump key:\n"; + opstream << KeyToChar(jumpkey); + opstream << "\nCrouch key:\n"; + opstream << KeyToChar(crouchkey); + opstream << "\nDraw key:\n"; + opstream << KeyToChar(drawkey); + opstream << "\nThrow key:\n"; + opstream << KeyToChar(throwkey); + opstream << "\nAttack key:\n"; + opstream << KeyToChar(attackkey); + opstream << "\nChat key:\n"; + opstream << KeyToChar(chatkey); + opstream.close(); + } + } + + static int oldwinfreeze; + if(winfreeze&&!oldwinfreeze){ + FSOUND_SetFrequency(FSOUND_ALL, 0.001); + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + } + if(winfreeze==0)oldwinfreeze=winfreeze; + else oldwinfreeze++; + + if((IsKeyDown(theKeyMap, jumpkey)||IsKeyDown(theKeyMap, MAC_SPACE_KEY))&&!oldjumpkeydown&&!campaign){ + if(winfreeze)winfreeze=0; + oldjumpkeydown=1; + } + if((IsKeyDown(theKeyMap, MAC_ESCAPE_KEY))&&!campaign&&gameon){ + if(winfreeze){ + mainmenu=9; + gameon=0; + } + } + if((IsKeyDown(theKeyMap, jumpkey)||IsKeyDown(theKeyMap, MAC_SPACE_KEY))){ + oldjumpkeydown=1; + } + if(!IsKeyDown(theKeyMap, jumpkey)&&!IsKeyDown(theKeyMap, MAC_SPACE_KEY))oldjumpkeydown=0; + + if(!freeze&&!winfreeze&&!(mainmenu&&gameon)&&(gameon||!gamestarted)){ + + static bool oldbuttondialogue; + + if(indialogue!=-1)talkdelay=1; + talkdelay-=multiplier; + + if(talkdelay<=0) + if(indialogue==-1&&(animation[player[0].targetanimation].height!=highheight)/*&&!hostile*/) + for(i=0;i49){ + realdialoguetype=dialoguetype[i]-50; + special=1; + } + else if(dialoguetype[i]>39){ + realdialoguetype=dialoguetype[i]-40; + special=1; + } + else if(dialoguetype[i]>29){ + realdialoguetype=dialoguetype[i]-30; + special=1; + } + else if(dialoguetype[i]>19){ + realdialoguetype=dialoguetype[i]-20; + special=1; + } + else if(dialoguetype[i]>9){ + realdialoguetype=dialoguetype[i]-10; + special=1; + } + else { + realdialoguetype=dialoguetype[i]; + special=0; + } + if((!hostile||(dialoguetype[i]>40&&dialoguetype[i]<50))&&realdialoguetype0&&(dialoguegonethrough[i]==0||!special)&&(special||(IsKeyDown(theKeyMap, attackkey)&&!oldbuttondialogue))){ + if(findDistancefast(&player[0].coords,&player[realdialoguetype].coords)<6||player[realdialoguetype].howactive>=typedead1||(dialoguetype[i]>40&&dialoguetype[i]<50)){ + whichdialogue=i; + for(j=0;j0){ + hotspot[i]=player[hotspottype[i]].coords; + } + } + } + + //Tutorial + if(tutoriallevel&&tutorialstagetime>tutorialmaxtime){ + tutorialstage++; + tutorialsuccess=0; + if(tutorialstage<=1){ + canattack=0; + cananger=0; + reversaltrain=0; + } + if(tutorialstage==1){ + tutorialmaxtime=5; + } + if(tutorialstage==2){ + tutorialmaxtime=2; + } + if(tutorialstage==3){ + tutorialmaxtime=600; + } + if(tutorialstage==4){ + tutorialmaxtime=1000; + } + if(tutorialstage==5){ + tutorialmaxtime=600; + } + if(tutorialstage==6){ + tutorialmaxtime=600; + } + if(tutorialstage==7){ + tutorialmaxtime=600; + } + if(tutorialstage==8){ + tutorialmaxtime=600; + } + if(tutorialstage==9){ + tutorialmaxtime=600; + } + if(tutorialstage==10){ + tutorialmaxtime=2; + } + if(tutorialstage==11){ + tutorialmaxtime=1000; + } + if(tutorialstage==12){ + tutorialmaxtime=1000; + } + if(tutorialstage==13){ + tutorialmaxtime=2; + } + if(tutorialstage==14){ + tutorialmaxtime=3; + + XYZ temp,temp2; + + temp.x=1011; + temp.y=84; + temp.z=491; + temp2.x=1025; + temp2.y=75; + temp2.z=447; + + player[1].coords=(temp+temp2)/2; + + float gLoc[3]; + float vel[3]; + gLoc[0]=player[1].coords.x; + gLoc[1]=player[1].coords.y; + gLoc[2]=player[1].coords.z; + vel[0]=0; + vel[1]=0; + vel[2]=0; + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + + for(i=0;i0)tutorialsuccess=1; + } + if(tutorialstage==41){ + if(player[0].weaponactive==-1&&player[0].num_weapons>0)tutorialsuccess=1; + } + if(tutorialstage==43){ + if(player[0].targetanimation==knifeslashstartanim)tutorialsuccess=1; + } + if(tutorialstage==44){ + if(animation[player[0].targetanimation].attack==reversal)tutorialsuccess=1; + } + if(tutorialstage==45){ + if(animation[player[0].targetanimation].attack==reversal)tutorialsuccess=1; + } + if(tutorialstage==46){ + if(animation[player[0].targetanimation].attack==reversal)tutorialsuccess=1; + } + if(tutorialstage==49){ + if(player[1].weaponstuck!=-1)tutorialsuccess=1; + } + if(tutorialsuccess>=1)tutorialstagetime=tutorialmaxtime-3; + + + if(tutorialstagetime==tutorialmaxtime-3){ + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + } + + if(tutorialsuccess>=1){ + if(tutorialstage==34||tutorialstage==35) + tutorialstagetime=tutorialmaxtime-1; + } + } + + if(tutoriallevel){ + if(tutorialstage<14||tutorialstage>=50){ + player[1].coords.y=300; + player[1].velocity=0; + } + } + + if(tutoriallevel!=1){ + if(bonustime==0&&bonus!=solidhit&&bonus!=spinecrusher&&bonus!=tracheotomy&&bonus!=backstab&&bonusvalue>10){ + PlaySoundEx( consolesuccesssound, samp[consolesuccesssound], NULL, TRUE); + FSOUND_SetVolume(channels[consolesuccesssound], 256); + FSOUND_SetPaused(channels[consolesuccesssound], FALSE); + } + } + else + if(bonustime==0){ + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + } + if(bonustime==0){ + if(bonus!=solidhit&&bonus!=twoxcombo&&bonus!=threexcombo&&bonus!=fourxcombo&&bonus!=megacombo)bonusnum[bonus]++; + else bonusnum[bonus]+=0.15; + if(tutoriallevel)bonusvalue=0; + bonusvalue/=bonusnum[bonus]; + bonustotal+=bonusvalue; + } + bonustime+=multiplier; + + if(environment==snowyenvironment){ + precipdelay-=multiplier; + while(precipdelay<0){ + precipdelay+=.04; + if(!detail)precipdelay+=.04; + XYZ footvel,footpoint; + + footvel=0; + footpoint=viewer+viewerfacing*6; + footpoint.y+=((float)abs(Random()%1200))/100-6; + footpoint.x+=((float)abs(Random()%1200))/100-6; + footpoint.z+=((float)abs(Random()%1200))/100-6; + sprites.MakeSprite(snowsprite, footpoint,footvel, 1,1,1, .1, 1); + } + } + for(k=0;kplayer[k].targetrotation){ + player[k].rotation-=multiplier*player[k].turnspeed; + } + else if(player[k].rotationplayer[k].targetrotation){ + player[k].rotation-=multiplier*player[k].turnspeed; + } + else if(player[k].rotationplayer[k].targetrotation){ + player[k].rotation-=multiplier*player[k].turnspeed; + } + else if(player[k].rotation0){ + if(!player[k].skeleton.free&&player[k].targetanimation!=climbanim&&player[k].targetanimation!=hanganim){ + bool tempcollide=0; + + if(player[k].collide<-.3)player[k].collide=-.3; + if(player[k].collide>1)player[k].collide=1; + player[k].collide-=multiplier*30; + + if(player[k].coords.y.5&&player[k].aitype==playercontrolled)||objects.position[i].y>player[k].coords.y))){ + lowpoint=player[k].coords; + if(player[k].targetanimation!=jumpupanim&&player[k].targetanimation!=jumpdownanim&&!player[k].isFlip())lowpoint.y+=1.25; + else lowpoint.y+=1.3; + if(player[k].coords.yterrain.getHeight(player[k].coords.x,player[k].coords.z)-.1){ + player[k].coords.y=terrain.getHeight(player[k].coords.x,player[k].coords.z); + } + /*while(player[k].coords.y.5) + if(whichhit!=-1){ + //if(k==0){ + if(whichhit!=-1)if(player[k].targetanimation!=jumpupanim&&player[k].targetanimation!=jumpdownanim)player[k].collided=1; + if(checkcollide(lowpoint7,lowpointtarget7)==-1) + if(checkcollide(lowpoint6,lowpointtarget6)==-1) + if(objects.model[i].LineCheckPossible(&lowpoint2,&lowpointtarget2,&colpoint,&objects.position[i],&objects.rotation[i])!=-1&&objects.model[i].LineCheckPossible(&lowpoint3,&lowpointtarget3,&colpoint,&objects.position[i],&objects.rotation[i])!=-1&&objects.model[i].LineCheckPossible(&lowpoint4,&lowpointtarget4,&colpoint,&objects.position[i],&objects.rotation[i])!=-1&&objects.model[i].LineCheckPossible(&lowpoint5,&lowpointtarget5,&colpoint,&objects.position[i],&objects.rotation[i])!=-1) + for(j=0;j<45;j++){ + lowpoint=player[k].coords; + lowpoint.y+=(float)j/13; + lowpointtarget=lowpoint+facing*1.4; + if(objects.model[i].LineCheckPossible(&lowpoint,&lowpointtarget,&colpoint2,&objects.position[i],&objects.rotation[i])==-1){ + if(j<=6){ + j=100; + } + /*if(j>=25&&(player[k].isRun()||player[k].targetanimation==sneakanim||player[k].targetanimation==walkanim)){ + j=100; + }*/ + if(j<=25&&player[k].targetanimation==jumpdownanim){ + j=100; + } + if(j!=100&&(/*j>25||(player[k].isRun()||player[k].targetanimation==sneakanim||player[k].targetanimation==walkanim)||*/player[k].targetanimation==jumpupanim||player[k].targetanimation==jumpdownanim)){ + lowpoint=DoRotation(objects.model[i].facenormals[whichhit],0,objects.rotation[k],0); + if(1==1/*dotproduct(&player[k].velocity,&lowpoint)>0||player[k].aitype!=playercontrolled||(player[k].isRun()||player[k].targetanimation==sneakanim||player[k].targetanimation==walkanim||player[k].targetanimation==jumpupanim)*/){ + lowpoint=player[k].coords; + lowpoint.y+=(float)j/13; + lowpointtarget=lowpoint+facing*1.3; + flatfacing=player[k].coords; + player[k].coords=colpoint-DoRotation(objects.model[i].facenormals[whichhit],0,objects.rotation[k],0)*.01; + player[k].coords.y=lowpointtarget.y-.07; + player[k].currentoffset=(flatfacing-player[k].coords)/player[k].scale; + + if(j>10||!player[k].isRun()){ + if(player[k].targetanimation==jumpdownanim||player[k].targetanimation==jumpupanim){ + if(k==0)FSOUND_SetPaused(channels[whooshsound], TRUE); + } + float gLoc[3]; + float vel[3]; + gLoc[0]=player[k].coords.x; + gLoc[1]=player[k].coords.y; + gLoc[2]=player[k].coords.z; + vel[0]=player[k].velocity.x; + vel[1]=player[k].velocity.y; + vel[2]=player[k].velocity.z; + PlaySoundEx( jumpsound, samp[jumpsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[jumpsound], gLoc, vel); + FSOUND_SetVolume(channels[jumpsound], 128); + FSOUND_SetPaused(channels[jumpsound], FALSE); + + lowpointtarget=DoRotation(objects.model[i].facenormals[whichhit],0,objects.rotation[i],0); + player[k].rotation=-asin(0-lowpointtarget.x); + player[k].rotation*=360/6.28; + if(lowpointtarget.z<0)player[k].rotation=180-player[k].rotation; + player[k].targetrotation=player[k].rotation; + player[k].lowrotation=player[k].rotation; + + //player[k].velocity=lowpointtarget*.03; + player[k].velocity=0; + + if(/*(player[k].isRun()||player[k].targetanimation==sneakanim||player[k].targetanimation==walkanim)||*/player[k].targetanimation==jumpupanim){ + //player[k].currentanimation=climbanim; + player[k].targetanimation=climbanim; + player[k].jumppower=0; + player[k].jumpclimb=1; + } + player[k].transspeed=6; + player[k].target=0; + + //player[k].currentframe=1; + player[k].targetframe=1; + if(j>25){ + //player[k].currentframe=0; + player[k].targetframe=0; + //player[k].currentanimation=hanganim; + player[k].targetanimation=hanganim; + player[k].jumppower=0; + } + } + j=100; + } + } + } + } + //} + } + } + } + } + } + if(player[k].collide<=0){ + if(!player[k].onterrain&&player[k].targetanimation!=jumpupanim&&player[k].targetanimation!=jumpdownanim&&player[k].targetanimation!=climbanim&&player[k].targetanimation!=hanganim&&!player[k].isWallJump()&&!player[k].isFlip()){ + if(player[k].currentanimation!=climbanim&&player[k].currentanimation!=tempanim&&player[k].targetanimation!=backhandspringanim&&(player[k].targetanimation!=rollanim||player[k].targetframe<2||player[k].targetframe>6)){ + if(player[k].targetanimation==staggerbackhighanim||player[k].targetanimation==staggerbackhardanim)player[k].RagDoll(0); + player[k].targetanimation=jumpdownanim; + player[k].targetframe=0; + player[k].target=0; + + float gLoc[3]; + float vel[3]; + gLoc[0]=player[k].coords.x; + gLoc[1]=player[k].coords.y; + gLoc[2]=player[k].coords.z; + vel[0]=player[k].velocity.x; + vel[1]=player[k].velocity.y; + vel[2]=player[k].velocity.z; + if(k==0){ + PlaySoundEx( whooshsound, samp[whooshsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[whooshsound], gLoc, vel); + FSOUND_SetVolume(channels[whooshsound], 128); + FSOUND_SetPaused(channels[whooshsound], FALSE); + } + } + player[k].velocity.y+=gravity; + } + } + } + } + player[k].realoldcoords=player[k].coords; + } + + static XYZ oldviewer; + + if(indialogue==-1){ + player[0].forwardkeydown=IsKeyDown(theKeyMap, forwardkey); + player[0].leftkeydown=IsKeyDown(theKeyMap, leftkey); + player[0].backkeydown=IsKeyDown(theKeyMap, backkey); + player[0].rightkeydown=IsKeyDown(theKeyMap, rightkey); + player[0].jumpkeydown=IsKeyDown(theKeyMap, jumpkey); + player[0].crouchkeydown=IsKeyDown(theKeyMap, crouchkey); + player[0].drawkeydown=IsKeyDown(theKeyMap, drawkey); + player[0].throwkeydown=IsKeyDown(theKeyMap, throwkey); + } + else + { + player[0].forwardkeydown=0; + player[0].leftkeydown=0; + player[0].backkeydown=0; + player[0].rightkeydown=0; + player[0].jumpkeydown=0; + player[0].crouchkeydown=0; + player[0].drawkeydown=0; + player[0].throwkeydown=0; + } + + if(!player[0].jumpkeydown)player[0].jumpclimb=0; + + + static bool endkeydown; + if(indialogue!=-1){ + cameramode=1; + if(directing){ + facing=0; + facing.z=-1; + + facing=DoRotation(facing,-rotation2,0,0); + facing=DoRotation(facing,0,0-rotation,0); + + flatfacing=0; + flatfacing.z=-1; + + flatfacing=DoRotation(flatfacing,0,-rotation,0); + + if(IsKeyDown(theKeyMap, forwardkey))viewer+=facing*multiplier*4; + if(IsKeyDown(theKeyMap, backkey))viewer-=facing*multiplier*4; + if(IsKeyDown(theKeyMap, leftkey))viewer+=DoRotation(flatfacing*multiplier,0,90,0)*4; + if(IsKeyDown(theKeyMap, rightkey))viewer+=DoRotation(flatfacing*multiplier,0,-90,0)*4; + if(IsKeyDown(theKeyMap, jumpkey))viewer.y+=multiplier*4; + if(IsKeyDown(theKeyMap, crouchkey))viewer.y-=multiplier*4; + if(!endkeydown&&(IsKeyDown(theKeyMap, MAC_1_KEY)||IsKeyDown(theKeyMap, MAC_2_KEY)||IsKeyDown(theKeyMap, MAC_3_KEY)||IsKeyDown(theKeyMap, MAC_4_KEY)||IsKeyDown(theKeyMap, MAC_5_KEY) + ||IsKeyDown(theKeyMap, MAC_6_KEY)||IsKeyDown(theKeyMap, MAC_7_KEY)||IsKeyDown(theKeyMap, MAC_8_KEY)||IsKeyDown(theKeyMap, MAC_9_KEY)||IsKeyDown(theKeyMap, MAC_0_KEY) + ||IsKeyDown(theKeyMap, MAC_MINUS_KEY))){ + int whichend; + if(IsKeyDown(theKeyMap, MAC_1_KEY))whichend=1; + if(IsKeyDown(theKeyMap, MAC_2_KEY))whichend=2; + if(IsKeyDown(theKeyMap, MAC_3_KEY))whichend=3; + if(IsKeyDown(theKeyMap, MAC_4_KEY))whichend=4; + if(IsKeyDown(theKeyMap, MAC_5_KEY))whichend=5; + if(IsKeyDown(theKeyMap, MAC_6_KEY))whichend=6; + if(IsKeyDown(theKeyMap, MAC_7_KEY))whichend=7; + if(IsKeyDown(theKeyMap, MAC_8_KEY))whichend=8; + if(IsKeyDown(theKeyMap, MAC_9_KEY))whichend=9; + if(IsKeyDown(theKeyMap, MAC_0_KEY))whichend=0; + if(IsKeyDown(theKeyMap, MAC_MINUS_KEY))whichend=-1; + if(whichend!=-1){ + participantfocus[whichdialogue][indialogue]=whichend; + participantlocation[whichdialogue][whichend]=player[whichend].coords; + participantrotation[whichdialogue][whichend]=player[whichend].rotation; + } + if(whichend==-1){ + participantfocus[whichdialogue][indialogue]=-1; + } + if(player[participantfocus[whichdialogue][indialogue]].dead){ + indialogue=-1; + directing=0; + cameramode=0; + } + dialoguecamera[whichdialogue][indialogue]=viewer; + dialoguecamerarotation[whichdialogue][indialogue]=rotation; + dialoguecamerarotation2[whichdialogue][indialogue]=rotation2; + indialogue++; + if(indialogue=numdialogueboxes[whichdialogue]){ + indialogue=-1; + directing=0; + cameramode=0; + } + } + if(!directing){ + FSOUND_SetPaused(channels[whooshsound], TRUE); + viewer=dialoguecamera[whichdialogue][indialogue]; + if(viewer.y0.5) + if((!endkeydown&&(IsKeyDown(theKeyMap, MAC_1_KEY)||IsKeyDown(theKeyMap, MAC_2_KEY)||IsKeyDown(theKeyMap, MAC_3_KEY)||IsKeyDown(theKeyMap, MAC_4_KEY)||IsKeyDown(theKeyMap, MAC_5_KEY) + ||IsKeyDown(theKeyMap, MAC_6_KEY)||IsKeyDown(theKeyMap, MAC_7_KEY)||IsKeyDown(theKeyMap, MAC_8_KEY)||IsKeyDown(theKeyMap, MAC_9_KEY)||IsKeyDown(theKeyMap, MAC_0_KEY) + ||IsKeyDown(theKeyMap, MAC_MINUS_KEY)))||(IsKeyDown(theKeyMap, attackkey)&&!oldbuttondialogue)){ + indialogue++; + endkeydown=1; + if(indialogue=numdialogueboxes[whichdialogue]){ + indialogue=-1; + directing=0; + cameramode=0; + if(dialoguetype[whichdialogue]>19&&dialoguetype[whichdialogue]<30){ + hostile=1; + } + if(dialoguetype[whichdialogue]>29&&dialoguetype[whichdialogue]<40){ + windialogue=1; + } + if(dialoguetype[whichdialogue]>49&&dialoguetype[whichdialogue]<60){ + hostile=1; + for(i=1;i2)environment=0; + Setenvironment(environment); + + envtogglekeydown=1; + } + + + if(!IsKeyDown(theKeyMap, MAC_J_KEY)){ + envtogglekeydown=0; + } + + if(IsKeyDown(theKeyMap, MAC_C_KEY)&&!cameratogglekeydown&&debugmode){ + cameramode=1-cameramode; + cameratogglekeydown=1; + } + + if(!IsKeyDown(theKeyMap, MAC_C_KEY)){ + cameratogglekeydown=0; + } + + if(IsKeyDown(theKeyMap, MAC_X_KEY)&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&!detailtogglekeydown&&debugmode){ + if(player[0].num_weapons>0){ + if(weapons.type[player[0].weaponids[0]]==sword)weapons.type[player[0].weaponids[0]]=staff; + else if(weapons.type[player[0].weaponids[0]]==staff)weapons.type[player[0].weaponids[0]]=knife; + else weapons.type[player[0].weaponids[0]]=sword; + if(weapons.type[player[0].weaponids[0]]==sword){ + weapons.mass[player[0].weaponids[0]]=1.5; + weapons.tipmass[player[0].weaponids[0]]=1; + weapons.length[player[0].weaponids[0]]=.8; + } + if(weapons.type[player[0].weaponids[0]]==staff){ + weapons.mass[player[0].weaponids[0]]=2; + weapons.tipmass[player[0].weaponids[0]]=1; + weapons.length[player[0].weaponids[0]]=1.5; + } + + if(weapons.type[player[0].weaponids[0]]==knife){ + weapons.mass[player[0].weaponids[0]]=1; + weapons.tipmass[player[0].weaponids[0]]=1.2; + weapons.length[player[0].weaponids[0]]=.25; + } + } + + /*for(i=0;i1) + for(i=1;i1) + for(i=1;i1) + for(i=1;i9)player[closest].whichskin=0; + if(player[closest].whichskin>2&&player[closest].creature==wolftype)player[closest].whichskin=0; + + if(player[closest].creature==rabbittype){ + if(player[closest].whichskin==0){ + LoadTextureSave(":Data:Textures:Fur3.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==1){ + LoadTextureSave(":Data:Textures:Fur.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==2){ + LoadTextureSave(":Data:Textures:Fur2.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==3){ + LoadTextureSave(":Data:Textures:Lynx.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==4){ + LoadTextureSave(":Data:Textures:Otter.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==5){ + LoadTextureSave(":Data:Textures:Opal.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==6){ + LoadTextureSave(":Data:Textures:Sable.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==7){ + LoadTextureSave(":Data:Textures:Chocolate.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==8){ + LoadTextureSave(":Data:Textures:BW2.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==9){ + LoadTextureSave(":Data:Textures:WB2.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + } + if(player[closest].creature==wolftype){ + k=abs(Random()%3); + if(player[closest].whichskin==0){ + LoadTextureSave(":Data:Textures:Wolf.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==1){ + LoadTextureSave(":Data:Textures:Darkwolf.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + else if(player[closest].whichskin==2){ + LoadTextureSave(":Data:Textures:Snowwolf.jpg",&player[closest].skeleton.drawmodel.textureptr,1,&player[closest].skeleton.skinText[0],&player[closest].skeleton.skinsize); + } + } + } + + if(player[closest].numclothes){ + for(i=0;i1) + for(i=1;i1) + for(i=1;i1) + for(i=1;i1&&numplayers1) + for(i=1;i0&&closest>=0){ + //player[closest]=player[numplayers-1]; + //player[closest].skeleton=player[numplayers-1].skeleton; + numplayers--; + } + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_DELETE_KEY)&&editorenabled&&!drawmodetogglekeydown&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + int closest=-1; + float closestdist=-1; + float distance; + if(max_objects>1) + for(i=1;i0&&closest>=0){ + objects.position[closest].y-=500; + } + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_M_KEY)&&!drawmodetogglekeydown&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&editorenabled&&debugmode){ + //drawmode++; + //if(drawmode>2)drawmode=0; + if(objects.numobjects1) + for(i=0;i1&&pathpointselected!=-1){ + numpathpointconnect[pathpointselected]++; + pathpointconnect[pathpointselected][numpathpointconnect[pathpointselected]-1]=numpathpoints-1; + } + pathpointselected=numpathpoints-1; + } + } + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_PERIOD_KEY)&&!drawmodetogglekeydown&&editorenabled){ + pathpointselected++; + if(pathpointselected>=numpathpoints)pathpointselected=-1; + drawmodetogglekeydown=1; + } + if(IsKeyDown(theKeyMap, MAC_COMMA_KEY)&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&!drawmodetogglekeydown&&editorenabled){ + pathpointselected--; + if(pathpointselected<=-2)pathpointselected=numpathpoints-1; + drawmodetogglekeydown=1; + } + if(IsKeyDown(theKeyMap, MAC_COMMA_KEY)&&IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&!drawmodetogglekeydown&&editorenabled){ + if(pathpointselected!=-1){ + numpathpoints--; + pathpoint[pathpointselected]=pathpoint[numpathpoints]; + numpathpointconnect[pathpointselected]=numpathpointconnect[numpathpoints]; + for(i=0;ifiretype)editortype=0; + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_LEFT_KEY)&&editorenabled&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&!IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + editorrotation-=multiplier*100; + if(editorrotation<-.01)editorrotation=-.01; + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_RIGHT_KEY)&&editorenabled&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&!IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + editorrotation+=multiplier*100; + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_UP_KEY)&&editorenabled&&!IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + editorsize+=multiplier; + drawmodetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_DOWN_KEY)&&editorenabled&&!IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + editorsize-=multiplier; + if(editorsize<.1)editorsize=.1; + drawmodetogglekeydown=1; + } + + + if(IsKeyDown(theKeyMap, MAC_ARROW_LEFT_KEY)&&!drawmodetogglekeydown&&editorenabled&&IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + mapradius-=multiplier*10; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_RIGHT_KEY)&&!drawmodetogglekeydown&&editorenabled&&IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + mapradius+=multiplier*10; + } + /* + if(IsKeyDown(theKeyMap, MAC_ARROW_LEFT_KEY)&&editorenabled&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + mapcenter.x+=multiplier*20; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_RIGHT_KEY)&&editorenabled&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + mapcenter.x-=multiplier*20; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_UP_KEY)&&editorenabled&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + mapcenter.z+=multiplier*20; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_DOWN_KEY)&&editorenabled&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + mapcenter.z-=multiplier*20; + } + */ + if(IsKeyDown(theKeyMap, MAC_ARROW_UP_KEY)&&editorenabled&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + editorrotation2+=multiplier*100; + } + + if(IsKeyDown(theKeyMap, MAC_ARROW_DOWN_KEY)&&editorenabled&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)){ + editorrotation2-=multiplier*100; + if(editorrotation2<-.01)editorrotation2=-.01; + } + if(IsKeyDown(theKeyMap, MAC_DELETE_KEY)&&editorenabled&&objects.numobjects&&!drawmodetogglekeydown&&!IsKeyDown(theKeyMap, MAC_SHIFT_KEY)){ + int closest=-1; + float closestdist=-1; + float distance; + for(i=0;i0&&closest>=0)objects.DeleteObject(closest); + drawmodetogglekeydown=1; + } + + + if(!IsKeyDown(theKeyMap, MAC_M_KEY)&&!IsKeyDown(theKeyMap, MAC_ARROW_LEFT_KEY)&&!IsKeyDown(theKeyMap, MAC_COMMA_KEY)&&!IsKeyDown(theKeyMap, MAC_PERIOD_KEY)&&!IsKeyDown(theKeyMap, MAC_ARROW_RIGHT_KEY)&&!IsKeyDown(theKeyMap, MAC_DELETE_KEY)&&!IsKeyDown(theKeyMap, MAC_P_KEY)){ + drawmodetogglekeydown=0; + } + + if(IsKeyDown(theKeyMap, MAC_N_KEY)&&!IsKeyDown(theKeyMap, MAC_CONTROL_KEY)&&!texturesizetogglekeydown&&debugmode){ + //if(!player[0].skeleton.free)player[0].damage+=500; + player[0].RagDoll(0); + //player[0].spurt=1; + //player[0].DoDamage(1000); + + float gLoc[3]; + float vel[3]; + gLoc[0]=player[0].coords.x; + gLoc[1]=player[0].coords.y; + gLoc[2]=player[0].coords.z; + vel[0]=player[0].velocity.x; + vel[1]=player[0].velocity.y; + vel[2]=player[0].velocity.z; + PlaySoundEx( whooshsound, samp[whooshsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[whooshsound], gLoc, vel); + FSOUND_SetVolume(channels[whooshsound], 128); + FSOUND_SetPaused(channels[whooshsound], FALSE); + //FSOUND_SetPaused(channels[whooshsound], TRUE); + + texturesizetogglekeydown=1; + } + + if(IsKeyDown(theKeyMap, MAC_N_KEY)&&IsKeyDown(theKeyMap, MAC_CONTROL_KEY)&&!texturesizetogglekeydown&&debugmode){ + + int closest=-1; + float closestdist=-1; + float distance; + for(i=0;i1&&player[k].backkeydown&&player[k].targetanimation!=backhandspringanim&&(player[k].isIdle()||player[k].isStop()||player[k].isRun()||player[k].targetanimation==walkanim)){ + for(i=0;i1) + for(i=0;i0&&weapons.type[player[k].weaponids[player[k].weaponactive]]==knife&&player[i].bloodloss>player[i].damagetolerance/2)player[k].targetanimation=knifefollowanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height!=lowheight&&!player[k].forwardkeydown&&!player[k].leftkeydown&&!player[k].rightkeydown&&!player[k].crouchkeydown&&player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==knife&&player[k].weaponmissdelay<=0)player[k].targetanimation=knifeslashstartanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<4.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height!=lowheight&&!player[k].crouchkeydown&&player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==sword&&player[k].weaponmissdelay<=0)player[k].targetanimation=swordslashanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<4.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height!=lowheight&&!player[k].crouchkeydown&&player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==staff&&player[k].weaponmissdelay<=0&&!player[k].leftkeydown&&!player[k].rightkeydown&&!player[k].forwardkeydown)player[k].targetanimation=staffhitanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<4.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height!=lowheight&&!player[k].crouchkeydown&&player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==staff&&player[k].weaponmissdelay<=0)player[k].targetanimation=staffspinhitanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height!=lowheight)player[k].targetanimation=spinkickanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height==lowheight&&animation[player[k].targetanimation].attack!=normalattack)player[k].targetanimation=lowkickanim; + } + else { + if(findDistancefast(&player[k].coords,&player[i].coords)<4.5*(player[k].scale*5)*(player[k].scale*5)){ + if(player[k].weaponactive==-1)randattack=abs(Random()%5); + else randattack=abs(Random()%5); + if(player[k].weaponactive==-1&&findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)){ + if(randattack==0&&animation[player[i].targetanimation].height!=lowheight)player[k].targetanimation=sweepanim; + else if(randattack==1&&animation[player[i].targetanimation].height!=lowheight&&player[k].weaponactive==-1)player[k].targetanimation=upunchanim; + else if(randattack==2&&animation[player[i].targetanimation].height!=lowheight)player[k].targetanimation=spinkickanim; + else if(animation[player[i].targetanimation].height==lowheight)player[k].targetanimation=lowkickanim; + } + if(player[k].weaponactive!=-1){ + if((tutoriallevel!=1||player[k].weaponactive==-1)&&findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)&&randattack==0&&animation[player[i].targetanimation].height!=lowheight)player[k].targetanimation=sweepanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)/*&&animation[player[i].targetanimation].height!=lowheight*/&&weapons.type[player[k].weaponids[player[k].weaponactive]]==knife&&player[k].weaponmissdelay<=0)player[k].targetanimation=knifeslashstartanim; + //else if(findDistancefast(&player[k].coords,&player[i].coords)<2.5&&player[k].weaponactive!=-1&&player[i].staggerdelay>0&&weapons.type[player[k].weaponids[player[k].weaponactive]]==knife)player[k].targetanimation=knifefollowanim; + else if(!(player[0].victim==&player[i]&&player[0].hasvictim&&player[0].targetanimation==swordslashanim)&&weapons.type[player[k].weaponids[player[k].weaponactive]]==sword&&player[k].weaponmissdelay<=0)player[k].targetanimation=swordslashanim; + else if(!(player[0].victim==&player[i]&&player[0].hasvictim&&player[0].targetanimation==swordslashanim)&&weapons.type[player[k].weaponids[player[k].weaponactive]]==staff&&player[k].weaponmissdelay<=0&&randattack<3)player[k].targetanimation=staffhitanim; + else if(!(player[0].victim==&player[i]&&player[0].hasvictim&&player[0].targetanimation==swordslashanim)&&weapons.type[player[k].weaponids[player[k].weaponactive]]==staff&&player[k].weaponmissdelay<=0&&randattack>=3)player[k].targetanimation=staffspinhitanim; + else if((tutoriallevel!=1||player[k].weaponactive==-1)&&findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)&&randattack==1&&animation[player[i].targetanimation].height!=lowheight)player[k].targetanimation=spinkickanim; + else if(findDistancefast(&player[k].coords,&player[i].coords)<2.5*(player[k].scale*5)*(player[k].scale*5)&&animation[player[i].targetanimation].height==lowheight&&animation[player[k].targetanimation].attack!=normalattack)player[k].targetanimation=lowkickanim; + } + } + } + if(player[k].targetanimation==upunchanim&&player[k].creature==wolftype)player[k].targetanimation=wolfslapanim; + } + if((tutoriallevel!=1||tutorialstage==22)&&player[i].howactive0&&player[k].madskills)||(player[i].surprised>0)||player[i].aitype==passivetype)||(player[k].weaponactive!=-1&&player[i].stunned>0))&&normaldotproduct(player[i].facing,player[i].coords-player[k].coords)>0&&(k==0)){ + if(player[k].weaponactive==-1){ + player[i].targetanimation=sneakattackedanim; + player[i].currentanimation=sneakattackedanim; + player[k].currentanimation=sneakattackanim; + player[k].targetanimation=sneakattackanim; + player[k].oldcoords=player[k].coords; + player[k].coords=player[i].coords; + } + if(player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==knife){ + player[i].targetanimation=knifesneakattackedanim; + player[i].currentanimation=knifesneakattackedanim; + player[k].currentanimation=knifesneakattackanim; + player[k].targetanimation=knifesneakattackanim; + player[i].oldcoords=player[i].coords; + player[i].coords=player[k].coords; + } + if(player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==sword){ + player[i].targetanimation=swordsneakattackedanim; + player[i].currentanimation=swordsneakattackedanim; + player[k].currentanimation=swordsneakattackanim; + player[k].targetanimation=swordsneakattackanim; + player[i].oldcoords=player[i].coords; + player[i].coords=player[k].coords; + } + if(player[k].weaponactive==-1||weapons.type[player[k].weaponids[player[k].weaponactive]]!=staff){ + player[k].victim=&player[i]; + player[k].hasvictim=1; + player[i].targettilt2=0; + player[i].targetframe=1; + player[i].currentframe=0; + player[i].target=0; + player[i].velocity=0; + player[k].targettilt2=player[i].targettilt2; + player[k].currentframe=player[i].currentframe; + player[k].targetframe=player[i].targetframe; + player[k].target=player[i].target; + player[k].velocity=0; + player[k].targetrotation=player[i].rotation; + player[k].rotation=player[i].rotation; + player[i].targetrotation=player[i].rotation; + } + } + if(animation[player[k].targetanimation].attack==normalattack&&player[k].victim==&player[i]&&(!player[i].skeleton.free)){ + oldattackkey=1; + player[k].targetframe=0; + player[k].target=0; + //player[k].velocity=0; + + rotatetarget=player[i].coords-player[k].coords; + Normalise(&rotatetarget); + player[k].targetrotation=-asin(0-rotatetarget.x); + player[k].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[k].targetrotation=180-player[k].targetrotation; + + player[k].targettilt2=-asin(rotatetarget.y)*360/6.28;//*-70; + + player[k].lastattack3=player[k].lastattack2; + player[k].lastattack2=player[k].lastattack; + player[k].lastattack=player[k].targetanimation; + //player[k].targettilt2=0; + //slomo=1; + //slomodelay=.2; + } + if(player[k].targetanimation==knifefollowanim&&player[k].victim==&player[i]){ + rotatetarget=player[i].coords-player[k].coords; + Normalise(&rotatetarget); + player[k].targetrotation=-asin(0-rotatetarget.x); + player[k].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[k].targetrotation=180-player[k].targetrotation; + player[k].targettilt2=-asin(rotatetarget.y)*360/6.28;//*-70; + oldattackkey=1; + player[k].victim=&player[i]; + player[k].hasvictim=1; + player[i].targetanimation=knifefollowedanim; + player[i].currentanimation=knifefollowedanim; + player[i].targettilt2=0; + player[i].targettilt2=player[k].targettilt2; + player[i].targetframe=1; + player[i].currentframe=0; + player[i].target=0; + player[i].velocity=0; + player[k].currentanimation=knifefollowanim; + player[k].targetanimation=knifefollowanim; + player[k].targettilt2=player[i].targettilt2; + player[k].currentframe=player[i].currentframe; + player[k].targetframe=player[i].targetframe; + player[k].target=player[i].target; + player[k].velocity=0; + player[k].oldcoords=player[k].coords; + player[i].coords=player[k].coords; + player[i].targetrotation=player[k].targetrotation; + player[i].rotation=player[k].targetrotation; + player[k].rotation=player[k].targetrotation; + player[i].rotation=player[k].targetrotation; + } + } + } + bool hasstaff=0; + if(player[k].weaponactive!=-1){ + if(weapons.type[player[k].weaponids[player[k].weaponactive]]==staff)hasstaff=1; + } + if(numplayers>1) + for(i=0;i1000||player[k].isRun()||(hasstaff)||(player[k].weaponactive!=-1&&player[i].skeleton.free&&(player[i].skeleton.longdead>2000||player[i].damage>player[i].damagetolerance/8||player[i].bloodloss>player[i].damagetolerance/2)&&findDistancefast(&player[k].coords,&player[i].coords)<1.5*(player[k].scale*5)*(player[k].scale*5)))){ + player[k].victim=&player[i]; + player[k].hasvictim=1; + if(player[k].weaponactive!=-1&&tutoriallevel!=1){ + if(player[k].crouchkeydown&&player[k].weaponactive!=-1&&weapons.type[player[k].weaponids[player[k].weaponactive]]==knife&&findDistancefast(&player[k].coords,&player[i].coords)<1.5*(player[k].scale*5)*(player[k].scale*5))player[k].targetanimation=crouchstabanim; + if(player[k].crouchkeydown&&findDistancefast(&player[k].coords,&player[i].coords)<1.5*(player[k].scale*5)*(player[k].scale*5)/*&&player[i].dead!=2*/&&weapons.type[player[k].weaponids[player[k].weaponactive]]==sword)player[k].targetanimation=swordgroundstabanim; + if(/*(player[k].crouchkeydown||!player[i].dead)&&*/findDistancefast(&player[k].coords,&player[i].coords)<3.5*(player[k].scale*5)*(player[k].scale*5)/*&&player[i].dead!=2*/&&weapons.type[player[k].weaponids[player[k].weaponactive]]==staff)player[k].targetanimation=staffgroundsmashanim; + } + if(findDistancefast(&player[k].coords,&player[i].coords)<2.5&&player[k].crouchkeydown&&player[k].targetanimation!=crouchstabanim&&(player[k].weaponactive==-1)&&player[i].dead&&player[i].skeleton.free&&player[i].skeleton.longdead>1000){ + player[k].targetanimation=killanim; + for(j=0;jcoords)&&i!=k&&(i==0||k==0)){ + player[k].victim=&player[i]; + } + } + } + if(player[k].aitype==playercontrolled) + if(player[k].attackkeydown&&(player[k].isRun())&&player[k].wasRun()&&((player[k].hasvictim&&findDistancefast(&player[k].coords,&player[k].victim->coords)<12*(player[k].scale*5)*(player[k].scale*5)&&findDistancefast(&player[k].coords,&player[k].victim->coords)>7*(player[k].scale*5)*(player[k].scale*5)&&!player[k].victim->skeleton.free&&player[k].victim->targetanimation!=getupfrombackanim&&player[k].victim->targetanimation!=getupfromfrontanim&&animation[player[k].victim->targetanimation].height!=lowheight&&player[k].aitype!=playercontrolled&&normaldotproduct(player[k].facing,player[k].victim->coords-player[k].coords)>0&&player[k].rabbitkickenabled)||player[k].jumpkeydown)){ + oldattackkey=1; + player[k].targetanimation=rabbitkickanim; + player[k].targetframe=0; + player[k].target=0; + } + if(animation[player[k].targetanimation].attack&&k==0){ + numattacks++; + bool armedstaff=0; + if(player[k].weaponactive!=-1){ + if(weapons.type[player[k].weaponids[player[k].weaponactive]]==staff)armedstaff=1; + } + bool armedsword=0; + if(player[k].weaponactive!=-1){ + if(weapons.type[player[k].weaponids[player[k].weaponactive]]==sword)armedsword=1; + } + bool armedknife=0; + if(player[k].weaponactive!=-1){ + if(weapons.type[player[k].weaponids[player[k].weaponactive]]==knife)armedknife=1; + } + if(armedstaff)numstaffattack++; + else if(armedsword)numswordattack++; + else if(armedknife)numknifeattack++; + else numunarmedattack++; + } + } + } + } + + //Collisions + static float collisionradius; + if(numplayers>1) + for(k=0;kplayer[k].coords.y-3) + if(player[i].coords.yplayer[k].coords.x-3) + if(player[i].coords.xplayer[k].coords.z-3) + if(player[i].coords.zskeleton.free)collisionradius=3; + if((!player[i].skeleton.oldfree||!player[k].skeleton.oldfree)&&(findDistancefast(&tempcoords1,&tempcoords2)1)||(player[k].skeleton.oldfree==1&&findLengthfast(&player[k].velocity)>1)||(player[i].skeleton.oldfree==0&&player[k].skeleton.oldfree==0)){ + rotatetarget=player[k].velocity-player[i].velocity; + if(((player[i].targetanimation!=getupfrombackanim&&player[i].targetanimation!=getupfromfrontanim)||player[i].skeleton.free)&&((player[k].targetanimation!=getupfrombackanim&&player[k].targetanimation!=getupfromfrontanim)||player[k].skeleton.free)) + if(((((findLengthfast(&rotatetarget)>150&&(i!=0&&k!=0))||(findLengthfast(&rotatetarget)>50&&player[0].rabbitkickragdoll/*currentanimation==rabbitkickanim*/&&(i==0||k==0)))&&normaldotproduct(rotatetarget,player[k].coords-player[i].coords)>0)&&((i==0||k==0)||((player[i].skeleton.oldfree==1&&k!=0&&animation[player[k].currentanimation].attack==neutral)||(player[k].skeleton.oldfree==1&&i!=0&&animation[player[i].currentanimation].attack==neutral)||(player[i].isFlip()&&!player[i].skeleton.oldfree&&(i==0||k==0))||(player[k].isFlip()&&!player[k].skeleton.oldfree&&(i==0||k==0))||(i==0||k==0))))||((player[i].targetanimation==jumpupanim||player[i].targetanimation==jumpdownanim||player[i].isFlip())&&(player[k].targetanimation==jumpupanim||player[k].targetanimation==jumpdownanim||player[k].isFlip())&&(i==0||k==0)&&(!player[i].skeleton.oldfree&&!player[k].skeleton.oldfree))){ + //If hit by body + if((i!=0||player[i].skeleton.free)&&(k!=0||player[k].skeleton.free)||(animation[player[i].targetanimation].height==highheight&&animation[player[k].targetanimation].height==highheight)){ + static float gLoc[3]; + static float vel[3]; + gLoc[0]=player[i].coords.x; + gLoc[1]=player[i].coords.y; + gLoc[2]=player[i].coords.z; + vel[0]=player[i].velocity.x; + vel[1]=player[i].velocity.y; + vel[2]=player[i].velocity.z; + if(tutoriallevel!=1){ + PlaySoundEx( heavyimpactsound, samp[heavyimpactsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[heavyimpactsound], gLoc, vel); + FSOUND_SetVolume(channels[heavyimpactsound], 256); + FSOUND_SetPaused(channels[heavyimpactsound], FALSE); + } + //player[i].velocity=player[k].velocity; + //player[k].velocity=player[i].velocity; + + player[i].RagDoll(0); + if(player[i].damage>player[i].damagetolerance-findLengthfast(&rotatetarget)/4&&!player[i].dead){ + bonus=aimbonus; + bonustime=0; + bonusvalue=150; + } + player[i].DoDamage(findLengthfast(&rotatetarget)/4); + player[k].RagDoll(0); + if(player[k].damage>player[k].damagetolerance-findLengthfast(&rotatetarget)/4&&!player[k].dead){ + bonus=aimbonus; + bonustime=0; + bonusvalue=150; + } + player[k].DoDamage(findLengthfast(&rotatetarget)/4); + + //if(player[i].skeleton.oldfree){ + for(j=0;j1&&checkdelay<=0){ + checkdelay=.015; + for(k=0;kplayer[k].coords.y-3) + if(player[i].coords.yplayer[k].coords.x-3) + if(player[i].coords.xplayer[k].coords.z-3) + if(player[i].coords.zplayer[k].skeleton.longdead&&player[k].skeleton.free!=2)||player[i].skeleton.free==2){ + stuck=i; + moving=k; + } + else + { + moving=i; + stuck=k; + } + isgood=1; + + if(isgood){ + above[moving]=stuck; + for(l=0;lnumchallengelevels-1)targetlevel=0; + loading=1; + leveltime=5; + slomotogglekeydown=1; + } + + /* + if(IsKeyDown(theKeyMap, MAC_Z_KEY)){ + //Respawn + FSOUND_SetPaused(channels[whooshsound], TRUE); + changedelay=0; + for(k=0;k.8)player[i].avoidcollided=0; + if(player[i].aitype!=playercontrolled&&indialogue==-1){ + player[i].jumpclimb=0; + //AI + if(editorenabled)player[i].stunned=1; + + player[i].pause=0; + //if(findDistancefastflat(&player[i].coords,&player[0].coords)<3/*&&player[0].coords.y>player[i].coords.y+.1*/)player[i].pause=1; + if(findDistancefastflat(&player[0].coords,&player[i].coords)<30&&player[0].coords.y>player[i].coords.y+2&&!player[0].onterrain)player[i].pause=1; + + /*if(player[i].aitype==passivetype&&player[i].numwaypoints<=1){ + player[i].forwardkeydown=0; + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].crouchkeydown=0; + player[i].attackkeydown=0; + player[i].jumpkeydown=0; + player[i].throwkeydown=0; + }*/ + + if(player[i].aitype==pathfindtype){ + if(player[i].finalpathfindpoint==-1){ + float closestdistance; + float tempdist; + int closest; + XYZ colpoint; + closest=-1; + closestdistance=-1; + for(j=0;j.8&&!player[i].jumpkeydown&&player[i].collided<.8)player[i].targetrotation+=90*(player[i].whichdirection*2-1); + + if(player[i].collided<1||player[i].targetanimation!=jumpupanim)player[i].jumpkeydown=0; + if((player[i].collided>.8&&player[i].jumppower>=5))player[i].jumpkeydown=1; + + if((tutoriallevel!=1||cananger)&&hostile&&!player[0].dead&&findDistancefast(&player[i].coords,&player[0].coords)<400&&player[i].occluded<25){ + if(findDistancefast(&player[i].coords,&player[0].coords)<12&&animation[player[0].targetanimation].height!=lowheight&&!editorenabled&&(player[0].coords.y0) + if(player[j].coords.y.5){ + player[i].howactive=typeactive; + } + + if(player[i].aitype==passivetype){ + player[i].aiupdatedelay-=multiplier; + player[i].losupdatedelay-=multiplier; + player[i].lastseentime+=multiplier; + player[i].pausetime-=multiplier; + if(player[i].lastseentime>1)player[i].lastseentime=1; + + if(player[i].aiupdatedelay<0){ + if(player[i].numwaypoints>1&&player[i].howactive==typeactive&&player[i].pausetime<=0){ + rotatetarget=player[i].waypoints[player[i].waypoint]-player[i].coords; + Normalise(&rotatetarget); + player[i].targetrotation=-asin(0-rotatetarget.x); + player[i].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetrotation=180-player[i].targetrotation; + player[i].lookrotation=player[i].targetrotation; + player[i].aiupdatedelay=.05; + + if(findDistancefastflat(&player[i].coords,&player[i].waypoints[player[i].waypoint])<1){ + if(player[i].waypointtype[player[i].waypoint]==wppause)player[i].pausetime=4; + player[i].waypoint++; + if(player[i].waypoint>player[i].numwaypoints-1)player[i].waypoint=0; + + } + } + + if(player[i].numwaypoints>1&&player[i].howactive==typeactive&&player[i].pausetime<=0)player[i].forwardkeydown=1; + else player[i].forwardkeydown=0; + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].crouchkeydown=0; + player[i].attackkeydown=0; + player[i].throwkeydown=0; + + if(player[i].avoidcollided>.8&&!player[i].jumpkeydown&&player[i].collided<.8){ + if(!player[i].avoidsomething)player[i].targetrotation+=90*(player[i].whichdirection*2-1); + else{ + XYZ leftpos,rightpos; + float leftdist,rightdist; + leftpos = player[i].coords+DoRotation(player[i].facing,0,90,0); + rightpos = player[i].coords-DoRotation(player[i].facing,0,90,0); + leftdist = findDistancefast(&leftpos, &player[i].avoidwhere); + rightdist = findDistancefast(&rightpos, &player[i].avoidwhere); + if(leftdist.8&&player[i].jumppower>=5))player[i].jumpkeydown=1; + + + if(!editorenabled){ + if(player[i].howactive0&&(tutoriallevel!=1||cananger)&&hostile) + for(j=0;j0&&(tutoriallevel!=1||cananger)&&hostile) + for(j=0;j14) + if(findDistancefast(&player[i].coords,&envsound[j])<2*((envsoundvol[j]-14)+(envsoundvol[j]-14)*(player[i].creature==rabbittype)*3)){ + player[i].aitype=attacktypecutoff; + } + } + + if(player[i].aitype!=passivetype){ + if(player[i].howactive==typesleeping){ + player[i].targetanimation=getupfromfrontanim; + player[i].targetframe=0; + player[i].target=0; + } + + player[i].howactive=typeactive; + } + } + + if(player[i].howactive0)){ + if(j==0&&player[j].num_weapons>0){ + if(weapons.bloody[player[j].weaponids[0]])smelldistance=100; + if(player[j].num_weapons==2) + if(weapons.bloody[player[j].weaponids[1]])smelldistance=100; + } + if(j!=0){ + smelldistance=100; + } + windsmell=windvector; + Normalise(&windsmell); + windsmell=windsmell*2+player[j].coords; + if(findDistancefast(&player[i].coords,&windsmell)0) + if((-1==checkcollide(DoRotation(player[i].skeleton.joints[player[i].skeleton.jointlabels[head]].position,0,player[i].rotation,0)*player[i].scale+player[i].coords,DoRotation(player[j].skeleton.joints[player[j].skeleton.jointlabels[head]].position,0,player[j].rotation,0)*player[j].scale+player[j].coords)&&!player[j].isWallJump())||(player[j].targetanimation==hanganim&&normaldotproduct(player[j].facing,player[i].coords-player[j].coords)<0)){ + player[i].lastseentime-=.2; + if(j==0&&animation[player[j].targetanimation].height==lowheight)player[i].lastseentime-=.4; + else player[i].lastseentime-=.6; + } + if(player[i].lastseentime<=0){ + player[i].aitype=searchtype; + player[i].lastchecktime=12; + player[i].lastseen=player[j].coords; + player[i].lastseentime=12; + } + } + } + } + } + if(player[i].aitype==attacktypecutoff&&musictype!=2){ + if(player[i].creature!=wolftype){ + player[i].stunned=.6; + player[i].surprised=.6; + } + if(player[i].creature==wolftype){ + player[i].stunned=.47; + player[i].surprised=.47; + } + numseen++; + } + } + + if(player[i].aitype==searchtype){ + player[i].aiupdatedelay-=multiplier; + player[i].losupdatedelay-=multiplier; + if(!player[i].pause)player[i].lastseentime-=multiplier; + player[i].lastchecktime-=multiplier; + + if(player[i].isRun()&&!player[i].onground){ + if(player[i].coords.y>terrain.getHeight(player[i].coords.x,player[i].coords.z)+10){ + test2=player[i].coords+player[i].facing; + test2.y+=5; + test=player[i].coords+player[i].facing; + test.y-=10; + j=checkcollide(test2,test,player[i].laststanding); + if(j==-1)j=checkcollide(test2,test); + if(j==-1){ + player[i].velocity=0; + player[i].targetanimation=player[i].getStop(); + player[i].targetframe=0; + player[i].target=0; + player[i].targetrotation+=180; + player[i].stunned=.5; + //player[i].aitype=passivetype; + player[i].aitype=pathfindtype; + player[i].finalfinaltarget=player[i].waypoints[player[i].waypoint]; + player[i].finalpathfindpoint=-1; + player[i].targetpathfindpoint=-1; + player[i].lastpathfindpoint=-1; + player[i].lastpathfindpoint2=-1; + player[i].lastpathfindpoint3=-1; + player[i].lastpathfindpoint4=-1; + } + else player[i].laststanding=j; + } + } + if(player[i].aiupdatedelay<0){ + rotatetarget=player[i].lastseen-player[i].coords; + Normalise(&rotatetarget); + player[i].targetrotation=-asin(0-rotatetarget.x); + player[i].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetrotation=180-player[i].targetrotation; + player[i].lookrotation=player[i].targetrotation; + player[i].aiupdatedelay=.05; + player[i].forwardkeydown=1; + + if(findDistancefastflat(&player[i].coords,&player[i].lastseen)<1*(player[i].scale*5)*(player[i].scale*5)||player[i].lastchecktime<0){ + player[i].forwardkeydown=0; + player[i].aiupdatedelay=1; + player[i].lastseen.x+=(float(Random()%100)-50)/25; + player[i].lastseen.z+=(float(Random()%100)-50)/25; + player[i].lastchecktime=3; + } + + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].crouchkeydown=0; + player[i].attackkeydown=0; + player[i].throwkeydown=0; + + if(player[i].avoidcollided>.8&&!player[i].jumpkeydown&&player[i].collided<.8){ + if(!player[i].avoidsomething)player[i].targetrotation+=90*(player[i].whichdirection*2-1); + else{ + XYZ leftpos,rightpos; + float leftdist,rightdist; + leftpos = player[i].coords+DoRotation(player[i].facing,0,90,0); + rightpos = player[i].coords-DoRotation(player[i].facing,0,90,0); + leftdist = findDistancefast(&leftpos, &player[i].avoidwhere); + rightdist = findDistancefast(&rightpos, &player[i].avoidwhere); + if(leftdist.8&&player[i].jumppower>=5))player[i].jumpkeydown=1; + + if(numenvsounds>0&&((tutoriallevel!=1||cananger)&&hostile)) + for(j=0;j0) + if((-1==checkcollide(DoRotation(player[i].skeleton.joints[player[i].skeleton.jointlabels[head]].position,0,player[i].rotation,0)*player[i].scale+player[i].coords,DoRotation(player[0].skeleton.joints[player[0].skeleton.jointlabels[head]].position,0,player[0].rotation,0)*player[0].scale+player[0].coords))||(player[j].targetanimation==hanganim&&normaldotproduct(player[j].facing,player[i].coords-player[j].coords)<0)){ + player[i].aitype=attacktypecutoff; + player[i].lastseentime=1; + } + } + if(player[i].lastseentime<0){ + //player[i].aitype=passivetype; + numescaped++; + player[i].aitype=pathfindtype; + player[i].finalfinaltarget=player[i].waypoints[player[i].waypoint]; + player[i].finalpathfindpoint=-1; + player[i].targetpathfindpoint=-1; + player[i].lastpathfindpoint=-1; + player[i].lastpathfindpoint2=-1; + player[i].lastpathfindpoint3=-1; + player[i].lastpathfindpoint4=-1; + } + } + + if(player[i].aitype!=gethelptype){ + player[i].runninghowlong=0; + } + + if(player[i].aitype==gethelptype){ + player[i].runninghowlong+=multiplier; + player[i].aiupdatedelay-=multiplier; + + if(player[i].aiupdatedelay<0||player[i].ally==0){ + player[i].aiupdatedelay=.2; + + int closest; + float closestdist; + closest=-1; + closestdist=-1; + float distance; + + if(!player[i].ally){ + for(j=0;j0){ + rotatetarget=player[player[i].ally].coords-player[i].coords; + Normalise(&rotatetarget); + player[i].targetrotation=-asin(0-rotatetarget.x); + player[i].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetrotation=180-player[i].targetrotation; + player[i].lookrotation=player[i].targetrotation; + player[i].aiupdatedelay=.05; + player[i].forwardkeydown=1; + + if(findDistancefastflat(&player[i].coords,&player[player[i].ally].coords)<3){ + player[i].aitype=searchtype; + player[i].lastseentime=12; + player[player[i].ally].aitype=searchtype; + if(player[player[i].ally].lastseentime.8&&!player[i].jumpkeydown&&player[i].collided<.8){ + if(!player[i].avoidsomething)player[i].targetrotation+=90*(player[i].whichdirection*2-1); + else{ + XYZ leftpos,rightpos; + float leftdist,rightdist; + leftpos = player[i].coords+DoRotation(player[i].facing,0,90,0); + rightpos = player[i].coords-DoRotation(player[i].facing,0,90,0); + leftdist = findDistancefast(&leftpos, &player[i].avoidwhere); + rightdist = findDistancefast(&rightpos, &player[i].avoidwhere); + if(leftdist.8&&player[i].jumppower>=5))player[i].jumpkeydown=1; + } + + if(player[i].aitype==getweapontype){ + player[i].aiupdatedelay-=multiplier; + player[i].lastchecktime-=multiplier; + + if(player[i].aiupdatedelay<0){ + player[i].aiupdatedelay=.2; + + int closest; + float closestdist; + closest=-1; + closestdist=-1; + float distance; + + if(player[i].ally<0){ + for(j=0;j=0){ + if(weapons.owner[player[i].ally]!=-1||findDistancefast(&player[i].coords,&weapons.position[player[i].ally])>16){ + player[i].aitype=attacktypecutoff; + player[i].lastseentime=1; + } + rotatetarget=weapons.position[player[i].ally]-player[i].coords; + Normalise(&rotatetarget); + player[i].targetrotation=-asin(0-rotatetarget.x); + player[i].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetrotation=180-player[i].targetrotation; + player[i].lookrotation=player[i].targetrotation; + player[i].aiupdatedelay=.05; + player[i].forwardkeydown=1; + + + if(player[i].avoidcollided>.8&&!player[i].jumpkeydown&&player[i].collided<.8){ + if(!player[i].avoidsomething)player[i].targetrotation+=90*(player[i].whichdirection*2-1); + else{ + XYZ leftpos,rightpos; + float leftdist,rightdist; + leftpos = player[i].coords+DoRotation(player[i].facing,0,90,0); + rightpos = player[i].coords-DoRotation(player[i].facing,0,90,0); + leftdist = findDistancefast(&leftpos, &player[i].avoidwhere); + rightdist = findDistancefast(&rightpos, &player[i].avoidwhere); + if(leftdist.8&&player[i].jumppower>=5))player[i].jumpkeydown=1; + } + + if(player[i].aitype==attacktypecutoff){ + player[i].aiupdatedelay-=multiplier; + if(player[i].damage.5)player[i].stunned=1; + } + if(player[i].wentforweapon<3) + for(j=0;jterrain.getHeight(player[i].coords.x,player[i].coords.z)+10){ + test2=player[i].coords+player[i].facing; + test2.y+=5; + test=player[i].coords+player[i].facing; + test.y-=10; + j=checkcollide(test2,test,player[i].laststanding); + if(j==-1)j=checkcollide(test2,test); + if(j==-1){ + player[i].velocity=0; + player[i].targetanimation=player[i].getStop(); + player[i].targetframe=0; + player[i].target=0; + player[i].targetrotation+=180; + player[i].stunned=.5; + //player[i].aitype=passivetype; + player[i].aitype=pathfindtype; + player[i].finalfinaltarget=player[i].waypoints[player[i].waypoint]; + player[i].finalpathfindpoint=-1; + player[i].targetpathfindpoint=-1; + player[i].lastpathfindpoint=-1; + player[i].lastpathfindpoint2=-1; + player[i].lastpathfindpoint3=-1; + player[i].lastpathfindpoint4=-1; + } + else player[i].laststanding=j; + } + } + if(player[0].coords.y>player[i].coords.y+5&&animation[player[0].targetanimation].height!=highheight&&!player[0].onterrain){ + player[i].aitype=pathfindtype; + player[i].finalfinaltarget=player[i].waypoints[player[i].waypoint]; + player[i].finalpathfindpoint=-1; + player[i].targetpathfindpoint=-1; + player[i].lastpathfindpoint=-1; + player[i].lastpathfindpoint2=-1; + player[i].lastpathfindpoint3=-1; + player[i].lastpathfindpoint4=-1; + } + if(player[i].aiupdatedelay<0&&!animation[player[i].targetanimation].attack&&player[i].targetanimation!=staggerbackhighanim&&player[i].targetanimation!=staggerbackhardanim&&player[i].targetanimation!=backhandspringanim&&player[i].targetanimation!=dodgebackanim){ + if(player[i].weaponactive==-1&&player[i].num_weapons>0)player[i].drawkeydown=Random()%2; + else player[i].drawkeydown=0; + player[i].rabbitkickenabled=Random()%2; + rotatetarget=player[player[i].aitarget].coords+player[player[i].aitarget].velocity; + if(findDistancefast(&player[player[i].aitarget].coords,&player[i].coords)5&&(player[0].weaponactive==-1||player[i].weaponactive!=-1))player[i].forwardkeydown=1; + else if((findDistancefast(&player[i].coords,&player[0].coords)>16||findDistancefast(&player[i].coords,&player[0].coords)<9)&&player[0].weaponactive!=-1)player[i].forwardkeydown=1; + else if(Random()%6==0||(player[i].creature==wolftype&&Random()%3==0))player[i].forwardkeydown=1; + else player[i].forwardkeydown=0; + if(player[0].dead){ + player[i].forwardkeydown=0; + if(Random()%10==0)player[i].forwardkeydown=1; + if(Random()%100==0){ + player[i].aitype=pathfindtype; + player[i].finalfinaltarget=player[i].waypoints[player[i].waypoint]; + player[i].finalpathfindpoint=-1; + player[i].targetpathfindpoint=-1; + player[i].lastpathfindpoint=-1; + player[i].lastpathfindpoint2=-1; + player[i].lastpathfindpoint3=-1; + player[i].lastpathfindpoint4=-1; + } + } + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].crouchkeydown=0; + player[i].throwkeydown=0; + + if(player[i].avoidcollided>.8&&!player[i].jumpkeydown&&player[i].collided<.8)player[i].targetrotation+=90*(player[i].whichdirection*2-1); + /*for(j=0;jid==i&&(player[j].targetanimation==spinkickanim&&player[j].targetframe<3)){ + player[i].crouchkeydown=1; + } + }*/ + if(Random()%2==0/*||player[0].weaponactive!=-1*/||player[i].weaponactive!=-1||player[i].creature==wolftype)player[i].attackkeydown=1; + else player[i].attackkeydown=0; + if((player[i].isRun())&&Random()%6&&findDistancefast(&player[i].coords,&player[0].coords)>7)player[i].attackkeydown=0; + //if(player[i].attackkeydown&&findDistancefast(&player[i].coords,&player[0].coords)<3&&player[i].targetanimation!=runanim&&!player[0].skeleton.free)player[i].crouchkeydown=1; + /*if(player[0].targetanimation==rabbitkickanim&&!player[0].skeleton.free){ + player[i].attackkeydown=0; + if(player[i].isIdle())player[i].crouchkeydown=1; + player[i].forwardkeydown=0; + player[i].aiupdatedelay=.02; + }*/ + + if(player[i].aitype!=playercontrolled&&(player[i].isIdle()||player[i].isCrouch()||player[i].isRun())){ + target=-2; + for(j=0;jcoords)<4&&player[j].victim==&player[i]&&(player[j].targetanimation==sweepanim||player[j].targetanimation==spinkickanim||player[j].targetanimation==staffhitanim||player[j].targetanimation==staffspinhitanim||player[j].targetanimation==winduppunchanim||player[j].targetanimation==upunchanim||player[j].targetanimation==wolfslapanim||player[j].targetanimation==knifeslashstartanim||((player[j].targetanimation==swordslashanim)&&(findDistancefast(&player[j].coords,&player[i].coords)<2||(player[i].weaponactive!=-1))))){ + if(target>=0)target=-1; + else target=j; + } + } + } + if(target>=0)player[target].Reverse(); + } + + if(player[i].collided<1)player[i].jumpkeydown=0; + if((player[i].collided>.8&&player[i].jumppower>=5)||(findDistancefast(&player[i].coords,&player[0].coords)>400&&player[i].onterrain&&player[i].creature==rabbittype))player[i].jumpkeydown=1; + if(normaldotproduct(player[i].facing,player[0].coords-player[i].coords)>0) + player[0].jumpkeydown=0; + if(player[0].targetanimation==jumpdownanim&&findDistancefast(&player[0].coords,&player[i].coords)<40)player[i].crouchkeydown=1; + if(player[i].jumpkeydown)player[i].attackkeydown=0; + //if(animation[player[i].targetanimation].attack==reversed)player[i].crouchkeydown=1; + + if(tutoriallevel==1){ + if(!canattack)player[i].attackkeydown=0; + } + + + facing=player[i].coords; + flatfacing=player[0].coords; + facing.y+=player[i].skeleton.joints[player[i].skeleton.jointlabels[head]].position.y*player[i].scale; + flatfacing.y+=player[0].skeleton.joints[player[0].skeleton.jointlabels[head]].position.y*player[0].scale; + if(player[i].occluded>=2) + if(-1!=checkcollide(facing,flatfacing)){ + if(!player[i].pause)player[i].lastseentime-=.2; + if(player[i].lastseentime<=0&&(player[i].creature!=wolftype||player[i].weaponstuck==-1)){ + player[i].aitype=searchtype; + player[i].lastchecktime=12; + player[i].lastseen=player[0].coords; + player[i].lastseentime=12; + } + } + else player[i].lastseentime=1; + } + } + if(animation[player[0].targetanimation].height==highheight&&(player[i].aitype==attacktypecutoff||player[i].aitype==searchtype)){ + if(player[0].coords.y>terrain.getHeight(player[0].coords.x,player[0].coords.z)+10){ + test=player[0].coords; + test.y-=40; + if(-1==checkcollide(player[0].coords,test))player[i].stunned=1; + } + } + // NOTE: Ask about logic of this call : NOTE + if((player[i].aitype==passivetype && !(player[i].numwaypoints>1)) || + player[i].stunned>0 || + (player[i].pause && (player[i].damage > player[i].superpermanentdamage))) + { + if(/*player[i].aitype==attacktypecutoff&&*/player[i].pause)player[i].lastseentime=1; + player[i].targetrotation=player[i].rotation; + player[i].forwardkeydown=0; + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].jumpkeydown=0; + player[i].attackkeydown=0; + player[i].crouchkeydown=0; + player[i].throwkeydown=0; + } + + + facing=0; + facing.z=-1; + + flatfacing=DoRotation(facing,0,player[i].rotation+180,0); + facing=flatfacing; + + if(player[i].aitype==attacktypecutoff){ + rotatetarget=player[0].coords-player[i].coords; + Normalise(&rotatetarget); + player[i].targetheadrotation=-asin(0-rotatetarget.x); + player[i].targetheadrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetheadrotation=180-player[i].targetheadrotation; + + player[i].targetheadrotation*=-1; + player[i].targetheadrotation+=180; + //player[i].targetheadrotation2=0; + player[i].targetheadrotation2=-asin(rotatetarget.y)*360/6.28; + } + else if(player[i].howactive>=typesleeping){ + player[i].targetheadrotation=player[i].targetrotation; + player[i].targetheadrotation2=0; + } + else { + if(player[i].interestdelay<=0){ + player[i].interestdelay=.7+(float)(abs(Random()%100))/100; + player[i].headtarget=player[i].coords; + player[i].headtarget.x+=(float)(abs(Random()%200)-100)/100; + player[i].headtarget.z+=(float)(abs(Random()%200)-100)/100; + player[i].headtarget.y+=(float)(abs(Random()%200)-100)/300; + player[i].headtarget+=player[i].facing*1.5; + } + rotatetarget=player[i].headtarget-player[i].coords; + Normalise(&rotatetarget); + player[i].targetheadrotation=-asin(0-rotatetarget.x); + player[i].targetheadrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetheadrotation=180-player[i].targetheadrotation; + + player[i].targetheadrotation*=-1; + player[i].targetheadrotation+=180; + player[i].targetheadrotation2=-asin(rotatetarget.y)*360/6.28; + } + //if(whichlevel==2)player[i].jumpkeydown=0; + } + if(animation[player[i].targetanimation].attack==reversed){ + //player[i].targetrotation=player[i].rotation; + player[i].forwardkeydown=0; + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].jumpkeydown=0; + player[i].attackkeydown=0; + //player[i].crouchkeydown=0; + player[i].throwkeydown=0; + } + + if(indialogue!=-1){ + player[i].forwardkeydown=0; + player[i].leftkeydown=0; + player[i].backkeydown=0; + player[i].rightkeydown=0; + player[i].jumpkeydown=0; + player[i].crouchkeydown=0; + player[i].drawkeydown=0; + player[i].throwkeydown=0; + } + + if(player[i].collided<-.3)player[i].collided=-.3; + if(player[i].collided>1)player[i].collided=1; + player[i].collided-=multiplier*4; + player[i].whichdirectiondelay-=multiplier; + if(player[i].avoidcollided<-.3||player[i].whichdirectiondelay<=0){ + player[i].avoidcollided=-.3; + player[i].whichdirection=abs(Random()%2); + player[i].whichdirectiondelay=.4; + } + if(player[i].avoidcollided>1)player[i].avoidcollided=1; + player[i].avoidcollided-=multiplier/4; + if(!player[i].skeleton.free)player[i].stunned-=multiplier; + if(!player[i].skeleton.free)player[i].surprised-=multiplier; + if(player[i].surprised<=0&&player[i].aitype==attacktypecutoff&&i!=0&&!player[i].dead&&!player[i].skeleton.free&&animation[player[i].targetanimation].attack==neutral)numresponded=1; + + if(!player[i].throwkeydown){ + player[i].throwtogglekeydown=0; + } + if(player[i].throwkeydown&&!player[i].throwtogglekeydown){ + if(player[i].weaponactive==-1&&player[i].num_weapons<2&&(player[i].isIdle()||player[i].isCrouch()||player[i].targetanimation==sneakanim||player[i].targetanimation==rollanim||player[i].targetanimation==backhandspringanim||player[i].isFlip()||player[i].isFlip()||player[i].aitype!=playercontrolled)){ + for(j=0;jid)) + if(findDistancefastflat(&player[i].coords,&weapons.position[j])<2&&player[i].weaponactive==-1){ + if(findDistancefast(&player[i].coords,&weapons.position[j])<1||player[i].victim){ + float gLoc[3]; + float vel[3]; + gLoc[0]=player[i].coords.x; + gLoc[1]=player[i].coords.y; + gLoc[2]=player[i].coords.z; + vel[0]=player[i].velocity.x; + vel[1]=player[i].velocity.y; + vel[2]=player[i].velocity.z; + if(weapons.type[j]!=staff){ + PlaySoundEx( knifedrawsound, samp[knifedrawsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[knifedrawsound], gLoc, vel); + FSOUND_SetVolume(channels[knifedrawsound], 128); + FSOUND_SetPaused(channels[knifedrawsound], FALSE); + } + + player[i].weaponactive=0; + weapons.owner[j]=player[i].id; + if(player[i].num_weapons>0){ + player[i].weaponids[player[i].num_weapons]=player[i].weaponids[0]; + } + player[i].num_weapons++; + player[i].weaponids[0]=j; + } + } + //} + } + } + else if ((player[i].isIdle()||player[i].isFlip()||player[i].aitype!=playercontrolled)&&findDistancefast(&player[i].coords,&weapons.position[j])<5&&player[i].coords.yid)) + if(findDistancefastflat(&player[i].coords,&weapons.position[k])<3&&player[i].weaponactive==-1){ + float gLoc[3]; + float vel[3]; + gLoc[0]=player[i].coords.x; + gLoc[1]=player[i].coords.y; + gLoc[2]=player[i].coords.z; + vel[0]=player[i].velocity.x; + vel[1]=player[i].velocity.y; + vel[2]=player[i].velocity.z; + if(weapons.type[k]!=staff){ + PlaySoundEx( knifedrawsound, samp[knifedrawsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[knifedrawsound], gLoc, vel); + FSOUND_SetVolume(channels[knifedrawsound], 128); + FSOUND_SetPaused(channels[knifedrawsound], FALSE); + } + + player[i].weaponactive=0; + weapons.owner[k]=player[i].id; + if(player[i].num_weapons>0){ + player[i].weaponids[player[i].num_weapons]=player[i].weaponids[0]; + } + player[i].num_weapons++; + player[i].weaponids[0]=k; + } + } + } + } + } + } + if(player[i].isCrouch()||player[i].targetanimation==sneakanim||player[i].isRun()||player[i].isIdle()||player[i].targetanimation==rollanim||player[i].targetanimation==backhandspringanim){ + if(numplayers>1) + for(j=0;j0&&player[j].weaponstuckwhere==1))||player[j].weaponstuck==-1||player[j].num_weapons>1)){ + if(player[i].targetanimation!=rollanim&&player[i].targetanimation!=backhandspringanim){ + player[i].throwtogglekeydown=1; + player[i].victim=&player[j]; + player[i].hasvictim=1; + player[i].targetanimation=crouchremoveknifeanim; + player[i].target=0; + player[i].targetframe=0; + rotatetarget=player[j].coords-player[i].coords; + Normalise(&rotatetarget); + player[i].targetrotation=-asin(0-rotatetarget.x); + player[i].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetrotation=180-player[i].targetrotation; + } + if(player[i].targetanimation==rollanim||player[i].targetanimation==backhandspringanim){ + player[i].throwtogglekeydown=1; + player[i].victim=&player[j]; + player[i].hasvictim=1; + int k = player[j].weaponids[0]; + if(player[i].hasvictim){ + float gLoc[3]; + float vel[3]; + gLoc[0]=player[i].coords.x; + gLoc[1]=player[i].coords.y; + gLoc[2]=player[i].coords.z; + vel[0]=player[i].velocity.x; + vel[1]=player[i].velocity.y; + vel[2]=player[i].velocity.z; + bool fleshstuck; + fleshstuck=0; + if(player[i].victim->weaponstuck!=-1){ + if(player[i].victim->weaponids[player[i].victim->weaponstuck]==k){ + fleshstuck=1; + } + } + if(!fleshstuck){ + if(weapons.type[k]!=staff){ + PlaySoundEx( knifedrawsound, samp[knifedrawsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[knifedrawsound], gLoc, vel); + FSOUND_SetVolume(channels[knifedrawsound], 128); + FSOUND_SetPaused(channels[knifedrawsound], FALSE); + } + } + if(fleshstuck){ + PlaySoundEx( fleshstabremovesound, samp[fleshstabremovesound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fleshstabremovesound], gLoc, vel); + FSOUND_SetVolume(channels[fleshstabremovesound], 128); + FSOUND_SetPaused(channels[fleshstabremovesound], FALSE); + } + + player[i].weaponactive=0; + if(weapons.owner[k]!=-1){ + if(player[i].victim->num_weapons==1)player[i].victim->num_weapons=0; + else player[i].victim->num_weapons=1; + + player[i].victim->skeleton.longdead=0; + player[i].victim->skeleton.free=1; + player[i].victim->skeleton.broken=0; + + for(int l=0;lskeleton.num_joints;l++){ + player[i].victim->skeleton.joints[l].velchange=0; + player[i].victim->skeleton.joints[l].locked=0; + } + + XYZ relative; + relative=0; + relative.y=10; + Normalise(&relative); + XYZ footvel,footpoint; + footvel=0; + footpoint=weapons.position[k]; + if(player[i].victim->weaponstuck!=-1){ + if(player[i].victim->weaponids[player[i].victim->weaponstuck]==k){ + if(bloodtoggle)sprites.MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3); + weapons.bloody[k]=2; + weapons.blooddrip[k]=5; + player[i].victim->weaponstuck=-1; + player[i].victim->bloodloss+=2000; + player[i].victim->DoDamage(2000); + } + } + if(player[i].victim->num_weapons>0){ + if(player[i].victim->weaponstuck!=0&&player[i].victim->weaponstuck!=-1)player[i].victim->weaponstuck=0; + if(player[i].victim->weaponids[0]==k) + player[i].victim->weaponids[0]=player[i].victim->weaponids[player[i].victim->num_weapons]; + } + + player[i].victim->weaponactive=-1; + + player[i].victim->skeleton.joints[player[i].victim->skeleton.jointlabels[abdomen]].velocity+=relative*6; + player[i].victim->skeleton.joints[player[i].victim->skeleton.jointlabels[neck]].velocity+=relative*6; + player[i].victim->skeleton.joints[player[i].victim->skeleton.jointlabels[rightshoulder]].velocity+=relative*6; + player[i].victim->skeleton.joints[player[i].victim->skeleton.jointlabels[leftshoulder]].velocity+=relative*6; + } + weapons.owner[k]=i; + if(player[i].num_weapons>0){ + player[i].weaponids[player[i].num_weapons]=player[i].weaponids[0]; + } + player[i].num_weapons++; + player[i].weaponids[0]=k; + } + } + } + } + } + } + if(player[i].weaponactive!=-1&&player[i].aitype==playercontrolled){ + if(weapons.type[player[i].weaponids[0]]==knife){ + if(player[i].isIdle()||player[i].isRun()||player[i].isCrouch()||player[i].targetanimation==sneakanim||player[i].isFlip()) + if(numplayers>1) + for(j=0;j1.5&&!player[j].skeleton.free&&-1==checkcollide(DoRotation(player[j].skeleton.joints[player[j].skeleton.jointlabels[head]].position,0,player[j].rotation,0)*player[j].scale+player[j].coords,DoRotation(player[i].skeleton.joints[player[i].skeleton.jointlabels[head]].position,0,player[i].rotation,0)*player[i].scale+player[i].coords)){ + if(!player[i].isFlip()){ + player[i].throwtogglekeydown=1; + player[i].victim=&player[j]; + player[i].targetanimation=knifethrowanim; + player[i].target=0; + player[i].targetframe=0; + rotatetarget=player[j].coords-player[i].coords; + Normalise(&rotatetarget); + player[i].targetrotation=-asin(0-rotatetarget.x); + player[i].targetrotation*=360/6.28; + if(rotatetarget.z<0)player[i].targetrotation=180-player[i].targetrotation; + + player[i].targettilt2=-asin(rotatetarget.y)*360/6.28; + } + if(player[i].isFlip()){ + if(player[i].weaponactive!=-1){ + player[i].throwtogglekeydown=1; + player[i].victim=&player[j]; + XYZ aim; + weapons.owner[player[i].weaponids[0]]=-1; + aim=player[i].victim->coords+DoRotation(player[i].victim->skeleton.joints[player[i].victim->skeleton.jointlabels[abdomen]].position,0,player[i].victim->rotation,0)*player[i].victim->scale+player[i].victim->velocity*findDistance(&player[i].victim->coords,&player[i].coords)/50-(player[i].coords+DoRotation(player[i].skeleton.joints[player[i].skeleton.jointlabels[righthand]].position,0,player[i].rotation,0)*player[i].scale); + Normalise(&aim); + + aim=DoRotation(aim,(float)abs(Random()%30)-15,(float)abs(Random()%30)-15,0); + + weapons.velocity[player[i].weaponids[0]]=aim*50; + weapons.tipvelocity[player[i].weaponids[0]]=aim*50; + weapons.missed[player[i].weaponids[0]]=0; + weapons.freetime[player[i].weaponids[0]]=0; + weapons.firstfree[player[i].weaponids[0]]=1; + weapons.physics[player[i].weaponids[0]]=0; + player[i].num_weapons--; + if(player[i].num_weapons){ + player[i].weaponids[0]=player[i].weaponids[player[i].num_weapons]; + } + player[i].weaponactive=-1; + } + } + } + } + } + } + if(player[i].weaponactive!=-1&&player[i].aitype==playercontrolled){ + if(player[i].isCrouch()||player[i].targetanimation==sneakanim) + { + player[i].throwtogglekeydown=1; + weapons.owner[player[i].weaponids[0]]=-1; + weapons.velocity[player[i].weaponids[0]]=player[i].velocity*.2; + if(weapons.velocity[player[i].weaponids[0]].x==0)weapons.velocity[player[i].weaponids[0]].x=.1; + weapons.tipvelocity[player[i].weaponids[0]]=weapons.velocity[player[i].weaponids[0]]; + weapons.missed[player[i].weaponids[0]]=1; + weapons.freetime[player[i].weaponids[0]]=0; + weapons.firstfree[player[i].weaponids[0]]=1; + weapons.physics[player[i].weaponids[0]]=1; + player[i].num_weapons--; + if(player[i].num_weapons){ + player[i].weaponids[0]=player[i].weaponids[player[i].num_weapons]; + if(player[i].weaponstuck==player[i].num_weapons)player[i].weaponstuck=0; + } + + player[i].weaponactive=-1; + for(j=0;j1) + for(j=0;j1) + for(j=0;jcoords)<3&&player[j].victim==&player[i]&&(player[j].targetanimation==sweepanim||player[j].targetanimation==upunchanim||player[j].targetanimation==wolfslapanim||((player[j].targetanimation==swordslashanim||player[j].targetanimation==knifeslashstartanim||player[j].targetanimation==staffhitanim||player[j].targetanimation==staffspinhitanim)&&findDistancefast(&player[j].coords,&player[i].coords)<2))){ + if(target>=0)target=-1; + else target=j; + } + } + } + if(target>=0)player[target].Reverse(); + player[i].lowreversaldelay=.5; + + if(player[i].isIdle()){ + player[i].targetanimation=player[i].getCrouch(); + player[i].target=0; + player[i].targetframe=0; + player[i].transspeed=10; + } + if(player[i].isRun()||(player[i].isStop()&&(player[i].leftkeydown||player[i].rightkeydown||player[i].forwardkeydown||player[i].backkeydown))){ + player[i].targetanimation=rollanim; + player[i].target=0; + player[i].targetframe=0; + player[i].transspeed=20; + } + } + if(!player[i].crouchkeydown){ + //Uncrouch + if(!player[i].isRun()&&player[i].targetanimation!=sneakanim&&i==0)player[i].superruntoggle=0; + target=-2; + if(player[i].isCrouch()){ + if(numplayers>1) + for(j=0;jcoords)<3&&player[j].victim==&player[i]&&(player[j].targetanimation==spinkickanim)&&player[i].isCrouch()){ + if(target>=0)target=-1; + else target=j; + } + } + } + if(target>=0)player[target].Reverse(); + player[i].highreversaldelay=.5; + + if(player[i].isCrouch()){ + if(!player[i].wasCrouch()){ + player[i].currentanimation=player[i].getCrouch(); + player[i].currentframe=0; + } + player[i].target=0; + player[i].targetanimation=player[i].getIdle(); + player[i].targetframe=0; + player[i].transspeed=10; + } + } + if(player[i].targetanimation==sneakanim){ + player[i].targetanimation=player[i].getIdle(); + player[i].target=0; + player[i].targetframe=0; + player[i].transspeed=10; + } + } + if(player[i].forwardkeydown){ + if(player[i].isIdle()||(player[i].isStop()&&player[i].targetrotation==player[i].rotation)||(player[i].isLanding()&&player[i].targetframe>0&&!player[i].jumpkeydown)||(player[i].isLandhard()&&player[i].targetframe>0&&!player[i].jumpkeydown&&player[i].crouchkeydown)){ + if(player[i].aitype==passivetype)player[i].targetanimation=walkanim; + else player[i].targetanimation=player[i].getRun(); + player[i].target=0; + player[i].targetframe=0; + } + if(player[i].isCrouch()){ + player[i].targetanimation=sneakanim; + if(player[i].wasCrouch())player[i].target=0; + player[i].targetframe=0; + } + if(player[i].targetanimation==hanganim/*&&(!player[i].forwardstogglekeydown||player[i].aitype!=playercontrolled)*/){ + player[i].targetanimation=climbanim; + player[i].target=0; + player[i].targetframe=1; + player[i].jumpclimb=1; + } + if(player[i].targetanimation==jumpupanim||player[i].targetanimation==jumpdownanim||player[i].isFlip()){ + player[i].velocity+=absflatfacing*5*multiplier; + } + player[i].forwardstogglekeydown=1; + movekey=1; + } + if (player[i].rightkeydown){ + if(player[i].isIdle()||(player[i].isStop()&&player[i].targetrotation==player[i].rotation)||(player[i].isLanding()&&player[i].targetframe>0&&!player[i].jumpkeydown)||(player[i].isLandhard()&&player[i].targetframe>0&&!player[i].jumpkeydown&&player[i].crouchkeydown)){ + player[i].targetanimation=player[i].getRun(); + player[i].target=0; + player[i].targetframe=0; + } + if(player[i].isCrouch()){ + player[i].targetanimation=sneakanim; + if(player[i].wasCrouch()) player[i].target=0; + player[i].targetframe=0; + } + if(player[i].targetanimation==jumpupanim||player[i].targetanimation==jumpdownanim||player[i].isFlip()){ + player[i].velocity+=DoRotation(absflatfacing*5*multiplier,0,-90,0); + } + player[i].targetrotation-=90; + if(player[i].forwardkeydown)player[i].targetrotation+=45; + if(player[i].backkeydown)player[i].targetrotation-=45; + movekey=1; + } + if ( player[i].leftkeydown){ + if(player[i].isIdle()||(player[i].isStop()&&player[i].targetrotation==player[i].rotation)||(player[i].isLanding()&&player[i].targetframe>0&&!player[i].jumpkeydown)||(player[i].isLandhard()&&player[i].targetframe>0&&!player[i].jumpkeydown&&player[i].crouchkeydown)){ + player[i].targetanimation=player[i].getRun(); + player[i].target=0; + player[i].targetframe=0; + } + if(player[i].isCrouch()){ + player[i].targetanimation=sneakanim; + if(player[i].wasCrouch())player[i].target=0; + player[i].targetframe=0; + } + if(player[i].targetanimation==jumpupanim||player[i].targetanimation==jumpdownanim||player[i].isFlip()){ + player[i].velocity-=DoRotation(absflatfacing*5*multiplier,0,-90,0); + } + player[i].targetrotation+=90; + if(player[i].forwardkeydown)player[i].targetrotation-=45; + if(player[i].backkeydown)player[i].targetrotation+=45; + movekey=1; + } + if(player[i].backkeydown){ + if(player[i].isIdle()||(player[i].isStop()&&player[i].targetrotation==player[i].rotation)||(player[i].isLanding()&&player[i].targetframe>0&&!player[i].jumpkeydown)||(player[i].isLandhard()&&player[i].targetframe>0&&!player[i].jumpkeydown&&player[i].crouchkeydown)){ + player[i].targetanimation=player[i].getRun(); + player[i].target=0; + player[i].targetframe=0; + } + if(player[i].isCrouch()){ + player[i].targetanimation=sneakanim; + if(player[i].wasCrouch())player[i].target=0; + player[i].targetframe=0; + } + if(player[i].targetanimation==jumpupanim||player[i].targetanimation==jumpdownanim||player[i].isFlip()){ + player[i].velocity-=absflatfacing*5*multiplier; + } + if(player[i].targetanimation==hanganim){ + player[i].currentanimation=jumpdownanim; + player[i].targetanimation=jumpdownanim; + player[i].target=0; + player[i].currentframe=0; + player[i].targetframe=1; + player[i].velocity=0; + player[i].velocity.y+=gravity; + player[i].coords.y-=1.4; + player[i].grabdelay=1; + } + if ( !player[i].leftkeydown&&!player[i].rightkeydown) + player[i].targetrotation+=180; + movekey=1; + } + if((player[i].jumpkeydown&&!player[i].jumpclimb)||player[i].jumpstart){ + if((((player[i].isLanding()&&player[i].targetframe>=3)||player[i].isRun()||player[i].targetanimation==walkanim||player[i].isCrouch()||player[i].targetanimation==sneakanim)&&player[i].jumppower>1)&&((player[i].targetanimation!=rabbitrunninganim&&player[i].targetanimation!=wolfrunninganim)||i!=0)){ + player[i].jumpstart=0; + player[i].targetanimation=jumpupanim; + player[i].target=0; + player[i].targetframe=0; + player[i].rotation=player[i].targetrotation; + player[i].transspeed=20; + player[i].FootLand(0,1); + player[i].FootLand(1,1); + + facing=0; + facing.z=-1; + flatfacing=DoRotation(facing,0,player[i].targetrotation+180,0); + + if(movekey)player[i].velocity=flatfacing*player[i].speed*45*player[i].scale; + if(!movekey)player[i].velocity=0; + + //Dodge sweep? + target=-2; + if(numplayers>1) + for(j=0;jcoords)<3&&player[j].victim==&player[i]&&(player[j].targetanimation==sweepanim)){ + if(target>=0)target=-1; + else target=j; + } + } + } + if(target>=0)player[i].velocity.y=1; + else if(player[i].crouchkeydown||player[i].aitype!=playercontrolled){ + player[i].velocity.y=7; + player[i].crouchtogglekeydown=1; + } + else player[i].velocity.y=5; + + if(mousejump&&i==0&&debugmode){ + if(!player[i].isLanding())player[i].tempdeltav=deltav; + if(player[i].tempdeltav<0)player[i].velocity.y-=(float)(player[i].tempdeltav)/multiplier/1000; + } + + player[i].coords.y+=.2; + player[i].jumppower-=1; + + static float gLoc[3]; + static float vel[3]; + gLoc[0]=player[i].coords.x; + gLoc[1]=player[i].coords.y; + gLoc[2]=player[i].coords.z; + vel[0]=player[i].velocity.x; + vel[1]=player[i].velocity.y; + vel[2]=player[i].velocity.z; + + if(i==0){ + PlaySoundEx( whooshsound, samp[whooshsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[whooshsound], gLoc, vel); + FSOUND_SetVolume(channels[whooshsound], 128); + FSOUND_SetPaused(channels[whooshsound], FALSE); + } + + PlaySoundEx( jumpsound, samp[jumpsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[jumpsound], gLoc, vel); + FSOUND_SetVolume(channels[jumpsound], 128); + FSOUND_SetPaused(channels[jumpsound], FALSE); + } + if((player[i].isIdle())&&player[i].jumppower>1){ + player[i].targetanimation=player[i].getLanding(); + player[i].landhard=0; + player[i].target=0; + player[i].targetframe=2; + player[i].jumpstart=1; + player[i].tempdeltav=deltav; + } + if(player[i].targetanimation==jumpupanim&&(((!floatjump&&!editorenabled)||!debugmode)||player[i].aitype!=playercontrolled)){ + if(player[i].jumppower>multiplier*6){ + player[i].velocity.y+=multiplier*6; + player[i].jumppower-=multiplier*6; + } + if(player[i].jumppower<=multiplier*6){ + player[i].velocity.y+=player[i].jumppower; + player[i].jumppower=0; + } + } + if(((floatjump||editorenabled)&&debugmode)&&i==0)player[i].velocity.y+=multiplier*30; + } + + if(!movekey){ + if(player[i].isRun()||player[i].targetanimation==walkanim){ + player[i].targetanimation=player[i].getStop(); + player[i].target=0; + player[i].targetframe=0; + } + if(player[i].targetanimation==sneakanim){ + player[i].targetanimation=player[i].getCrouch(); + if(player[i].currentanimation==sneakanim)player[i].target=0; + player[i].targetframe=0; + } + } + if(player[i].targetanimation==walkanim&&(player[i].aitype==attacktypecutoff||player[i].aitype==searchtype||(player[i].aitype==passivetype&&player[i].numwaypoints<=1))){ + player[i].targetanimation=player[i].getStop(); + player[i].target=0; + player[i].targetframe=0; + } + if(player[i].isRun()&&(player[i].aitype==passivetype)){ + player[i].targetanimation=player[i].getStop(); + player[i].target=0; + player[i].targetframe=0; + } + } + } + if(player[i].targetanimation==rollanim)player[i].targetrotation=oldtargetrotation; + } + + //Rotation + for(k=0;k180){ + if(player[k].rotation>player[k].targetrotation)player[k].rotation-=360; + else player[k].rotation+=360; + } + + if(abs(player[k].rotation-player[k].targetrotation)>90&&(player[k].isRun()||player[k].targetanimation==walkanim)){ + player[k].targetanimation=player[k].getStop(); + player[k].targetframe=0; + player[k].target=0; + } + + if(player[k].targetanimation==backhandspringanim||player[k].targetanimation==dodgebackanim){ + player[k].targettilt=0; + } + if(player[k].targetanimation!=jumpupanim&&player[k].targetanimation!=backhandspringanim&&player[k].targetanimation!=jumpdownanim&&!player[k].isFlip()){ + player[k].targettilt=0; + if(player[k].jumppower<0&&!player[k].jumpkeydown)player[k].jumppower=0; + player[k].jumppower+=multiplier*7; + if(player[k].isCrouch())player[k].jumppower+=multiplier*7; + //*(1-(player[k].damage/player[k].damagetolerance)) + if(player[k].jumppower>5)player[k].jumppower=5; + } + + if(player[k].isRun()){ + player[k].targettilt=(player[k].rotation-player[k].targetrotation)/4; + } + + if(abs(player[k].tilt-player[k].targettilt)player[k].targettilt){ + player[k].tilt-=multiplier*150; + } + else if(player[k].tilt=0;j--){ + envsoundlife[j]-=multiplier; + if(envsoundlife[j]<0){ + numenvsounds--; + envsoundlife[j]=envsoundlife[numenvsounds]; + envsound[j]=envsound[numenvsounds]; + } + } + if(!slomo)FSOUND_SetFrequency(FSOUND_ALL, 22050); + if(slomo)FSOUND_SetFrequency(FSOUND_ALL, slomofreq); + + if(tutoriallevel==1){ + XYZ temp; + XYZ temp2; + XYZ temp3; + XYZ oldtemp; + XYZ oldtemp2; + temp.x=1011; + temp.y=84; + temp.z=491; + temp2.x=1025; + temp2.y=75; + temp2.z=447; + temp3.x=1038; + temp3.y=76; + temp3.z=453; + oldtemp=temp; + oldtemp2=temp2; + if(tutorialstage>=51) + if(findDistancefast(&temp,&player[0].coords)>=findDistancefast(&temp,&temp2)-1||findDistancefast(&temp3,&player[0].coords)<4){ + FSOUND_SetFrequency(FSOUND_ALL, 0.001); + + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + FSOUND_SetVolume(channels[stream_music3], 256); + + gameon=0; + mainmenu=5; + + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + if(tutorialstage<51) + if(findDistancefast(&temp,&player[0].coords)>=findDistancefast(&temp,&temp2)-1||findDistancefast(&temp3,&player[0].coords)<4){ + float gLoc[3]; + float vel[3]; + gLoc[0]=player[0].coords.x; + gLoc[1]=player[0].coords.y; + gLoc[2]=player[0].coords.z; + vel[0]=0; + vel[1]=0; + vel[2]=0; + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + + player[0].coords=(oldtemp+oldtemp2)/2; + + flashr=1; + flashg=1; + flashb=1; + flashamount=1; + flashdelay=1; + } + if(tutorialstage>=14&&tutorialstage<50) + if(findDistancefast(&temp,&player[1].coords)>=findDistancefast(&temp,&temp2)-1||findDistancefast(&temp3,&player[1].coords)<4){ + float gLoc[3]; + float vel[3]; + gLoc[0]=player[1].coords.x; + gLoc[1]=player[1].coords.y; + gLoc[2]=player[1].coords.z; + vel[0]=0; + vel[1]=0; + vel[2]=0; + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + + for(int i=0;i90)rotation2=90; + if(rotation2<-70)rotation2=-70; + } + if(mainmenu)rotation+=multiplier*5; + if(!mainmenu&&!indemo&&!registered){ + FSOUND_SetFrequency(FSOUND_ALL, 0.001); + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + FSOUND_SetVolume(channels[stream_music3], 256); + + gameon=0; + mainmenu=12; + + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + + if(tryquit==1&&!registered&&mainmenu!=12){ + FSOUND_SetFrequency(FSOUND_ALL, 0.001); + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + FSOUND_SetVolume(channels[stream_music3], 256); + + gameon=0; + mainmenu=12; + + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + //} +} + +void Game::TickOnceAfter(){ + static XYZ colviewer; + static XYZ coltarget; + static XYZ target; + static XYZ col; + static float brotate; + static XYZ facing; + static int i,j; + static float changedelay; + static bool alldead; + static float unseendelay; + static float cameraspeed; + + if(!mainmenu){ + + if(environment==snowyenvironment)music1=stream_music1snow; + if(environment==grassyenvironment)music1=stream_music1grass; + if(environment==desertenvironment)music1=stream_music1desert; + + realthreat=0; + + musictype=music1; + for(i=0;i0){ + musictype=stream_music2; + } + } + + + if(loading==2){ + musictype=stream_music3; + musicvolume[2]=512; + musicvolume[0]=0; + musicvolume[1]=0; + musicvolume[3]=0; + } + + if(musictoggle){ + if(musictype!=oldmusictype&&musictype==stream_music2){ + static float gLoc[3]; + static float vel[3]; + gLoc[0]=cameraloc.x; + gLoc[1]=cameraloc.y; + gLoc[2]=cameraloc.z; + vel[0]=0; + vel[1]=0; + vel[2]=0; + PlaySoundEx( alarmsound, samp[alarmsound], NULL, TRUE); + FSOUND_SetVolume(channels[alarmsound], 512); + FSOUND_SetPaused(channels[alarmsound], FALSE); + + } + } + musicselected=musictype; + + if(musicselected==music1)musicvolume[0]+=multiplier*450; + else musicvolume[0]-=multiplier*450; + if(musicselected==stream_music2)musicvolume[1]+=multiplier*450; + else musicvolume[1]-=multiplier*450; + if(musicselected==stream_music3)musicvolume[2]+=multiplier*450; + else musicvolume[2]-=multiplier*450; + /* + if(musicselected==music1)musicvolume[0]+=multiplier*100; + else musicvolume[0]-=multiplier*450; + if(musicselected==music2)musicvolume[1]+=multiplier*150; + else if(player[0].dead)musicvolume[1]-=multiplier*450; + else musicvolume[1]-=multiplier*100; + if(musicselected==music3)musicvolume[2]+=multiplier*450; + else musicvolume[2]-=multiplier*450;*/ + + for(i=0;i<3;i++){ + if(musicvolume[i]<0)musicvolume[i]=0; + if(musicvolume[i]>512)musicvolume[i]=512; + } + + if(musicvolume[2]>128&&!loading&&!mainmenu)musicvolume[2]=128; + + if(musictoggle){ + if(musicvolume[0]>0&&oldmusicvolume[0]<=0){ + PlayStreamEx( music1, strm[music1], NULL, TRUE); + FSOUND_SetPaused(channels[music1], FALSE); + } + if(musicvolume[1]>0&&oldmusicvolume[1]<=0){ + PlayStreamEx( stream_music2, strm[stream_music2], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music2], FALSE); + } + if(musicvolume[2]>0&&oldmusicvolume[2]<=0){ + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + } + } + + if(!musictoggle){ + FSOUND_SetPaused(channels[music1], TRUE); + FSOUND_SetPaused(channels[stream_music2], TRUE); + FSOUND_SetPaused(channels[stream_music3], TRUE); + + for(i=0;i<4;i++){ + oldmusicvolume[i]=0; + musicvolume[i]=0; + } + } + + if(musictoggle){ + if(musicvolume[0]<=0&&oldmusicvolume[0]>0){ + FSOUND_SetPaused(channels[music1], TRUE); + } + if(musicvolume[1]<=0&&oldmusicvolume[1]>0){ + FSOUND_SetPaused(channels[stream_music2], TRUE); + } + if(musicvolume[2]<=0&&oldmusicvolume[2]>0){ + FSOUND_SetPaused(channels[stream_music3], TRUE); + } + + if(musicvolume[0]!=oldmusicvolume[0]){ + FSOUND_SetVolume(channels[music1], musicvolume[0]); + } + if(musicvolume[1]!=oldmusicvolume[1]){ + FSOUND_SetVolume(channels[stream_music2], musicvolume[1]); + } + if(musicvolume[2]!=oldmusicvolume[2]){ + FSOUND_SetVolume(channels[stream_music3], musicvolume[2]); + } + + for(i=0;i<3;i++){ + oldmusicvolume[i]=musicvolume[i]; + } + } + + killhotspot=2; + if(numhotspots) + for(i=0;i10&&hotspottype[i]<20){ + if(player[hotspottype[i]-10].dead==0){ + killhotspot=0; + } + else if(killhotspot==2) + killhotspot=1; + } + } + if(killhotspot==2)killhotspot=0; + + + winhotspot=0; + if(numhotspots) + for(i=0;i1) + for(i=1;imaxalarmed)maxalarmed=numalarmed; + + if(changedelay<=0&&!loading&&!editorenabled&&gameon&&!tutoriallevel&&changedelay!=-999&&!won){ + if(player[0].dead&&changedelay<=0){ + changedelay=1; + targetlevel=whichlevel; + } + alldead=1; + if(numplayers>1) + for(i=1;inumchallengelevels-1)targetlevel=0; + } + if(winhotspot||windialogue){ + changedelay=0.1; + targetlevel=whichlevel+1; + if(targetlevel>numchallengelevels-1)targetlevel=0; + } + + + if(killhotspot){ + changedelay=1; + targetlevel=whichlevel+1; + if(targetlevel>numchallengelevels-1)targetlevel=0; + } + + if(changedelay>0&&!player[0].dead&&!won){ + //high scores, awards, win + if(campaign){ + won=1; + accountcampaignchoices[accountactive][accountcampaignchoicesmade[accountactive]]=whichchoice; + accountcampaignchoicesmade[accountactive]++; + accountcampaignscore[accountactive]+=bonustotal; + scoreadded=1; + accountcampaigntime[accountactive]+=leveltime; + if(accountcampaignscore[accountactive]>accountcampaignhighscore[accountactive])accountcampaignhighscore[accountactive]=accountcampaignscore[accountactive]; + + //if(accountprogress[accountactive]accounthighscore[accountactive][whichlevel])accounthighscore[accountactive][whichlevel]=bonustotal-startbonustotal; + if(accountfasttime[accountactive][whichlevel]==0||leveltime3&&!registered){ + FSOUND_SetFrequency(FSOUND_ALL, 0.001); + PlayStreamEx( stream_music3, strm[stream_music3], NULL, TRUE); + FSOUND_SetPaused(channels[stream_music3], FALSE); + FSOUND_SetVolume(channels[stream_music3], 256); + + gameon=0; + mainmenu=12; + accountprogress[accountactive]=3; + + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 9999.0f, 99999.0f); + PlaySoundEx( fireendsound, samp[fireendsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[fireendsound], gLoc, vel); + FSOUND_SetVolume(channels[fireendsound], 256); + FSOUND_SetPaused(channels[fireendsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[fireendsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + else{ + if(whichlevel!=-2&&!loading&&!player[0].dead){ + winfreeze=1; + changedelay=-999; + } + if(player[0].dead)loading=1; + } + } + } + + if(campaign) + if(mainmenu==0&&winfreeze&&(campaignchoosenext[campaignchoicewhich[whichchoice]])==1){ + if(campaignnumnext[campaignchoicewhich[whichchoice]]==0){ + endgame=1; + } + } + else if(mainmenu==0&&winfreeze){ + if(campaignchoosenext[campaignchoicewhich[whichchoice]]==2) + stealthloading=1; + else stealthloading=0; + + if(!stealthloading){ + float gLoc[3]={0,0,0}; + float vel[3]={0,0,0}; + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 9999.0f, 99999.0f); + PlaySoundEx( firestartsound, samp[firestartsound], NULL, TRUE); + FSOUND_3D_SetAttributes(channels[firestartsound], gLoc, vel); + FSOUND_SetVolume(channels[firestartsound], 256); + FSOUND_SetPaused(channels[firestartsound], FALSE); + FSOUND_Sample_SetMinMaxDistance(samp[firestartsound], 8.0f, 2000.0f); + + flashr=1; + flashg=0; + flashb=0; + flashamount=1; + flashdelay=1; + } + + startbonustotal=0; + + // ifstream ipstream(":Data:Campaigns:main.txt"); + ifstream ipstream("./Data/Campaigns/main.txt"); + //campaignnumlevels=0; + //accountcampaignchoicesmade[accountactive]=0; + ipstream.ignore(256,':'); + ipstream >> campaignnumlevels; + for(i=0;i> campaignmapname[i]; + ipstream.ignore(256,':'); + ipstream >> campaigndescription[i]; + for(j=0;j<256;j++){ + if(campaigndescription[i][j]=='_')campaigndescription[i][j]=' '; + } + ipstream.ignore(256,':'); + ipstream >> campaignchoosenext[i]; + ipstream.ignore(256,':'); + ipstream >> campaignnumnext[i]; + if(campaignnumnext[i]) + for(j=0;j> campaignnextlevel[i][j]; + campaignnextlevel[i][j]-=1; + } + ipstream.ignore(256,':'); + ipstream >> campaignlocationx[i]; + ipstream.ignore(256,':'); + ipstream >> campaignlocationy[i]; + } + ipstream.close(); + + for(i=0;itarget.y) + target.y=player[0].skeleton.joints[i].position.y*player[0].scale+player[0].coords.y; + } + target.y+=.1; + } + if(player[0].skeleton.free!=2&&!autocam){ + cameraspeed=20; + if(findLengthfast(&player[0].velocity)>400){ + cameraspeed=20+(findLength(&player[0].velocity)-20)*.96; + } + if(player[0].skeleton.free==0&&player[0].targetanimation!=hanganim&&player[0].targetanimation!=climbanim)target.y+=1.4; + coltarget=target-cameraloc; + if(findLengthfast(&coltarget)2.3)cameradist=2.3; + viewer=cameraloc-facing*cameradist; + colviewer=viewer; + coltarget=cameraloc; + objects.SphereCheckPossible(&colviewer, findDistance(&colviewer,&coltarget)); + if(terrain.patchobjectnum[player[0].whichpatchx][player[0].whichpatchz]) + for(j=0;j400){ + cameraspeed=20+(findLength(&player[0].velocity)-20)*.96; + } + if(player[0].skeleton.free==0&&player[0].targetanimation!=hanganim&&player[0].targetanimation!=climbanim)target.y+=1.4; + cameradist+=multiplier*5; + if(cameradist>3.3)cameradist=3.3; + coltarget=target-cameraloc; + if(findLengthfast(&coltarget)1) + { + Normalise(&coltarget); + if(player[0].targetanimation!=hanganim&&player[0].targetanimation!=climbanim&&player[0].currentanimation!=climbanim&&player[0].currentoffset.x==0)cameraloc=cameraloc+coltarget*multiplier*cameraspeed; + else cameraloc=cameraloc+coltarget*multiplier*8; + } + if(editorenabled)cameraloc=target; + viewer=cameraloc; + colviewer=viewer; + coltarget=cameraloc; + objects.SphereCheckPossible(&colviewer, findDistance(&colviewer,&coltarget)); + if(terrain.patchobjectnum[player[0].whichpatchx][player[0].whichpatchz]) + for(j=0;j.8)camerashake=.8; + //if(woozy>10)woozy=10; + //woozy+=multiplier; + woozy+=multiplier; + if(player[0].dead)camerashake=0; + if(player[0].dead)woozy=0; + camerashake-=multiplier*2; + blackout-=multiplier*2; + //if(player[0].isCrouch())woozy-=multiplier*8; + if(camerashake<0)camerashake=0; + if(blackout<0)blackout=0; + //if(woozy<0)woozy=0; + if(camerashake){ + viewer.x+=(float)(Random()%100)*.0005*camerashake; + viewer.y+=(float)(Random()%100)*.0005*camerashake; + viewer.z+=(float)(Random()%100)*.0005*camerashake; + } + } +} \ No newline at end of file diff --git a/Source/Globals.cpp b/Source/Globals.cpp new file mode 100644 index 0000000..0a4c6d2 --- /dev/null +++ b/Source/Globals.cpp @@ -0,0 +1,250 @@ +#include "gl.h" +#include "Quaternions.h" +#include "Lights.h" +#include "Skeleton.h" +#include "fmod.h" +#include "Terrain.h" +#include "Sprites.h" +//#include +#include "Frustum.h" +#include "Objects.h" +#include "Weapons.h" +#include "Person.h" +#include "TGALoader.h" + +#include "Constants.h" + +bool visibleloading = 0; +FSOUND_SAMPLE *samp[100] = {0}; +FSOUND_STREAM * strm[20] = {0}; +int channels[100] = {0}; + +float volume = 0;bool buttons[3] = {0}; +bool oldbuttons[3] = {0}; +bool ismotionblur = 0; +float usermousesensitivity = 0; +bool floatjump = 0; +bool cellophane = 0; +bool autoslomo = 0; +bool decals = 0; +bool invertmouse = 0; +bool texttoggle = 0; +float blurness = 0; +float targetblurness = 0; +float windvar = 0; +float precipdelay = 0; +float gamespeed = 0; +float oldgamespeed = 0; +float tintr = 0,tintg = 0,tintb = 0; +int difficulty = 0; +float multiplier = 0; +float realmultiplier = 0; +float screenwidth = 0,screenheight = 0; +float viewdistance = 0; +XYZ viewer; +XYZ viewerfacing; +XYZ lightlocation; +float fadestart = 0; +int environment = 0; +float texscale = 0; +float gravity = 0; +Light light; +Animation animation[animation_count]; +Skeleton testskeleton; +int numsounds = 0; +Terrain terrain; +Sprites sprites; +float sps = 0; +#ifdef WIN32 +HDC hDC; +#else +AGLContext gaglContext; +#endif +int kTextureSize = 0; +int detail = 0; +FRUSTUM frustum; +float texdetail = 0; +float realtexdetail = 0; +float terraindetail = 0; +float playerdist = 0; +Objects objects; +int slomo = 0; +float slomodelay = 0; +GLubyte bloodText[512*512*3] = {0}; +GLubyte wolfbloodText[512*512*3] = {0}; +float colors[3] = {0}; +int bloodtoggle = 0; +bool osx = 0; +float camerashake = 0; +float woozy = 0; +float blackout = 0; +bool foliage = 0; +bool musictoggle = 0; +bool trilinear; +Weapons weapons; +bool damageeffects = 0; +//apvector player(maxplayers); +Person player[maxplayers]; +int numplayers = 0; +bool ambientsound = 0; +bool mousejump = 0; +bool freeze = 0; +bool winfreeze = 0; +float flashamount = 0,flashr = 0,flashg = 0,flashb = 0; +int flashdelay = 0; +bool vblsync = 0; +float motionbluramount = 0; +bool keyboardfrozen = 0; +int newnetmessages = 0; +char netmessages[256] = {0}; +char mapname[256] = {0}; +bool loadingstuff = 0; +bool stillloading = 0; +bool showpoints = 0; +bool alwaysblur = 0; +bool immediate = 0; +bool velocityblur = 0; +int test = 0; +XYZ windvector; +short vRefNum = 0; +long dirID = 0; +int mainmenu = 0; +int oldmainmenu = 0; +GLubyte texturearray[512*512*3] = {0}; +int loadscreencolor = 0; +int whichjointstartarray[26] = {0}; +int whichjointendarray[26] = {0}; +int kBitsPerPixel = 0; + +int numhotspots = 0; +XYZ hotspot[40]; +int hotspottype[40] = {0}; +float hotspotsize[40] = {0}; +char hotspottext[40][256] = {0}; +int currenthotspot = 0; +int winhotspot = 0; +int windialogue = 0; +int killhotspot = 0; + +float menupulse = 0; + +int numdialogues = 0; +int numdialogueboxes[max_dialogues] = {0}; +int dialoguetype[max_dialogues] = {0}; +int dialogueboxlocation[max_dialogues][max_dialoguelength] = {0}; +float dialogueboxcolor[max_dialogues][max_dialoguelength][3] = {0}; +int dialogueboxsound[max_dialogues][max_dialoguelength] = {0}; +char dialoguetext[max_dialogues][max_dialoguelength][128] = {0}; +char dialoguename[max_dialogues][max_dialoguelength][64] = {0}; +XYZ dialoguecamera[max_dialogues][max_dialoguelength] = {0}; +XYZ participantlocation[max_dialogues][10] = {0}; +int participantfocus[max_dialogues][max_dialoguelength] = {0}; +int participantaction[max_dialogues][max_dialoguelength] = {0}; +float participantrotation[max_dialogues][10] = {0}; +XYZ participantfacing[max_dialogues][max_dialoguelength][10] = {0}; +float dialoguecamerarotation[max_dialogues][max_dialoguelength] = {0}; +float dialoguecamerarotation2[max_dialogues][max_dialoguelength] = {0}; +int indialogue = 0; +int whichdialogue = 0; +int directing = 0; +float dialoguetime = 0; +int dialoguegonethrough[20] = {0}; + +float smoketex = 0; + +float slomospeed = 0; +float slomofreq = 0; + +int tutoriallevel = 0; +int tutorialstage = 0; +float tutorialstagetime = 0; +float tutorialmaxtime = 0; +float tutorialsuccess = 0; + +bool againbonus = 0; + +float damagedealt = 0; +float damagetaken = 0; + +int maptype = 0; + +int editoractive = 0; +int editorpathtype = 0; + +bool reversaltrain = 0; +bool cananger = 0; +bool canattack = 0; + +bool skyboxtexture = 0; +float skyboxr = 0; +float skyboxg = 0; +float skyboxb = 0; +float skyboxlightr = 0; +float skyboxlightg = 0; +float skyboxlightb = 0; + +float bonusnum[100] = {0}; + +int hostile = 0; +float hostiletime = 0; + +XYZ envsound[30] = {0}; +float envsoundvol[30] = {0}; +float envsoundlife[30] = {0}; +int numenvsounds; + + +bool tilt2weird = 0; +bool tiltweird = 0; +bool midweird = 0; +bool proportionweird = 0; +bool vertexweird[6] = {0}; +TGAImageRec texture; +bool debugmode = 0; + +int oldbonus = 0; +int bonus = 0; +float bonusvalue = 0; +float bonustotal = 0; +float startbonustotal = 0; +float bonustime = 0; + +int numaccounts = 0; +int accountactive = 0; +int accountdifficulty[10] = {0}; +int accountprogress[10] = {0}; +float accountpoints[10] = {0}; +float accounthighscore[10][50] = {0}; +float accountfasttime[10][50] = {0}; +bool accountunlocked[10][60] = {0}; +char accountname[10][256] = {0}; +float accountcampaignhighscore[10] = {0}; +float accountcampaignfasttime[10] = {0}; +float accountcampaignscore[10] = {0}; +float accountcampaigntime[10] = {0}; +int accountcampaignchoicesmade[10] = {0};int accountcampaignchoices[10][5000] = {0}; +bool won = 0; + + +bool campaign = 0; + +int numfalls = 0; +int numflipfail = 0; +int numseen = 0; +int numresponded = 0; +int numstaffattack = 0; +int numswordattack = 0; +int numknifeattack = 0; +int numunarmedattack = 0; +int numescaped = 0; +int numflipped = 0; +int numwallflipped = 0; +int numthrowkill = 0; +int numafterkill = 0; +int numreversals = 0; +int numattacks = 0; +int maxalarmed = 0; + +bool gamestarted = 0; + +//TextureList textures; diff --git a/Source/Lights.cpp b/Source/Lights.cpp new file mode 100644 index 0000000..63d1a7c --- /dev/null +++ b/Source/Lights.cpp @@ -0,0 +1,125 @@ +/**> HEADER FILES <**/ +#include "Lights.h" + +void SetUpLight(Light* whichsource, int whichlight){ + static float qattenuation[]={0.0002f}; + static float cattenuation[]={1.5f}; + static float lattenuation[]={0.5f}; + static float zattenuation[]={0.0f}; + + //Initialize lights + + if(whichlight==0){ + GLfloat LightAmbient[]= { whichsource->ambient[0], whichsource->ambient[1], whichsource->ambient[2], 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 0.0f }; + + //glLightfv(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT0); + } + + if(whichlight==1){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT1); + } + + if(whichlight==2){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT2, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT2, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT2, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT2); + } + + if(whichlight==3){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT3, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT3, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT3, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT3, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT3); + } + + if(whichlight==4){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT4, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT4, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT4, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT4, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT4); + } + + if(whichlight==5){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT5, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT5, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT5, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT5, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT5); + } + + if(whichlight==6){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT6, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT6, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT6, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT6, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT6); + } + + if(whichlight==7){ + GLfloat LightAmbient[]= { 0, 0, 0, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT7, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT7, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT7, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT7, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT7); + } +} + +void SetUpMainLight(Light* whichsource, int whichlight, float ambientr, float ambientg, float ambientb){ + static float qattenuation[]={0.0f}; + + //Initialize lights + + if(whichlight==0){ + GLfloat LightAmbient[]= { ambientr, ambientg, ambientb, 1.0f}; + GLfloat LightDiffuse[]= { whichsource->color[0], whichsource->color[1], whichsource->color[2], 1.0f }; + GLfloat LightPosition[]= { whichsource->location.x, whichsource->location.y, whichsource->location.z, 1.0f }; + + glLightfv(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, qattenuation); + glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); + glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse); + glEnable(GL_LIGHT0); + } +} \ No newline at end of file diff --git a/Source/Lights.h b/Source/Lights.h new file mode 100644 index 0000000..32d9f56 --- /dev/null +++ b/Source/Lights.h @@ -0,0 +1,21 @@ +#ifndef _LIGHTS_H_ +#define _LIGHTS_H_ + + +/**> HEADER FILES <**/ +#include "gl.h" +#include "Quaternions.h" + +class Light{ +public: + GLint type; + GLfloat color[3]; + GLfloat ambient[3]; + int attach; + XYZ location; +}; + +void SetUpMainLight(Light* whichsource, int whichlight, float ambientr, float ambientg, float ambientb); +void SetUpLight(Light* whichsource, int whichlight); + +#endif \ No newline at end of file diff --git a/Source/LinkedList.h b/Source/LinkedList.h new file mode 100644 index 0000000..6bf5337 --- /dev/null +++ b/Source/LinkedList.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Portions Copyright (c) 1999-2002 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 1.1 (the "License"). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * Modified: $Date: 2002/04/27 20:52:48 $ + * Revision: $Id: LinkedList.h,v 1.3 2002/04/27 20:52:48 lane Exp $ + */ + + +/* + File: LinkedList.h + + Contains: + +*/ + +#ifndef __LINKEDLIST__ +#define __LINKEDLIST__ + + +//we cant just use "macintosh_build" - the mac macho_build is designated as "posix_build" but may +//include open transport in some cases +#ifndef __OPENTRANSPORT__ +//#if (!macintosh_build) + +#include //for OTGetLinkObject replacement + +#include "OPUtils.h" //for true/false + +#if (windows_build) + +// ECF 010928 win32 syncronization routines for safe critical sections. We can't simply use TryEnterCriticalSection() +// to return a true/false value because it's not available in win95 and 98 +class OSCriticalSection +{ + public: + NMBoolean locked; + OSCriticalSection() {locked = false; InitializeCriticalSection(&theCriticalSection);} + ~OSCriticalSection() {DeleteCriticalSection(&theCriticalSection);} + NMBoolean acquire() { if (locked == true) return false; //dont have to wait in this case + EnterCriticalSection(&theCriticalSection); + if (locked) {LeaveCriticalSection(&theCriticalSection); return false;} + else {locked = true; LeaveCriticalSection(&theCriticalSection); return true;}} + void release() { EnterCriticalSection(&theCriticalSection); + locked = false; LeaveCriticalSection(&theCriticalSection);} + + CRITICAL_SECTION theCriticalSection; +}; +#endif //windows_build + +#if (posix_build) +#include +class OSCriticalSection +{ + public: + OSCriticalSection() {pthread_mutex_init(&theMutex,NULL);} + ~OSCriticalSection() {pthread_mutex_destroy(&theMutex);} + NMBoolean acquire() { int error = pthread_mutex_trylock(&theMutex); + if (error) return false; else return true;} + void release() { pthread_mutex_unlock(&theMutex);} + + pthread_mutex_t theMutex; +}; + +#endif //(posix_build) + +/* ------------------------------------------------------------------------- + ** OTLIFO + ** + ** These are functions to implement a LIFO list that is interrupt-safe. + ** The only function which is not is OTReverseList. Normally, you create + ** a LIFO list, populate it at interrupt time, and then use OTLIFOStealList + ** to atomically remove the list, and OTReverseList to flip the list so that + ** it is a FIFO list, which tends to be more useful. + ------------------------------------------------------------------------- */ + + class OTLink; + class OTLIFO; + + class OTLink + { + public: + OTLink* fNext; + void Init() + { fNext = NULL; } + }; + + class OTLIFO + { + public: + OSCriticalSection theLock; + OTLink* fHead; + + void Init() + { fHead = NULL; } + + void Enqueue(OTLink* link) + { + while (true) {if (theLock.acquire()) break;} + link->fNext = fHead; + fHead = link; + theLock.release(); + } + + + OTLink* Dequeue() + { + while (true) {if (theLock.acquire()) break;} + OTLink *origHead = fHead; + fHead = fHead->fNext; + theLock.release(); + return origHead; + } + + + OTLink* StealList() + { + while (true) {if (theLock.acquire()) break;} + OTLink *origHead = fHead; + fHead = NULL; + theLock.release(); + return origHead; + } + + + NMBoolean IsEmpty() + { + return fHead == NULL; + } + }; + +/* ------------------------------------------------------------------------- + ** OTList + ** + ** An OTList is a non-interrupt-safe list, but has more features than the + ** OTLIFO list. It is a standard singly-linked list. + ------------------------------------------------------------------------- */ + + typedef struct OTList OTList; + + typedef NMBoolean (*OTListSearchProcPtr)(const void* ref, OTLink* linkToCheck); + // + // Remove the last link from the list + // + extern OTLink* OTRemoveLast(OTList* pList); + // + // Return the first link from the list + // + extern OTLink* OTGetFirst(OTList* pList); + // + // Return the last link from the list + // + extern OTLink* OTGetLast(OTList* pList); + // + // Return true if the link is present in the list + // + extern NMBoolean OTIsInList(OTList* pList, OTLink* link); + // + // Find a link in the list which matches the search criteria + // established by the search proc and the refPtr. This is done + // by calling the search proc, passing it the refPtr and each + // link in the list, until the search proc returns true. + // NULL is returned if the search proc never returned true. + // + extern OTLink* OTFindLink(OTList* pList, OTListSearchProcPtr proc, const void* refPtr); + // + // Remove the specified link from the list, returning true if it was found + // + extern NMBoolean OTRemoveLink(OTList*, OTLink*); + // + // Similar to OTFindLink, but it also removes it from the list. + // + extern OTLink* OTFindAndRemoveLink(OTList* pList, OTListSearchProcPtr proc, const void* refPtr); + // + // Return the "index"th link in the list + // + extern OTLink* OTGetIndexedLink(OTList* pList, size_t index); + + struct OTList + { + OTLink* fHead; + + void Init() + { fHead = NULL; } + + NMBoolean IsEmpty() + { return fHead == NULL; } + + void AddFirst(OTLink* link) + { + link->fNext = fHead; + fHead = link; + } + + void AddLast(OTLink* link) + { + if (fHead == NULL) + fHead = link->fNext; + else + { + OTLink *current = fHead; + + while (current->fNext != NULL) + current = current->fNext; + + current->fNext = link; + } + + + link->fNext = fHead; + fHead = link; + } + + + OTLink* GetFirst() + { return OTGetFirst(this); } + + OTLink* GetLast() + { return OTGetLast(this); } + + OTLink* RemoveFirst() + { + OTLink *origHead = fHead; + fHead = fHead->fNext; + return origHead; + } + + OTLink* RemoveLast() + { return OTRemoveLast(this); } + + NMBoolean IsInList(OTLink* link) + { return OTIsInList(this, link); } + + OTLink* FindLink(OTListSearchProcPtr proc, const void* ref) + { return OTFindLink(this, proc, ref); } + + NMBoolean RemoveLink(OTLink* link) + { return OTRemoveLink(this, link); } + + OTLink* RemoveLink(OTListSearchProcPtr proc, const void* ref) + { return OTFindAndRemoveLink(this, proc, ref); } + + OTLink* GetIndexedLink(size_t index) + { return OTGetIndexedLink(this, index); } + }; + + +//FIXME!! this is a recursive function and will crash and burn on large lists +static OTLink* OTReverseList(OTLink *headRef) +{ + OTLink *first; + OTLink *rest; + + if (headRef == NULL) return NULL; + + first = headRef; + rest = (OTLink *) first->fNext; + + if (rest == NULL) return headRef; + + rest = OTReverseList(rest); + + first->fNext->fNext = first; + first->fNext = NULL; + + return rest; +} + + + #define OTGetLinkObject(link, struc, field) \ + ((struc*)((char*)(link) - offsetof(struc, field))) + +#endif //!macintosh_build +#endif /* __LINKEDLIST__ */ + diff --git a/Source/MD5.CC b/Source/MD5.CC new file mode 100644 index 0000000..7a18e9f --- /dev/null +++ b/Source/MD5.CC @@ -0,0 +1,544 @@ +// MD5.CC - source code for the C++/object oriented translation and +// modification of MD5. + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + +MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm +MDDRIVER.C - test driver for MD2, MD4 and MD5 + + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +*/ + + + + + + +#include "md5.h" + +#include +//#include +#include + + + + +// MD5 simple initialization method + +MD5::MD5(){ + + init(); + +} + + + + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block, and updating the +// context. + +void MD5::update (uint1 *input, uint4 input_length) { + + uint4 input_index, buffer_index; + uint4 buffer_space; // how much space is left in buffer + + if (finalized){ // so we can't update! + cerr << "MD5::update: Can't update a finalized digest!" << endl; + return; + } + + // Compute number of bytes mod 64 + buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); + + // Update number of bits + if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) + count[1]++; + + count[1] += ((uint4)input_length >> 29); + + + buffer_space = 64 - buffer_index; // how much space is left in buffer + + // Transform as many times as possible. + if (input_length >= buffer_space) { // ie. we have enough to fill the buffer + // fill the rest of the buffer and transform + memcpy (buffer + buffer_index, input, buffer_space); + transform (buffer); + + // now, transform each 64-byte piece of the input, bypassing the buffer + for (input_index = buffer_space; input_index + 63 < input_length; + input_index += 64) + transform (input+input_index); + + buffer_index = 0; // so we can buffer remaining + } + else + input_index=0; // so we can buffer the whole input + + + // and here we do the buffering: + memcpy(buffer+buffer_index, input+input_index, input_length-input_index); +} + + + +// MD5 update for files. +// Like above, except that it works on files (and uses above as a primitive.) + +void MD5::update(FILE *file){ + + unsigned char buffer[1024]; + int len; + + while (len=fread(buffer, 1, 1024, file)) + update(buffer, len); + + fclose (file); + +} + + + + + + +// MD5 update for istreams. +// Like update for files; see above. + +void MD5::update(istream& stream){ + + unsigned char buffer[1024]; + int len; + + while (stream.good()){ + stream.read((char *)buffer, (long)1024); // note that return value of read is unusable. + len=stream.gcount(); + update(buffer, len); + } + +} + + + + + + +// MD5 update for ifstreams. +// Like update for files; see above. + +void MD5::update(ifstream& stream){ + + unsigned char buffer[1024]; + int len; + + while (stream.good()){ + stream.read((char *)buffer, (long)1024); // note that return value of read is unusable. + len=stream.gcount(); + update(buffer, len); + } + +} + + + + + + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. + + +void MD5::finalize (){ + + unsigned char bits[8]; + unsigned int index, padLen; + static uint1 PADDING[64]={ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (finalized){ + cerr << "MD5::finalize: Already finalized this digest!" << endl; + return; + } + + // Save number of bits + encode (bits, count, 8); + + // Pad out to 56 mod 64. + index = (uint4) ((count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update (PADDING, padLen); + + // Append length (before padding) + update (bits, 8); + + // Store state in digest + encode (digest, state, 16); + + // Zeroize sensitive information + memset (buffer, 0, sizeof(*buffer)); + + finalized=1; + +} + + + + +MD5::MD5(FILE *file){ + + init(); // must be called be all constructors + update(file); + finalize (); +} + + + + +MD5::MD5(istream& stream){ + + init(); // must called by all constructors + update (stream); + finalize(); +} + + + +MD5::MD5(ifstream& stream){ + + init(); // must called by all constructors + update (stream); + finalize(); +} + + + +unsigned char *MD5::raw_digest(){ + + uint1 *s = new uint1[16]; + + if (!finalized){ + cerr << "MD5::raw_digest: Can't get digest if you haven't "<< + "finalized the digest!" <> 8) & 0xff); + output[j+2] = (uint1) ((input[i] >> 16) & 0xff); + output[j+3] = (uint1) ((input[i] >> 24) & 0xff); + } +} + + + + +// Decodes input (unsigned char) into output (UINT4). Assumes len is +// a multiple of 4. +void MD5::decode (uint4 *output, uint1 *input, uint4 len){ + + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} + + + + + +// Note: Replace "for loop" with standard memcpy if possible. +void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){ + + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; +} + + + +// Note: Replace "for loop" with standard memset if possible. +void MD5::memset (uint1 *output, uint1 value, uint4 len){ + + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = value; +} + + + +// ROTATE_LEFT rotates x left n bits. + +inline unsigned int MD5::rotate_left (uint4 x, uint4 n){ + return (x << n) | (x >> (32-n)) ; +} + + + + +// F, G, H and I are basic MD5 functions. + +inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){ + return (x & y) | (~x & z); +} + +inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){ + return (x & z) | (y & ~z); +} + +inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){ + return x ^ y ^ z; +} + +inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){ + return y ^ (x | ~z); +} + + + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. + + +inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += F(b, c, d) + x + ac; + a = rotate_left (a, s) +b; + } + + inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += G(b, c, d) + x + ac; + a = rotate_left (a, s) +b; + } + + inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += H(b, c, d) + x + ac; + a = rotate_left (a, s) +b; + } + + inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += I(b, c, d) + x + ac; + a = rotate_left (a, s) +b; + } diff --git a/Source/MacInput.cpp b/Source/MacInput.cpp new file mode 100644 index 0000000..9b9f909 --- /dev/null +++ b/Source/MacInput.cpp @@ -0,0 +1,803 @@ +/**> HEADER FILES <**/ +#include "MacInput.h" +#include "String.h" + +extern bool keyboardfrozen; + +/********************> IsKeyDown() <*****/ +Boolean IsKeyDown( unsigned char *keyMap, unsigned short theKey ) +{ + if(keyboardfrozen)return 0; + + static long keyMapIndex; + static Boolean isKeyDown; + static 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; + +} + +unsigned short CharToKey(char* which) +{ + if(!strcmp(which,"a")){ + return MAC_A_KEY; + } + if(!strcmp(which,"b")){ + return MAC_B_KEY; + } + if(!strcmp(which,"c")){ + return MAC_C_KEY; + } + if(!strcmp(which,"d")){ + return MAC_D_KEY; + } + if(!strcmp(which,"e")){ + return MAC_E_KEY; + } + if(!strcmp(which,"f")){ + return MAC_F_KEY; + } + if(!strcmp(which,"g")){ + return MAC_G_KEY; + } + if(!strcmp(which,"h")){ + return MAC_H_KEY; + } + if(!strcmp(which,"i")){ + return MAC_I_KEY; + } + if(!strcmp(which,"j")){ + return MAC_J_KEY; + } + if(!strcmp(which,"k")){ + return MAC_K_KEY; + } + if(!strcmp(which,"l")){ + return MAC_L_KEY; + } + if(!strcmp(which,"m")){ + return MAC_M_KEY; + } + if(!strcmp(which,"n")){ + return MAC_N_KEY; + } + if(!strcmp(which,"o")){ + return MAC_O_KEY; + } + if(!strcmp(which,"p")){ + return MAC_P_KEY; + } + if(!strcmp(which,"q")){ + return MAC_Q_KEY; + } + if(!strcmp(which,"r")){ + return MAC_R_KEY; + } + if(!strcmp(which,"s")){ + return MAC_S_KEY; + } + if(!strcmp(which,"t")){ + return MAC_T_KEY; + } + if(!strcmp(which,"u")){ + return MAC_U_KEY; + } + if(!strcmp(which,"v")){ + return MAC_V_KEY; + } + if(!strcmp(which,"w")){ + return MAC_W_KEY; + } + if(!strcmp(which,"x")){ + return MAC_X_KEY; + } + if(!strcmp(which,"y")){ + return MAC_Y_KEY; + } + if(!strcmp(which,"z")){ + return MAC_Z_KEY; + } + if(!strcmp(which,"0")){ + return MAC_NUMPAD_0_KEY; + } + if(!strcmp(which,"1")){ + return MAC_NUMPAD_1_KEY; + } + if(!strcmp(which,"2")){ + return MAC_NUMPAD_2_KEY; + } + if(!strcmp(which,"3")){ + return MAC_NUMPAD_3_KEY; + } + if(!strcmp(which,"4")){ + return MAC_NUMPAD_4_KEY; + } + if(!strcmp(which,"5")){ + return MAC_NUMPAD_5_KEY; + } + if(!strcmp(which,"6")){ + return MAC_NUMPAD_6_KEY; + } + if(!strcmp(which,"7")){ + return MAC_NUMPAD_7_KEY; + } + if(!strcmp(which,"8")){ + return MAC_NUMPAD_8_KEY; + } + if(!strcmp(which,"9")){ + return MAC_NUMPAD_9_KEY; + } + if(!strcmp(which,"enter")){ + return MAC_ENTER_KEY; + } + if(!strcmp(which,"control")){ + return MAC_CONTROL_KEY; + } + if(!strcmp(which,"return")){ + return MAC_RETURN_KEY; + } + if(!strcmp(which,"space")){ + return MAC_SPACE_KEY; + } + if(!strcmp(which,"shift")){ + return MAC_SHIFT_KEY; + } + if(!strcmp(which,"uparrow")){ + return MAC_ARROW_UP_KEY; + } + if(!strcmp(which,"downarrow")){ + return MAC_ARROW_DOWN_KEY; + } + if(!strcmp(which,"leftarrow")){ + return MAC_ARROW_LEFT_KEY; + } + if(!strcmp(which,"rightarrow")){ + return MAC_ARROW_RIGHT_KEY; + } +} + +char* KeyToChar(unsigned short which) +{ + static int i; + + if(which==MAC_A_KEY){ + return "a"; + } + if(which==MAC_B_KEY){ + return "b"; + } + if(which==MAC_C_KEY){ + return "c"; + } + if(which==MAC_D_KEY){ + return "d"; + } + if(which==MAC_E_KEY){ + return "e"; + } + if(which==MAC_F_KEY){ + return "f"; + } + if(which==MAC_G_KEY){ + return "g"; + } + if(which==MAC_H_KEY){ + return "h"; + } + if(which==MAC_I_KEY){ + return "i"; + } + if(which==MAC_J_KEY){ + return "j"; + } + if(which==MAC_K_KEY){ + return "k"; + } + if(which==MAC_L_KEY){ + return "l"; + } + if(which==MAC_M_KEY){ + return "m"; + } + if(which==MAC_N_KEY){ + return "n"; + } + if(which==MAC_O_KEY){ + return "o"; + } + if(which==MAC_P_KEY){ + return "p"; + } + if(which==MAC_Q_KEY){ + return "q"; + } + if(which==MAC_R_KEY){ + return "r"; + } + if(which==MAC_S_KEY){ + return "s"; + } + if(which==MAC_T_KEY){ + return "t"; + } + if(which==MAC_U_KEY){ + return "u"; + } + if(which==MAC_V_KEY){ + return "v"; + } + if(which==MAC_W_KEY){ + return "w"; + } + if(which==MAC_X_KEY){ + return "x"; + } + if(which==MAC_Y_KEY){ + return "y"; + } + if(which==MAC_Z_KEY){ + return "z"; + } + if(which==MAC_NUMPAD_1_KEY){ + return "1"; + } + if(which==MAC_NUMPAD_2_KEY){ + return "2"; + } + if(which==MAC_NUMPAD_3_KEY){ + return "3"; + } + if(which==MAC_NUMPAD_4_KEY){ + return "4"; + } + if(which==MAC_NUMPAD_5_KEY){ + return "5"; + } + if(which==MAC_NUMPAD_6_KEY){ + return "6"; + } + if(which==MAC_NUMPAD_7_KEY){ + return "7"; + } + if(which==MAC_NUMPAD_8_KEY){ + return "8"; + } + if(which==MAC_NUMPAD_9_KEY){ + return "9"; + } + if(which==MAC_ENTER_KEY){ + return "enter"; + } + if(which==MAC_NUMPAD_0_KEY){ + return "0"; + } + if(which==MAC_1_KEY){ + return "1"; + } + if(which==MAC_2_KEY){ + return "2"; + } + if(which==MAC_3_KEY){ + return "3"; + } + if(which==MAC_4_KEY){ + return "4"; + } + if(which==MAC_5_KEY){ + return "5"; + } + if(which==MAC_6_KEY){ + return "6"; + } + if(which==MAC_7_KEY){ + return "7"; + } + if(which==MAC_8_KEY){ + return "8"; + } + if(which==MAC_9_KEY){ + return "9"; + } + if(which==MAC_0_KEY){ + return "0"; + } + if(which==MAC_F1_KEY){ + return "F1"; + } + if(which==MAC_F2_KEY){ + return "F2"; + } + if(which==MAC_F3_KEY){ + return "F3"; + } + if(which==MAC_F4_KEY){ + return "F4"; + } + if(which==MAC_F5_KEY){ + return "F5"; + } + if(which==MAC_F6_KEY){ + return "F6"; + } + if(which==MAC_F7_KEY){ + return "F7"; + } + if(which==MAC_F8_KEY){ + return "F8"; + } + if(which==MAC_F9_KEY){ + return "F9"; + } + if(which==MAC_F10_KEY){ + return "F10"; + } + if(which==MAC_F11_KEY){ + return "F11"; + } + if(which==MAC_F12_KEY){ + return "F12"; + } + if(which==MAC_ESCAPE_KEY){ + return "escape"; + } + if(which==MAC_DELETE_KEY){ + return "backspace"; + } + if(which==MAC_TAB_KEY){ + return "tab"; + } + if(which==MAC_TILDE_KEY){ + return "`"; + } + if(which==MAC_CAPS_LOCK_KEY){ + return "caps lock"; + } + if(which==MAC_COMMAND_KEY){ + return "command"; + } + if(which==MAC_OPTION_KEY){ + return "option"; + } + if(which==MAC_DEL_KEY){ + return "delete"; + } + if(which==MAC_INSERT_KEY){ + return "insert"; + } + if(which==MAC_HOME_KEY){ + return "home"; + } + if(which==MAC_END_KEY){ + return "end"; + } + if(which==MAC_PAGE_UP_KEY){ + return "page up"; + } + if(which==MAC_PAGE_DOWN_KEY){ + return "page down"; + } + if(which==MAC_NUMPAD_CLEAR_KEY){ + return "clear"; + } + if(which==MAC_CONTROL_KEY){ + return "control"; + } + if(which==MAC_SPACE_KEY){ + return "space"; + } + if(which==MAC_RETURN_KEY){ + return "return"; + } + if(which==MAC_SHIFT_KEY){ + return "shift"; + } + if(which==MAC_ARROW_UP_KEY){ + return "uparrow"; + } + if(which==MAC_ARROW_DOWN_KEY){ + return "downarrow"; + } + if(which==MAC_ARROW_LEFT_KEY){ + return "leftarrow"; + } + if(which==MAC_ARROW_RIGHT_KEY){ + return "rightarrow"; + } + if(which==MAC_MINUS_KEY||which==MAC_NUMPAD_MINUS_KEY){ + return "-"; + } + if(which==MAC_PLUS_KEY||which==MAC_NUMPAD_EQUALS_KEY){ + return "="; + } + if(which==MAC_NUMPAD_PLUS_KEY){ + return "+"; + } + if(which==MAC_NUMPAD_ASTERISK_KEY){ + return "*"; + } + if(which==MAC_SLASH_KEY||which==MAC_NUMPAD_SLASH_KEY){ + return "/"; + } + if(which==MAC_BACKSLASH_KEY){ + return "\\"; + } + if(which==MAC_LEFTBRACKET_KEY){ + return "["; + } + if(which==MAC_RIGHTBRACKET_KEY){ + return "]"; + } + if(which==MAC_PERIOD_KEY||which==MAC_NUMPAD_PERIOD_KEY){ + return "."; + } + if(which==MAC_COMMA_KEY){ + return ","; + } + if(which==MAC_APOSTROPHE_KEY){ + return "\""; + } + if(which==MAC_SEMICOLON_KEY){ + return ";"; + } + return "unknown"; +} + +char KeyToSingleChar(unsigned short which) +{ + static int i; + + if(which==MAC_A_KEY){ + return 'a'; + } + if(which==MAC_B_KEY){ + return 'b'; + } + if(which==MAC_C_KEY){ + return 'c'; + } + if(which==MAC_D_KEY){ + return 'd'; + } + if(which==MAC_E_KEY){ + return 'e'; + } + if(which==MAC_F_KEY){ + return 'f'; + } + if(which==MAC_G_KEY){ + return 'g'; + } + if(which==MAC_H_KEY){ + return 'h'; + } + if(which==MAC_I_KEY){ + return 'i'; + } + if(which==MAC_J_KEY){ + return 'j'; + } + if(which==MAC_K_KEY){ + return 'k'; + } + if(which==MAC_L_KEY){ + return 'l'; + } + if(which==MAC_M_KEY){ + return 'm'; + } + if(which==MAC_N_KEY){ + return 'n'; + } + if(which==MAC_O_KEY){ + return 'o'; + } + if(which==MAC_P_KEY){ + return 'p'; + } + if(which==MAC_Q_KEY){ + return 'q'; + } + if(which==MAC_R_KEY){ + return 'r'; + } + if(which==MAC_S_KEY){ + return 's'; + } + if(which==MAC_T_KEY){ + return 't'; + } + if(which==MAC_U_KEY){ + return 'u'; + } + if(which==MAC_V_KEY){ + return 'v'; + } + if(which==MAC_W_KEY){ + return 'w'; + } + if(which==MAC_X_KEY){ + return 'x'; + } + if(which==MAC_Y_KEY){ + return 'y'; + } + if(which==MAC_Z_KEY){ + return 'z'; + } + if(which==MAC_NUMPAD_1_KEY){ + return '1'; + } + if(which==MAC_NUMPAD_2_KEY){ + return '2'; + } + if(which==MAC_NUMPAD_3_KEY){ + return '3'; + } + if(which==MAC_NUMPAD_4_KEY){ + return '4'; + } + if(which==MAC_NUMPAD_5_KEY){ + return '5'; + } + if(which==MAC_NUMPAD_6_KEY){ + return '6'; + } + if(which==MAC_NUMPAD_7_KEY){ + return '7'; + } + if(which==MAC_NUMPAD_8_KEY){ + return '8'; + } + if(which==MAC_NUMPAD_9_KEY){ + return '9'; + } + if(which==MAC_NUMPAD_0_KEY){ + return '0'; + } + if(which==MAC_1_KEY){ + return '1'; + } + if(which==MAC_2_KEY){ + return '2'; + } + if(which==MAC_3_KEY){ + return '3'; + } + if(which==MAC_4_KEY){ + return '4'; + } + if(which==MAC_5_KEY){ + return '5'; + } + if(which==MAC_6_KEY){ + return '6'; + } + if(which==MAC_7_KEY){ + return '7'; + } + if(which==MAC_8_KEY){ + return '8'; + } + if(which==MAC_9_KEY){ + return '9'; + } + if(which==MAC_0_KEY){ + return '0'; + } + if(which==MAC_SPACE_KEY){ + return ' '; + } + if(which==MAC_MINUS_KEY||which==MAC_NUMPAD_MINUS_KEY){ + return '-'; + } + if(which==MAC_PLUS_KEY||which==MAC_NUMPAD_EQUALS_KEY){ + return '='; + } + if(which==MAC_NUMPAD_PLUS_KEY){ + return '+'; + } + if(which==MAC_NUMPAD_ASTERISK_KEY){ + return '*'; + } + if(which==MAC_SLASH_KEY||which==MAC_NUMPAD_SLASH_KEY){ + return '/'; + } + if(which==MAC_BACKSLASH_KEY){ + return '\\'; + } + if(which==MAC_LEFTBRACKET_KEY){ + return '['; + } + if(which==MAC_RIGHTBRACKET_KEY){ + return ']'; + } + if(which==MAC_PERIOD_KEY||which==MAC_NUMPAD_PERIOD_KEY){ + return '.'; + } + if(which==MAC_COMMA_KEY){ + return ','; + } + if(which==MAC_APOSTROPHE_KEY){ + return '\''; + } + if(which==MAC_SEMICOLON_KEY){ + return ';'; + } + return '\0'; +} + +char Shift(char which) +{ + static int i; + + if(which=='a'){ + return 'A'; + } + if(which=='b'){ + return 'B'; + } + if(which=='c'){ + return 'C'; + } + if(which=='d'){ + return 'D'; + } + if(which=='e'){ + return 'E'; + } + if(which=='f'){ + return 'F'; + } + if(which=='g'){ + return 'G'; + } + if(which=='h'){ + return 'H'; + } + if(which=='e'){ + return 'E'; + } + if(which=='f'){ + return 'F'; + } + if(which=='g'){ + return 'G'; + } + if(which=='h'){ + return 'H'; + } + if(which=='i'){ + return 'I'; + } + if(which=='j'){ + return 'J'; + } + if(which=='k'){ + return 'K'; + } + if(which=='l'){ + return 'L'; + } + if(which=='m'){ + return 'M'; + } + if(which=='n'){ + return 'N'; + } + if(which=='o'){ + return 'O'; + } + if(which=='p'){ + return 'P'; + } + if(which=='q'){ + return 'Q'; + } + if(which=='r'){ + return 'R'; + } + if(which=='s'){ + return 'S'; + } + if(which=='t'){ + return 'T'; + } + if(which=='u'){ + return 'U'; + } + if(which=='v'){ + return 'V'; + } + if(which=='w'){ + return 'W'; + } + if(which=='x'){ + return 'X'; + } + if(which=='y'){ + return 'Y'; + } + if(which=='z'){ + return 'Z'; + } + if(which=='1'){ + return '!'; + } + if(which=='2'){ + return '@'; + } + if(which=='3'){ + return '#'; + } + if(which=='4'){ + return '$'; + } + if(which=='5'){ + return '%'; + } + if(which=='6'){ + return '^'; + } + if(which=='7'){ + return '&'; + } + if(which=='8'){ + return '*'; + } + if(which=='9'){ + return '('; + } + if(which=='0'){ + return ')'; + } + if(which=='-'){ + return '_'; + } + if(which=='='){ + return '+'; + } + if(which=='['){ + return '{'; + } + if(which==']'){ + return '}'; + } + if(which=='\\'){ + return '|'; + } + if(which=='.'){ + return '>'; + } + if(which==','){ + return '<'; + } + if(which=='/'){ + return '?'; + } + if(which==';'){ + return ':'; + } + if(which=='\''){ + return '\"'; + } + return which; +} + +bool Compare(char *thestring, char *tocompare, int start, int end) +{ + static int i; + for(i=start;i<=end;i++){ + if(thestring[i]!=tocompare[i-start]&&thestring[i]!=tocompare[i-start]+'A'-'a')return 0; + } + return 1; +} \ No newline at end of file diff --git a/Source/MacInput.h b/Source/MacInput.h new file mode 100644 index 0000000..64db734 --- /dev/null +++ b/Source/MacInput.h @@ -0,0 +1,123 @@ +#ifndef _MACINPUT_H_ +#define _MACINPUT_H_ + +/**> HEADER FILES <**/ +#include +#include +#include //Mouse + +/**> 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 +#define MAC_TILDE_KEY 0x32 +#define MAC_MINUS_KEY 0x1B +#define MAC_PLUS_KEY 0x18 +#define MAC_SLASH_KEY 0x2C +#define MAC_PERIOD_KEY 0x2F +#define MAC_COMMA_KEY 0x2B +#define MAC_BACKSLASH_KEY 0x2A +#define MAC_LEFTBRACKET_KEY 0x21 +#define MAC_RIGHTBRACKET_KEY 0x1E +#define MAC_NUMPAD_CLEAR_KEY 0x47#define MAC_NUMPAD_MINUS_KEY 0x4E +#define MAC_NUMPAD_EQUALS_KEY 0x51 +#define MAC_NUMPAD_PLUS_KEY 0x45 +#define MAC_NUMPAD_SLASH_KEY 0x4B +#define MAC_NUMPAD_ASTERISK_KEY 0x43 +#define MAC_NUMPAD_ENTER_KEY 0x4C +#define MAC_NUMPAD_PERIOD_KEY 0x41 +#define MAC_SEMICOLON_KEY 0x29 +#define MAC_APOSTROPHE_KEY 0x27 + +/**> 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(); +unsigned short CharToKey(char* which); +char* KeyToChar(unsigned short which); +char KeyToSingleChar(unsigned short which); +char Shift(char which); +bool Compare(char *thestring, char *tocompare, int start, int end); + +#endif \ No newline at end of file diff --git a/Source/Models.cpp b/Source/Models.cpp new file mode 100644 index 0000000..b1be7f5 --- /dev/null +++ b/Source/Models.cpp @@ -0,0 +1,1529 @@ +#include "Models.h" +//#include "altivec.h" +#include "Game.h" + +extern float multiplier; +extern float viewdistance; +extern XYZ viewer; +extern float fadestart; +extern float texdetail; +extern bool decals; +extern int loadscreencolor; + +#include "Game.h" +extern Game * pgame; +extern bool visibleloading; +//Functions +void *allocate_aligned(size_t pointer_size, size_t byte_alignment) +{ + uintptr_t pointer = (uintptr_t)malloc(pointer_size + byte_alignment + 1); + uintptr_t aligned_pointer = (pointer + byte_alignment + 1); + aligned_pointer -= (aligned_pointer % byte_alignment); + *(uint8_t *)(aligned_pointer - 1) = (aligned_pointer - pointer); + return (void *)aligned_pointer; +} + +void free_aligned(void *aligned_pointer) +{ + free((uint8_t *)(aligned_pointer) - *((uint8_t *)(aligned_pointer) - 1)); +} + +void dealloc(void* param){ + free(param); + param=0; +} + +int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate) +{ + static int j; + static float distance; + static float olddistance; + static int intersecting; + static int firstintersecting; + static 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,p2,&boundingspherecenter, + &boundingsphereradius))return -1; + firstintersecting=-1; + + for (j=0;jx)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z); + if((distancex)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z); + if((distancex)+(facenormals[firstintersecting].y*p2->y)+(facenormals[firstintersecting].z*p2->z)-((facenormals[firstintersecting].x*vertex[Triangles[firstintersecting].vertex[0]].x)+(facenormals[firstintersecting].y*vertex[Triangles[firstintersecting].vertex[0]].y)+(facenormals[firstintersecting].z*vertex[Triangles[firstintersecting].vertex[0]].z))); + *p2-=facenormals[firstintersecting]*distance; + + if(*rotate)*p2=DoRotation(*p2,0,*rotate,0); + *p2=*p2+*move; + return firstintersecting; +} + +int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate) +{ + static int j; + static float distance; + static float olddistance; + static int intersecting; + static int firstintersecting; + static XYZ point; + + *p1=*p1-*move; + *p2=*p2-*move; + if(!sphere_line_intersection(p1,p2,&boundingspherecenter, + &boundingsphereradius))return -1; + firstintersecting=-1; + if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0); + if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0); + + if(numpossible>0&&numpossible=0&&possible[j]x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z); + if((distance=0&&possible[j]x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z); + if((distance0){ + distance=abs((facenormals[firstintersecting].x*p2->x)+(facenormals[firstintersecting].y*p2->y)+(facenormals[firstintersecting].z*p2->z)-((facenormals[firstintersecting].x*vertex[Triangles[firstintersecting].vertex[0]].x)+(facenormals[firstintersecting].y*vertex[Triangles[firstintersecting].vertex[0]].y)+(facenormals[firstintersecting].z*vertex[Triangles[firstintersecting].vertex[0]].z))); + *p2-=facenormals[firstintersecting]*distance; + } + + if(*rotate)*p2=DoRotation(*p2,0,*rotate,0); + *p2=*p2+*move; + return firstintersecting; +} + +int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate) +{ + static int i,j; + static float distance; + static float olddistance; + static int intersecting; + static int firstintersecting; + static XYZ point; + static XYZ oldp1; + static XYZ start,end; + + firstintersecting=-1; + + oldp1=*p1; + *p1=*p1-*move; + if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0); + if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1; + + for(i=0;i<4;i++){ + for (j=0;jx)+(facenormals[j].y*p1->y)+(facenormals[j].z*p1->z)-((facenormals[j].x*vertex[Triangles[j].vertex[0]].x)+(facenormals[j].y*vertex[Triangles[j].vertex[0]].y)+(facenormals[j].z*vertex[Triangles[j].vertex[0]].z))); + if(distancey=point.y+radius; + }*/ + } + } + if((distanceradius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;} + + for (j=0;jx)+(facenormals[j].y*p1->y)+(facenormals[j].z*p1->z)-((facenormals[j].x*vertex[Triangles[j].vertex[0]].x)+(facenormals[j].y*vertex[Triangles[j].vertex[0]].y)+(facenormals[j].z*vertex[Triangles[j].vertex[0]].z))); + if(distance=0&&jboundingsphereradius){ + boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2; + boundingspherecenter=(vertex[i]+vertex[j])/2; + } + } + } + boundingsphereradius=fast_sqrt(boundingsphereradius); + + return 1; +} + + +bool Model::load(char *filename,bool texture ) +{ + FILE *tfile; + long i; + + LOGFUNC; + + LOG(std::string("Loading model...") + filename); + + if(visibleloading){ + loadscreencolor=2; + pgame->LoadingScreen(); + } + + int oldvertexNum,oldTriangleNum; + oldvertexNum=vertexNum; + oldTriangleNum=TriangleNum; + + type = normaltype; + color=0; + + tfile=fopen( filename, "rb" ); + // read model settings + + + fseek(tfile, 0, SEEK_SET); + funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum); + + // read the model data + /*if(owner)dealloc(owner); + if(possible)dealloc(possible); + if(vertex)dealloc(vertex); + if(normals)dealloc(normals); + if(facenormals)dealloc(facenormals); + if(Triangles)dealloc(Triangles); + if(vArray)dealloc(vArray);*/ + deallocate(); + + numpossible=0; + + owner = (int*)malloc(sizeof(int)*vertexNum); + possible = (int*)malloc(sizeof(int)*TriangleNum); + vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum); + normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum); + facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum); + Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum); + vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24); + + for(i=0;iboundingsphereradius){ + boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2; + boundingspherecenter=(vertex[i]+vertex[j])/2; + } + } + } + boundingsphereradius=fast_sqrt(boundingsphereradius); + + return 1; +} + +bool Model::loaddecal(char *filename,bool texture ) +{ + FILE *tfile; + long i,j; + + LOGFUNC; + + LOG(std::string("Loading decal...") + filename); + + int oldvertexNum,oldTriangleNum; + oldvertexNum=vertexNum; + oldTriangleNum=TriangleNum; + + type = decalstype; + numdecals=0; + color=0; + + tfile=fopen( filename, "rb" ); + // read model settings + + + fseek(tfile, 0, SEEK_SET); + funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum); + + // read the model data + + /*if(owner)dealloc(owner); + if(possible)dealloc(possible); + if(vertex)dealloc(vertex); + if(normals)dealloc(normals); + if(facenormals)dealloc(facenormals); + if(Triangles)dealloc(Triangles); + if(vArray)dealloc(vArray);*/ + deallocate(); + + numpossible=0; + + owner = (int*)malloc(sizeof(int)*vertexNum); + possible = (int*)malloc(sizeof(int)*TriangleNum); + vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum); + normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum); + facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum); + Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum); + vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24); + + + for(i=0;iboundingsphereradius){ + boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2; + boundingspherecenter=(vertex[i]+vertex[j])/2; + } + } + } + boundingsphereradius=fast_sqrt(boundingsphereradius); + + //allow decals + if(!decaltexcoords){ + decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals); + for(i=0;iboundingsphereradius){ + boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2; + boundingspherecenter=(vertex[i]+vertex[j])/2; + } + } + } + boundingsphereradius=fast_sqrt(boundingsphereradius); +} + +void Model::ScaleNormals(float xscale,float yscale,float zscale) +{ + if(type!=normaltype&&type!=decalstype)return; + static int i; + for(i=0; iboundingsphereradius){ + boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2; + boundingspherecenter=(vertex[i]+vertex[j])/2; + } + } + } + boundingsphereradius=fast_sqrt(boundingsphereradius); +} + +void Model::Rotate(float xang,float yang,float zang) +{ + static int i; + for(i=0; iboundingsphereradius){ + boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2; + boundingspherecenter=(vertex[i]+vertex[j])/2; + } + } + } + boundingsphereradius=fast_sqrt(boundingsphereradius); +} + + +void Model::CalculateNormals(bool facenormalise) +{ + if(visibleloading){ + loadscreencolor=3; + pgame->LoadingScreen(); + } + static int i; + if(type!=normaltype&&type!=decalstype)return; + + for(i=0; i=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){ + if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z) + &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z) + &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){ + */ + glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]); + if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z); + if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z); + if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y); + glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z); + + glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]); + if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z); + if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z); + if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y); + glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z); + + glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]); + if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z); + if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z); + if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y); + glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z); + //} + //} + } + glEnd(); +} + +void Model::draw() +{ + if(type!=normaltype&&type!=decalstype)return; + + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]); + if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]); + glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr); + +#ifndef WIN32 + glLockArraysEXT( 0, TriangleNum*3); +#endif + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); +#ifndef WIN32 + glUnlockArraysEXT(); +#endif + + + if(!color)glDisableClientState(GL_NORMAL_ARRAY); + if(color)glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + //drawimmediate(); +} + +void Model::drawdifftex(GLuint texture) +{ + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]); + if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]); + + glBindTexture(GL_TEXTURE_2D,(unsigned long)texture); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + + +#ifndef WIN32 + glLockArraysEXT( 0, TriangleNum*3); +#endif + glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3); +#ifndef WIN32 + glUnlockArraysEXT(); +#endif + + + if(!color)glDisableClientState(GL_NORMAL_ARRAY); + if(color)glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + //drawdiffteximmediate(texture); +} + +void Model::drawdiffteximmediate(GLuint texture) +{ + glBindTexture(GL_TEXTURE_2D,(unsigned long)texture); + + glBegin(GL_TRIANGLES); + for(int i=0;i=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){ + if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z) + &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z) + &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){ + */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]); + if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z); + if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z); + if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y); + glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z); + + glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]); + if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z); + if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z); + if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y); + glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z); + + glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]); + if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z); + if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z); + if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y); + glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z); + //} + //} + } + glEnd(); +} + +void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture) +{ + if(decals){ + if(type!=decalstype)return; + static int i,j; + static float distancemult; + static int lasttype; + static float viewdistsquared; + static bool blend; + + viewdistsquared=viewdistance*viewdistance; + blend=1; + + lasttype=-1; + glEnable(GL_BLEND); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(0); + if(numdecals>max_model_decals)numdecals=max_model_decals; + for(i=0;i58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2); + } + if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){ + glColor4f(1,1,1,decalopacity[i]); + if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25); + if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2); + } + lasttype=decaltype[i]; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glPushMatrix(); + glBegin(GL_TRIANGLES); + for(int j=0;j<3;j++) + { + glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z); + } + glEnd(); + glPopMatrix(); + } + for(i=numdecals-1;i>=0;i--){ + decalalivetime[i]+=multiplier; + if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3; + if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4; + if(decaltype[i]==shadowdecal)DeleteDecal(i); + if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i); + } + glAlphaFunc(GL_GREATER, 0.0001); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + } +} + +void Model::DeleteDecal(int which) +{ + if(decals){ + if(type!=decalstype)return; + decaltype[which]=decaltype[numdecals-1]; + decalposition[which]=decalposition[numdecals-1]; + for(int i=0;i<3;i++){ + decalvertex[which][i]=decalvertex[numdecals-1][i]; + decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0]; + decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1]; + } + decalrotation[which]=decalrotation[numdecals-1]; + decalalivetime[which]=decalalivetime[numdecals-1]; + decalopacity[which]=decalopacity[numdecals-1]; + numdecals--; + } +} + +void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){ + if(decals){ + if(type!=decalstype)return; + + static float placex,placez; + static XYZ rot; + //static XYZ point,point1,point2; + static float distance; + static int i,j; + + if(*opacity>0) + if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size)) + for(i=0;iy||vertex[Triangles[i].vertex[1]].yy||vertex[Triangles[i].vertex[2]].yy)){ + decalposition[numdecals]=*where; + decaltype[numdecals]=atype; + decalrotation[numdecals]=*rotation; + decalalivetime[numdecals]=0; + distance=abs(((facenormals[i].x*where->x)+(facenormals[i].y*where->y)+(facenormals[i].z*where->z)-((facenormals[i].x*vertex[Triangles[i].vertex[0]].x)+(facenormals[i].y*vertex[Triangles[i].vertex[0]].y)+(facenormals[i].z*vertex[Triangles[i].vertex[0]].z)))/facenormals[i].y); + decalopacity[numdecals]=*opacity-distance/10; + + if(decalopacity[numdecals>0]){ + placex=vertex[Triangles[i].vertex[0]].x; + placez=vertex[Triangles[i].vertex[0]].z; + + decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5; + decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5; + + decalvertex[numdecals][0].x=placex; + decalvertex[numdecals][0].z=placez; + decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y; + + + placex=vertex[Triangles[i].vertex[1]].x; + placez=vertex[Triangles[i].vertex[1]].z; + + decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5; + decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5; + + decalvertex[numdecals][1].x=placex; + decalvertex[numdecals][1].z=placez; + decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y; + + + placex=vertex[Triangles[i].vertex[2]].x; + placez=vertex[Triangles[i].vertex[2]].z; + + decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5; + decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5; + + decalvertex[numdecals][2].x=placex; + decalvertex[numdecals][2].z=placez; + decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y; + + if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0)) + if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0)) + if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1)) + if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1)) + { + if(decalrotation[numdecals]){ + for(j=0;j<3;j++){ + rot.y=0; + rot.x=decaltexcoords[numdecals][j][0]-.5; + rot.z=decaltexcoords[numdecals][j][1]-.5; + rot=DoRotation(rot,0,-decalrotation[numdecals],0); + decaltexcoords[numdecals][j][0]=rot.x+.5; + decaltexcoords[numdecals][j][1]=rot.z+.5; + } + } + if(numdecals0) + if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size)) + for(i=0;iabs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){ + decalposition[numdecals]=where; + decaltype[numdecals]=atype; + decalrotation[numdecals]=rotation; + decalalivetime[numdecals]=0; + decalopacity[numdecals]=opacity-distance/10; + + if(decalopacity[numdecals>0]){ + placex=vertex[Triangles[i].vertex[0]].x; + placez=vertex[Triangles[i].vertex[0]].z; + + decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5; + decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5; + + decalvertex[numdecals][0].x=placex; + decalvertex[numdecals][0].z=placez; + decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y; + + + placex=vertex[Triangles[i].vertex[1]].x; + placez=vertex[Triangles[i].vertex[1]].z; + + decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5; + decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5; + + decalvertex[numdecals][1].x=placex; + decalvertex[numdecals][1].z=placez; + decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y; + + + placex=vertex[Triangles[i].vertex[2]].x; + placez=vertex[Triangles[i].vertex[2]].z; + + decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5; + decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5; + + decalvertex[numdecals][2].x=placex; + decalvertex[numdecals][2].z=placez; + decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y; + + if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0)) + if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0)) + if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1)) + if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1)) + { + if(decalrotation[numdecals]){ + for(j=0;j<3;j++){ + rot.y=0; + rot.x=decaltexcoords[numdecals][j][0]-.5; + rot.z=decaltexcoords[numdecals][j][1]-.5; + rot=DoRotation(rot,0,-decalrotation[numdecals],0); + decaltexcoords[numdecals][j][0]=rot.x+.5; + decaltexcoords[numdecals][j][1]=rot.z+.5; + } + } + if(numdecalsabs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){ + decalposition[numdecals]=where; + decaltype[numdecals]=atype; + decalrotation[numdecals]=rotation; + decalalivetime[numdecals]=0; + decalopacity[numdecals]=opacity-distance/10; + + if(decalopacity[numdecals>0]){ + placex=vertex[Triangles[i].vertex[0]].y; + placez=vertex[Triangles[i].vertex[0]].z; + + decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5; + decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5; + + decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x; + decalvertex[numdecals][0].z=placez; + decalvertex[numdecals][0].y=placex; + + + placex=vertex[Triangles[i].vertex[1]].y; + placez=vertex[Triangles[i].vertex[1]].z; + + decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5; + decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5; + + decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x; + decalvertex[numdecals][1].z=placez; + decalvertex[numdecals][1].y=placex; + + + placex=vertex[Triangles[i].vertex[2]].y; + placez=vertex[Triangles[i].vertex[2]].z; + + decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5; + decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5; + + decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x; + decalvertex[numdecals][2].z=placez; + decalvertex[numdecals][2].y=placex; + + if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0)) + if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0)) + if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1)) + if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1)) + { + if(decalrotation[numdecals]){ + for(j=0;j<3;j++){ + rot.y=0; + rot.x=decaltexcoords[numdecals][j][0]-.5; + rot.z=decaltexcoords[numdecals][j][1]-.5; + rot=DoRotation(rot,0,-decalrotation[numdecals],0); + decaltexcoords[numdecals][j][0]=rot.x+.5; + decaltexcoords[numdecals][j][1]=rot.z+.5; + } + } + if(numdecalsabs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){ + decalposition[numdecals]=where; + decaltype[numdecals]=atype; + decalrotation[numdecals]=rotation; + decalalivetime[numdecals]=0; + decalopacity[numdecals]=opacity-distance/10; + + if(decalopacity[numdecals>0]){ + placex=vertex[Triangles[i].vertex[0]].x; + placez=vertex[Triangles[i].vertex[0]].y; + + decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5; + decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5; + + decalvertex[numdecals][0].x=placex; + decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z; + decalvertex[numdecals][0].y=placez; + + + placex=vertex[Triangles[i].vertex[1]].x; + placez=vertex[Triangles[i].vertex[1]].y; + + decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5; + decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5; + + decalvertex[numdecals][1].x=placex; + decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z; + decalvertex[numdecals][1].y=placez; + + + placex=vertex[Triangles[i].vertex[2]].x; + placez=vertex[Triangles[i].vertex[2]].y; + + decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5; + decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5; + + decalvertex[numdecals][2].x=placex; + decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z; + decalvertex[numdecals][2].y=placez; + + if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0)) + if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0)) + if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1)) + if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1)) + { + if(decalrotation[numdecals]){ + for(j=0;j<3;j++){ + rot.y=0; + rot.x=decaltexcoords[numdecals][j][0]-.5; + rot.z=decaltexcoords[numdecals][j][1]-.5; + rot=DoRotation(rot,0,-decalrotation[numdecals],0); + decaltexcoords[numdecals][j][0]=rot.x+.5; + decaltexcoords[numdecals][j][1]=rot.z+.5; + } + } + if(numdecals Model Loading <**/ +// +// Model Maximums +// +#include "gl.h" +#include +#include +#include +#include + +#include "Constants.h" +#include "Terrain.h" +#include "binio.h" +#include "Quaternions.h" + +// +// Textures List +// +typedef struct { + long xsz,ysz; + GLubyte *txt; +} ModelTexture; + +// +// Model Structures +// + +class TexturedTriangle{ +public: + short vertex[3]; + float gx[3],gy[3]; +}; + +#define max_model_decals 300 + +#define nothing 0 +#define normaltype 4 +#define notextype 1 +#define rawtype 2 +#define decalstype 3 + +class Model{ +public: + short vertexNum,TriangleNum; + bool hastexture; + + int type,oldtype; + + int* possible; + int* owner; + XYZ* vertex; + XYZ* normals; + XYZ* facenormals; + TexturedTriangle* Triangles; + GLfloat* vArray; + + /*int possible[max_model_vertex]; + int owner[max_textured_triangle]; + XYZ vertex[max_model_vertex]; + XYZ normals[max_model_vertex]; + XYZ facenormals[max_textured_triangle]; + TexturedTriangle Triangles[max_textured_triangle]; + GLfloat vArray[max_textured_triangle*24];*/ + + GLuint textureptr; + ModelTexture Texture; + int numpossible; + bool color; + + XYZ boundingspherecenter; + float boundingsphereradius; + + float*** decaltexcoords; + XYZ** decalvertex; + int* decaltype; + float* decalopacity; + float* decalrotation; + float* decalalivetime; + XYZ* decalposition; + + /*float decaltexcoords[max_model_decals][3][2]; + XYZ decalvertex[max_model_decals][3]; + int decaltype[max_model_decals]; + float decalopacity[max_model_decals]; + float decalrotation[max_model_decals]; + float decalalivetime[max_model_decals]; + XYZ decalposition[max_model_decals];*/ + + int numdecals; + + bool flat; + + void DeleteDecal(int which); + void MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation); + void MakeDecal(int atype, XYZ where, float size, float opacity, float rotation); + void drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture); + int SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate); + int SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate); + int LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate); + int LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate); + int LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate); + int LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate); + void UpdateVertexArray(); + void UpdateVertexArrayNoTex(); + void UpdateVertexArrayNoTexNoNorm(); + bool loadnotex(char *filename); + bool loadraw(char *filename); + bool load(char *filename,bool texture); + bool loaddecal(char *filename,bool texture); + void Scale(float xscale,float yscale,float zscale); + void FlipTexCoords(); + void UniformTexCoords(); + void ScaleTexCoords(float howmuch); + void ScaleNormals(float xscale,float yscale,float zscale); + void Translate(float xtrans,float ytrans,float ztrans); + void CalculateNormals(bool facenormalise); + void draw(); + void drawdifftex(GLuint texture); + void drawimmediate(); + void drawdiffteximmediate(GLuint texture); + void Rotate(float xang,float yang,float zang); + ~Model(); + void deallocate(); + Model(); +}; + +#endif \ No newline at end of file diff --git a/Source/MoreFilesX.c b/Source/MoreFilesX.c new file mode 100644 index 0000000..617f492 --- /dev/null +++ b/Source/MoreFilesX.c @@ -0,0 +1,2770 @@ +/* + File: MoreFilesX.c + + Contains: A collection of useful high-level File Manager routines + which use the HFS Plus APIs wherever possible. + + Version: MoreFilesX 1.0.1 + + Copyright: © 1992-2002 by Apple Computer, Inc., all rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: For bug reports, consult the following page on + the World Wide Web: + http://developer.apple.com/bugreporter/ + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <4> 8/22/02 JL [3016251] Changed FSMoveRenameObjectUnicode to not use + the Temporary folder because it isn't available on + NFS volumes. + <3> 4/19/02 JL [2853905] Fixed #if test around header includes. + <2> 4/19/02 JL [2850624] Fixed C++ compile errors and Project Builder + warnings. + <2> 4/19/02 JL [2853901] Updated standard disclaimer. + <1> 1/25/02 JL MoreFilesX 1.0 +*/ + +#if defined(__MACH__) + #include + #include +#else + #include + #include +#endif + +#include "MoreFilesX.h" + +/* Set BuildingMoreFilesXForMacOS9 to 1 if building for Mac OS 9 */ +#ifndef BuildingMoreFilesXForMacOS9 + #define BuildingMoreFilesXForMacOS9 0 +#endif + +/*****************************************************************************/ + +#pragma mark ----- Local type definitions ----- + +struct FSIterateContainerGlobals +{ + IterateContainerFilterProcPtr iterateFilter; /* pointer to IterateFilterProc */ + FSCatalogInfoBitmap whichInfo; /* fields of the CatalogInfo to get */ + FSCatalogInfo catalogInfo; /* FSCatalogInfo */ + FSRef ref; /* FSRef */ + FSSpec spec; /* FSSpec */ + FSSpec *specPtr; /* pointer to spec field, or NULL */ + HFSUniStr255 name; /* HFSUniStr255 */ + HFSUniStr255 *namePtr; /* pointer to name field, or NULL */ + void *yourDataPtr; /* a pointer to caller supplied data the filter may need to access */ + ItemCount maxLevels; /* maximum levels to iterate through */ + ItemCount currentLevel; /* the current level FSIterateContainerLevel is on */ + Boolean quitFlag; /* set to true if filter wants to kill interation */ + Boolean containerChanged; /* temporary - set to true if the current container changed during iteration */ + OSErr result; /* result */ + ItemCount actualObjects; /* number of objects returned */ +}; +typedef struct FSIterateContainerGlobals FSIterateContainerGlobals; + +struct FSDeleteContainerGlobals +{ + OSErr result; /* result */ + ItemCount actualObjects; /* number of objects returned */ + FSCatalogInfo catalogInfo; /* FSCatalogInfo */ +}; +typedef struct FSDeleteContainerGlobals FSDeleteContainerGlobals; + +/*****************************************************************************/ + +#pragma mark ----- Local prototypes ----- + +static +void +FSDeleteContainerLevel( + const FSRef *container, + FSDeleteContainerGlobals *theGlobals); + +static +void +FSIterateContainerLevel( + FSIterateContainerGlobals *theGlobals); + +static +OSErr +GenerateUniqueHFSUniStr( + long *startSeed, + const FSRef *dir1, + const FSRef *dir2, + HFSUniStr255 *uniqueName); + +/*****************************************************************************/ + +#pragma mark ----- File Access Routines ----- + +/*****************************************************************************/ + +OSErr +FSCopyFork( + SInt16 srcRefNum, + SInt16 dstRefNum, + void *copyBufferPtr, + ByteCount copyBufferSize) +{ + OSErr srcResult; + OSErr dstResult; + OSErr result; + SInt64 forkSize; + ByteCount readActualCount; + + /* check input parameters */ + require_action((NULL != copyBufferPtr) && (0 != copyBufferSize), BadParameter, result = paramErr); + + /* get source fork size */ + result = FSGetForkSize(srcRefNum, &forkSize); + require_noerr(result, SourceFSGetForkSizeFailed); + + /* allocate disk space for destination fork */ + result = FSSetForkSize(dstRefNum, fsFromStart, forkSize); + require_noerr(result, DestinationFSSetForkSizeFailed); + + /* reset source fork's position to 0 */ + result = FSSetForkPosition(srcRefNum, fsFromStart, 0); + require_noerr(result, SourceFSSetForkPositionFailed); + + /* reset destination fork's position to 0 */ + result = FSSetForkPosition(dstRefNum, fsFromStart, 0); + require_noerr(result, DestinationFSSetForkPositionFailed); + + /* If copyBufferSize is greater than 4K bytes, make it a multiple of 4k bytes */ + /* This will make writes on local volumes faster */ + if ( (copyBufferSize >= 0x00001000) && ((copyBufferSize & 0x00000fff) != 0) ) + { + copyBufferSize &= ~(0x00001000 - 1); + } + + /* copy source to destination */ + srcResult = dstResult = noErr; + while ( (noErr == srcResult) && (noErr == dstResult) ) + { + srcResult = FSReadFork(srcRefNum, fsAtMark + noCacheMask, 0, copyBufferSize, copyBufferPtr, &readActualCount); + dstResult = FSWriteFork(dstRefNum, fsAtMark + noCacheMask, 0, readActualCount, copyBufferPtr, NULL); + } + + /* make sure there were no errors at the destination */ + require_noerr_action(dstResult, DestinationFSWriteForkFailed, result = dstResult); + + /* make sure the error at the source was eofErr */ + require_action(eofErr == srcResult, SourceResultNotEofErr, result = srcResult); + + /* everything went as expected */ + result = noErr; + +SourceResultNotEofErr: +DestinationFSWriteForkFailed: +DestinationFSSetForkPositionFailed: +SourceFSSetForkPositionFailed: +DestinationFSSetForkSizeFailed: +SourceFSGetForkSizeFailed: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- Volume Access Routines ----- + +/*****************************************************************************/ + +OSErr +FSGetVolParms( + FSVolumeRefNum volRefNum, + UInt32 bufferSize, + GetVolParmsInfoBuffer *volParmsInfo, + UInt32 *actualInfoSize) +{ + OSErr result; + HParamBlockRec pb; + + /* check parameters */ + require_action((NULL != volParmsInfo) && (NULL != actualInfoSize), + BadParameter, result = paramErr); + + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioVRefNum = volRefNum; + pb.ioParam.ioBuffer = (Ptr)volParmsInfo; + pb.ioParam.ioReqCount = (SInt32)bufferSize; + result = PBHGetVolParmsSync(&pb); + require_noerr(result, PBHGetVolParmsSync); + + /* return number of bytes the file system returned in volParmsInfo buffer */ + *actualInfoSize = (UInt32)pb.ioParam.ioActCount; + +PBHGetVolParmsSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVRefNum( + const FSRef *ref, + FSVolumeRefNum *vRefNum) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action(NULL != vRefNum, BadParameter, result = paramErr); + + /* get the volume refNum from the FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* return volume refNum from catalogInfo */ + *vRefNum = catalogInfo.volume; + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVInfo( + FSVolumeRefNum volume, + HFSUniStr255 *volumeName, /* can be NULL */ + UInt64 *freeBytes, /* can be NULL */ + UInt64 *totalBytes) /* can be NULL */ +{ + OSErr result; + FSVolumeInfo info; + + /* ask for the volume's sizes only if needed */ + result = FSGetVolumeInfo(volume, 0, NULL, + (((NULL != freeBytes) || (NULL != totalBytes)) ? kFSVolInfoSizes : kFSVolInfoNone), + &info, volumeName, NULL); + require_noerr(result, FSGetVolumeInfo); + + if ( NULL != freeBytes ) + { + *freeBytes = info.freeBytes; + } + if ( NULL != totalBytes ) + { + *totalBytes = info.totalBytes; + } + +FSGetVolumeInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVolFileSystemID( + FSVolumeRefNum volume, + UInt16 *fileSystemID, /* can be NULL */ + UInt16 *signature) /* can be NULL */ +{ + OSErr result; + FSVolumeInfo info; + + result = FSGetVolumeInfo(volume, 0, NULL, kFSVolInfoFSInfo, &info, NULL, NULL); + require_noerr(result, FSGetVolumeInfo); + + if ( NULL != fileSystemID ) + { + *fileSystemID = info.filesystemID; + } + if ( NULL != signature ) + { + *signature = info.signature; + } + +FSGetVolumeInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetMountedVolumes( + FSRef ***volumeRefsHandle, /* pointer to handle of FSRefs */ + ItemCount *numVolumes) +{ + OSErr result; + OSErr memResult; + ItemCount volumeIndex; + FSRef ref; + + /* check parameters */ + require_action((NULL != volumeRefsHandle) && (NULL != numVolumes), + BadParameter, result = paramErr); + + /* No volumes yet */ + *numVolumes = 0; + + /* Allocate a handle for the results */ + *volumeRefsHandle = (FSRef **)NewHandle(0); + require_action(NULL != *volumeRefsHandle, NewHandle, result = memFullErr); + + /* Call FSGetVolumeInfo in loop to get all volumes starting with the first */ + volumeIndex = 1; + do + { + result = FSGetVolumeInfo(0, volumeIndex, NULL, kFSVolInfoNone, NULL, NULL, &ref); + if ( noErr == result ) + { + /* concatenate the FSRef to the end of the handle */ + PtrAndHand(&ref, (Handle)*volumeRefsHandle, sizeof(FSRef)); + memResult = MemError(); + require_noerr_action(memResult, MemoryAllocationFailed, result = memResult); + + ++(*numVolumes); /* increment the volume count */ + ++volumeIndex; /* and the volumeIndex to get the next volume*/ + } + } while ( noErr == result ); + + /* nsvErr is OK -- it just means there are no more volumes */ + require(nsvErr == result, FSGetVolumeInfo); + + return ( noErr ); + + /**********************/ + +MemoryAllocationFailed: +FSGetVolumeInfo: + + /* dispose of handle if already allocated and clear the outputs */ + if ( NULL != *volumeRefsHandle ) + { + DisposeHandle((Handle)*volumeRefsHandle); + *volumeRefsHandle = NULL; + } + *numVolumes = 0; + +NewHandle: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- FSRef/FSpec/Path/Name Conversion Routines ----- + +/*****************************************************************************/ + +OSErr +FSRefMakeFSSpec( + const FSRef *ref, + FSSpec *spec) +{ + OSErr result; + + /* check parameters */ + require_action(NULL != spec, BadParameter, result = paramErr); + + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, spec, NULL); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMakeFSRef( + FSVolumeRefNum volRefNum, + SInt32 dirID, + ConstStr255Param name, + FSRef *ref) +{ + OSErr result; + FSRefParam pb; + + /* check parameters */ + require_action(NULL != ref, BadParameter, result = paramErr); + + pb.ioVRefNum = volRefNum; + pb.ioDirID = dirID; + pb.ioNamePtr = (StringPtr)name; + pb.newRef = ref; + result = PBMakeFSRefSync(&pb); + require_noerr(result, PBMakeFSRefSync); + +PBMakeFSRefSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSStatus +FSMakePath( + SInt16 volRefNum, + SInt32 dirID, + ConstStr255Param name, + UInt8 *path, + UInt32 maxPathSize) +{ + OSStatus result; + FSRef ref; + + /* check parameters */ + require_action(NULL != path, BadParameter, result = paramErr); + + /* convert the inputs to an FSRef */ + result = FSMakeFSRef(volRefNum, dirID, name, &ref); + require_noerr(result, FSMakeFSRef); + + /* and then convert the FSRef to a path */ + result = FSRefMakePath(&ref, path, maxPathSize); + require_noerr(result, FSRefMakePath); + +FSRefMakePath: +FSMakeFSRef: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSStatus +FSPathMakeFSSpec( + const UInt8 *path, + FSSpec *spec, + Boolean *isDirectory) /* can be NULL */ +{ + OSStatus result; + FSRef ref; + + /* check parameters */ + require_action(NULL != spec, BadParameter, result = paramErr); + + /* convert the POSIX path to an FSRef */ + result = FSPathMakeRef(path, &ref, isDirectory); + require_noerr(result, FSPathMakeRef); + + /* and then convert the FSRef to an FSSpec */ + result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: +FSPathMakeRef: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +UnicodeNameGetHFSName( + UniCharCount nameLength, + const UniChar *name, + TextEncoding textEncodingHint, + Boolean isVolumeName, + Str31 hfsName) +{ + OSStatus result; + ByteCount unicodeByteLength; + ByteCount unicodeBytesConverted; + ByteCount actualPascalBytes; + UnicodeMapping uMapping; + UnicodeToTextInfo utInfo; + + /* check parameters */ + require_action(NULL != hfsName, BadParameter, result = paramErr); + + /* make sure output is valid in case we get errors or there's nothing to convert */ + hfsName[0] = 0; + + unicodeByteLength = nameLength * sizeof(UniChar); + if ( 0 == unicodeByteLength ) + { + /* do nothing */ + result = noErr; + } + else + { + /* if textEncodingHint is kTextEncodingUnknown, get a "default" textEncodingHint */ + if ( kTextEncodingUnknown == textEncodingHint ) + { + ScriptCode script; + RegionCode region; + + script = (ScriptCode)GetScriptManagerVariable(smSysScript); + region = (RegionCode)GetScriptManagerVariable(smRegionCode); + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, + NULL, &textEncodingHint ); + if ( paramErr == result ) + { + /* ok, ignore the region and try again */ + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, + kTextRegionDontCare, NULL, &textEncodingHint ); + } + if ( noErr != result ) + { + /* ok... try something */ + textEncodingHint = kTextEncodingMacRoman; + } + } + + uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, + kUnicodeCanonicalDecompVariant, kUnicode16BitFormat); + uMapping.otherEncoding = GetTextEncodingBase(textEncodingHint); + uMapping.mappingVersion = kUnicodeUseHFSPlusMapping; + + result = CreateUnicodeToTextInfo(&uMapping, &utInfo); + require_noerr(result, CreateUnicodeToTextInfo); + + result = ConvertFromUnicodeToText(utInfo, unicodeByteLength, name, kUnicodeLooseMappingsMask, + 0, NULL, 0, NULL, /* offsetCounts & offsetArrays */ + isVolumeName ? kHFSMaxVolumeNameChars : kHFSMaxFileNameChars, + &unicodeBytesConverted, &actualPascalBytes, &hfsName[1]); + require_noerr(result, ConvertFromUnicodeToText); + + hfsName[0] = (unsigned char)actualPascalBytes; /* fill in length byte */ + +ConvertFromUnicodeToText: + + /* verify the result in debug builds -- there's really not anything you can do if it fails */ + verify_noerr(DisposeUnicodeToTextInfo(&utInfo)); + } + +CreateUnicodeToTextInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +HFSNameGetUnicodeName( + ConstStr31Param hfsName, + TextEncoding textEncodingHint, + HFSUniStr255 *unicodeName) +{ + ByteCount unicodeByteLength; + OSStatus result; + UnicodeMapping uMapping; + TextToUnicodeInfo tuInfo; + ByteCount pascalCharsRead; + + /* check parameters */ + require_action(NULL != unicodeName, BadParameter, result = paramErr); + + /* make sure output is valid in case we get errors or there's nothing to convert */ + unicodeName->length = 0; + + if ( 0 == StrLength(hfsName) ) + { + result = noErr; + } + else + { + /* if textEncodingHint is kTextEncodingUnknown, get a "default" textEncodingHint */ + if ( kTextEncodingUnknown == textEncodingHint ) + { + ScriptCode script; + RegionCode region; + + script = GetScriptManagerVariable(smSysScript); + region = GetScriptManagerVariable(smRegionCode); + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, + NULL, &textEncodingHint); + if ( paramErr == result ) + { + /* ok, ignore the region and try again */ + result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, + kTextRegionDontCare, NULL, &textEncodingHint); + } + if ( noErr != result ) + { + /* ok... try something */ + textEncodingHint = kTextEncodingMacRoman; + } + } + + uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, + kUnicodeCanonicalDecompVariant, kUnicode16BitFormat); + uMapping.otherEncoding = GetTextEncodingBase(textEncodingHint); + uMapping.mappingVersion = kUnicodeUseHFSPlusMapping; + + result = CreateTextToUnicodeInfo(&uMapping, &tuInfo); + require_noerr(result, CreateTextToUnicodeInfo); + + result = ConvertFromTextToUnicode(tuInfo, hfsName[0], &hfsName[1], + 0, /* no control flag bits */ + 0, NULL, 0, NULL, /* offsetCounts & offsetArrays */ + sizeof(unicodeName->unicode), /* output buffer size in bytes */ + &pascalCharsRead, &unicodeByteLength, unicodeName->unicode); + require_noerr(result, ConvertFromTextToUnicode); + + /* convert from byte count to char count */ + unicodeName->length = unicodeByteLength / sizeof(UniChar); + +ConvertFromTextToUnicode: + + /* verify the result in debug builds -- there's really not anything you can do if it fails */ + verify_noerr(DisposeTextToUnicodeInfo(&tuInfo)); + } + +CreateTextToUnicodeInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- File/Directory Manipulation Routines ----- + +/*****************************************************************************/ + +Boolean FSRefValid(const FSRef *ref) +{ + return ( noErr == FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, NULL, NULL) ); +} + +/*****************************************************************************/ + +OSErr +FSGetParentRef( + const FSRef *ref, + FSRef *parentRef) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action(NULL != parentRef, BadParameter, result = paramErr); + + result = FSGetCatalogInfo(ref, kFSCatInfoNodeID, &catalogInfo, NULL, NULL, parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* + * Note: FSRefs always point to real file system objects. So, there cannot + * be a FSRef to the parent of volume root directories. Early versions of + * Mac OS X do not handle this case correctly and incorrectly return a + * FSRef for the parent of volume root directories instead of returning an + * invalid FSRef (a cleared FSRef is invalid). The next three lines of code + * ensure that you won't run into this bug. WW9D! + */ + if ( fsRtDirID == catalogInfo.nodeID ) + { + /* clear parentRef and return noErr which is the proper behavior */ + memset(parentRef, 0, sizeof(FSRef)); + } + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetFileDirName( + const FSRef *ref, + HFSUniStr255 *outName) +{ + OSErr result; + + /* check parameters */ + require_action(NULL != outName, BadParameter, result = paramErr); + + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, outName, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetNodeID( + const FSRef *ref, + long *nodeID, /* can be NULL */ + Boolean *isDirectory) /* can be NULL */ +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information to get */ + whichInfo = kFSCatInfoNone; /* start with none */ + if ( NULL != nodeID ) + { + whichInfo |= kFSCatInfoNodeID; + } + if ( NULL != isDirectory ) + { + whichInfo |= kFSCatInfoNodeFlags; + } + + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + if ( NULL != nodeID ) + { + *nodeID = catalogInfo.nodeID; + } + if ( NULL != isDirectory ) + { + *isDirectory = (0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags)); + } + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetUserPrivilegesPermissions( + const FSRef *ref, + UInt8 *userPrivileges, /* can be NULL */ + UInt32 permissions[4]) /* can be NULL */ +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information to get */ + whichInfo = kFSCatInfoNone; /* start with none */ + if ( NULL != userPrivileges ) + { + whichInfo |= kFSCatInfoUserPrivs; + } + if ( NULL != permissions ) + { + whichInfo |= kFSCatInfoPermissions; + } + + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + if ( NULL != userPrivileges ) + { + *userPrivileges = catalogInfo.userPrivileges; + } + if ( NULL != permissions ) + { + BlockMoveData(&catalogInfo.permissions, permissions, sizeof(UInt32) * 4); + } + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSCheckLock( + const FSRef *ref) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSVolumeInfo volumeInfo; + + /* get nodeFlags and vRefNum for container */ + result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoVolume, &catalogInfo, NULL, NULL,NULL); + require_noerr(result, FSGetCatalogInfo); + + /* is file locked? */ + if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) ) + { + result = fLckdErr; /* file is locked */ + } + else + { + /* file isn't locked, but is volume locked? */ + + /* get volume flags */ + result = FSGetVolumeInfo(catalogInfo.volume, 0, NULL, kFSVolInfoFlags, &volumeInfo, NULL, NULL); + require_noerr(result, FSGetVolumeInfo); + + if ( 0 != (volumeInfo.flags & kFSVolFlagHardwareLockedMask) ) + { + result = wPrErr; /* volume locked by hardware */ + } + else if ( 0 != (volumeInfo.flags & kFSVolFlagSoftwareLockedMask) ) + { + result = vLckdErr; /* volume locked by software */ + } + } + +FSGetVolumeInfo: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetForkSizes( + const FSRef *ref, + UInt64 *dataLogicalSize, /* can be NULL */ + UInt64 *rsrcLogicalSize) /* can be NULL */ +{ + OSErr result; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo catalogInfo; + + whichInfo = kFSCatInfoNodeFlags; + if ( NULL != dataLogicalSize ) + { + /* get data fork size */ + whichInfo |= kFSCatInfoDataSizes; + } + if ( NULL != rsrcLogicalSize ) + { + /* get resource fork size */ + whichInfo |= kFSCatInfoRsrcSizes; + } + + /* get nodeFlags and catalog info */ + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL,NULL); + require_noerr(result, FSGetCatalogInfo); + + /* make sure FSRef was to a file */ + require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), FSRefNotFile, result = notAFileErr); + + if ( NULL != dataLogicalSize ) + { + /* return data fork size */ + *dataLogicalSize = catalogInfo.dataLogicalSize; + } + if ( NULL != rsrcLogicalSize ) + { + /* return resource fork size */ + *rsrcLogicalSize = catalogInfo.rsrcLogicalSize; + } + +FSRefNotFile: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetTotalForkSizes( + const FSRef *ref, + UInt64 *totalLogicalSize, /* can be NULL */ + UInt64 *totalPhysicalSize, /* can be NULL */ + ItemCount *forkCount) /* can be NULL */ +{ + OSErr result; + CatPositionRec forkIterator; + SInt64 forkSize; + SInt64 *forkSizePtr; + UInt64 forkPhysicalSize; + UInt64 *forkPhysicalSizePtr; + + /* Determine if forkSize needed */ + if ( NULL != totalLogicalSize) + { + *totalLogicalSize = 0; + forkSizePtr = &forkSize; + } + else + { + forkSizePtr = NULL; + } + + /* Determine if forkPhysicalSize is needed */ + if ( NULL != totalPhysicalSize ) + { + *totalPhysicalSize = 0; + forkPhysicalSizePtr = &forkPhysicalSize; + } + else + { + forkPhysicalSizePtr = NULL; + } + + /* zero fork count if returning it */ + if ( NULL != forkCount ) + { + *forkCount = 0; + } + + /* Iterate through the forks to get the sizes */ + forkIterator.initialize = 0; + do + { + result = FSIterateForks(ref, &forkIterator, NULL, forkSizePtr, forkPhysicalSizePtr); + if ( noErr == result ) + { + if ( NULL != totalLogicalSize ) + { + *totalLogicalSize += forkSize; + } + + if ( NULL != totalPhysicalSize ) + { + *totalPhysicalSize += forkPhysicalSize; + } + + if ( NULL != forkCount ) + { + ++*forkCount; + } + } + } while ( noErr == result ); + + /* any error result other than errFSNoMoreItems is serious */ + require(errFSNoMoreItems == result, FSIterateForks); + + /* Normal exit */ + result = noErr; + +FSIterateForks: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSBumpDate( + const FSRef *ref) +{ + OSStatus result; + FSCatalogInfo catalogInfo; + UTCDateTime oldDateTime; +#if !BuildingMoreFilesXForMacOS9 + FSRef parentRef; + Boolean notifyParent; +#endif + +#if !BuildingMoreFilesXForMacOS9 + /* Get the node flags, the content modification date and time, and the parent ref */ + result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoContentMod, &catalogInfo, NULL, NULL, &parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* Notify the parent if this is a file */ + notifyParent = (0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)); +#else + /* Get the content modification date and time */ + result = FSGetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); +#endif + + oldDateTime = catalogInfo.contentModDate; + + /* Get the current date and time */ + result = GetUTCDateTime(&catalogInfo.contentModDate, kUTCDefaultOptions); + require_noerr(result, GetUTCDateTime); + + /* if the old date and time is the the same as the current, bump the seconds by one */ + if ( (catalogInfo.contentModDate.fraction == oldDateTime.fraction) && + (catalogInfo.contentModDate.lowSeconds == oldDateTime.lowSeconds) && + (catalogInfo.contentModDate.highSeconds == oldDateTime.highSeconds) ) + { + ++catalogInfo.contentModDate.lowSeconds; + if ( 0 == catalogInfo.contentModDate.lowSeconds ) + { + ++catalogInfo.contentModDate.highSeconds; + } + } + + /* Bump the content modification date and time */ + result = FSSetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + +#if !BuildingMoreFilesXForMacOS9 + /* + * The problem with FNNotify is that it is not available under Mac OS 9 + * and there's no way to test for that except for looking for the symbol + * or something. So, I'll just conditionalize this for those who care + * to send a notification. + */ + + /* Send a notification for the parent of the file, or for the directory */ + result = FNNotify(notifyParent ? &parentRef : ref, kFNDirectoryModifiedMessage, kNilOptions); + require_noerr(result, FNNotify); +#endif + + /* ignore errors from FSSetCatalogInfo (volume might be write protected) and FNNotify */ +FNNotify: +FSSetCatalogInfo: + + return ( noErr ); + + /**********************/ + +GetUTCDateTime: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetFinderInfo( + const FSRef *ref, + FinderInfo *info, /* can be NULL */ + ExtendedFinderInfo *extendedInfo, /* can be NULL */ + Boolean *isDirectory) /* can be NULL */ +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information is really needed */ + whichInfo = kFSCatInfoNone; + + if ( NULL != info ) + { + /* get FinderInfo */ + whichInfo |= kFSCatInfoFinderInfo; + } + + if ( NULL != extendedInfo ) + { + /* get ExtendedFinderInfo */ + whichInfo |= kFSCatInfoFinderXInfo; + } + + if ( NULL != isDirectory ) + { + whichInfo |= kFSCatInfoNodeFlags; + } + + result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* return FinderInfo if requested */ + if ( NULL != info ) + { + BlockMoveData(catalogInfo.finderInfo, info, sizeof(FinderInfo)); + } + + /* return ExtendedFinderInfo if requested */ + if ( NULL != extendedInfo) + { + BlockMoveData(catalogInfo.extFinderInfo, extendedInfo, sizeof(ExtendedFinderInfo)); + } + + /* set isDirectory Boolean if requested */ + if ( NULL != isDirectory) + { + *isDirectory = (0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags)); + } + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSSetFinderInfo( + const FSRef *ref, + const FinderInfo *info, + const ExtendedFinderInfo *extendedInfo) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSCatalogInfoBitmap whichInfo; + + /* determine what catalog information will be set */ + whichInfo = kFSCatInfoNone; /* start with none */ + if ( NULL != info ) + { + /* set FinderInfo */ + whichInfo |= kFSCatInfoFinderInfo; + BlockMoveData(info, catalogInfo.finderInfo, sizeof(FinderInfo)); + } + if ( NULL != extendedInfo ) + { + /* set ExtendedFinderInfo */ + whichInfo |= kFSCatInfoFinderXInfo; + BlockMoveData(extendedInfo, catalogInfo.extFinderInfo, sizeof(ExtendedFinderInfo)); + } + + result = FSSetCatalogInfo(ref, whichInfo, &catalogInfo); + require_noerr(result, FSGetCatalogInfo); + +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSChangeCreatorType( + const FSRef *ref, + OSType fileCreator, + OSType fileType) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSRef parentRef; + + /* get nodeFlags, finder info, and parent FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoFinderInfo, &catalogInfo , NULL, NULL, &parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* make sure FSRef was to a file */ + require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), FSRefNotFile, result = notAFileErr); + + /* If fileType not 0x00000000, change fileType */ + if ( fileType != (OSType)0x00000000 ) + { + ((FileInfo *)&catalogInfo.finderInfo)->fileType = fileType; + } + + /* If creator not 0x00000000, change creator */ + if ( fileCreator != (OSType)0x00000000 ) + { + ((FileInfo *)&catalogInfo.finderInfo)->fileCreator = fileCreator; + } + + /* now, save the new information back to disk */ + result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + + /* and attempt to bump the parent directory's mod date to wake up */ + /* the Finder to the change we just made (ignore errors from this) */ + verify_noerr(FSBumpDate(&parentRef)); + +FSSetCatalogInfo: +FSRefNotFile: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSChangeFinderFlags( + const FSRef *ref, + Boolean setBits, + UInt16 flagBits) +{ + OSErr result; + FSCatalogInfo catalogInfo; + FSRef parentRef; + + /* get the current finderInfo */ + result = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, &parentRef); + require_noerr(result, FSGetCatalogInfo); + + /* set or clear the appropriate bits in the finderInfo.finderFlags */ + if ( setBits ) + { + /* OR in the bits */ + ((FileInfo *)&catalogInfo.finderInfo)->finderFlags |= flagBits; + } + else + { + /* AND out the bits */ + ((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~flagBits; + } + + /* save the modified finderInfo */ + result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + + /* and attempt to bump the parent directory's mod date to wake up the Finder */ + /* to the change we just made (ignore errors from this) */ + verify_noerr(FSBumpDate(&parentRef)); + +FSSetCatalogInfo: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSSetInvisible( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kIsInvisible) ); +} + +OSErr +FSClearInvisible( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kIsInvisible) ); +} + +/*****************************************************************************/ + +OSErr +FSSetNameLocked( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kNameLocked) ); +} + +OSErr +FSClearNameLocked( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kNameLocked) ); +} + +/*****************************************************************************/ + +OSErr +FSSetIsStationery( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kIsStationery) ); +} + +OSErr +FSClearIsStationery( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kIsStationery) ); +} + +/*****************************************************************************/ + +OSErr +FSSetHasCustomIcon( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, true, kHasCustomIcon) ); +} + +OSErr +FSClearHasCustomIcon( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kHasCustomIcon) ); +} + +/*****************************************************************************/ + +OSErr +FSClearHasBeenInited( + const FSRef *ref) +{ + return ( FSChangeFinderFlags(ref, false, kHasBeenInited) ); +} + +/*****************************************************************************/ + +OSErr +FSCopyFileMgrAttributes( + const FSRef *sourceRef, + const FSRef *destinationRef, + Boolean copyLockBit) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* get the source information */ + result = FSGetCatalogInfo(sourceRef, kFSCatInfoSettableInfo, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* don't copy the hasBeenInited bit; clear it */ + ((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~kHasBeenInited; + + /* should the locked bit be copied? */ + if ( !copyLockBit ) + { + /* no, make sure the locked bit is clear */ + catalogInfo.nodeFlags &= ~kFSNodeLockedMask; + } + + /* set the destination information */ + result = FSSetCatalogInfo(destinationRef, kFSCatInfoSettableInfo, &catalogInfo); + require_noerr(result, FSSetCatalogInfo); + +FSSetCatalogInfo: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMoveRenameObjectUnicode( + const FSRef *ref, + const FSRef *destDirectory, + UniCharCount nameLength, + const UniChar *name, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef) /* if function fails along the way, newRef is final location of file */ +{ + OSErr result; + FSVolumeRefNum vRefNum; + FSCatalogInfo catalogInfo; + FSRef originalDirectory; + TextEncoding originalTextEncodingHint; + HFSUniStr255 originalName; + HFSUniStr255 uniqueName; /* unique name given to object while moving it to destination */ + long theSeed; /* the seed for generating unique names */ + + /* check parameters */ + require_action(NULL != newRef, BadParameter, result = paramErr); + + /* newRef = input to start with */ + BlockMoveData(ref, newRef, sizeof(FSRef)); + + /* get destDirectory's vRefNum */ + result = FSGetCatalogInfo(destDirectory, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL); + require_noerr(result, DestinationBad); + + /* save vRefNum */ + vRefNum = catalogInfo.volume; + + /* get ref's vRefNum, TextEncoding, name and parent directory*/ + result = FSGetCatalogInfo(ref, kFSCatInfoTextEncoding + kFSCatInfoVolume, &catalogInfo, &originalName, NULL, &originalDirectory); + require_noerr(result, SourceBad); + + /* save TextEncoding */ + originalTextEncodingHint = catalogInfo.textEncodingHint; + + /* make sure ref and destDirectory are on same volume */ + require_action(vRefNum == catalogInfo.volume, NotSameVolume, result = diffVolErr); + + /* Skip a few steps if we're not renaming */ + if ( NULL != name ) + { + /* generate a name that is unique in both directories */ + theSeed = 0x4a696d4c; /* a fine unlikely filename */ + + result = GenerateUniqueHFSUniStr(&theSeed, &originalDirectory, destDirectory, &uniqueName); + require_noerr(result, GenerateUniqueHFSUniStrFailed); + + /* Rename the object to uniqueName */ + result = FSRenameUnicode(ref, uniqueName.length, uniqueName.unicode, kTextEncodingUnknown, newRef); + require_noerr(result, FSRenameUnicodeBeforeMoveFailed); + + /* Move object to its new home */ + result = FSMoveObject(newRef, destDirectory, newRef); + require_noerr(result, FSMoveObjectAfterRenameFailed); + + /* Rename the object to new name */ + result = FSRenameUnicode(ref, nameLength, name, textEncodingHint, newRef); + require_noerr(result, FSRenameUnicodeAfterMoveFailed); + } + else + { + /* Move object to its new home */ + result = FSMoveObject(newRef, destDirectory, newRef); + require_noerr(result, FSMoveObjectNoRenameFailed); + } + + return ( result ); + + /*************/ + +/* + * failure handling code when renaming + */ + +FSRenameUnicodeAfterMoveFailed: + + /* Error handling: move object back to original location - ignore errors */ + verify_noerr(FSMoveObject(newRef, &originalDirectory, newRef)); + +FSMoveObjectAfterRenameFailed: + + /* Error handling: rename object back to original name - ignore errors */ + verify_noerr(FSRenameUnicode(newRef, originalName.length, originalName.unicode, originalTextEncodingHint, newRef)); + +FSRenameUnicodeBeforeMoveFailed: +GenerateUniqueHFSUniStrFailed: + +/* + * failure handling code for renaming or not + */ +FSMoveObjectNoRenameFailed: +NotSameVolume: +SourceBad: +DestinationBad: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +/* + The FSDeleteContainerLevel function deletes the contents of a container + directory. All files and subdirectories in the specified container are + deleted. If a locked file or directory is encountered, it is unlocked + and then deleted. If any unexpected errors are encountered, + FSDeleteContainerLevel quits and returns to the caller. + + container --> FSRef to a directory. + theGlobals --> A pointer to a FSDeleteContainerGlobals struct + which contains the variables that do not need to + be allocated each time FSDeleteContainerLevel + recurses. That lets FSDeleteContainerLevel use + less stack space per recursion level. +*/ + +static +void +FSDeleteContainerLevel( + const FSRef *container, + FSDeleteContainerGlobals *theGlobals) +{ + /* level locals */ + FSIterator iterator; + FSRef itemToDelete; + UInt16 nodeFlags; + + /* Open FSIterator for flat access and give delete optimization hint */ + theGlobals->result = FSOpenIterator(container, kFSIterateFlat + kFSIterateDelete, &iterator); + require_noerr(theGlobals->result, FSOpenIterator); + + /* delete the contents of the directory */ + do + { + /* get 1 item to delete */ + theGlobals->result = FSGetCatalogInfoBulk(iterator, 1, &theGlobals->actualObjects, + NULL, kFSCatInfoNodeFlags, &theGlobals->catalogInfo, + &itemToDelete, NULL, NULL); + if ( (noErr == theGlobals->result) && (1 == theGlobals->actualObjects) ) + { + /* save node flags in local in case we have to recurse */ + nodeFlags = theGlobals->catalogInfo.nodeFlags; + + /* is it a file or directory? */ + if ( 0 != (nodeFlags & kFSNodeIsDirectoryMask) ) + { + /* it's a directory -- delete its contents before attempting to delete it */ + FSDeleteContainerLevel(&itemToDelete, theGlobals); + } + /* are we still OK to delete? */ + if ( noErr == theGlobals->result ) + { + /* is item locked? */ + if ( 0 != (nodeFlags & kFSNodeLockedMask) ) + { + /* then attempt to unlock it (ignore result since FSDeleteObject will set it correctly) */ + theGlobals->catalogInfo.nodeFlags = nodeFlags & ~kFSNodeLockedMask; + (void) FSSetCatalogInfo(&itemToDelete, kFSCatInfoNodeFlags, &theGlobals->catalogInfo); + } + /* delete the item */ + theGlobals->result = FSDeleteObject(&itemToDelete); + } + } + } while ( noErr == theGlobals->result ); + + /* we found the end of the items normally, so return noErr */ + if ( errFSNoMoreItems == theGlobals->result ) + { + theGlobals->result = noErr; + } + + /* close the FSIterator (closing an open iterator should never fail) */ + verify_noerr(FSCloseIterator(iterator)); + +FSOpenIterator: + + return; +} + +/*****************************************************************************/ + +OSErr +FSDeleteContainerContents( + const FSRef *container) +{ + FSDeleteContainerGlobals theGlobals; + + /* delete container's contents */ + FSDeleteContainerLevel(container, &theGlobals); + + return ( theGlobals.result ); +} + +/*****************************************************************************/ + +OSErr +FSDeleteContainer( + const FSRef *container) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* get nodeFlags for container */ + result = FSGetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo, NULL, NULL,NULL); + require_noerr(result, FSGetCatalogInfo); + + /* make sure container is a directory */ + require_action(0 != (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), ContainerNotDirectory, result = dirNFErr); + + /* delete container's contents */ + result = FSDeleteContainerContents(container); + require_noerr(result, FSDeleteContainerContents); + + /* is container locked? */ + if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) ) + { + /* then attempt to unlock container (ignore result since FSDeleteObject will set it correctly) */ + catalogInfo.nodeFlags &= ~kFSNodeLockedMask; + (void) FSSetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo); + } + + /* delete the container */ + result = FSDeleteObject(container); + +FSDeleteContainerContents: +ContainerNotDirectory: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +/* + The FSIterateContainerLevel function iterates the contents of a container + directory and calls a IterateContainerFilterProc function once for each + file and directory found. + + theGlobals --> A pointer to a FSIterateContainerGlobals struct + which contains the variables needed globally by + all recusion levels of FSIterateContainerLevel. + That makes FSIterateContainer thread safe since + each call to it uses its own global world. + It also contains the variables that do not need + to be allocated each time FSIterateContainerLevel + recurses. That lets FSIterateContainerLevel use + less stack space per recursion level. +*/ + +static +void +FSIterateContainerLevel( + FSIterateContainerGlobals *theGlobals) +{ + FSIterator iterator; + + /* If maxLevels is zero, we aren't checking levels */ + /* If currentLevel < maxLevels, look at this level */ + if ( (theGlobals->maxLevels == 0) || + (theGlobals->currentLevel < theGlobals->maxLevels) ) + { + /* Open FSIterator for flat access to theGlobals->ref */ + theGlobals->result = FSOpenIterator(&theGlobals->ref, kFSIterateFlat, &iterator); + require_noerr(theGlobals->result, FSOpenIterator); + + ++theGlobals->currentLevel; /* Go to next level */ + + /* Call FSGetCatalogInfoBulk in loop to get all items in the container */ + do + { + theGlobals->result = FSGetCatalogInfoBulk(iterator, 1, &theGlobals->actualObjects, + &theGlobals->containerChanged, theGlobals->whichInfo, &theGlobals->catalogInfo, + &theGlobals->ref, theGlobals->specPtr, theGlobals->namePtr); + if ( (noErr == theGlobals->result || errFSNoMoreItems == theGlobals->result) && + (0 != theGlobals->actualObjects) ) + { + /* Call the IterateFilterProc */ + theGlobals->quitFlag = CallIterateContainerFilterProc(theGlobals->iterateFilter, + theGlobals->containerChanged, theGlobals->currentLevel, + &theGlobals->catalogInfo, &theGlobals->ref, + theGlobals->specPtr, theGlobals->namePtr, theGlobals->yourDataPtr); + /* Is it a directory? */ + if ( 0 != (theGlobals->catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) ) + { + /* Keep going? */ + if ( !theGlobals->quitFlag ) + { + /* Dive again if the IterateFilterProc didn't say "quit" */ + FSIterateContainerLevel(theGlobals); + } + } + } + /* time to fall back a level? */ + } while ( (noErr == theGlobals->result) && (!theGlobals->quitFlag) ); + + /* errFSNoMoreItems is OK - it only means we hit the end of this level */ + /* afpAccessDenied is OK, too - it only means we cannot see inside a directory */ + if ( (errFSNoMoreItems == theGlobals->result) || + (afpAccessDenied == theGlobals->result) ) + { + theGlobals->result = noErr; + } + + --theGlobals->currentLevel; /* Return to previous level as we leave */ + + /* Close the FSIterator (closing an open iterator should never fail) */ + verify_noerr(FSCloseIterator(iterator)); + } + +FSOpenIterator: + + return; +} + +/*****************************************************************************/ + +OSErr +FSIterateContainer( + const FSRef *container, + ItemCount maxLevels, + FSCatalogInfoBitmap whichInfo, + Boolean wantFSSpec, + Boolean wantName, + IterateContainerFilterProcPtr iterateFilter, + void *yourDataPtr) +{ + OSErr result; + FSIterateContainerGlobals theGlobals; + + /* make sure there is an iterateFilter */ + require_action(iterateFilter != NULL, NoIterateFilter, result = paramErr); + + /* + * set up the globals we need to access from the recursive routine + */ + theGlobals.iterateFilter = iterateFilter; + /* we need the node flags no matter what was requested so we can detect files vs. directories */ + theGlobals.whichInfo = whichInfo | kFSCatInfoNodeFlags; + /* start with input container -- the first OpenIterator will ensure it is a directory */ + theGlobals.ref = *container; + if ( wantFSSpec ) + { + theGlobals.specPtr = &theGlobals.spec; + } + else + { + theGlobals.specPtr = NULL; + } + if ( wantName ) + { + theGlobals.namePtr = &theGlobals.name; + } + else + { + theGlobals.namePtr = NULL; + } + theGlobals.yourDataPtr = yourDataPtr; + theGlobals.maxLevels = maxLevels; + theGlobals.currentLevel = 0; + theGlobals.quitFlag = false; + theGlobals.containerChanged = false; + theGlobals.result = noErr; + theGlobals.actualObjects = 0; + + /* here we go into recursion land... */ + FSIterateContainerLevel(&theGlobals); + result = theGlobals.result; + require_noerr(result, FSIterateContainerLevel); + +FSIterateContainerLevel: +NoIterateFilter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetDirectoryItems( + const FSRef *container, + FSRef ***refsHandle, /* pointer to handle of FSRefs */ + ItemCount *numRefs, + Boolean *containerChanged) +{ + /* Grab items 10 at a time. */ + enum { kMaxItemsPerBulkCall = 10 }; + + OSErr result; + OSErr memResult; + FSIterator iterator; + FSRef refs[kMaxItemsPerBulkCall]; + ItemCount actualObjects; + Boolean changed; + + /* check parameters */ + require_action((NULL != refsHandle) && (NULL != numRefs) && (NULL != containerChanged), + BadParameter, result = paramErr); + + *numRefs = 0; + *containerChanged = false; + *refsHandle = (FSRef **)NewHandle(0); + require_action(NULL != *refsHandle, NewHandle, result = memFullErr); + + /* open an FSIterator */ + result = FSOpenIterator(container, kFSIterateFlat, &iterator); + require_noerr(result, FSOpenIterator); + + /* Call FSGetCatalogInfoBulk in loop to get all items in the container */ + do + { + result = FSGetCatalogInfoBulk(iterator, kMaxItemsPerBulkCall, &actualObjects, + &changed, kFSCatInfoNone, NULL, refs, NULL, NULL); + + /* if the container changed, set containerChanged for output, but keep going */ + if ( changed ) + { + *containerChanged = changed; + } + + /* any result other than noErr and errFSNoMoreItems is serious */ + require((noErr == result) || (errFSNoMoreItems == result), FSGetCatalogInfoBulk); + + /* add objects to output array and count */ + if ( 0 != actualObjects ) + { + /* concatenate the FSRefs to the end of the handle */ + PtrAndHand(refs, (Handle)*refsHandle, actualObjects * sizeof(FSRef)); + memResult = MemError(); + require_noerr_action(memResult, MemoryAllocationFailed, result = memResult); + + *numRefs += actualObjects; + } + } while ( noErr == result ); + + verify_noerr(FSCloseIterator(iterator)); /* closing an open iterator should never fail, but... */ + + return ( noErr ); + + /**********************/ + +MemoryAllocationFailed: +FSGetCatalogInfoBulk: + + /* close the iterator */ + verify_noerr(FSCloseIterator(iterator)); + +FSOpenIterator: + /* dispose of handle if already allocated and clear the outputs */ + if ( NULL != *refsHandle ) + { + DisposeHandle((Handle)*refsHandle); + *refsHandle = NULL; + } + *numRefs = 0; + +NewHandle: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +/* + The GenerateUniqueName function generates a HFSUniStr255 name that is + unique in both dir1 and dir2. + + startSeed --> A pointer to a long which is used to generate the + unique name. + <-- It is modified on output to a value which should + be used to generate the next unique name. + dir1 --> The first directory. + dir2 --> The second directory. + uniqueName <-- A pointer to a HFSUniStr255 where the unique name + is to be returned. +*/ + +static +OSErr +GenerateUniqueHFSUniStr( + long *startSeed, + const FSRef *dir1, + const FSRef *dir2, + HFSUniStr255 *uniqueName) +{ + OSErr result; + long i; + FSRefParam pb; + FSRef newRef; + unsigned char hexStr[17] = "0123456789ABCDEF"; + + /* set up the parameter block */ + pb.name = uniqueName->unicode; + pb.nameLength = 8; /* always 8 characters */ + pb.textEncodingHint = kTextEncodingUnknown; + pb.newRef = &newRef; + + /* loop until we get fnfErr with a filename in both directories */ + result = noErr; + while ( fnfErr != result ) + { + /* convert startSeed to 8 character Unicode string */ + uniqueName->length = 8; + for ( i = 0; i < 8; ++i ) + { + uniqueName->unicode[i] = hexStr[((*startSeed >> ((7-i)*4)) & 0xf)]; + } + + /* try in dir1 */ + pb.ref = dir1; + result = PBMakeFSRefUnicodeSync(&pb); + if ( fnfErr == result ) + { + /* try in dir2 */ + pb.ref = dir2; + result = PBMakeFSRefUnicodeSync(&pb); + if ( fnfErr != result ) + { + /* exit if anything other than noErr or fnfErr */ + require_noerr(result, Dir2PBMakeFSRefUnicodeSyncFailed); + } + } + else + { + /* exit if anything other than noErr or fnfErr */ + require_noerr(result, Dir1PBMakeFSRefUnicodeSyncFailed); + } + + /* increment seed for next pass through loop, */ + /* or for next call to GenerateUniqueHFSUniStr */ + ++(*startSeed); + } + + /* we have a unique file name which doesn't exist in dir1 or dir2 */ + result = noErr; + +Dir2PBMakeFSRefUnicodeSyncFailed: +Dir1PBMakeFSRefUnicodeSyncFailed: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSExchangeObjectsCompat( + const FSRef *sourceRef, + const FSRef *destRef, + FSRef *newSourceRef, + FSRef *newDestRef) +{ + enum + { + /* get all settable info except for mod dates, plus the volume refNum and parent directory ID */ + kGetCatInformationMask = (kFSCatInfoSettableInfo | + kFSCatInfoVolume | + kFSCatInfoParentDirID) & + ~(kFSCatInfoContentMod | kFSCatInfoAttrMod), + /* set everything possible except for mod dates */ + kSetCatinformationMask = kFSCatInfoSettableInfo & + ~(kFSCatInfoContentMod | kFSCatInfoAttrMod) + }; + + OSErr result; + GetVolParmsInfoBuffer volParmsInfo; + UInt32 infoSize; + FSCatalogInfo sourceCatalogInfo; /* source file's catalog information */ + FSCatalogInfo destCatalogInfo; /* destination file's catalog information */ + HFSUniStr255 sourceName; /* source file's Unicode name */ + HFSUniStr255 destName; /* destination file's Unicode name */ + FSRef sourceCurrentRef; /* FSRef to current location of source file throughout this function */ + FSRef destCurrentRef; /* FSRef to current location of destination file throughout this function */ + FSRef sourceParentRef; /* FSRef to parent directory of source file */ + FSRef destParentRef; /* FSRef to parent directory of destination file */ + HFSUniStr255 sourceUniqueName; /* unique name given to source file while exchanging it with destination */ + HFSUniStr255 destUniqueName; /* unique name given to destination file while exchanging it with source */ + long theSeed; /* the seed for generating unique names */ + Boolean sameParentDirs; /* true if source and destinatin parent directory is the same */ + + /* check parameters */ + require_action((NULL != newSourceRef) && (NULL != newDestRef), BadParameter, result = paramErr); + + /* output refs and current refs = input refs to start with */ + BlockMoveData(sourceRef, newSourceRef, sizeof(FSRef)); + BlockMoveData(sourceRef, &sourceCurrentRef, sizeof(FSRef)); + + BlockMoveData(destRef, newDestRef, sizeof(FSRef)); + BlockMoveData(destRef, &destCurrentRef, sizeof(FSRef)); + + /* get source volume's vRefNum */ + result = FSGetCatalogInfo(&sourceCurrentRef, kFSCatInfoVolume, &sourceCatalogInfo, NULL, NULL, NULL); + require_noerr(result, DetermineSourceVRefNumFailed); + + /* see if that volume supports FSExchangeObjects */ + result = FSGetVolParms(sourceCatalogInfo.volume, sizeof(GetVolParmsInfoBuffer), + &volParmsInfo, &infoSize); + if ( (noErr == result) && VolSupportsFSExchangeObjects(&volParmsInfo) ) + { + /* yes - use FSExchangeObjects */ + result = FSExchangeObjects(sourceRef, destRef); + } + else + { + /* no - emulate FSExchangeObjects */ + + /* Note: The compatibility case won't work for files with *Btree control blocks. */ + /* Right now the only *Btree files are created by the system. */ + + /* get all catalog information and Unicode names for each file */ + result = FSGetCatalogInfo(&sourceCurrentRef, kGetCatInformationMask, &sourceCatalogInfo, &sourceName, NULL, &sourceParentRef); + require_noerr(result, SourceFSGetCatalogInfoFailed); + + result = FSGetCatalogInfo(&destCurrentRef, kGetCatInformationMask, &destCatalogInfo, &destName, NULL, &destParentRef); + require_noerr(result, DestFSGetCatalogInfoFailed); + + /* make sure source and destination are on same volume */ + require_action(sourceCatalogInfo.volume == destCatalogInfo.volume, NotSameVolume, result = diffVolErr); + + /* make sure both files are *really* files */ + require_action((0 == (sourceCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) && + (0 == (destCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)), NotAFile, result = notAFileErr); + + /* generate 2 names that are unique in both directories */ + theSeed = 0x4a696d4c; /* a fine unlikely filename */ + + result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &sourceUniqueName); + require_noerr(result, GenerateUniqueHFSUniStr1Failed); + + result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &destUniqueName); + require_noerr(result, GenerateUniqueHFSUniStr2Failed); + + /* rename sourceCurrentRef to sourceUniqueName */ + result = FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef); + require_noerr(result, FSRenameUnicode1Failed); + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + + /* rename destCurrentRef to destUniqueName */ + result = FSRenameUnicode(&destCurrentRef, destUniqueName.length, destUniqueName.unicode, kTextEncodingUnknown, newDestRef); + require_noerr(result, FSRenameUnicode2Failed); + BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef)); + + /* are the source and destination parent directories the same? */ + sameParentDirs = ( sourceCatalogInfo.parentDirID == destCatalogInfo.parentDirID ); + if ( !sameParentDirs ) + { + /* move source file to dest parent directory */ + result = FSMoveObject(&sourceCurrentRef, &destParentRef, newSourceRef); + require_noerr(result, FSMoveObject1Failed); + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + + /* move dest file to source parent directory */ + result = FSMoveObject(&destCurrentRef, &sourceParentRef, newDestRef); + require_noerr(result, FSMoveObject2Failed); + BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef)); + } + + /* At this point, the files are in their new locations (if they were moved). */ + /* The source file is named sourceUniqueName and is in the directory referred to */ + /* by destParentRef. The destination file is named destUniqueName and is in the */ + /* directory referred to by sourceParentRef. */ + + /* give source file the dest file's catalog information except for mod dates */ + result = FSSetCatalogInfo(&sourceCurrentRef, kSetCatinformationMask, &destCatalogInfo); + require_noerr(result, FSSetCatalogInfo1Failed); + + /* give dest file the source file's catalog information except for mod dates */ + result = FSSetCatalogInfo(&destCurrentRef, kSetCatinformationMask, &sourceCatalogInfo); + require_noerr(result, FSSetCatalogInfo2Failed); + + /* rename source file with dest file's name */ + result = FSRenameUnicode(&sourceCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newSourceRef); + require_noerr(result, FSRenameUnicode3Failed); + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + + /* rename dest file with source file's name */ + result = FSRenameUnicode(&destCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newDestRef); + require_noerr(result, FSRenameUnicode4Failed); + + /* we're done with no errors, so swap newSourceRef and newDestRef */ + BlockMoveData(newDestRef, newSourceRef, sizeof(FSRef)); + BlockMoveData(&sourceCurrentRef, newDestRef, sizeof(FSRef)); + } + + return ( result ); + + /**********************/ + +/* If there are any failures while emulating FSExchangeObjects, attempt to reverse any steps */ +/* already taken. In any case, newSourceRef and newDestRef will refer to the files in whatever */ +/* state and location they ended up in so that both files can be found by the calling code. */ + +FSRenameUnicode4Failed: + + /* attempt to rename source file to sourceUniqueName */ + if ( noErr == FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef) ) + { + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + } + +FSRenameUnicode3Failed: + + /* attempt to restore dest file's catalog information */ + verify_noerr(FSSetCatalogInfo(&destCurrentRef, kFSCatInfoSettableInfo, &destCatalogInfo)); + +FSSetCatalogInfo2Failed: + + /* attempt to restore source file's catalog information */ + verify_noerr(FSSetCatalogInfo(&sourceCurrentRef, kFSCatInfoSettableInfo, &sourceCatalogInfo)); + +FSSetCatalogInfo1Failed: + + if ( !sameParentDirs ) + { + /* attempt to move dest file back to dest directory */ + if ( noErr == FSMoveObject(&destCurrentRef, &destParentRef, newDestRef) ) + { + BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef)); + } + } + +FSMoveObject2Failed: + + if ( !sameParentDirs ) + { + /* attempt to move source file back to source directory */ + if ( noErr == FSMoveObject(&sourceCurrentRef, &sourceParentRef, newSourceRef) ) + { + BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef)); + } + } + +FSMoveObject1Failed: + + /* attempt to rename dest file to original name */ + verify_noerr(FSRenameUnicode(&destCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newDestRef)); + +FSRenameUnicode2Failed: + + /* attempt to rename source file to original name */ + verify_noerr(FSRenameUnicode(&sourceCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newSourceRef)); + +FSRenameUnicode1Failed: +GenerateUniqueHFSUniStr2Failed: +GenerateUniqueHFSUniStr1Failed: +NotAFile: +NotSameVolume: +DestFSGetCatalogInfoFailed: +SourceFSGetCatalogInfoFailed: +DetermineSourceVRefNumFailed: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- Shared Environment Routines ----- + +/*****************************************************************************/ + +OSErr +FSLockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart) +{ + OSErr result; + ParamBlockRec pb; + + pb.ioParam.ioRefNum = refNum; + pb.ioParam.ioReqCount = rangeLength; + pb.ioParam.ioPosMode = fsFromStart; + pb.ioParam.ioPosOffset = rangeStart; + result = PBLockRangeSync(&pb); + require_noerr(result, PBLockRangeSync); + +PBLockRangeSync: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSUnlockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart) +{ + OSErr result; + ParamBlockRec pb; + + pb.ioParam.ioRefNum = refNum; + pb.ioParam.ioReqCount = rangeLength; + pb.ioParam.ioPosMode = fsFromStart; + pb.ioParam.ioPosOffset = rangeStart; + result = PBUnlockRangeSync(&pb); + require_noerr(result, PBUnlockRangeSync); + +PBUnlockRangeSync: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetDirAccess( + const FSRef *ref, + SInt32 *ownerID, /* can be NULL */ + SInt32 *groupID, /* can be NULL */ + SInt32 *accessRights) /* can be NULL */ +{ + OSErr result; + FSSpec spec; + HParamBlockRec pb; + + /* get FSSpec from FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* get directory access info for FSSpec */ + pb.accessParam.ioNamePtr = (StringPtr)spec.name; + pb.accessParam.ioVRefNum = spec.vRefNum; + pb.fileParam.ioDirID = spec.parID; + result = PBHGetDirAccessSync(&pb); + require_noerr(result, PBHGetDirAccessSync); + + /* return the IDs and access rights */ + if ( NULL != ownerID ) + { + *ownerID = pb.accessParam.ioACOwnerID; + } + if ( NULL != groupID ) + { + *groupID = pb.accessParam.ioACGroupID; + } + if ( NULL != accessRights ) + { + *accessRights = pb.accessParam.ioACAccess; + } + +PBHGetDirAccessSync: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSSetDirAccess( + const FSRef *ref, + SInt32 ownerID, + SInt32 groupID, + SInt32 accessRights) +{ + OSErr result; + FSSpec spec; + HParamBlockRec pb; + + enum + { + /* Just the bits that can be set */ + kSetDirAccessSettableMask = (kioACAccessBlankAccessMask + + kioACAccessEveryoneWriteMask + kioACAccessEveryoneReadMask + kioACAccessEveryoneSearchMask + + kioACAccessGroupWriteMask + kioACAccessGroupReadMask + kioACAccessGroupSearchMask + + kioACAccessOwnerWriteMask + kioACAccessOwnerReadMask + kioACAccessOwnerSearchMask) + }; + + /* get FSSpec from FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* set directory access info for FSSpec */ + pb.accessParam.ioNamePtr = (StringPtr)spec.name; + pb.accessParam.ioVRefNum = spec.vRefNum; + pb.fileParam.ioDirID = spec.parID; + pb.accessParam.ioACOwnerID = ownerID; + pb.accessParam.ioACGroupID = groupID; + pb.accessParam.ioACAccess = accessRights & kSetDirAccessSettableMask; + result = PBHSetDirAccessSync(&pb); + require_noerr(result, PBHSetDirAccessSync); + +PBHSetDirAccessSync: +FSGetCatalogInfo: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVolMountInfoSize( + FSVolumeRefNum volRefNum, + SInt16 *size) +{ + OSErr result; + ParamBlockRec pb; + + /* check parameters */ + require_action(NULL != size, BadParameter, result = paramErr); + + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioVRefNum = volRefNum; + pb.ioParam.ioBuffer = (Ptr)size; + result = PBGetVolMountInfoSize(&pb); + require_noerr(result, PBGetVolMountInfoSize); + +PBGetVolMountInfoSize: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSGetVolMountInfo( + FSVolumeRefNum volRefNum, + void *volMountInfo) +{ + OSErr result; + ParamBlockRec pb; + + /* check parameters */ + require_action(NULL != volMountInfo, BadParameter, result = paramErr); + + pb.ioParam.ioNamePtr = NULL; + pb.ioParam.ioVRefNum = volRefNum; + pb.ioParam.ioBuffer = (Ptr)volMountInfo; + result = PBGetVolMountInfo(&pb); + require_noerr(result, PBGetVolMountInfo); + +PBGetVolMountInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSVolumeMount( + const void *volMountInfo, + FSVolumeRefNum *volRefNum) +{ + OSErr result; + ParamBlockRec pb; + + /* check parameters */ + require_action(NULL != volRefNum, BadParameter, result = paramErr); + + pb.ioParam.ioBuffer = (Ptr)volMountInfo; + result = PBVolumeMount(&pb); + require_noerr(result, PBVolumeMount); + + /* return the volume reference number */ + *volRefNum = pb.ioParam.ioVRefNum; + +PBVolumeMount: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMapID( + FSVolumeRefNum volRefNum, + SInt32 ugID, + SInt16 objType, + Str31 name) +{ + OSErr result; + HParamBlockRec pb; + + /* check parameters */ + require_action(NULL != name, BadParameter, result = paramErr); + + pb.objParam.ioNamePtr = NULL; + pb.objParam.ioVRefNum = volRefNum; + pb.objParam.ioObjType = objType; + pb.objParam.ioObjNamePtr = name; + pb.objParam.ioObjID = ugID; + result = PBHMapIDSync(&pb); + require_noerr(result, PBHMapIDSync); + +PBHMapIDSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMapName( + FSVolumeRefNum volRefNum, + ConstStr255Param name, + SInt16 objType, + SInt32 *ugID) +{ + OSErr result; + HParamBlockRec pb; + + /* check parameters */ + require_action(NULL != ugID, BadParameter, result = paramErr); + + pb.objParam.ioNamePtr = NULL; + pb.objParam.ioVRefNum = volRefNum; + pb.objParam.ioObjType = objType; + pb.objParam.ioObjNamePtr = (StringPtr)name; + result = PBHMapNameSync(&pb); + require_noerr(result, PBHMapNameSync); + + /* return the user or group ID */ + *ugID = pb.objParam.ioObjID; + +PBHMapNameSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSCopyFile( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *copyName, /* can be NULL (no rename during copy) */ + TextEncoding textEncodingHint, + FSRef *newRef) /* can be NULL */ +{ + OSErr result; + FSSpec srcFileSpec; + FSCatalogInfo catalogInfo; + HParamBlockRec pb; + Str31 hfsName; + GetVolParmsInfoBuffer volParmsInfo; + UInt32 infoSize; + + /* get source FSSpec from source FSRef */ + result = FSGetCatalogInfo(srcFileRef, kFSCatInfoNone, NULL, NULL, &srcFileSpec, NULL); + require_noerr(result, FSGetCatalogInfo_srcFileRef); + + /* Make sure the volume supports CopyFile */ + result = FSGetVolParms(srcFileSpec.vRefNum, sizeof(GetVolParmsInfoBuffer), + &volParmsInfo, &infoSize); + require_action((noErr == result) && VolHasCopyFile(&volParmsInfo), + NoCopyFileSupport, result = paramErr); + + /* get destination volume reference number and destination directory ID from destination FSRef */ + result = FSGetCatalogInfo(dstDirectoryRef, kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo_dstDirectoryRef); + + /* tell the server to copy the object */ + pb.copyParam.ioVRefNum = srcFileSpec.vRefNum; + pb.copyParam.ioDirID = srcFileSpec.parID; + pb.copyParam.ioNamePtr = (StringPtr)srcFileSpec.name; + pb.copyParam.ioDstVRefNum = catalogInfo.volume; + pb.copyParam.ioNewDirID = (long)catalogInfo.nodeID; + pb.copyParam.ioNewName = NULL; + if ( NULL != copyName ) + { + result = UnicodeNameGetHFSName(nameLength, copyName, textEncodingHint, false, hfsName); + require_noerr(result, UnicodeNameGetHFSName); + + pb.copyParam.ioCopyName = hfsName; + } + else + { + pb.copyParam.ioCopyName = NULL; + } + result = PBHCopyFileSync(&pb); + require_noerr(result, PBHCopyFileSync); + + if ( NULL != newRef ) + { + verify_noerr(FSMakeFSRef(pb.copyParam.ioDstVRefNum, pb.copyParam.ioNewDirID, + pb.copyParam.ioCopyName, newRef)); + } + +PBHCopyFileSync: +UnicodeNameGetHFSName: +FSGetCatalogInfo_dstDirectoryRef: +NoCopyFileSupport: +FSGetCatalogInfo_srcFileRef: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSMoveRename( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *moveName, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef) /* can be NULL */ +{ + OSErr result; + FSSpec srcFileSpec; + FSCatalogInfo catalogInfo; + HParamBlockRec pb; + Str31 hfsName; + GetVolParmsInfoBuffer volParmsInfo; + UInt32 infoSize; + + /* get source FSSpec from source FSRef */ + result = FSGetCatalogInfo(srcFileRef, kFSCatInfoNone, NULL, NULL, &srcFileSpec, NULL); + require_noerr(result, FSGetCatalogInfo_srcFileRef); + + /* Make sure the volume supports MoveRename */ + result = FSGetVolParms(srcFileSpec.vRefNum, sizeof(GetVolParmsInfoBuffer), + &volParmsInfo, &infoSize); + require_action((noErr == result) && VolHasMoveRename(&volParmsInfo), + NoMoveRenameSupport, result = paramErr); + + /* get destination volume reference number and destination directory ID from destination FSRef */ + result = FSGetCatalogInfo(dstDirectoryRef, kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo_dstDirectoryRef); + + /* make sure the source and destination are on the same volume */ + require_action(srcFileSpec.vRefNum == catalogInfo.volume, NotSameVolume, result = diffVolErr); + + /* tell the server to move and rename the object */ + pb.copyParam.ioVRefNum = srcFileSpec.vRefNum; + pb.copyParam.ioDirID = srcFileSpec.parID; + pb.copyParam.ioNamePtr = (StringPtr)srcFileSpec.name; + pb.copyParam.ioNewDirID = (long)catalogInfo.nodeID; + pb.copyParam.ioNewName = NULL; + if ( NULL != moveName ) + { + result = UnicodeNameGetHFSName(nameLength, moveName, textEncodingHint, false, hfsName); + require_noerr(result, UnicodeNameGetHFSName); + + pb.copyParam.ioCopyName = hfsName; + } + else + { + pb.copyParam.ioCopyName = NULL; + } + result = PBHMoveRenameSync(&pb); + require_noerr(result, PBHMoveRenameSync); + + if ( NULL != newRef ) + { + verify_noerr(FSMakeFSRef(pb.copyParam.ioVRefNum, pb.copyParam.ioNewDirID, + pb.copyParam.ioCopyName, newRef)); + } + +PBHMoveRenameSync: +UnicodeNameGetHFSName: +NotSameVolume: +FSGetCatalogInfo_dstDirectoryRef: +NoMoveRenameSupport: +FSGetCatalogInfo_srcFileRef: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- File ID Routines ----- + +/*****************************************************************************/ + +OSErr +FSResolveFileIDRef( + FSVolumeRefNum volRefNum, + SInt32 fileID, + FSRef *ref) +{ + OSErr result; + FIDParam pb; + Str255 tempStr; + + /* check parameters */ + require_action(NULL != ref, BadParameter, result = paramErr); + + /* resolve the file ID reference */ + tempStr[0] = 0; + pb.ioNamePtr = tempStr; + pb.ioVRefNum = volRefNum; + pb.ioFileID = fileID; + result = PBResolveFileIDRefSync((HParmBlkPtr)&pb); + require_noerr(result, PBResolveFileIDRefSync); + + /* and then make an FSRef to the file */ + result = FSMakeFSRef(volRefNum, pb.ioSrcDirID, tempStr, ref); + require_noerr(result, FSMakeFSRef); + +FSMakeFSRef: +PBResolveFileIDRefSync: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSCreateFileIDRef( + const FSRef *ref, + SInt32 *fileID) +{ + OSErr result; + FSSpec spec; + FIDParam pb; + + /* check parameters */ + require_action(NULL != fileID, BadParameter, result = paramErr); + + /* Get an FSSpec from the FSRef */ + result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* Create (or get) the file ID reference using the FSSpec */ + pb.ioNamePtr = (StringPtr)spec.name; + pb.ioVRefNum = spec.vRefNum; + pb.ioSrcDirID = spec.parID; + result = PBCreateFileIDRefSync((HParmBlkPtr)&pb); + require((noErr == result) || (fidExists == result) || (afpIDExists == result), + PBCreateFileIDRefSync); + + /* return the file ID reference */ + *fileID = pb.ioFileID; + +PBCreateFileIDRefSync: +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +#pragma mark ----- Utility Routines ----- + +/*****************************************************************************/ + +Ptr +GetTempBuffer( + ByteCount buffReqSize, + ByteCount *buffActSize) +{ + enum + { + kSlopMemory = 0x00008000 /* 32K - Amount of free memory to leave when allocating buffers */ + }; + + Ptr tempPtr; + + /* check parameters */ + require_action(NULL != buffActSize, BadParameter, tempPtr = NULL); + + /* Make request a multiple of 4K bytes */ + buffReqSize = buffReqSize & 0xfffff000; + + if ( buffReqSize < 0x00001000 ) + { + /* Request was smaller than 4K bytes - make it 4K */ + buffReqSize = 0x00001000; + } + + /* Attempt to allocate the memory */ + tempPtr = NewPtr(buffReqSize); + + /* If request failed, go to backup plan */ + if ( (tempPtr == NULL) && (buffReqSize > 0x00001000) ) + { + /* + ** Try to get largest 4K byte block available + ** leaving some slop for the toolbox if possible + */ + long freeMemory = (FreeMem() - kSlopMemory) & 0xfffff000; + + buffReqSize = MaxBlock() & 0xfffff000; + + if ( buffReqSize > freeMemory ) + { + buffReqSize = freeMemory; + } + + if ( buffReqSize == 0 ) + { + buffReqSize = 0x00001000; + } + + tempPtr = NewPtr(buffReqSize); + } + + /* Return bytes allocated */ + if ( tempPtr != NULL ) + { + *buffActSize = buffReqSize; + } + else + { + *buffActSize = 0; + } + +BadParameter: + + return ( tempPtr ); +} + +/*****************************************************************************/ + +OSErr +FileRefNumGetFSRef( + short refNum, + FSRef *ref) +{ + return ( FSGetForkCBInfo(refNum, 0, NULL, NULL, NULL, ref, NULL) ); +} + +/*****************************************************************************/ + +OSErr +FSSetDefault( + const FSRef *newDefault, + FSRef *oldDefault) +{ + OSErr result; + FSVolumeRefNum vRefNum; + long dirID; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action((NULL != newDefault) && (NULL != oldDefault), BadParameter, result = paramErr); + + /* Get nodeFlags, vRefNum and dirID (nodeID) of newDefault */ + result = FSGetCatalogInfo(newDefault, + kFSCatInfoNodeFlags + kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* Make sure newDefault is a directory */ + require_action(0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags), NewDefaultNotDirectory, + result = dirNFErr); + + /* Get the current working directory. */ + result = HGetVol(NULL, &vRefNum, &dirID); + require_noerr(result, HGetVol); + + /* Return the oldDefault FSRef */ + result = FSMakeFSRef(vRefNum, dirID, NULL, oldDefault); + require_noerr(result, FSMakeFSRef); + + /* Set the new current working directory */ + result = HSetVol(NULL, catalogInfo.volume, catalogInfo.nodeID); + require_noerr(result, HSetVol); + +HSetVol: +FSMakeFSRef: +HGetVol: +NewDefaultNotDirectory: +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ + +OSErr +FSRestoreDefault( + const FSRef *oldDefault) +{ + OSErr result; + FSCatalogInfo catalogInfo; + + /* check parameters */ + require_action(NULL != oldDefault, BadParameter, result = paramErr); + + /* Get nodeFlags, vRefNum and dirID (nodeID) of oldDefault */ + result = FSGetCatalogInfo(oldDefault, + kFSCatInfoNodeFlags + kFSCatInfoVolume + kFSCatInfoNodeID, + &catalogInfo, NULL, NULL, NULL); + require_noerr(result, FSGetCatalogInfo); + + /* Make sure oldDefault is a directory */ + require_action(0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags), OldDefaultNotDirectory, + result = dirNFErr); + + /* Set the current working directory to oldDefault */ + result = HSetVol(NULL, catalogInfo.volume, catalogInfo.nodeID); + require_noerr(result, HSetVol); + +HSetVol: +OldDefaultNotDirectory: +FSGetCatalogInfo: +BadParameter: + + return ( result ); +} + +/*****************************************************************************/ diff --git a/Source/MoreFilesX.h b/Source/MoreFilesX.h new file mode 100644 index 0000000..856e22c --- /dev/null +++ b/Source/MoreFilesX.h @@ -0,0 +1,1827 @@ +/* + File: MoreFilesX.h + + Contains: A collection of useful high-level File Manager routines + which use the HFS Plus APIs wherever possible. + + Version: MoreFilesX 1.0.1 + + Copyright: © 1992-2002 by Apple Computer, Inc., all rights reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + File Ownership: + + DRI: Apple Macintosh Developer Technical Support + + Other Contact: For bug reports, consult the following page on + the World Wide Web: + http://developer.apple.com/bugreporter/ + + Technology: DTS Sample Code + + Writers: + + (JL) Jim Luther + + Change History (most recent first): + + <3> 4/19/02 JL [2853905] Fixed #if test around header includes. + <2> 4/19/02 JL [2853901] Updated standard disclaimer. + <1> 1/25/02 JL MoreFilesX 1.0 + + Notes: + What do those arrows in the documentation for each routine mean? + + --> The parameter is an input + + <-- The parameter is an output. The pointer to the variable + where the output will be returned (must not be NULL). + + <** The parameter is an optional output. If it is not a + NULL pointer, it points to the variable where the output + will be returned. If it is a NULL pointer, the output will + not be returned and will possibly let the routine and the + File Manager do less work. If you don't need an optional output, + don't ask for it. + **> The parameter is an optional input. If it is not a + NULL pointer, it points to the variable containing the + input data. If it is a NULL pointer, the input is not used + and will possibly let the routine and the File Manager + do less work. +*/ + +#ifndef __MOREFILESX__ +#define __MOREFILESX__ + +#ifndef __CARBON__ + #if defined(__MACH__) + #include + #else + #include + #endif +#endif + +#if PRAGMA_ONCE +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=mac68k +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(push, 2) +#elif PRAGMA_STRUCT_PACK + #pragma pack(2) +#endif + +/*****************************************************************************/ + +#ifndef WIN32 +#pragma mark ----- FinderInfo and ExtendedFinderInfo ----- +#endif + +/* + * FSGetFinderInfo and FSSetFinderInfo use these unions for Finder information. + */ + +union FinderInfo +{ + FileInfo file; + FolderInfo folder; +}; +typedef union FinderInfo FinderInfo; + +union ExtendedFinderInfo +{ + ExtendedFileInfo file; + ExtendedFolderInfo folder; +}; +typedef union ExtendedFinderInfo ExtendedFinderInfo; + +/*****************************************************************************/ + +#pragma mark ----- GetVolParmsInfoBuffer Macros ----- + +/* + * Macros to get information out of GetVolParmsInfoBuffer. + */ + +/* version 1 field getters */ +#define GetVolParmsInfoVersion(volParms) \ + ((volParms)->vMVersion) +#define GetVolParmsInfoAttrib(volParms) \ + ((volParms)->vMAttrib) +#define GetVolParmsInfoLocalHand(volParms) \ + ((volParms)->vMLocalHand) +#define GetVolParmsInfoServerAdr(volParms) \ + ((volParms)->vMServerAdr) + +/* version 2 field getters (assume zero result if version < 2) */ +#define GetVolParmsInfoVolumeGrade(volParms) \ + (((volParms)->vMVersion >= 2) ? (volParms)->vMVolumeGrade : 0) +#define GetVolParmsInfoForeignPrivID(volParms) \ + (((volParms)->vMVersion >= 2) ? (volParms)->vMForeignPrivID : 0) + +/* version 3 field getters (assume zero result if version < 3) */ +#define GetVolParmsInfoExtendedAttributes(volParms) \ + (((volParms)->vMVersion >= 3) ? (volParms)->vMExtendedAttributes : 0) + +/* attribute bits supported by all versions of GetVolParmsInfoBuffer */ +#define VolIsNetworkVolume(volParms) \ + ((volParms)->vMServerAdr != 0) +#define VolHasLimitFCBs(volParms) \ + (((volParms)->vMAttrib & (1L << bLimitFCBs)) != 0) +#define VolHasLocalWList(volParms) \ + (((volParms)->vMAttrib & (1L << bLocalWList)) != 0) +#define VolHasNoMiniFndr(volParms) \ + (((volParms)->vMAttrib & (1L << bNoMiniFndr)) != 0) +#define VolHasNoVNEdit(volParms) \ + (((volParms)->vMAttrib & (1L << bNoVNEdit)) != 0) +#define VolHasNoLclSync(volParms) \ + (((volParms)->vMAttrib & (1L << bNoLclSync)) != 0) +#define VolHasTrshOffLine(volParms) \ + (((volParms)->vMAttrib & (1L << bTrshOffLine)) != 0) +#define VolHasNoSwitchTo(volParms) \ + (((volParms)->vMAttrib & (1L << bNoSwitchTo)) != 0) +#define VolHasNoDeskItems(volParms) \ + (((volParms)->vMAttrib & (1L << bNoDeskItems)) != 0) +#define VolHasNoBootBlks(volParms) \ + (((volParms)->vMAttrib & (1L << bNoBootBlks)) != 0) +#define VolHasAccessCntl(volParms) \ + (((volParms)->vMAttrib & (1L << bAccessCntl)) != 0) +#define VolHasNoSysDir(volParms) \ + (((volParms)->vMAttrib & (1L << bNoSysDir)) != 0) +#define VolHasExtFSVol(volParms) \ + (((volParms)->vMAttrib & (1L << bHasExtFSVol)) != 0) +#define VolHasOpenDeny(volParms) \ + (((volParms)->vMAttrib & (1L << bHasOpenDeny)) != 0) +#define VolHasCopyFile(volParms) \ + (((volParms)->vMAttrib & (1L << bHasCopyFile)) != 0) +#define VolHasMoveRename(volParms) \ + (((volParms)->vMAttrib & (1L << bHasMoveRename)) != 0) +#define VolHasDesktopMgr(volParms) \ + (((volParms)->vMAttrib & (1L << bHasDesktopMgr)) != 0) +#define VolHasShortName(volParms) \ + (((volParms)->vMAttrib & (1L << bHasShortName)) != 0) +#define VolHasFolderLock(volParms) \ + (((volParms)->vMAttrib & (1L << bHasFolderLock)) != 0) +#define VolHasPersonalAccessPrivileges(volParms) \ + (((volParms)->vMAttrib & (1L << bHasPersonalAccessPrivileges)) != 0) +#define VolHasUserGroupList(volParms) \ + (((volParms)->vMAttrib & (1L << bHasUserGroupList)) != 0) +#define VolHasCatSearch(volParms) \ + (((volParms)->vMAttrib & (1L << bHasCatSearch)) != 0) +#define VolHasFileIDs(volParms) \ + (((volParms)->vMAttrib & (1L << bHasFileIDs)) != 0) +#define VolHasBTreeMgr(volParms) \ + (((volParms)->vMAttrib & (1L << bHasBTreeMgr)) != 0) +#define VolHasBlankAccessPrivileges(volParms) \ + (((volParms)->vMAttrib & (1L << bHasBlankAccessPrivileges)) != 0) +#define VolSupportsAsyncRequests(volParms) \ + (((volParms)->vMAttrib & (1L << bSupportsAsyncRequests)) != 0) +#define VolSupportsTrashVolumeCache(volParms) \ + (((volParms)->vMAttrib & (1L << bSupportsTrashVolumeCache)) != 0) + +/* attribute bits supported by version 3 and greater versions of GetVolParmsInfoBuffer */ +#define VolIsEjectable(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bIsEjectable)) != 0) +#define VolSupportsHFSPlusAPIs(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsHFSPlusAPIs)) != 0) +#define VolSupportsFSCatalogSearch(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsFSCatalogSearch)) != 0) +#define VolSupportsFSExchangeObjects(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsFSExchangeObjects)) != 0) +#define VolSupports2TBFiles(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupports2TBFiles)) != 0) +#define VolSupportsLongNames(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsLongNames)) != 0) +#define VolSupportsMultiScriptNames(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsMultiScriptNames)) != 0) +#define VolSupportsNamedForks(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsNamedForks)) != 0) +#define VolSupportsSubtreeIterators(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsSubtreeIterators)) != 0) +#define VolL2PCanMapFileBlocks(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bL2PCanMapFileBlocks)) != 0) +#define VolParentModDateChanges(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bParentModDateChanges)) != 0) +#define VolAncestorModDateChanges(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bAncestorModDateChanges)) != 0) +#define VolSupportsSymbolicLinks(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bSupportsSymbolicLinks)) != 0) +#define VolIsAutoMounted(volParms) \ + ((GetVolParmsInfoExtendedAttributes(volParms) & (1L << bIsAutoMounted)) != 0) + +/*****************************************************************************/ + +#pragma mark ----- userPrivileges Bit Masks and Macros ----- + +/* + * Bit masks and macros to get common information out of userPrivileges byte + * returned by FSGetCatalogInfo. + * + * Note: The userPrivileges byte is the same as the ioACUser byte returned + * by PBGetCatInfo, and is the 1's complement of the user's privileges + * byte returned in ioACAccess by PBHGetDirAccess. That's where the + * ioACUser names came from. + * + * The userPrivileges are user's effective privileges based on the + * user ID and the groups that user belongs to, and the owner, group, + * and everyone privileges for the given directory. + */ + +enum +{ + /* mask for just the access restriction bits */ + kioACUserAccessMask = (kioACUserNoSeeFolderMask + + kioACUserNoSeeFilesMask + + kioACUserNoMakeChangesMask), + /* common access privilege settings */ + kioACUserFull = 0x00, /* no access restiction bits on */ + kioACUserNone = kioACUserAccessMask, /* all access restiction bits on */ + kioACUserDropBox = (kioACUserNoSeeFolderMask + + kioACUserNoSeeFilesMask), /* make changes, but not see files or folders */ + kioACUserBulletinBoard = kioACUserNoMakeChangesMask /* see files and folders, but not make changes */ +}; + + +/* Macros for testing ioACUser bits. */ + +#define UserIsOwner(userPrivileges) \ + (((userPrivileges) & kioACUserNotOwnerMask) == 0) +#define UserHasFullAccess(userPrivileges) \ + (((userPrivileges) & (kioACUserAccessMask)) == kioACUserFull) +#define UserHasDropBoxAccess(userPrivileges) \ + (((userPrivileges) & kioACUserAccessMask) == kioACUserDropBox) +#define UserHasBulletinBoard(userPrivileges) \ + (((userPrivileges) & kioACUserAccessMask) == kioACUserBulletinBoard) +#define UserHasNoAccess(userPrivileges) \ + (((userPrivileges) & kioACUserAccessMask) == kioACUserNone) + +/*****************************************************************************/ + +#pragma mark ----- File Access Routines ----- + +/*****************************************************************************/ + +#pragma mark FSCopyFork + +OSErr +FSCopyFork( + SInt16 srcRefNum, + SInt16 dstRefNum, + void *copyBufferPtr, + ByteCount copyBufferSize); + +/* + The FSCopyFork function copies all data from the source fork to the + destination fork of open file forks and makes sure the destination EOF + is equal to the source EOF. + + srcRefNum --> The source file reference number. + dstRefNum --> The destination file reference number. + copyBufferPtr --> Pointer to buffer to use during copy. The + buffer should be at least 4K-bytes minimum. + The larger the buffer, the faster the copy + (up to a point). + copyBufferSize --> The size of the copy buffer. +*/ + +/*****************************************************************************/ + +#pragma mark ----- Volume Access Routines ----- + +/*****************************************************************************/ + +#pragma mark FSGetVolParms + +OSErr +FSGetVolParms( + FSVolumeRefNum volRefNum, + UInt32 bufferSize, + GetVolParmsInfoBuffer *volParmsInfo, + UInt32 *actualInfoSize); + +/* + The FSGetVolParms function returns information about the characteristics + of a volume. A result of paramErr usually just means the volume doesn't + support GetVolParms and the feature you were going to check + for isn't available. + + volRefNum --> Volume specification. + bufferSize --> Size of buffer pointed to by volParmsInfo. + volParmsInfo <-- A GetVolParmsInfoBuffer record where the volume + attributes information is returned. + actualInfoSize <-- The number of bytes actually returned + in volParmsInfo. + + __________ + + Also see: The GetVolParmsInfoBuffer Macros for checking attribute bits + in this file +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVRefNum + +OSErr +FSGetVRefNum( + const FSRef *ref, + FSVolumeRefNum *vRefNum); + +/* + The FSGetVRefNum function determines the volume reference + number of a volume from a FSRef. + + ref --> The FSRef. + vRefNum <-- The volume reference number. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVInfo + +OSErr +FSGetVInfo( + FSVolumeRefNum volume, + HFSUniStr255 *volumeName, /* can be NULL */ + UInt64 *freeBytes, /* can be NULL */ + UInt64 *totalBytes); /* can be NULL */ + +/* + The FSGetVInfo function returns the name, available space (in bytes), + and total space (in bytes) for the specified volume. + + volume --> The volume reference number. + volumeName <** An optional pointer to a HFSUniStr255. + If not NULL, the volume name will be returned in + the HFSUniStr255. + freeBytes <** An optional pointer to a UInt64. + If not NULL, the number of free bytes on the + volume will be returned in the UInt64. + totalBytes <** An optional pointer to a UInt64. + If not NULL, the total number of bytes on the + volume will be returned in the UInt64. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVolFileSystemID + +OSErr +FSGetVolFileSystemID( + FSVolumeRefNum volume, + UInt16 *fileSystemID, /* can be NULL */ + UInt16 *signature); /* can be NULL */ + +/* + The FSGetVolFileSystemID function returns the file system ID and signature + of a mounted volume. The file system ID identifies the file system + that handles requests to a particular volume. The signature identifies the + volume type of the volume (for example, FSID 0 is Macintosh HFS Plus, HFS + or MFS, where a signature of 0x4244 identifies the volume as HFS). + Here's a partial list of file system ID numbers (only Apple's file systems + are listed): + FSID File System + ----- ----------------------------------------------------- + $0000 Macintosh HFS Plus, HFS or MFS + $0100 ProDOS File System + $0101 PowerTalk Mail Enclosures + $4147 ISO 9660 File Access (through Foreign File Access) + $4242 High Sierra File Access (through Foreign File Access) + $464D QuickTake File System (through Foreign File Access) + $4953 Macintosh PC Exchange (MS-DOS) + $4A48 Audio CD Access (through Foreign File Access) + $4D4B Apple Photo Access (through Foreign File Access) + $6173 AppleShare (later versions of AppleShare only) + + See the Technical Note "FL 35 - Determining Which File System + Is Active" and the "Guide to the File System Manager" for more + information. + + volume --> The volume reference number. + fileSystemID <** An optional pointer to a UInt16. + If not NULL, the volume's file system ID will + be returned in the UInt16. + signature <** An optional pointer to a UInt16. + If not NULL, the volume's signature will + be returned in the UInt16. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetMountedVolumes + +OSErr +FSGetMountedVolumes( + FSRef ***volumeRefsHandle, /* pointer to handle of FSRefs */ + ItemCount *numVolumes); + +/* + The FSGetMountedVolumes function returns the list of volumes currently + mounted in an array of FSRef records. The array of FSRef records is + returned in a Handle, volumeRefsHandle, which is allocated by + FSGetMountedVolumes. The caller is responsible for disposing of + volumeRefsHandle if the FSGetMountedVolumes returns noErr. + + volumeRefsHandle <-- Pointer to an FSRef Handle where the array of + FSRefs is to be returned. + numVolumes <-- The number of volumes returned in the array. +*/ + +/*****************************************************************************/ + +#pragma mark ----- FSRef/FSpec/Path/Name Conversion Routines ----- + +/*****************************************************************************/ + +#pragma mark FSRefMakeFSSpec + +OSErr +FSRefMakeFSSpec( + const FSRef *ref, + FSSpec *spec); + +/* + The FSRefMakeFSSpec function returns an FSSpec for the file or + directory specified by the ref parameter. + + ref --> An FSRef specifying the file or directory. + spec <-- The FSSpec. +*/ + +/*****************************************************************************/ + +#pragma mark FSMakeFSRef + +OSErr +FSMakeFSRef( + FSVolumeRefNum volRefNum, + SInt32 dirID, + ConstStr255Param name, + FSRef *ref); + +/* + The FSMakeFSRef function creates an FSRef from the traditional + volume reference number, directory ID and pathname inputs. It is + functionally equivalent to FSMakeFSSpec followed by FSpMakeFSRef. + + volRefNum --> Volume specification. + dirID --> Directory specification. + name --> The file or directory name, or NULL. + ref <-- The FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark FSMakePath + +OSStatus +FSMakePath( + SInt16 vRefNum, + SInt32 dirID, + ConstStr255Param name, + UInt8 *path, + UInt32 maxPathSize); + +/* + The FSMakePath function creates a pathname from the traditional volume reference + number, directory ID, and pathname inputs. It is functionally equivalent to + FSMakeFSSpec, FSpMakeFSRef, FSRefMakePath. + + volRefNum --> Volume specification. + dirID --> Directory specification. + name --> The file or directory name, or NULL. + path <-- A pointer to a buffer which FSMakePath will + fill with a C string representing the pathname + to the file or directory specified. The format of + the pathname returned can be determined with the + Gestalt selector gestaltFSAttr's + gestaltFSUsesPOSIXPathsForConversion bit. + If the gestaltFSUsesPOSIXPathsForConversion bit is + clear, the pathname is a Mac OS File Manager full + pathname in a C string, and file or directory names + in the pathname may be mangled as returned by + the File Manager. If the + gestaltFSUsesPOSIXPathsForConversion bit is set, + the pathname is a UTF8 encoded POSIX absolute + pathname in a C string. In either case, the + pathname returned can be passed back to + FSPathMakeRef to create an FSRef to the file or + directory, or FSPathMakeFSSpec to craete an FSSpec + to the file or directory. + maxPathSize --> The size of the path buffer in bytes. If the path + buffer is too small for the pathname string, + FSMakePath returns pathTooLongErr or + buffersTooSmall. +*/ + +/*****************************************************************************/ + +#pragma mark FSPathMakeFSSpec + +OSStatus +FSPathMakeFSSpec( + const UInt8 *path, + FSSpec *spec, + Boolean *isDirectory); /* can be NULL */ + +/* + The FSPathMakeFSSpec function converts a pathname to an FSSpec. + + path --> A pointer to a C String that is the pathname. The + format of the pathname you must supply can be + determined with the Gestalt selector gestaltFSAttr's + gestaltFSUsesPOSIXPathsForConversion bit. + If the gestaltFSUsesPOSIXPathsForConversion bit is + clear, the pathname must be a Mac OS File Manager + full pathname in a C string. If the + gestaltFSUsesPOSIXPathsForConversion bit is set, + the pathname must be a UTF8 encoded POSIX absolute + pathname in a C string. + spec <-- The FSSpec. + isDirectory <** An optional pointer to a Boolean. + If not NULL, true will be returned in the Boolean + if the specified path is a directory, or false will + be returned in the Boolean if the specified path is + a file. +*/ + +/*****************************************************************************/ + +#pragma mark UnicodeNameGetHFSName + +OSErr +UnicodeNameGetHFSName( + UniCharCount nameLength, + const UniChar *name, + TextEncoding textEncodingHint, + Boolean isVolumeName, + Str31 hfsName); + +/* + The UnicodeNameGetHFSName function converts a Unicode string + to a Pascal Str31 (or Str27) string using an algorithm similar to that used + by the File Manager. Note that if the name is too long or cannot be converted + using the given text encoding hint, you will get an error instead of the + mangled name that the File Manager would return. + + nameLength --> Number of UniChar in name parameter. + name --> The Unicode string to convert. + textEncodingHint --> The text encoding hint used for the conversion. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + isVolumeName --> If true, the output name will be limited to + 27 characters (kHFSMaxVolumeNameChars). If false, + the output name will be limited to 31 characters + (kHFSMaxFileNameChars). + hfsName <-- The hfsName as a Pascal string. + + __________ + + Also see: HFSNameGetUnicodeName +*/ + +/*****************************************************************************/ + +#pragma mark HFSNameGetUnicodeName + +OSErr +HFSNameGetUnicodeName( + ConstStr31Param hfsName, + TextEncoding textEncodingHint, + HFSUniStr255 *unicodeName); + +/* + The HFSNameGetUnicodeName function converts a Pascal Str31 string to an + Unicode HFSUniStr255 string using the same routines as the File Manager. + + hfsName --> The Pascal string to convert. + textEncodingHint --> The text encoding hint used for the conversion. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + unicodeName <-- The Unicode string. + + __________ + + Also see: UnicodeNameGetHFSName +*/ + +/*****************************************************************************/ + +#pragma mark ----- File/Directory Manipulation Routines ----- + +/*****************************************************************************/ + +#pragma mark FSRefValid + +Boolean FSRefValid(const FSRef *ref); + +/* + The FSRefValid function determines if an FSRef is valid. If the result is + true, then the FSRef refers to an existing file or directory. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetParentRef + +OSErr +FSGetParentRef( + const FSRef *ref, + FSRef *parentRef); + +/* + The FSGetParentRef function gets the parent directory FSRef of the + specified object. + + Note: FSRefs always point to real file system objects. So, there cannot + be a FSRef to the parent of volume root directories. If you call + FSGetParentRef with a ref to the root directory of a volume, the + function result will be noErr and the parentRef will be invalid (using it + for other file system requests will fail). + + ref --> FSRef to a file or directory. + parentRef <-- The parent directory's FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetFileDirName + +OSErr +FSGetFileDirName( + const FSRef *ref, + HFSUniStr255 *outName); + +/* + The FSGetFileDirName function gets the name of the file or directory + specified. + + ref --> FSRef to a file or directory. + outName <-- The file or directory name. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetNodeID + +OSErr +FSGetNodeID( + const FSRef *ref, + long *nodeID, /* can be NULL */ + Boolean *isDirectory); /* can be NULL */ + +/* + The GetNodeIDFromFSRef function gets the node ID number of the + file or directory specified (note: the node ID is the directory ID + for directories). + + ref --> FSRef to a file or directory. + nodeID <** An optional pointer to a long. + If not NULL, the node ID will be returned in + the long. + isDirectory <** An optional pointer to a Boolean. + If not NULL, true will be returned in the Boolean + if the object is a directory, or false will be + returned in the Boolean if object is a file. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetUserPrivilegesPermissions + +OSErr +FSGetUserPrivilegesPermissions( + const FSRef *ref, + UInt8 *userPrivileges, /* can be NULL */ + UInt32 permissions[4]); /* can be NULL */ + +/* + The FSGetUserPrivilegesPermissions function gets the userPrivileges and/or + permissions of the file or directory specified. + + ref --> FSRef to a file or directory. + userPrivileges <** An optional pointer to a UInt8. + If not NULL, the userPrivileges will be returned + in the UInt8. + permissions <** An optional pointer to an UInt32[4] array. + If not NULL, the permissions will be returned + in the UInt32[4] array. +*/ + +/*****************************************************************************/ + +#pragma mark FSCheckLock + +OSErr +FSCheckLock( + const FSRef *ref); + +/* + The FSCheckLock function determines if a file or directory is locked. + If FSCheckLock returns noErr, then the file or directory is not locked + and the volume it is on is not locked either. If FSCheckLock returns + fLckdErr, then the file or directory is locked. If FSCheckLock returns + wPrErr, then the volume is locked by hardware (i.e., locked tab on + removable media). If FSCheckLock returns vLckdErr, then the volume is + locked by software. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetForkSizes + +OSErr +FSGetForkSizes( + const FSRef *ref, + UInt64 *dataLogicalSize, /* can be NULL */ + UInt64 *rsrcLogicalSize); /* can be NULL */ + +/* + The FSGetForkSizes returns the size of the data and/or resource fork for + the specified file. + + ref --> FSRef to a file or directory. + dataLogicalSize <** An optional pointer to a UInt64. + If not NULL, the data fork's size will be + returned in the UInt64. + rsrcLogicalSize <** An optional pointer to a UInt64. + If not NULL, the resource fork's size will be + returned in the UInt64. + + __________ + + Also see: FSGetTotalForkSizes +*/ + +/*****************************************************************************/ + +#pragma mark FSGetTotalForkSizes + +OSErr +FSGetTotalForkSizes( + const FSRef *ref, + UInt64 *totalLogicalSize, /* can be NULL */ + UInt64 *totalPhysicalSize, /* can be NULL */ + ItemCount *forkCount); /* can be NULL */ + +/* + The FSGetTotalForkSizes returns the total logical size and/or the total + physical size of the specified file (i.e., it adds the sizes of all file + forks). It optionally returns the number of file forks. + + ref --> FSRef to a file or directory. + totalLogicalSize <** An optional pointer to a UInt64. + If not NULL, the sum of all fork logical sizes + will be returned in the UInt64. + totalPhysicalSize <** An optional pointer to a UInt64. + If not NULL, the sum of all fork physical sizes + will be returned in the UInt64. + forkCount <** An optional pointer to a ItemCount. + If not NULL, the number of file forks + will be returned in the ItemCount. + + __________ + + Also see: FSGetForkSizes +*/ + +/*****************************************************************************/ + +#pragma mark FSBumpDate + +OSErr +FSBumpDate( + const FSRef *ref); + +/* + The FSBumpDate function changes the content modification date of a file + or directory to the current date/time. If the content modification date + is already equal to the current date/time, then add one second to the + content modification date. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetFinderInfo + +OSErr +FSGetFinderInfo( + const FSRef *ref, + FinderInfo *info, /* can be NULL */ + ExtendedFinderInfo *extendedInfo, /* can be NULL */ + Boolean *isDirectory); /* can be NULL */ + +/* + The FSGetFinderInfo function gets the finder information for a file or + directory. + + ref --> FSRef to a file or directory. + info <** An optional pointer to a FinderInfo. + If not NULL, the FileInfo (if ref is a file) or + the FolderInfo (if ref is a folder) will be + returned in the FinderInfo. + extendedInfo <** An optional pointer to a ExtendedFinderInfo. + If not NULL, the ExtendedFileInfo (if ref is a file) + or the ExtendedFolderInfo (if ref is a folder) will + be returned in the ExtendedFinderInfo. + isDirectory <** An optional pointer to a Boolean. + If not NULL, true will be returned in the Boolean + if the object is a directory, or false will be + returned in the Boolean if object is a file. + + __________ + + Also see: FSSetFinderInfo +*/ + +/*****************************************************************************/ + +#pragma mark FSSetFinderInfo + +OSErr +FSSetFinderInfo( + const FSRef *ref, + const FinderInfo *info, /* can be NULL */ + const ExtendedFinderInfo *extendedInfo); /* can be NULL */ + +/* + The FSSetFinderInfo function sets the finder information for a file or + directory. + + ref --> FSRef to a file or directory. + info **> A pointer to a FinderInfo record with the new + FileInfo (if ref is a file) or new FolderInfo + (if ref is a folder), or NULL if the FinderInfo + is not to be changed. + extendedInfo **> A pointer to a FinderInfo record with the new + ExtendedFileInfo (if ref is a file) or new + ExtendedFolderInfo (if ref is a folder), or NULL + if the ExtendedFinderInfo is not to be changed. + + __________ + + Also see: FSGetFinderInfo +*/ + +/*****************************************************************************/ + +#pragma mark FSChangeCreatorType + +OSErr +FSChangeCreatorType( + const FSRef *ref, + OSType fileCreator, + OSType fileType); + +/* + The FSChangeCreatorType function changes the creator and/or file type of a file. + + ref --> FSRef to a file. + creator --> The new creator type or 0x00000000 to leave + the creator type alone. + fileType --> The new file type or 0x00000000 to leave the + file type alone. +*/ + +/*****************************************************************************/ + +#pragma mark FSChangeFinderFlags + +OSErr +FSChangeFinderFlags( + const FSRef *ref, + Boolean setBits, + UInt16 flagBits); + +/* + The FSChangeFinderFlags function sets or clears flag bits in + the finderFlags field of a file's FileInfo record or a + directory's FolderInfo record. + + ref --> FSRef to a file or directory. + setBits --> If true, then set the bits specified in flagBits. + If false, then clear the bits specified in flagBits. + flagBits --> The flagBits parameter specifies which Finder Flag + bits to set or clear. If a bit in flagBits is set, + then the same bit in fdFlags is either set or + cleared depending on the state of the setBits + parameter. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetInvisible + +OSErr +FSSetInvisible( + const FSRef *ref); + +#pragma mark FSClearInvisible + +OSErr +FSClearInvisible( + const FSRef *ref); + +/* + The FSSetInvisible and FSClearInvisible functions set or clear the + kIsInvisible bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetNameLocked + +OSErr +FSSetNameLocked( + const FSRef *ref); + +#pragma mark FSClearNameLocked + +OSErr +FSClearNameLocked( + const FSRef *ref); + +/* + The FSSetNameLocked and FSClearNameLocked functions set or clear the + kNameLocked bit bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetIsStationery + +OSErr +FSSetIsStationery( + const FSRef *ref); + +#pragma mark FSClearIsStationery + +OSErr +FSClearIsStationery( + const FSRef *ref); + +/* + The FSSetIsStationery and FSClearIsStationery functions set or clear the + kIsStationery bit bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetHasCustomIcon + +OSErr +FSSetHasCustomIcon( + const FSRef *ref); + +#pragma mark FSClearHasCustomIcon + +OSErr +FSClearHasCustomIcon( + const FSRef *ref); + +/* + The FSSetHasCustomIcon and FSClearHasCustomIcon functions set or clear the + kHasCustomIcon bit bit in the finderFlags field of the specified file or + directory's finder information. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSClearHasBeenInited + +OSErr +FSClearHasBeenInited( + const FSRef *ref); + +/* + The FSClearHasBeenInited function clears the kHasBeenInited bit in the + finderFlags field of the specified file or directory's finder information. + + Note: There is no FSSetHasBeenInited function because ONLY the Finder + should set the kHasBeenInited bit. + + ref --> FSRef to a file or directory. +*/ + +/*****************************************************************************/ + +#pragma mark FSCopyFileMgrAttributes + +OSErr +FSCopyFileMgrAttributes( + const FSRef *sourceRef, + const FSRef *destinationRef, + Boolean copyLockBit); + +/* + The CopyFileMgrAttributes function copies all File Manager attributes + from the source file or directory to the destination file or directory. + If copyLockBit is true, then set the locked state of the destination + to match the source. + + sourceRef --> FSRef to a file or directory. + destinationRef --> FSRef to a file or directory. + copyLockBit --> If true, set the locked state of the destination + to match the source. +*/ + +/*****************************************************************************/ + +#pragma mark FSMoveRenameObjectUnicode + +OSErr +FSMoveRenameObjectUnicode( + const FSRef *ref, + const FSRef *destDirectory, + UniCharCount nameLength, + const UniChar *name, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef); /* if function fails along the way, newRef is final location of file */ + +/* + The FSMoveRenameObjectUnicode function moves a file or directory and + optionally renames it. The source and destination locations must be on + the same volume. + + Note: If the input ref parameter is invalid, this call will fail and + newRef, like ref, will be invalid. + + ref --> FSRef to a file or directory. + destDirectory --> FSRef to the destination directory. + nameLength --> Number of UniChar in name parameter. + name --> An Unicode string with the new name for the + moved object, or NULL if no rename is wanted. + textEncodingHint --> The text encoding hint used for the rename. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + newRef <-- The new FSRef of the object moved. Note that if + this function fails at any step along the way, + newRef is still then final location of the object. +*/ + +/*****************************************************************************/ + +#pragma mark FSDeleteContainerContents + +OSErr +FSDeleteContainerContents( + const FSRef *container); + +/* + The FSDeleteContainerContents function deletes the contents of a container + directory. All files and subdirectories in the specified container are + deleted. If a locked file or directory is encountered, it is unlocked and + then deleted. If any unexpected errors are encountered, + FSDeleteContainerContents quits and returns to the caller. + + container --> FSRef to a directory. + + __________ + + Also see: FSDeleteContainer +*/ + +/*****************************************************************************/ + +#pragma mark FSDeleteContainer + +OSErr +FSDeleteContainer( + const FSRef *container); + +/* + The FSDeleteContainer function deletes a container directory and its contents. + All files and subdirectories in the specified container are deleted. + If a locked file or directory is encountered, it is unlocked and then + deleted. After deleting the container's contents, the container is + deleted. If any unexpected errors are encountered, FSDeleteContainer + quits and returns to the caller. + + container --> FSRef to a directory. + + __________ + + Also see: FSDeleteContainerContents +*/ + +/*****************************************************************************/ + +#pragma mark IterateContainerFilterProcPtr + +typedef CALLBACK_API( Boolean , IterateContainerFilterProcPtr ) ( + Boolean containerChanged, + ItemCount currentLevel, + const FSCatalogInfo *catalogInfo, + const FSRef *ref, + const FSSpec *spec, + const HFSUniStr255 *name, + void *yourDataPtr); + +/* + This is the prototype for the IterateContainerFilterProc function which + is called once for each file and directory found by FSIterateContainer. + The IterateContainerFilterProc can use the read-only data it receives for + whatever it wants. + + The result of the IterateContainerFilterProc function indicates if + iteration should be stopped. To stop iteration, return true; to continue + iteration, return false. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within the IterateContainerFilterProc. + + containerChanged --> Set to true if the container's contents changed + during iteration. + currentLevel --> The current recursion level into the container. + 1 = the container, 2 = the container's immediate + subdirectories, etc. + catalogInfo --> The catalog information for the current object. + Only the fields requested by the whichInfo + parameter passed to FSIterateContainer are valid. + ref --> The FSRef to the current object. + spec --> The FSSpec to the current object if the wantFSSpec + parameter passed to FSIterateContainer is true. + name --> The name of the current object if the wantName + parameter passed to FSIterateContainer is true. + yourDataPtr --> An optional pointer to whatever data structure you + might want to access from within the + IterateFilterProc. + result <-- To stop iteration, return true; to continue + iteration, return false. + + __________ + + Also see: FSIterateContainer +*/ + +/*****************************************************************************/ + +#pragma mark CallIterateContainerFilterProc + +#define CallIterateContainerFilterProc(userRoutine, containerChanged, currentLevel, catalogInfo, ref, spec, name, yourDataPtr) \ + (*(userRoutine))((containerChanged), (currentLevel), (catalogInfo), (ref), (spec), (name), (yourDataPtr)) + +/*****************************************************************************/ + +#pragma mark FSIterateContainer + +OSErr +FSIterateContainer( + const FSRef *container, + ItemCount maxLevels, + FSCatalogInfoBitmap whichInfo, + Boolean wantFSSpec, + Boolean wantName, + IterateContainerFilterProcPtr iterateFilter, + void *yourDataPtr); + +/* + The FSIterateContainer function performs a recursive iteration (scan) of the + specified container directory and calls your IterateContainerFilterProc + function once for each file and directory found. + + The maxLevels parameter lets you control how deep the recursion goes. + If maxLevels is 1, FSIterateContainer only scans the specified directory; + if maxLevels is 2, FSIterateContainer scans the specified directory and + one subdirectory below the specified directory; etc. Set maxLevels to + zero to scan all levels. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within your IterateContainerFilterProc. + + container --> The FSRef to the container directory to iterate. + maxLevels --> Maximum number of directory levels to scan or + zero to scan all directory levels. + whichInfo --> The fields of the FSCatalogInfo you wish to get. + wantFSSpec --> Set to true if you want the FSSpec to each + object passed to your IterateContainerFilterProc. + wantName --> Set to true if you want the name of each + object passed to your IterateContainerFilterProc. + iterateFilter --> A pointer to the IterateContainerFilterProc you + want called once for each file and directory found + by FSIterateContainer. + yourDataPtr --> An optional pointer to whatever data structure you + might want to access from within the + IterateFilterProc. +*/ + +/*****************************************************************************/ + +#pragma mark FSGetDirectoryItems + +OSErr +FSGetDirectoryItems( + const FSRef *container, + FSRef ***refsHandle, /* pointer to handle of FSRefs */ + ItemCount *numRefs, + Boolean *containerChanged); + +/* + The FSGetDirectoryItems function returns the list of items in the specified + container. The array of FSRef records is returned in a Handle, refsHandle, + which is allocated by FSGetDirectoryItems. The caller is responsible for + disposing of refsHandle if the FSGetDirectoryItems returns noErr. + + container --> FSRef to a directory. + refsHandle <-- Pointer to an FSRef Handle where the array of + FSRefs is to be returned. + numRefs <-- The number of FSRefs returned in the array. + containerChanged <-- Set to true if the container changes while the + list of items is being obtained. +*/ + +/*****************************************************************************/ + +#pragma mark FSExchangeObjectsCompat + +OSErr +FSExchangeObjectsCompat( + const FSRef *sourceRef, + const FSRef *destRef, + FSRef *newSourceRef, + FSRef *newDestRef); + +/* + The FSExchangeObjectsCompat function exchanges the data between two files. + + The FSExchangeObjectsCompat function is an enhanced version of + FSExchangeObjects function. The two enhancements FSExchangeObjectsCompat + provides are: + + 1, FSExchangeObjectsCompat will work on volumes which do not support + FSExchangeObjects. FSExchangeObjectsCompat does this by emulating + FSExchangeObjects through a series of File Manager operations. If + there is a failure at any step along the way, FSExchangeObjectsCompat + attempts to undo any steps already taken to leave the files in their + original state in their original locations. + + 2. FSExchangeObjectsCompat returns new FSRefs to the source and + destination files. Note that if this function fails at any step along + the way, newSourceRef and newDestRef still give you access to the final + locations of the files being exchanged -- even if they are renamed or + not in their original locations. + + sourceRef --> FSRef to the source file. + destRef --> FSRef to the destination file. + newSourceRef <-- The new FSRef to the source file. + newDestRef <-- The new FSRef to the destination file. +*/ + +/*****************************************************************************/ + +#pragma mark ----- Shared Environment Routines ----- + +/*****************************************************************************/ + +#pragma mark FSLockRange + +OSErr +FSLockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart); + +/* + The LockRange function locks (denies access to) a portion of a file + that was opened with shared read/write permission. + + refNum --> The file reference number of an open file. + rangeLength --> The number of bytes in the range. + rangeStart --> The starting byte in the range to lock. + + __________ + + Also see: UnlockRange +*/ + +/*****************************************************************************/ + +#pragma mark FSUnlockRange + +OSErr +FSUnlockRange( + SInt16 refNum, + SInt32 rangeLength, + SInt32 rangeStart); + +/* + The UnlockRange function unlocks (allows access to) a previously locked + portion of a file that was opened with shared read/write permission. + + refNum --> The file reference number of an open file. + rangeLength --> The number of bytes in the range. + rangeStart --> The starting byte in the range to unlock. + + __________ + + Also see: LockRange +*/ + +/*****************************************************************************/ + +#pragma mark FSGetDirAccess + +OSErr +FSGetDirAccess( + const FSRef *ref, + SInt32 *ownerID, /* can be NULL */ + SInt32 *groupID, /* can be NULL */ + SInt32 *accessRights); /* can be NULL */ + +/* + The FSGetDirAccess function retrieves the directory access control + information for a directory on a shared volume. + + ref --> An FSRef specifying the directory. + ownerID <** An optional pointer to a SInt32. + If not NULL, the directory's owner ID + will be returned in the SInt32. + groupID <** An optional pointer to a SInt32. + If not NULL, the directory's group ID, or 0 + if no group affiliation, will be returned in + the SInt32. + accessRights <** An optional pointer to a SInt32. + If not NULL, the directory's access rights + will be returned in the SInt32. + + __________ + + Also see: FSSetDirAccess, FSMapID, FSMapName +*/ + +/*****************************************************************************/ + +#pragma mark FSSetDirAccess + +OSErr +FSSetDirAccess( + const FSRef *ref, + SInt32 ownerID, + SInt32 groupID, + SInt32 accessRights); + +/* + The FSpSetDirAccess function changes the directory access control + information for a directory on a shared volume. You must be the owner of + a directory to change its access control information. + + ref --> An FSRef specifying the directory. + ownerID --> The directory's owner ID. + groupID --> The directory's group ID or 0 if no group affiliation. + accessRights --> The directory's access rights. + + __________ + + Also see: FSGetDirAccess, FSMapID, FSMapName +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVolMountInfoSize + +OSErr +FSGetVolMountInfoSize( + FSVolumeRefNum volRefNum, + SInt16 *size); + +/* + The FSGetVolMountInfoSize function determines the how much space the + program needs to allocate for a volume mounting information record. + + volRefNum --> Volume specification. + size <-- The space needed (in bytes) of the volume + mounting information record. + + __________ + + Also see: FSGetVolMountInfo, VolumeMount +*/ + +/*****************************************************************************/ + +#pragma mark FSGetVolMountInfo + +OSErr +FSGetVolMountInfo( + FSVolumeRefNum volRefNum, + void *volMountInfo); + +/* + The FSGetVolMountInfo function retrieves a volume mounting information + record containing all the information needed to mount the volume, + except for passwords. + + volRefNum --> Volume specification. + volMountInfo <-- The volume mounting information. + + __________ + + Also see: FSGetVolMountInfoSize, VolumeMount +*/ + +/*****************************************************************************/ + +#pragma mark FSVolumeMount + +OSErr +FSVolumeMount( + const void *volMountInfo, + FSVolumeRefNum *volRefNum); + +/* + The VolumeMount function mounts a volume using a volume mounting + information record. + + volMountInfo --> A volume mounting information record. + volRefNum <-- The volume reference number. + + __________ + + Also see: FSGetVolMountInfoSize, FSGetVolMountInfo +*/ + +/*****************************************************************************/ + +#pragma mark FSMapID + +OSErr +FSMapID( + FSVolumeRefNum volRefNum, + SInt32 ugID, + SInt16 objType, + Str31 name); + +/* + The FSMapID function determines the name of a user or group if you know + the user or group ID. + + volRefNum --> Volume specification. + objType --> The mapping function code: + kOwnerID2Name to map a user ID to a user name + kGroupID2Name to map a group ID to a group name + name <** An optional pointer to a buffer (minimum Str31). + If not NULL, the user or group name + will be returned in the buffer. + + __________ + + Also see: FSGetDirAccess, FSSetDirAccess, FSMapName +*/ + +/*****************************************************************************/ + +#pragma mark FSMapName + +OSErr +FSMapName( + FSVolumeRefNum volRefNum, + ConstStr255Param name, + SInt16 objType, + SInt32 *ugID); + +/* + The FSMapName function determines the user or group ID if you know the + user or group name. + + volRefNum --> Volume specification. + name --> The user or group name. + objType --> The mapping function code: + kOwnerName2ID to map a user name to a user ID + kGroupName2ID to map a user name to a group ID + ugID <-- The user or group ID. + + __________ + + Also see: FSGetDirAccess, FSSetDirAccess, FSMapID +*/ + +/*****************************************************************************/ + +#pragma mark FSCopyFile + +OSErr +FSCopyFile( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *copyName, /* can be NULL (no rename during copy) */ + TextEncoding textEncodingHint, + FSRef *newRef); /* can be NULL */ + +/* + The FSCopyFile function duplicates a file and optionally renames it. + The source and destination volumes must be on the same file server. + This function instructs the server to copy the file. + + srcFileRef --> An FSRef specifying the source file. + dstDirectoryRef --> An FSRef specifying the destination directory. + nameLength --> Number of UniChar in copyName parameter (ignored + if copyName is NULL). + copyName --> Points to the new file name if the file is to be + renamed, or NULL if the file isn't to be renamed. + textEncodingHint --> The text encoding hint used for the rename. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + newRef <** An optional pointer to a FSRef. + If not NULL, the FSRef of the duplicated file + will be returned in the FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark FSMoveRename + +OSErr +FSMoveRename( + const FSRef *srcFileRef, + const FSRef *dstDirectoryRef, + UniCharCount nameLength, + const UniChar *moveName, /* can be NULL (no rename during move) */ + TextEncoding textEncodingHint, + FSRef *newRef); /* can be NULL */ + +/* + The FSMoveRename function moves a file or directory (object), and + optionally renames it. The source and destination locations must be on + the same shared volume. + + srcFileRef --> An FSRef specifying the source file. + dstDirectoryRef --> An FSRef specifying the destination directory. + nameLength --> Number of UniChar in moveName parameter (ignored + if copyName is NULL) + moveName --> Points to the new object name if the object is to be + renamed, or NULL if the object isn't to be renamed. + textEncodingHint --> The text encoding hint used for the rename. + You can pass kTextEncodingUnknown to use the + "default" textEncodingHint. + newRef <** An optional pointer to a FSRef. + If not NULL, the FSRef of the moved object + will be returned in the FSRef. +*/ + +/*****************************************************************************/ + +#pragma mark ----- File ID Routines ----- + +/*****************************************************************************/ + +#pragma mark FSResolveFileIDRef + +OSErr +FSResolveFileIDRef( + FSVolumeRefNum volRefNum, + SInt32 fileID, + FSRef *ref); + +/* + The FSResolveFileIDRef function returns an FSRef for the file with the + specified file ID reference. + + volRefNum --> Volume specification. + fileID --> The file ID reference. + ref <-- The FSRef for the file ID reference. + + __________ + + Also see: FSCreateFileIDRef, FSDeleteFileIDRef +*/ + +/*****************************************************************************/ + +#pragma mark FSCreateFileIDRef + +OSErr +FSCreateFileIDRef( + const FSRef *ref, + SInt32 *fileID); + +/* + The FSCreateFileIDRef function creates a file ID reference for the + specified file, or if a file ID reference already exists, supplies + the file ID reference and returns the result code fidExists or afpIDExists. + + ref --> The FSRef for the file. + fileID <-- The file ID reference (if result is noErr, + fidExists, or afpIDExists). + + __________ + + Also see: GetFSRefFromFileIDRef, FSDeleteFileIDRef +*/ + +/*****************************************************************************/ + +#pragma mark FSDeleteFileIDRef + +/* + Why is there no FSDeleteFileIDRef routine? There are two reasons: + + 1. Since Mac OS 8.1, PBDeleteFileIDRef hasn't deleted file ID references. + On HFS volumes, deleting a file ID reference breaks aliases (which + use file ID references to track files as they are moved around on a + volume) and file ID references are automatically deleted when the file + they refer to is deleted. On HFS Plus volumes, file ID references are + always created when a file is created, deleted when the file is deleted, + and cannot be deleted at any other time. + + 2. PBDeleteFileIDRef causes a memory access fault under Mac OS X 10.0 + through 10.1.x. While this will be fixed in a future release, the + implementation, like the Mac OS 8/9 implementation, does not delete + file ID references. + + __________ + + Also see: GetFSRefFromFileIDRef, FSCreateFileIDRef +*/ + +/*****************************************************************************/ + +#pragma mark ----- Utility Routines ----- + +/*****************************************************************************/ + +#pragma mark GetTempBuffer + +Ptr +GetTempBuffer( + ByteCount buffReqSize, + ByteCount *buffActSize); + +/* + The GetTempBuffer function allocates a temporary buffer for file system + operations which is at least 4K bytes and a multiple of 4K bytes. + + buffReqSize --> Size you'd like the buffer to be. + buffActSize <-- The size of the buffer allocated. + function result <-- Pointer to memory allocated, or NULL if no memory + was available. The caller is responsible for + disposing of this buffer with DisposePtr. +*/ + +/*****************************************************************************/ + +#pragma mark FileRefNumGetFSRef + +OSErr +FileRefNumGetFSRef( + short refNum, + FSRef *ref); + +/* + The FileRefNumGetFSRef function gets the FSRef of an open file. + + refNum --> The file reference number of an open file. + ref <-- The FSRef to the open file. +*/ + +/*****************************************************************************/ + +#pragma mark FSSetDefault + +OSErr +FSSetDefault( + const FSRef *newDefault, + FSRef *oldDefault); + +/* + The FSSetDefault function sets the current working directory to the + directory specified by newDefault. The previous current working directory + is returned in oldDefault and must be used to restore the current working + directory to its previous state with the FSRestoreDefault function. + These two functions are designed to be used as a wrapper around + Standard I/O routines where the location of the file is implied to be the + current working directory. This is how you should use these functions: + + result = FSSetDefault(&newDefault, &oldDefault); + if ( noErr == result ) + { + // call the Stdio functions like remove, rename, + // fopen, freopen, etc here! + + result = FSRestoreDefault(&oldDefault); + } + + newDefault --> An FSRef that specifies the new current working + directory. + oldDefault <-- The previous current working directory's FSRef. + + __________ + + Also see: FSRestoreDefault +*/ + +/*****************************************************************************/ + +#pragma mark FSRestoreDefault + +OSErr +FSRestoreDefault( + const FSRef *oldDefault); + +/* + The FSRestoreDefault function restores the current working directory + to the directory specified by oldDefault. The oldDefault parameter was + previously obtained from the FSSetDefault function. + These two functions are designed to be used as a wrapper around + Standard I/O routines where the location of the file is implied to be the + current working directory. This is how you should use these functions: + + result = FSSetDefault(&newDefault, &oldDefault); + if ( noErr == result ) + { + // call the Stdio functions like remove, rename, + // fopen, freopen, etc here! + + result = FSRestoreDefault(&oldDefault); + } + + oldDefault --> The FSRef of the location to restore. + + __________ + + Also see: FSSetDefault +*/ + +/*****************************************************************************/ + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=reset +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(pop) +#elif PRAGMA_STRUCT_PACK + #pragma pack() +#endif + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __MOREFILESX__ */ + diff --git a/Source/Objects.cpp b/Source/Objects.cpp new file mode 100644 index 0000000..67feaac --- /dev/null +++ b/Source/Objects.cpp @@ -0,0 +1,777 @@ +#include "Objects.h" +extern XYZ viewer; +extern float viewdistance; +extern float lightambient[3],lightbrightness[3]; +extern float fadestart; +extern int environment; +extern float texscale; +extern Light light; +extern float multiplier; +extern float gravity; +extern FRUSTUM frustum; +extern Terrain terrain; +extern float terraindetail; +extern bool foliage; +extern int detail; +extern float blurness; +extern float windvar; +extern float playerdist; +extern bool skyboxtexture; +extern Sprites sprites; + +//Functions + +bool Objects::checkcollide(XYZ startpoint,XYZ endpoint,int which){ + static XYZ colpoint,colviewer,coltarget; + static int i; + + startpoint.y+=.1; + endpoint.y+=.1; + startpoint.y-=.1; + endpoint.y-=.1; + + for(i=0;ix/(terrain.size/subdivision*terrain.scale*terraindetail); + whichpatchz=p1->z/(terrain.size/subdivision*terrain.scale*terraindetail); + + if(whichpatchx>=0&&whichpatchz>=0&&whichpatchx0&&terrain.patchobjectnum[whichpatchx][whichpatchz]<500) + for(j=0;j