summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Audio.cpp616
-rw-r--r--Audio.h101
-rw-r--r--Audio_DLL.cpp175
-rw-r--r--C2_Ice.MAK895
-rw-r--r--C2_Ice.dsp282
-rw-r--r--C2_Ice.dsw29
-rw-r--r--C2_Ice.optbin0 -> 49664 bytes
-rw-r--r--C2_Ice.plg64
-rw-r--r--Characters.cpp3690
-rw-r--r--Game.cpp1731
-rw-r--r--Hunt.h1114
-rw-r--r--Hunt2.cpp1718
-rw-r--r--IceAge.ealbin0 -> 1948 bytes
-rw-r--r--Interface.cpp193
-rw-r--r--Loading.cpp159
-rw-r--r--Render3DFX.cpp4051
-rw-r--r--RenderSoft.cpp2537
-rw-r--r--Resources.cpp1988
-rw-r--r--a.bat1
-rw-r--r--action.icobin0 -> 2238 bytes
-rw-r--r--mathematics.cpp956
-rw-r--r--renderasm.cpp4445
-rw-r--r--renderd3d.cpp5333
-rw-r--r--resource.h18
-rw-r--r--resource.rc72
-rw-r--r--trophy00.savbin0 -> 1660 bytes
-rw-r--r--trophy01.savbin0 -> 1656 bytes
-rw-r--r--v_3dfx.renbin0 -> 411136 bytes
-rw-r--r--v_d3d.renbin0 -> 380928 bytes
-rw-r--r--v_soft.renbin0 -> 407040 bytes
30 files changed, 30168 insertions, 0 deletions
diff --git a/Audio.cpp b/Audio.cpp
new file mode 100644
index 0000000..15e3d70
--- /dev/null
+++ b/Audio.cpp
@@ -0,0 +1,616 @@
+#include <windows.h>
+#include <math.h>
+
+#define _AUDIO_
+#include "audio.h"
+
+HANDLE hAudioThread;
+DWORD AudioTId;
+WAVEFORMATEX wf;
+HWND hwndApp;
+BOOL AudioNeedRestore;
+char logtt[128];
+void PrintLog(LPSTR l);
+
+int InitDirectSound( HWND );
+BOOL CALLBACK EnumerateSoundDevice(GUID FAR *, LPSTR, LPSTR, LPVOID );
+
+void Audio_MixSound(int DestAddr, int SrcAddr, int MixLen, int LVolume, int RVolume);
+void Audio_MixChannels();
+void Audio_MixAmbient();
+void Audio_MixAmbient3d();
+
+
+DWORD WINAPI ProcessAudioThread (LPVOID ptr)
+{
+ for (;;) {
+ if (iSoundActive)
+ ProcessAudio();
+ Sleep(70);
+ }
+ return 0;
+}
+
+
+
+void Init_SetCooperative()
+{
+
+}
+
+
+int InitDirectSound( HWND hwnd)
+{
+ PrintLog("\n");
+ PrintLog("==Init Direct Sound==\n");
+
+ HRESULT hres;
+ iTotalSoundDevices = 0;
+
+ lpSoundBuffer = (char*) _SoundBufferData;
+ if( !lpSoundBuffer )
+ return 0;
+ PrintLog("Back Sound Buffer created.\n");
+
+ for( int i = 0; i < MAX_SOUND_DEVICE; i++ )
+ sdd[i].DSC.dwSize = sizeof( DSCAPS );
+
+
+ hres = DirectSoundEnumerate( (LPDSENUMCALLBACK)EnumerateSoundDevice, NULL);
+ if( hres != DS_OK ) {
+ wsprintf(logtt, "DirectSoundEnumerate Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("DirectSoundEnumerate: Ok\n");
+
+
+ iTotal16SD = 0;
+ for( i = 0; i < iTotalSoundDevices; i++ ) {
+ LPDIRECTSOUND lpds;
+ if( DirectSoundCreate( &sdd[i].Guid, &lpds, NULL ) != DS_OK ) continue;
+
+ if( lpds->GetCaps( &sdd[i].DSC ) != DS_OK ) continue;
+
+ if( sdd[i].DSC.dwFlags & (DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO | DSCAPS_SECONDARY16BIT | DSCAPS_SECONDARYSTEREO ) ) {
+ sdd[i].status = 1;
+ iTotal16SD++;
+ wsprintf(logtt,"Acceptable device: %d\n",i);
+ PrintLog(logtt);
+ }
+ }
+
+ if (!iTotal16SD) return 0;
+ iCurrentDriver = 0;
+ while( !sdd[iCurrentDriver].status )
+ iCurrentDriver++;
+
+ wsprintf(logtt,"Device selected : %d\n",iCurrentDriver);
+ PrintLog(logtt);
+
+
+ hres = DirectSoundCreate( &sdd[iCurrentDriver].Guid, &lpDS, NULL );
+ if( (hres != DS_OK) || (!lpDS) ) {
+ wsprintf(logtt, "DirectSoundCreate Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("DirectSoundCreate: Ok\n");
+
+
+ PrimaryMode = TRUE;
+ PrintLog("Attempting to set WRITEPRIMARY CooperativeLevel:\n");
+ hres = lpDS->SetCooperativeLevel( hwnd, DSSCL_WRITEPRIMARY );
+ if (hres != DS_OK) {
+ wsprintf(logtt, "SetCooperativeLevel Error: %Xh\n", hres);
+ PrintLog(logtt);
+ PrimaryMode = FALSE;
+ } else
+ PrintLog("Set Cooperative : Ok\n");
+
+
+ if (!PrimaryMode) {
+ PrintLog("Attempting to set EXCLUSIVE CooperativeLevel:\n");
+ hres = lpDS->SetCooperativeLevel( hwnd, DSSCL_EXCLUSIVE);
+ if (hres != DS_OK) {
+ wsprintf(logtt, "==>>SetCooperativeLevel Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("Set Cooperative : Ok\n");
+ }
+
+
+/*======= creating primary buffer ==============*/
+ CopyMemory( &WaveFormat, &wf, sizeof( WAVEFORMATEX ) );
+
+ DSBUFFERDESC dsbd;
+ dsbd.dwSize = sizeof( DSBUFFERDESC );
+ dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
+ dsbd.dwBufferBytes = 0;
+ dsbd.lpwfxFormat = NULL;
+ dsbd.dwReserved = 0;
+
+ hres = lpDS->CreateSoundBuffer( &dsbd, &lpdsPrimary, NULL );
+ if( hres != DS_OK ) {
+ wsprintf(logtt, "==>>CreatePrimarySoundBuffer Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("CreateSoundBuffer: Ok (Primary)\n");
+ lpdsWork = lpdsPrimary;
+
+ hres = lpdsPrimary->SetFormat( &wf );
+ if( hres != DS_OK ) {
+ wsprintf(logtt, "SetFormat Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("SetFormat : Ok\n");
+
+
+
+
+
+ if (PrimaryMode) goto SKIPSECONDARY;
+
+// ========= creating secondary ================//
+ dsbd.dwSize = sizeof( DSBUFFERDESC );
+ dsbd.dwFlags = 0;
+ dsbd.dwBufferBytes = 2*8192;
+ dsbd.lpwfxFormat = &wf;
+ dsbd.dwReserved = 0;
+
+ hres = lpDS->CreateSoundBuffer( &dsbd, &lpdsSecondary, NULL );
+ if( hres != DS_OK ) {
+ wsprintf(logtt, "CreateSecondarySoundBuffer Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("CreateSoundBuffer: Ok (Secondary)\n");
+ lpdsWork = lpdsSecondary;
+
+
+SKIPSECONDARY:
+
+
+ DSBCAPS dsbc;
+ dsbc.dwSize = sizeof( DSBCAPS );
+ lpdsWork->GetCaps( &dsbc );
+ iBufferLength = dsbc.dwBufferBytes;
+ iBufferLength /= 8192;
+
+ hres = lpdsWork->Play( 0, 0, DSBPLAY_LOOPING );
+ if( hres != DS_OK ) {
+ wsprintf(logtt, "Play Error: %Xh\n", hres);
+ PrintLog(logtt);
+ return 0;
+ }
+ PrintLog("Play : Ok\n");
+
+
+
+
+ iSoundActive = 1;
+ FillMemory( channel, sizeof( CHANNEL )*MAX_CHANNEL, 0 );
+ ambient.iLength = 0;
+
+ hAudioThread = CreateThread(NULL, 0, ProcessAudioThread, NULL, 0, &AudioTId);
+ SetThreadPriority(hAudioThread, THREAD_PRIORITY_HIGHEST);
+
+ PrintLog("Direct Sound activated.\n");
+ return 1;
+}
+
+
+void InitAudioSystem(HWND hw)
+{
+ hwndApp = hw;
+ wf.wFormatTag = WAVE_FORMAT_PCM;
+ wf.nChannels = 2;
+ wf.nSamplesPerSec = 11025*2;
+ wf.nAvgBytesPerSec = 44100*2;
+ wf.nBlockAlign = 4;
+ wf.wBitsPerSample = 16;
+ wf.cbSize = 0;
+ if( !InitDirectSound( hwndApp ) )
+ PrintLog("Sound System failed\n");
+}
+
+
+void AudioStop()
+{
+ FillMemory(&ambient, sizeof(ambient), 0);
+ FillMemory(&mambient, sizeof(mambient), 0);
+ FillMemory(&ambient2, sizeof(ambient2), 0);
+ FillMemory(channel, sizeof( CHANNEL )*MAX_CHANNEL, 0 );
+ AudioNeedRestore = TRUE;
+}
+
+
+void AudioSetCameraPos(float cx, float cy, float cz, float ca, float cb)
+{
+ xCamera = (int) cx;
+ yCamera = (int) cy;
+ zCamera = (int) cz;
+ alphaCamera = ca;
+ cosa = (float)cos(ca);
+ sina = (float)sin(ca);
+}
+
+
+void SetAmbient(int length, short int* lpdata, int av)
+{
+ if (!iSoundActive) return;
+
+ if (ambient.lpData == lpdata) return;
+
+ ambient2 = ambient;
+
+ ambient.iLength = length;
+ ambient.lpData = lpdata;
+ ambient.iPosition = 0;
+ ambient.volume = 0;
+ ambient.avolume = av;
+}
+
+
+void SetAmbient3d(int length, short int* lpdata, float cx, float cy, float cz)
+{
+ if (!iSoundActive) return;
+
+ if (mambient.iPosition >= length) mambient.iPosition = 0;
+
+ mambient.iLength = length;
+ mambient.lpData = lpdata;
+ mambient.x = cx;
+ mambient.y = cy;
+ mambient.z = cz;
+}
+
+
+
+void AddVoice3dv(int length, short int* lpdata, float cx, float cy, float cz, int vol)
+{
+ if (!iSoundActive) return;
+ if (lpdata == 0) return;
+
+ for( int i = 0; i < MAX_CHANNEL; i++ )
+ if( !channel[i].status ) {
+ channel[i].iLength = length;
+ channel[i].lpData = lpdata;
+ channel[i].iPosition = 0;
+
+ channel[i].x = (int)cx;
+ channel[i].y = (int)cy;
+ channel[i].z = (int)cz;
+
+ channel[i].status = 1;
+ channel[i].volume = vol;
+
+ return;
+ }
+ return;
+}
+
+
+void AddVoice3d(int length, short int* lpdata, float cx, float cy, float cz)
+{
+ AddVoice3dv(length, lpdata, cx, cy, cz, 256);
+}
+
+
+void AddVoicev(int length, short int* lpdata, int v)
+{
+ AddVoice3dv(length, lpdata, 0, 0, 0, v);
+}
+
+
+
+void AddVoice(int length, short int* lpdata)
+{
+ AddVoice3dv(length, lpdata, 0,0,0, 256);
+}
+
+
+
+
+BOOL CALLBACK EnumerateSoundDevice( GUID* lpGuid, LPSTR lpstrDescription, LPSTR lpstrModule, LPVOID lpContext)
+{
+ if( lpGuid == NULL )
+ if( !iTotalSoundDevices )
+ return TRUE;
+ else
+ return FALSE;
+ wsprintf(logtt,"Device%d: ",iTotalSoundDevices);
+ PrintLog(logtt);
+ PrintLog(lpstrDescription);
+ PrintLog("/");
+ PrintLog(lpstrModule);
+ PrintLog("\n");
+
+
+ CopyMemory( &sdd[iTotalSoundDevices].Guid, lpGuid, sizeof( GUID ) );
+
+ iTotalSoundDevices++;
+
+ return TRUE;
+}
+
+
+void Audio_Shutdown()
+{
+ if (!iSoundActive) return;
+
+ lpdsWork->Stop();
+ TerminateThread(hAudioThread ,0);
+}
+
+void Audio_Restore()
+{
+ if (!iSoundActive) return;
+
+ lpdsWork->Stop();
+ lpdsWork->Restore();
+ HRESULT hres = lpdsWork->Play( 0, 0, DSBPLAY_LOOPING );
+ if (hres != DS_OK) AudioNeedRestore = TRUE;
+ else AudioNeedRestore = FALSE;
+
+ if (!AudioNeedRestore)
+ PrintLog("Audio restored.\n");
+}
+
+
+int ProcessAudio()
+{
+ LPVOID lpStart1;
+ LPVOID lpStart2;
+ DWORD len1, len2;
+ HRESULT hres;
+ static int PrevBlock = 1;
+
+ if (AudioNeedRestore) Audio_Restore();
+ if (AudioNeedRestore) return 1;
+
+ hres = lpdsWork->GetCurrentPosition( &len1, &dwWritePos );
+ hres = lpdsWork->GetCurrentPosition( &len2, &dwWritePos );
+ if( hres != DS_OK ) { AudioNeedRestore = TRUE; return 0; }
+
+ if ( (len1>len2) || (len1<len2+16) )
+ hres = lpdsWork->GetCurrentPosition( &len2, &dwWritePos );
+
+ if (len1+len2==0) {
+ Sleep(5);
+ lpdsWork->GetCurrentPosition( &len2, &dwWritePos );
+ if (!len2) { AudioNeedRestore = TRUE; return 0; }
+ }
+
+ dwPlayPos = len2;
+
+ int CurBlock = dwPlayPos / (4096*2);
+ if (CurBlock==PrevBlock) return 1;
+
+ if( (int)dwPlayPos < CurBlock*4096*2 + 2) return 1; // it's no time to put info
+
+ FillMemory( lpSoundBuffer, MAX_BUFFER_LENGTH*2, 0 );
+ Audio_MixChannels();
+ Audio_MixAmbient();
+ Audio_MixAmbient3d();
+
+ PrevBlock = CurBlock;
+ int NextBlock = (CurBlock + 1) % iBufferLength;
+ hres = lpdsWork->Lock(NextBlock*4096*2, 4096*2, &lpStart1, &len1, &lpStart2, &len2, 0 );
+ if( hres != DS_OK ) {
+ return 0;
+ }
+
+ CopyMemory( lpStart1, lpSoundBuffer, 4096*2);
+
+ hres = lpdsWork->Unlock( lpStart1, len1, lpStart2, len2 );
+ if( hres != DS_OK )
+ return 0;
+
+ return 1;
+}
+
+
+void CalcLRVolumes(int v0, int x, int y, int z, int &lv, int &rv)
+{
+ if (x==0) {
+ lv = v0*180;
+ rv = v0*180;
+ return; }
+
+ v0*=200;
+ x-=xCamera;
+ y-=yCamera;
+ z-=zCamera;
+ float xx = (float)x * cosa + (float)z * sina;
+ float yy = (float)y;
+ float zz = (float)fabs((float)z * cosa - (float)x * sina);
+
+ float xa = (float)fabs(xx);
+ float l = 0.8f;
+ float r = 0.8f;
+ float d = (float)sqrt( xx*xx + yy*yy + zz*zz) - MIN_RADIUS;
+ float k;
+ if (d<=0) k=1.f;
+ //else k = (MAX_RADIUS - d) / MAX_RADIUS;
+ else k = 1224.f / (1224 + d);
+ if (d>6000) {
+ d-=6000;
+ k = k * (4000 - d) / (4000);
+ }
+ if (k<0) k=0.f;
+
+ float fi = (float)atan2(xa, zz);
+ r = 0.7f + 0.3f * fi / (3.141593f/2.f);
+ l = 0.7f - 0.6f * fi / (3.141593f/2.f);
+
+ if (xx>0) { lv=(int)(v0*l*k); rv=(int)(v0*r*k); }
+ else { lv=(int)(v0*r*k); rv=(int)(v0*l*k); }
+}
+
+
+void Audio_MixChannels()
+{
+ int iMixLen;
+ int srcofs;
+ int LV, RV;
+
+ for( int i = 0; i < MAX_CHANNEL; i++ )
+ if( channel[ i ].status ) {
+ if( channel[ i ].iPosition + 2048*2 >= channel[ i ].iLength )
+ iMixLen = (channel[ i ].iLength - channel[ i ].iPosition)>>1;
+ else
+ iMixLen = 1024*2;
+
+ srcofs = (int) channel[i].lpData + channel[i].iPosition;
+ CalcLRVolumes(channel[i].volume, channel[i].x, channel[i].y, channel[i].z, LV, RV);
+ if (LV || RV)
+ Audio_MixSound((int)lpSoundBuffer, srcofs, iMixLen, LV, RV);
+
+ if (channel[ i ].iPosition + 2048*2 >= channel[ i ].iLength )
+ channel[ i ].status = 0; else channel[ i ].iPosition += 2048*2;
+ }
+}
+
+
+void Audio_DoMixAmbient(AMBIENT &ambient)
+{
+ if (ambient.lpData==0) return;
+ int iMixLen,srcofs;
+ int v = (32000 * ambient.volume * ambient.avolume) / 256 / 256;
+
+ if( ambient.iPosition + 2048*2 >= ambient.iLength )
+ iMixLen = (ambient.iLength - ambient.iPosition)>>1;
+ else iMixLen = 1024*2;
+
+ srcofs = (int) ambient.lpData + ambient.iPosition;
+ Audio_MixSound((int)lpSoundBuffer, srcofs, iMixLen, v, v);
+
+ if (ambient.iPosition + 2048*2 >= ambient.iLength )
+ ambient.iPosition=0; else ambient.iPosition += 2048*2;
+
+ if (iMixLen<1024*2) {
+ Audio_MixSound((int)lpSoundBuffer + iMixLen*4,
+ (int)ambient.lpData, 1024*2-iMixLen, v, v);
+ ambient.iPosition+=(1024*2-iMixLen)*2;
+ }
+}
+
+
+void Audio_MixAmbient()
+{
+ Audio_DoMixAmbient(ambient);
+ if (ambient.volume<256) ambient.volume = min(ambient.volume+16, 256);
+
+ if (ambient2.volume) Audio_DoMixAmbient(ambient2);
+ if (ambient2.volume>0) ambient2.volume = max(ambient2.volume-16, 0);
+}
+
+
+
+
+
+
+
+
+
+void Audio_MixAmbient3d()
+{
+ if (mambient.lpData==0) return;
+ int iMixLen,srcofs;
+ int LV, RV;
+
+ CalcLRVolumes(256, (int)mambient.x, (int)mambient.y, (int)mambient.z, LV, RV);
+ if (!(LV || RV)) return;
+
+
+ if( mambient.iPosition + 2048*2 >= mambient.iLength )
+ iMixLen = (mambient.iLength - mambient.iPosition)>>1;
+ else iMixLen = 1024*2;
+
+ srcofs = (int) mambient.lpData + mambient.iPosition;
+ Audio_MixSound((int)lpSoundBuffer, srcofs, iMixLen, LV, RV);
+
+ if (mambient.iPosition + 2048*2 >= mambient.iLength )
+ mambient.iPosition=0; else mambient.iPosition += 2048*2;
+
+ if (iMixLen<1024*2) {
+ Audio_MixSound((int)lpSoundBuffer + iMixLen*4,
+ (int)mambient.lpData, 1024*2-iMixLen, LV, RV);
+ mambient.iPosition+=(1024*2-iMixLen)*2;
+ }
+}
+
+
+
+
+
+
+void Audio_MixSound(int DestAddr, int SrcAddr, int MixLen, int LVolume, int RVolume)
+{
+_asm {
+ mov edi, DestAddr
+ mov ecx, MixLen
+ mov esi, SrcAddr
+ }
+
+SOUND_CYCLE :
+
+_asm {
+ movsx eax, word ptr [esi]
+ imul LVolume
+ sar eax, 16
+ mov bx, word ptr [edi]
+
+ add ax, bx
+ jo LEFT_CHECK_OVERFLOW
+ mov word ptr [edi], ax
+ jmp CYCLE_RIGHT
+ }
+LEFT_CHECK_OVERFLOW :
+__asm {
+ cmp bx, 0
+ js LEFT_MAX_NEGATIVE
+ mov ax, 32767
+ mov word ptr [edi], ax
+ jmp CYCLE_RIGHT
+}
+LEFT_MAX_NEGATIVE :
+__asm mov word ptr [edi], -32767
+
+
+
+
+CYCLE_RIGHT :
+__asm {
+ movsx eax, word ptr [esi]
+ imul dword ptr RVolume
+ sar eax, 16
+ mov bx, word ptr [edi+2]
+
+ add ax, bx
+ jo RIGHT_CHECK_OVERFLOW
+ mov word ptr [edi+2], ax
+ jmp CYCLE_CONTINUE
+}
+RIGHT_CHECK_OVERFLOW :
+__asm {
+ cmp bx, 0
+ js RIGHT_MAX_NEGATIVE
+ mov word ptr [edi+2], 32767
+ jmp CYCLE_CONTINUE
+}
+RIGHT_MAX_NEGATIVE :
+__asm mov word ptr [edi+2], -32767
+
+CYCLE_CONTINUE :
+__asm {
+ add edi, 4
+ add esi, 2
+ dec ecx
+ jnz SOUND_CYCLE
+}
+} \ No newline at end of file
diff --git a/Audio.h b/Audio.h
new file mode 100644
index 0000000..e6e2f11
--- /dev/null
+++ b/Audio.h
@@ -0,0 +1,101 @@
+#include <dsound.h>
+
+#ifdef _AUDIO_
+ #define _SOUND_H_
+#else
+ #define _SOUND_H_ extern
+#endif
+
+#define MAX_SOUND_DEVICE 16
+#define MAX_VOICE 1024
+#define MAX_CHANNEL 16
+#define MAX_SB_LENGTH 1024 // number of shorts of the buffer
+#define MAX_BUFFER_LENGTH MAX_SB_LENGTH*4 // real lenght of buffer in bytes
+
+#define LEFT_LOW 32
+#define LEFT_MIDDLE 88
+#define LEFT_HIGH 144
+
+#define RIGHT_LOW 144
+#define RIGHT_MIDDLE 200
+#define RIGHT_HIGH 256
+
+#define MAX_RADIUS 6000
+#define MIN_RADIUS 512
+
+
+typedef struct tagSOUNDDEVICEDESC {
+ GUID Guid;
+ char* lpstrDescription;
+ char* lpstrModule;
+ DSCAPS DSC;
+ int status;
+} SOUNDDEVICEDESC;
+
+typedef struct tagCHANNEL {
+ int status; // 0 means that channel is free
+ int iLength; // filled when appropriate voice is assigned to the channel
+ int iPosition; // position of next portion to read
+ short int* lpData;
+ int x, y, z; // coords of the voice
+ int volume; // for aligning
+} CHANNEL;
+
+typedef struct tagAMBIENT {
+ int iLength;
+ short int* lpData; // voice this channel is referenced to
+ int iPosition; // position of next portion to read
+ int volume, avolume;
+} AMBIENT;
+
+typedef struct tagMAMBIENT {
+ int iLength;
+ short int* lpData; // voice this channel is referenced to
+ int iPosition; // position of next portion to read
+ float x,y,z;
+} MAMBIENT;
+
+
+
+
+
+void AddVoice(int, short int*);
+void AddVoicev(int, short int*);
+void AddVoice3d(int, short int*, float, float, float);
+void AddVoice3dv(int, short int*, float, float, float, int);
+
+void SetAmbient(int, short int*, int);
+void SetAmbient3d(int, short int*, float, float, float);
+void SetAmbient3d(int, short int*, float, float, float, int);
+void InitAudioSystem(HWND);
+
+int ProcessAudio( void );
+void AudioSetCameraPosition( float, float, float, float, float);
+void AudioStop();
+
+
+
+_SOUND_H_ SOUNDDEVICEDESC sdd[MAX_SOUND_DEVICE];
+_SOUND_H_ int iTotalSoundDevices;
+_SOUND_H_ int iTotal16SD;
+_SOUND_H_ int iCurrentDriver;
+_SOUND_H_ int iBufferLength;
+_SOUND_H_ int iSoundActive; // prevent playing voices on not ready device
+_SOUND_H_ int iNeedNextWritePosition; // is set to 1 when first voice is added
+_SOUND_H_ DWORD dwPlayPos;
+_SOUND_H_ DWORD dwWritePos;
+
+_SOUND_H_ char _SoundBufferData[1024*16];
+_SOUND_H_ char* lpSoundBuffer;
+
+_SOUND_H_ LPDIRECTSOUND lpDS;
+_SOUND_H_ WAVEFORMATEX WaveFormat;
+_SOUND_H_ LPDIRECTSOUNDBUFFER lpdsPrimary, lpdsSecondary, lpdsWork;
+_SOUND_H_ BOOL PrimaryMode;
+
+_SOUND_H_ CHANNEL channel[ MAX_CHANNEL ];
+_SOUND_H_ AMBIENT ambient, ambient2;
+_SOUND_H_ MAMBIENT mambient;
+
+_SOUND_H_ int xCamera, yCamera, zCamera;
+_SOUND_H_ float alphaCamera, cosa, sina;
diff --git a/Audio_DLL.cpp b/Audio_DLL.cpp
new file mode 100644
index 0000000..311cf52
--- /dev/null
+++ b/Audio_DLL.cpp
@@ -0,0 +1,175 @@
+#include <windows.h>
+#include "hunt.h"
+
+#define req_versionH 0x0001
+#define req_versionL 0x0002
+
+HINSTANCE hAudioDLL = NULL;
+void DoHalt(LPSTR);
+
+typedef void (WINAPI * LPFUNC1)(void);
+typedef void (WINAPI * LPFUNC2)(HWND, HANDLE);
+typedef void (WINAPI * LPFUNC3)(float, float, float, float, float);
+typedef void (WINAPI * LPFUNC4)(int, short int*, int);
+typedef void (WINAPI * LPFUNC5)(int, short int*, float, float, float);
+typedef void (WINAPI * LPFUNC6)(int, short int*, float, float, float, int);
+
+typedef int (WINAPI * LPFUNC7)(void);
+typedef void (WINAPI * LPFUNC8)(int, float);
+
+typedef void (WINAPI * LPFUNC9)(int, AudioQuad *);
+LPFUNC9 audio_uploadgeometry;
+
+LPFUNC1 audio_restore;
+LPFUNC1 audiostop;
+LPFUNC1 audio_shutdown;
+
+LPFUNC2 initaudiosystem;
+LPFUNC3 audiosetcamerapos;
+LPFUNC4 setambient;
+LPFUNC5 setambient3d;
+LPFUNC6 addvoice3dv;
+LPFUNC7 audio_getversion;
+LPFUNC8 audio_setenvironment;
+
+
+void Audio_Shutdown()
+{
+ if (audio_shutdown) audio_shutdown();
+ if (hAudioDLL) FreeLibrary(hAudioDLL);
+ hAudioDLL = NULL;
+ audio_shutdown = NULL;
+}
+
+
+void InitAudioSystem(HWND hw, HANDLE hlog, int driver)
+{
+ Audio_Shutdown();
+
+ switch (driver) {
+ case 0:
+ hAudioDLL = LoadLibrary("a_soft.dll");
+ if (!hAudioDLL) DoHalt("Can't load A_SOFT.DLL");
+ break;
+ case 1:
+ hAudioDLL = LoadLibrary("a_ds3d.dll");
+ if (!hAudioDLL) DoHalt("Can't load A_DS3D.DLL");
+ break;
+ case 2:
+ hAudioDLL = LoadLibrary("a_a3d.dll");
+ if (!hAudioDLL) DoHalt("Can't load A_A3D.DLL");
+ break;
+ case 3:
+ hAudioDLL = LoadLibrary("a_eax.dll");
+ if (!hAudioDLL) DoHalt("Can't load A_EAX.DLL");
+ break;
+ }
+
+
+ initaudiosystem = (LPFUNC2) GetProcAddress(hAudioDLL, "InitAudioSystem");
+ if (!initaudiosystem) DoHalt("Can't find procedure address.");
+
+ audio_restore = (LPFUNC1) GetProcAddress(hAudioDLL, "Audio_Restore");
+ if (!audio_restore) DoHalt("Can't find procedure address.");
+
+ audiostop = (LPFUNC1) GetProcAddress(hAudioDLL, "AudioStop");
+ if (!audiostop) DoHalt("Can't find procedure address.");
+
+ audio_shutdown = (LPFUNC1) GetProcAddress(hAudioDLL, "Audio_Shutdown");
+ if (!audio_shutdown) DoHalt("Can't find procedure address.");
+
+ audiosetcamerapos = (LPFUNC3) GetProcAddress(hAudioDLL, "AudioSetCameraPos");
+ if (!audiosetcamerapos) DoHalt("Can't find procedure address.");
+
+ setambient = (LPFUNC4) GetProcAddress(hAudioDLL, "SetAmbient");
+ if (!setambient) DoHalt("Can't find procedure address.");
+
+ setambient3d = (LPFUNC5) GetProcAddress(hAudioDLL, "SetAmbient3d");
+ if (!setambient3d) DoHalt("Can't find procedure address.");
+
+ addvoice3dv = (LPFUNC6) GetProcAddress(hAudioDLL, "AddVoice3dv");
+ if (!addvoice3dv) DoHalt("Can't find procedure address.");
+
+ audio_getversion = (LPFUNC7) GetProcAddress(hAudioDLL, "Audio_GetVersion");
+ if (!audio_getversion) DoHalt("Can't find procedure address.");
+
+ audio_setenvironment = (LPFUNC8) GetProcAddress(hAudioDLL, "Audio_SetEnvironment");
+ if (!audio_setenvironment) DoHalt("Can't find procedure address.");
+
+ audio_uploadgeometry = (LPFUNC9) GetProcAddress(hAudioDLL, "Audio_UploadGeometry");
+ if (!audio_uploadgeometry) DoHalt("Can't find procedure Audio_UploadGeometry address.");
+
+ int v1 = audio_getversion()>>16;
+ int v2 = audio_getversion() & 0xFFFF;
+ if ( (v1!=req_versionH) || (v2<req_versionL) )
+ DoHalt("Incorrect audio driver version.");
+
+ initaudiosystem(hw, hlog);
+}
+
+void Audio_UploadGeometry()
+{
+ UploadGeometry();
+ audio_uploadgeometry(AudioFCount, data);
+}
+
+void AudioStop()
+{
+ audiostop();
+}
+
+void Audio_Restore()
+{
+ if (audio_restore)
+ audio_restore();
+}
+
+
+
+void AudioSetCameraPos(float cx, float cy, float cz, float ca, float cb)
+{
+ audiosetcamerapos(cx, cy, cz, ca, cb);
+}
+
+
+void Audio_SetEnvironment(int e, float f)
+{
+ audio_setenvironment(e, f);
+}
+
+void SetAmbient(int length, short int* lpdata, int av)
+{
+ setambient(length, lpdata, av);
+}
+
+
+void SetAmbient3d(int length, short int* lpdata, float cx, float cy, float cz)
+{
+ setambient3d(length, lpdata, cx, cy, cz);
+}
+
+
+void AddVoice3dv(int length, short int* lpdata, float cx, float cy, float cz, int vol)
+{
+ addvoice3dv(length, lpdata, cx, cy, cz, vol);
+}
+
+
+
+
+void AddVoice3d(int length, short int* lpdata, float cx, float cy, float cz)
+{
+ AddVoice3dv(length, lpdata, cx, cy, cz, 256);
+}
+
+
+void AddVoicev(int length, short int* lpdata, int v)
+{
+ AddVoice3dv(length, lpdata, 0,0,0, v);
+}
+
+
+void AddVoice(int length, short int* lpdata)
+{
+ AddVoice3dv(length, lpdata, 0,0,0, 256);
+} \ No newline at end of file
diff --git a/C2_Ice.MAK b/C2_Ice.MAK
new file mode 100644
index 0000000..c0b865f
--- /dev/null
+++ b/C2_Ice.MAK
@@ -0,0 +1,895 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on C2.DSP
+!IF "$(CFG)" == ""
+CFG=C2 - Win32 Debug_D3D
+!MESSAGE No configuration specified. Defaulting to C2 - Win32 Debug_D3D.
+!ENDIF
+
+!IF "$(CFG)" != "C2 - Win32 Debug_Soft" && "$(CFG)" != "C2 - Win32 Debug_3DFX"\
+ && "$(CFG)" != "C2 - Win32 Debug_D3D" && "$(CFG)" != "C2 - Win32 Release_Soft"\
+ && "$(CFG)" != "C2 - Win32 Release_3DFX" && "$(CFG)" !=\
+ "C2 - Win32 Release_D3D"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "C2.MAK" CFG="C2 - Win32 Debug_D3D"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "C2 - Win32 Debug_Soft" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Debug_3DFX" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Debug_D3D" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Release_Soft" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Release_3DFX" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Release_D3D" (based on "Win32 (x86) Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft"
+
+OUTDIR=.\DEBUG_S
+INTDIR=.\DEBUG_S
+# Begin Custom Macros
+OutDir=.\DEBUG_S
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\C2.exe"
+
+!ELSE
+
+ALL : "$(OUTDIR)\C2.exe"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\Audio_DLL.obj"
+ -@erase "$(INTDIR)\Characters.obj"
+ -@erase "$(INTDIR)\Game.obj"
+ -@erase "$(INTDIR)\Hunt2.obj"
+ -@erase "$(INTDIR)\Interface.obj"
+ -@erase "$(INTDIR)\mathematics.obj"
+ -@erase "$(INTDIR)\Render3DFX.obj"
+ -@erase "$(INTDIR)\renderd3d.obj"
+ -@erase "$(INTDIR)\RenderSoft.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\Resources.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(INTDIR)\vc50.pdb"
+ -@erase "$(OUTDIR)\C2.exe"
+ -@erase "$(OUTDIR)\C2.ilk"
+ -@erase "$(OUTDIR)\C2.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /D "_soft" /Fp"$(INTDIR)\C2.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\DEBUG_S/
+CPP_SBRS=.
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\C2.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib\
+ user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\
+ uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB\
+ /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\C2.pdb" /debug\
+ /machine:I386 /out:"$(OUTDIR)\C2.exe" /pdbtype:sept
+LINK32_OBJS= \
+ "$(INTDIR)\Audio_DLL.obj" \
+ "$(INTDIR)\Characters.obj" \
+ "$(INTDIR)\Game.obj" \
+ "$(INTDIR)\Hunt2.obj" \
+ "$(INTDIR)\Interface.obj" \
+ "$(INTDIR)\mathematics.obj" \
+ "$(INTDIR)\Render3DFX.obj" \
+ "$(INTDIR)\renderd3d.obj" \
+ "$(INTDIR)\RenderSoft.obj" \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\Resources.obj"
+
+"$(OUTDIR)\C2.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_3DFX"
+
+OUTDIR=.\DEBUG_FX
+INTDIR=.\DEBUG_FX
+# Begin Custom Macros
+OutDir=.\DEBUG_FX
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\C2.exe"
+
+!ELSE
+
+ALL : "$(OUTDIR)\C2.exe"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\Audio_DLL.obj"
+ -@erase "$(INTDIR)\Characters.obj"
+ -@erase "$(INTDIR)\Game.obj"
+ -@erase "$(INTDIR)\Hunt2.obj"
+ -@erase "$(INTDIR)\Interface.obj"
+ -@erase "$(INTDIR)\mathematics.obj"
+ -@erase "$(INTDIR)\Render3DFX.obj"
+ -@erase "$(INTDIR)\renderd3d.obj"
+ -@erase "$(INTDIR)\RenderSoft.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\Resources.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(INTDIR)\vc50.pdb"
+ -@erase "$(OUTDIR)\C2.exe"
+ -@erase "$(OUTDIR)\C2.ilk"
+ -@erase "$(OUTDIR)\C2.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /D "_3dfx" /Fp"$(INTDIR)\C2.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\DEBUG_FX/
+CPP_SBRS=.
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\C2.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib\
+ user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\
+ uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB\
+ /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\C2.pdb" /debug\
+ /machine:I386 /out:"$(OUTDIR)\C2.exe" /pdbtype:sept
+LINK32_OBJS= \
+ "$(INTDIR)\Audio_DLL.obj" \
+ "$(INTDIR)\Characters.obj" \
+ "$(INTDIR)\Game.obj" \
+ "$(INTDIR)\Hunt2.obj" \
+ "$(INTDIR)\Interface.obj" \
+ "$(INTDIR)\mathematics.obj" \
+ "$(INTDIR)\Render3DFX.obj" \
+ "$(INTDIR)\renderd3d.obj" \
+ "$(INTDIR)\RenderSoft.obj" \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\Resources.obj"
+
+"$(OUTDIR)\C2.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_D3D"
+
+OUTDIR=.\DEBUG_3D
+INTDIR=.\DEBUG_3D
+# Begin Custom Macros
+OutDir=.\DEBUG_3D
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\C2.exe"
+
+!ELSE
+
+ALL : "$(OUTDIR)\C2.exe"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\Audio_DLL.obj"
+ -@erase "$(INTDIR)\Characters.obj"
+ -@erase "$(INTDIR)\Game.obj"
+ -@erase "$(INTDIR)\Hunt2.obj"
+ -@erase "$(INTDIR)\Interface.obj"
+ -@erase "$(INTDIR)\mathematics.obj"
+ -@erase "$(INTDIR)\Render3DFX.obj"
+ -@erase "$(INTDIR)\renderd3d.obj"
+ -@erase "$(INTDIR)\RenderSoft.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\Resources.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(INTDIR)\vc50.pdb"
+ -@erase "$(OUTDIR)\C2.exe"
+ -@erase "$(OUTDIR)\C2.ilk"
+ -@erase "$(OUTDIR)\C2.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /D "_d3d" /Fp"$(INTDIR)\C2.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\DEBUG_3D/
+CPP_SBRS=.
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\C2.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib\
+ user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\
+ uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB\
+ /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\C2.pdb" /debug\
+ /machine:I386 /out:"$(OUTDIR)\C2.exe" /pdbtype:sept
+LINK32_OBJS= \
+ "$(INTDIR)\Audio_DLL.obj" \
+ "$(INTDIR)\Characters.obj" \
+ "$(INTDIR)\Game.obj" \
+ "$(INTDIR)\Hunt2.obj" \
+ "$(INTDIR)\Interface.obj" \
+ "$(INTDIR)\mathematics.obj" \
+ "$(INTDIR)\Render3DFX.obj" \
+ "$(INTDIR)\renderd3d.obj" \
+ "$(INTDIR)\RenderSoft.obj" \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\Resources.obj"
+
+"$(OUTDIR)\C2.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_Soft"
+
+OUTDIR=.\REL_SOFT
+INTDIR=.\REL_SOFT
+# Begin Custom Macros
+OutDir=.\REL_SOFT
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\v_soft.ren"
+
+!ELSE
+
+ALL : "$(OUTDIR)\v_soft.ren"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\Audio_DLL.obj"
+ -@erase "$(INTDIR)\Characters.obj"
+ -@erase "$(INTDIR)\Game.obj"
+ -@erase "$(INTDIR)\Hunt2.obj"
+ -@erase "$(INTDIR)\Interface.obj"
+ -@erase "$(INTDIR)\mathematics.obj"
+ -@erase "$(INTDIR)\Render3DFX.obj"
+ -@erase "$(INTDIR)\renderd3d.obj"
+ -@erase "$(INTDIR)\RenderSoft.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\Resources.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(OUTDIR)\v_soft.ilk"
+ -@erase "$(OUTDIR)\v_soft.ren"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G5 /ML /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D\
+ "_WINDOWS" /D "_soft" /Fp"$(INTDIR)\C2.pch" /YX /Fo"$(INTDIR)\\"\
+ /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\REL_SOFT/
+CPP_SBRS=.
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\C2.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib\
+ user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\
+ uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB\
+ /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\v_soft.pdb"\
+ /machine:I386 /out:"$(OUTDIR)\v_soft.ren"
+LINK32_OBJS= \
+ "$(INTDIR)\Audio_DLL.obj" \
+ "$(INTDIR)\Characters.obj" \
+ "$(INTDIR)\Game.obj" \
+ "$(INTDIR)\Hunt2.obj" \
+ "$(INTDIR)\Interface.obj" \
+ "$(INTDIR)\mathematics.obj" \
+ "$(INTDIR)\Render3DFX.obj" \
+ "$(INTDIR)\renderd3d.obj" \
+ "$(INTDIR)\RenderSoft.obj" \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\Resources.obj"
+
+"$(OUTDIR)\v_soft.ren" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_3DFX"
+
+OUTDIR=.\REL_3DFX
+INTDIR=.\REL_3DFX
+# Begin Custom Macros
+OutDir=.\REL_3DFX
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\v_3dfx.ren"
+
+!ELSE
+
+ALL : "$(OUTDIR)\v_3dfx.ren"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\Audio_DLL.obj"
+ -@erase "$(INTDIR)\Characters.obj"
+ -@erase "$(INTDIR)\Game.obj"
+ -@erase "$(INTDIR)\Hunt2.obj"
+ -@erase "$(INTDIR)\Interface.obj"
+ -@erase "$(INTDIR)\mathematics.obj"
+ -@erase "$(INTDIR)\Render3DFX.obj"
+ -@erase "$(INTDIR)\renderd3d.obj"
+ -@erase "$(INTDIR)\RenderSoft.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\Resources.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(OUTDIR)\v_3dfx.ilk"
+ -@erase "$(OUTDIR)\v_3dfx.ren"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G5 /ML /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D\
+ "_WINDOWS" /D "_3dfx" /Fp"$(INTDIR)\C2.pch" /YX /Fo"$(INTDIR)\\"\
+ /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\REL_3DFX/
+CPP_SBRS=.
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\C2.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib\
+ user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\
+ uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB\
+ /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\v_3dfx.pdb"\
+ /machine:I386 /out:"$(OUTDIR)\v_3dfx.ren"
+LINK32_OBJS= \
+ "$(INTDIR)\Audio_DLL.obj" \
+ "$(INTDIR)\Characters.obj" \
+ "$(INTDIR)\Game.obj" \
+ "$(INTDIR)\Hunt2.obj" \
+ "$(INTDIR)\Interface.obj" \
+ "$(INTDIR)\mathematics.obj" \
+ "$(INTDIR)\Render3DFX.obj" \
+ "$(INTDIR)\renderd3d.obj" \
+ "$(INTDIR)\RenderSoft.obj" \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\Resources.obj"
+
+"$(OUTDIR)\v_3dfx.ren" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_D3D"
+
+OUTDIR=.\REL_D3D
+INTDIR=.\REL_D3D
+# Begin Custom Macros
+OutDir=.\REL_D3D
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\v_d3d.ren"
+
+!ELSE
+
+ALL : "$(OUTDIR)\v_d3d.ren"
+
+!ENDIF
+
+CLEAN :
+ -@erase "$(INTDIR)\Audio_DLL.obj"
+ -@erase "$(INTDIR)\Characters.obj"
+ -@erase "$(INTDIR)\Game.obj"
+ -@erase "$(INTDIR)\Hunt2.obj"
+ -@erase "$(INTDIR)\Interface.obj"
+ -@erase "$(INTDIR)\mathematics.obj"
+ -@erase "$(INTDIR)\Render3DFX.obj"
+ -@erase "$(INTDIR)\renderd3d.obj"
+ -@erase "$(INTDIR)\RenderSoft.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\Resources.obj"
+ -@erase "$(INTDIR)\vc50.idb"
+ -@erase "$(OUTDIR)\v_d3d.ilk"
+ -@erase "$(OUTDIR)\v_d3d.ren"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G5 /ML /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D\
+ "_WINDOWS" /D "_d3d" /Fp"$(INTDIR)\C2.pch" /YX /Fo"$(INTDIR)\\"\
+ /Fd"$(INTDIR)\\" /FD /c
+CPP_OBJS=.\REL_D3D/
+CPP_SBRS=.
+
+.c{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_OBJS)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(CPP_SBRS)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\C2.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib\
+ user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\
+ uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB\
+ /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\v_d3d.pdb"\
+ /machine:I386 /out:"$(OUTDIR)\v_d3d.ren"
+LINK32_OBJS= \
+ "$(INTDIR)\Audio_DLL.obj" \
+ "$(INTDIR)\Characters.obj" \
+ "$(INTDIR)\Game.obj" \
+ "$(INTDIR)\Hunt2.obj" \
+ "$(INTDIR)\Interface.obj" \
+ "$(INTDIR)\mathematics.obj" \
+ "$(INTDIR)\Render3DFX.obj" \
+ "$(INTDIR)\renderd3d.obj" \
+ "$(INTDIR)\RenderSoft.obj" \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\Resources.obj"
+
+"$(OUTDIR)\v_d3d.ren" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft" || "$(CFG)" == "C2 - Win32 Debug_3DFX"\
+ || "$(CFG)" == "C2 - Win32 Debug_D3D" || "$(CFG)" == "C2 - Win32 Release_Soft"\
+ || "$(CFG)" == "C2 - Win32 Release_3DFX" || "$(CFG)" ==\
+ "C2 - Win32 Release_D3D"
+SOURCE=.\Audio_DLL.cpp
+
+"$(INTDIR)\Audio_DLL.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\Characters.cpp
+DEP_CPP_CHARA=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Characters.obj" : $(SOURCE) $(DEP_CPP_CHARA) "$(INTDIR)"
+
+
+SOURCE=.\Game.cpp
+DEP_CPP_GAME_=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Game.obj" : $(SOURCE) $(DEP_CPP_GAME_) "$(INTDIR)"
+
+
+SOURCE=.\Hunt2.cpp
+DEP_CPP_HUNT2=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Hunt2.obj" : $(SOURCE) $(DEP_CPP_HUNT2) "$(INTDIR)"
+
+
+SOURCE=.\Interface.cpp
+DEP_CPP_INTER=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Interface.obj" : $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)"
+
+
+SOURCE=.\mathematics.cpp
+DEP_CPP_MATHE=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\mathematics.obj" : $(SOURCE) $(DEP_CPP_MATHE) "$(INTDIR)"
+
+
+SOURCE=.\Render3DFX.cpp
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft"
+
+
+"$(INTDIR)\Render3DFX.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_3DFX"
+
+DEP_CPP_RENDE=\
+ "..\..\vc\include\3dfx.h"\
+ "..\..\vc\include\glide.h"\
+ "..\..\vc\include\glidesys.h"\
+ "..\..\vc\include\glideutl.h"\
+ "..\..\vc\include\sst1vid.h"\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Render3DFX.obj" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_D3D"
+
+
+"$(INTDIR)\Render3DFX.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_Soft"
+
+
+"$(INTDIR)\Render3DFX.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_3DFX"
+
+DEP_CPP_RENDE=\
+ "..\..\vc\include\3dfx.h"\
+ "..\..\vc\include\glide.h"\
+ "..\..\vc\include\glidesys.h"\
+ "..\..\vc\include\glideutl.h"\
+ "..\..\vc\include\sst1vid.h"\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Render3DFX.obj" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_D3D"
+
+
+"$(INTDIR)\Render3DFX.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\renderd3d.cpp
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft"
+
+
+"$(INTDIR)\renderd3d.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_3DFX"
+
+
+"$(INTDIR)\renderd3d.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_D3D"
+
+DEP_CPP_RENDER=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\renderd3d.obj" : $(SOURCE) $(DEP_CPP_RENDER) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_Soft"
+
+
+"$(INTDIR)\renderd3d.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_3DFX"
+
+
+"$(INTDIR)\renderd3d.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_D3D"
+
+DEP_CPP_RENDER=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\renderd3d.obj" : $(SOURCE) $(DEP_CPP_RENDER) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\RenderSoft.cpp
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft"
+
+DEP_CPP_RENDERS=\
+ ".\Hunt.h"\
+ ".\renderasm.cpp"\
+
+
+"$(INTDIR)\RenderSoft.obj" : $(SOURCE) $(DEP_CPP_RENDERS) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_3DFX"
+
+
+"$(INTDIR)\RenderSoft.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_D3D"
+
+
+"$(INTDIR)\RenderSoft.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_Soft"
+
+DEP_CPP_RENDERS=\
+ ".\Hunt.h"\
+ ".\renderasm.cpp"\
+
+
+"$(INTDIR)\RenderSoft.obj" : $(SOURCE) $(DEP_CPP_RENDERS) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_3DFX"
+
+
+"$(INTDIR)\RenderSoft.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_D3D"
+
+
+"$(INTDIR)\RenderSoft.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\resource.rc
+DEP_RSC_RESOU=\
+ ".\action.ico"\
+
+
+"$(INTDIR)\resource.res" : $(SOURCE) $(DEP_RSC_RESOU) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+SOURCE=.\Resources.cpp
+DEP_CPP_RESOUR=\
+ ".\Hunt.h"\
+
+
+"$(INTDIR)\Resources.obj" : $(SOURCE) $(DEP_CPP_RESOUR) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/C2_Ice.dsp b/C2_Ice.dsp
new file mode 100644
index 0000000..35a6fda
--- /dev/null
+++ b/C2_Ice.dsp
@@ -0,0 +1,282 @@
+# Microsoft Developer Studio Project File - Name="C2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=C2 - Win32 Debug_D3D
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "C2_Ice.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "C2_Ice.mak" CFG="C2 - Win32 Debug_D3D"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "C2 - Win32 Debug_Soft" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Debug_3DFX" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Debug_D3D" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Release_Soft" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Release_3DFX" (based on "Win32 (x86) Application")
+!MESSAGE "C2 - Win32 Release_D3D" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=C:\VC98\BIN\VECTORCL.EXE
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "C2___Win"
+# PROP BASE Intermediate_Dir "C2___Win"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DEBUG_S"
+# PROP Intermediate_Dir "DEBUG_S"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_soft" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_3DFX"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "C2___Wi0"
+# PROP BASE Intermediate_Dir "C2___Wi0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DEBUG_FX"
+# PROP Intermediate_Dir "DEBUG_FX"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_3dfx" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_D3D"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "C2___Wi1"
+# PROP BASE Intermediate_Dir "C2___Wi1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DEBUG_3D"
+# PROP Intermediate_Dir "DEBUG_3D"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_d3d" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_Soft"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "C2___Wi2"
+# PROP BASE Intermediate_Dir "C2___Wi2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "REL_SOFT"
+# PROP Intermediate_Dir "REL_SOFT"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G5 /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G5 /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_soft" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /incremental:yes /machine:I386
+# ADD LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /incremental:yes /machine:I386 /out:"REL_SOFT/v_soft.ren"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_3DFX"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "C2___Wi3"
+# PROP BASE Intermediate_Dir "C2___Wi3"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "REL_3DFX"
+# PROP Intermediate_Dir "REL_3DFX"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G5 /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G5 /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_3dfx" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /incremental:yes /machine:I386
+# ADD LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /incremental:yes /machine:I386 /out:"REL_3DFX/v_3dfx.ren"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_D3D"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "C2___Wi4"
+# PROP BASE Intermediate_Dir "C2___Wi4"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "REL_D3D"
+# PROP Intermediate_Dir "REL_D3D"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G5 /W3 /Gi /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G5 /W3 /Gi /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_d3d" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib GLIDE2x.LIB SST1INIT.LIB /nologo /subsystem:windows /incremental:yes /machine:I386
+# ADD LINK32 ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib sincos.obj /nologo /subsystem:windows /incremental:yes /machine:I386 /out:"v_d3d.ren"
+
+!ENDIF
+
+# Begin Target
+
+# Name "C2 - Win32 Debug_Soft"
+# Name "C2 - Win32 Debug_3DFX"
+# Name "C2 - Win32 Debug_D3D"
+# Name "C2 - Win32 Release_Soft"
+# Name "C2 - Win32 Release_3DFX"
+# Name "C2 - Win32 Release_D3D"
+# Begin Source File
+
+SOURCE=.\Action.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\Audio_DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Characters.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Game.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Hunt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Hunt2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Interface.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mathematics.cpp
+
+!IF "$(CFG)" == "C2 - Win32 Debug_Soft"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_3DFX"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Debug_D3D"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_Soft"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_3DFX"
+
+!ELSEIF "$(CFG)" == "C2 - Win32 Release_D3D"
+
+# ADD CPP /YX
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Render3DFX.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\renderd3d.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RenderSoft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resources.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/C2_Ice.dsw b/C2_Ice.dsw
new file mode 100644
index 0000000..de83eff
--- /dev/null
+++ b/C2_Ice.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "C2"=.\C2_Ice.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/C2_Ice.opt b/C2_Ice.opt
new file mode 100644
index 0000000..3c5439c
--- /dev/null
+++ b/C2_Ice.opt
Binary files differ
diff --git a/C2_Ice.plg b/C2_Ice.plg
new file mode 100644
index 0000000..0bb9765
--- /dev/null
+++ b/C2_Ice.plg
@@ -0,0 +1,64 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: C2 - Win32 Release_D3D--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\WINDOWS\TEMP\RSP50D0.TMP" with contents
+[
+/nologo /G5 /ML /W3 /Gi /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_d3d" /Fp"REL_D3D/C2_Ice.pch" /YX /Fo"REL_D3D/" /Fd"REL_D3D/" /FD /c
+"C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp"
+]
+Creating command line "cl.exe @C:\WINDOWS\TEMP\RSP50D0.TMP"
+Creating temporary file "C:\WINDOWS\TEMP\RSP50D1.TMP" with contents
+[
+ole32.lib oleaut32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib winmm.lib ddraw.lib dsound.lib wsock32.lib sincos.obj /nologo /subsystem:windows /incremental:yes /pdb:"REL_D3D/v_d3d.pdb" /machine:I386 /out:"v_d3d.ren"
+.\REL_D3D\Audio_DLL.obj
+.\REL_D3D\Characters.obj
+.\REL_D3D\Game.obj
+.\REL_D3D\Hunt2.obj
+.\REL_D3D\Interface.obj
+.\REL_D3D\mathematics.obj
+.\REL_D3D\Render3DFX.obj
+.\REL_D3D\renderd3d.obj
+.\REL_D3D\RenderSoft.obj
+.\REL_D3D\Resources.obj
+.\REL_D3D\resource.res
+]
+Creating command line "link.exe @C:\WINDOWS\TEMP\RSP50D1.TMP"
+<h3>Output Window</h3>
+Compiling...
+Characters.cpp
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1217) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1218) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1219) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1220) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1664) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1665) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1861) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(1862) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2055) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2056) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2251) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2252) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2447) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2448) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2642) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2643) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2848) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(2849) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(3036) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(3037) : warning C4305: '=' : truncation from 'const double' to 'float'
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(3519) : warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
+C:\MSD50\MyProjects\AudioDrivers\C2_Ice\Characters.cpp(3520) : warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
+Linking...
+
+
+
+<h3>Results</h3>
+v_d3d.ren - 0 error(s), 22 warning(s)
+</pre>
+</body>
+</html>
diff --git a/Characters.cpp b/Characters.cpp
new file mode 100644
index 0000000..766a1c9
--- /dev/null
+++ b/Characters.cpp
@@ -0,0 +1,3690 @@
+#include "Hunt.h"
+#include "stdio.h"
+
+BOOL NewPhase;
+
+#define fx_DIE 0
+
+
+
+
+//======= new ============//
+#define PIG_WALK 0
+#define PIG_RUN 1
+#define PIG_IDLE1 2
+#define PIG_IDLE2 3
+#define PIG_IDLE3 4
+#define PIG_DIE 5
+#define PIG_SLP 6
+
+#define DIM_FLY 0
+#define DIM_FLYP 1
+#define DIM_FALL 2
+#define DIM_DIE 3
+
+#define BRO_WALK 0
+#define BRO_RUN 1
+#define BRO_IDLE1 2
+#define BRO_IDLE2 3
+#define BRO_IDLE3 4
+#define BRO_DIE 5
+#define BRO_SLP 6
+
+#define DIA_WALK 0
+#define DIA_RUN 1
+#define DIA_SWIM 1
+#define DIA_IDLE1 2
+#define DIA_IDLE2 3
+#define DIA_JUMP 4
+#define DIA_SLIDE 5
+#define DIA_EAT 6
+#define DIA_DIE 7
+#define DIA_SLP 8
+
+#define DER_WALK 0
+#define DER_RUN 1
+#define DER_IDLE1 2
+#define DER_IDLE2 3
+#define DER_DIE 4
+#define DER_SLP 5
+
+#define MAM_WALK 0
+#define MAM_RUN 1
+#define MAM_IDLE1 2
+#define MAM_IDLE2 3
+#define MAM_DIE 4
+#define MAM_SLP 5
+
+
+//
+
+int CurDino;
+
+void SetNewTargetPlace(TCharacter *cptr, float R);
+
+
+void ProcessPrevPhase(TCharacter *cptr)
+{
+ cptr->PPMorphTime+=TimeDt;
+ if (cptr->PPMorphTime > PMORPHTIME) cptr->PrevPhase = cptr->Phase;
+
+ cptr->PrevPFTime+=TimeDt;
+ cptr->PrevPFTime %= cptr->pinfo->Animation[cptr->PrevPhase].AniTime;
+}
+
+
+void ActivateCharacterFx(TCharacter *cptr)
+{
+ if (cptr->AI) //== not hunter ==//
+ if (UNDERWATER) return;
+ int fx = cptr->pinfo->Anifx[cptr->Phase];
+ if (fx==-1) return;
+
+ if ( VectorLength(SubVectors(PlayerPos, cptr->pos) ) > 68 * 256) return;
+
+ AddVoice3d(cptr->pinfo->SoundFX[fx].length,
+ cptr->pinfo->SoundFX[fx].lpData,
+ cptr->pos.x,cptr->pos.y,cptr->pos.z);
+}
+
+
+void ResetCharacter(TCharacter *cptr)
+{
+ cptr->AI = DinoInfo[cptr->CType].AI;
+ cptr->pinfo = &ChInfo[cptr->CType];
+ cptr->State = 0;
+ cptr->StateF = 0;
+ cptr->Phase = 0;
+ cptr->FTime = 0;
+ cptr->PrevPhase = 0;
+ cptr->PrevPFTime = 0;
+ cptr->PPMorphTime = 0;
+ cptr->beta = 0;
+ cptr->gamma = 0;
+ cptr->tggamma = 0;
+ cptr->bend = 0;
+ cptr->rspeed = 0;
+ cptr->AfraidTime = 0;
+ cptr->BloodTTime = 0;
+ cptr->BloodTime = 0;
+
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ cptr->Health = DinoInfo[cptr->CType].Health0;
+ if (OptAgres>128) cptr->Health= (cptr->Health*OptAgres)/128;
+
+ cptr->scale = (float)(DinoInfo[cptr->CType].Scale0 + rRand(DinoInfo[cptr->CType].ScaleA)) / 1000.f;
+}
+
+
+void AddDeadBody(TCharacter *cptr, int phase)
+{
+ if (!MyHealth) return;
+
+ if (ExitTime)
+ AddMessage("Transportation cancelled.");
+ ExitTime = 0;
+
+ OPTICMODE = FALSE;
+ BINMODE = FALSE;
+ Characters[ChCount].CType = 0;
+ Characters[ChCount].alpha = CameraAlpha;
+ ResetCharacter(&Characters[ChCount]);
+
+ int v = rRand(3);
+ if (phase != HUNT_BREATH)
+ AddVoicev(fxScream[r].length, fxScream[r].lpData, 256);
+
+ Characters[ChCount].Health = 0;
+ MyHealth = 0;
+ if (cptr) {
+ float pl = 170;
+ //if (cptr->AI==AI_SPINO) pl = 200.f;
+ //if (cptr->AI==AI_CERAT) pl = 320.f;
+ Characters[ChCount].pos.x = cptr->pos.x + cptr->lookx * pl * cptr->scale;
+ Characters[ChCount].pos.z = cptr->pos.z + cptr->lookz * pl * cptr->scale;
+ Characters[ChCount].pos.y = GetLandQH(Characters[ChCount].pos.x, Characters[ChCount].pos.z);
+ } else {
+ Characters[ChCount].pos.x = PlayerX;
+ Characters[ChCount].pos.z = PlayerZ;
+ Characters[ChCount].pos.y = PlayerY;
+ }
+
+ Characters[ChCount].Phase = phase;
+ Characters[ChCount].PrevPhase = phase;
+
+ ActivateCharacterFx(&Characters[ChCount]);
+
+
+ DemoPoint.pos = Characters[ChCount].pos;
+ DemoPoint.DemoTime = 1;
+ DemoPoint.CIndex = ChCount;
+
+ ChCount++;
+}
+
+
+
+float AngleDifference(float a, float b)
+{
+ a-=b;
+ a = (float)fabs(a);
+ if (a > pi) a = 2*pi - a;
+ return a;
+}
+
+float CorrectedAlpha(float a, float b)
+{
+ float d = (float)fabs(a-b);
+ if (d<pi) return (a+b)/2;
+ else d = (a+pi*2-b);
+
+ if (d<0) d+=2*pi;
+ if (d>2*pi) d-=2*pi;
+ return d;
+}
+
+void ThinkY_Beta_Gamma(TCharacter *cptr, float blook, float glook, float blim, float glim)
+{
+ cptr->pos.y = GetLandH(cptr->pos.x, cptr->pos.z);
+
+ //=== beta ===//
+ float hlook = GetLandH(cptr->pos.x + cptr->lookx * blook, cptr->pos.z + cptr->lookz * blook);
+ float hlook2 = GetLandH(cptr->pos.x - cptr->lookx * blook, cptr->pos.z - cptr->lookz * blook);
+ DeltaFunc(cptr->beta, (hlook2 - hlook) / (blook * 3.2f), TimeDt / 800.f);
+
+ if (cptr->beta > blim) cptr->beta = blim;
+ if (cptr->beta <-blim) cptr->beta =-blim;
+
+ //=== gamma ===//
+ hlook = GetLandH(cptr->pos.x + cptr->lookz * glook, cptr->pos.z - cptr->lookx*glook);
+ hlook2 = GetLandH(cptr->pos.x - cptr->lookz * glook, cptr->pos.z + cptr->lookx*glook);
+ cptr->tggamma =(hlook - hlook2) / (glook * 3.2f);
+ if (cptr->tggamma > glim) cptr->tggamma = glim;
+ if (cptr->tggamma <-glim) cptr->tggamma =-glim;
+/*
+ if (DEBUG) cptr->tggamma = 0;
+ if (DEBUG) cptr->beta = 0;
+ */
+}
+
+
+
+
+int CheckPlaceCollisionP(Vector3d &v)
+{
+ int ccx = (int)v.x / 256;
+ int ccz = (int)v.z / 256;
+
+ if (ccx<4 || ccz<4 || ccx>1008 || ccz>1008) return 1;
+
+ int F = (FMap[ccz][ccx-1] | FMap[ccz-1][ccx] | FMap[ccz-1][ccx-1] |
+ FMap[ccz][ccx] |
+ FMap[ccz+1][ccx] | FMap[ccz][ccx+1] | FMap[ccz+1][ccx+1]);
+
+ if (F & (fmWater + fmNOWAY)) return 1;
+
+
+ float h = GetLandH(v.x, v.z);
+ v.y = h;
+
+ float hh = GetLandH(v.x-164, v.z-164); if ( fabs(hh-h) > 160 ) return 1;
+ hh = GetLandH(v.x+164, v.z-164); if ( fabs(hh-h) > 160 ) return 1;
+ hh = GetLandH(v.x-164, v.z+164); if ( fabs(hh-h) > 160 ) return 1;
+ hh = GetLandH(v.x+164, v.z+164); if ( fabs(hh-h) > 160 ) return 1;
+
+ for (int z=-2; z<=2; z++)
+ for (int x=-2; x<=2; x++)
+ if (OMap[ccz+z][ccx+x]!=255) {
+ int ob = OMap[ccz+z][ccx+x];
+ if (MObjects[ob].info.Radius<10) continue;
+ float CR = (float)MObjects[ob].info.Radius + 64;
+
+ float oz = (ccz+z) * 256.f + 128.f;
+ float ox = (ccx+x) * 256.f + 128.f;
+
+ float r = (float) sqrt( (ox-v.x)*(ox-v.x) + (oz-v.z)*(oz-v.z) );
+ if (r<CR) return 1;
+ }
+
+ return 0;
+}
+
+
+
+
+int CheckPlaceCollision(Vector3d &v, BOOL wc, BOOL mc)
+{
+ int ccx = (int)v.x / 256;
+ int ccz = (int)v.z / 256;
+
+ if (ccx<4 || ccz<4 || ccx>1018 || ccz>1018) return 1;
+
+ if (wc)
+ if ( (FMap[ccz][ccx-1] | FMap[ccz-1][ccx] | FMap[ccz-1][ccx-1] |
+ FMap[ccz][ccx] |
+ FMap[ccz+1][ccx] | FMap[ccz][ccx+1] | FMap[ccz+1][ccx+1]) & fmWater)
+ return 1;
+
+
+ float h = GetLandH(v.x, v.z);
+ if (! (FMap[ccz][ccx] & fmWater) )
+ if (fabs(h - v.y) > 64) return 1;
+
+ v.y = h;
+
+ float hh = GetLandH(v.x-64, v.z-64); if ( fabs(hh-h) > 100 ) return 1;
+ hh = GetLandH(v.x+64, v.z-64); if ( fabs(hh-h) > 100 ) return 1;
+ hh = GetLandH(v.x-64, v.z+64); if ( fabs(hh-h) > 100 ) return 1;
+ hh = GetLandH(v.x+64, v.z+64); if ( fabs(hh-h) > 100 ) return 1;
+
+ if (mc)
+ for (int z=-2; z<=2; z++)
+ for (int x=-2; x<=2; x++)
+ if (OMap[ccz+z][ccx+x]!=255) {
+ int ob = OMap[ccz+z][ccx+x];
+ if (MObjects[ob].info.Radius<10) continue;
+ float CR = (float)MObjects[ob].info.Radius + 64;
+
+ float oz = (ccz+z) * 256.f + 128.f;
+ float ox = (ccx+x) * 256.f + 128.f;
+
+ float r = (float) sqrt( (ox-v.x)*(ox-v.x) + (oz-v.z)*(oz-v.z) );
+ if (r<CR) return 1;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+int CheckPlaceCollision2(Vector3d &v, BOOL wc)
+{
+ int ccx = (int)v.x / 256;
+ int ccz = (int)v.z / 256;
+
+ if (ccx<4 || ccz<4 || ccx>1018 || ccz>1018) return 1;
+
+ if (wc)
+ if ( (FMap[ccz][ccx-1] | FMap[ccz-1][ccx] | FMap[ccz-1][ccx-1] |
+ FMap[ccz][ccx] |
+ FMap[ccz+1][ccx] | FMap[ccz][ccx+1] | FMap[ccz+1][ccx+1]) & fmWater)
+ return 1;
+
+ float h = GetLandH(v.x, v.z);
+ /*if (! (FMap[ccz][ccx] & fmWater) )
+ if (fabs(h - v.y) > 64) return 1;*/
+ v.y = h;
+
+ float hh = GetLandH(v.x-64, v.z-64); if ( fabs(hh-h) > 100 ) return 1;
+ hh = GetLandH(v.x+64, v.z-64); if ( fabs(hh-h) > 100 ) return 1;
+ hh = GetLandH(v.x-64, v.z+64); if ( fabs(hh-h) > 100 ) return 1;
+ hh = GetLandH(v.x+64, v.z+64); if ( fabs(hh-h) > 100 ) return 1;
+
+ return 0;
+}
+
+
+
+int CheckPossiblePath(TCharacter *cptr, BOOL wc, BOOL mc)
+{
+ Vector3d p = cptr->pos;
+ float lookx = (float)f_cos(cptr->tgalpha);
+ float lookz = (float)f_sin(cptr->tgalpha);
+ int c=0;
+ for (int t=0; t<20; t++) {
+ p.x+=lookx * 64.f;
+ p.z+=lookz * 64.f;
+ if (CheckPlaceCollision(p, wc, mc)) c++;
+ }
+ return c;
+}
+
+
+void LookForAWay(TCharacter *cptr, BOOL wc, BOOL mc)
+{
+ float alpha = cptr->tgalpha;
+ float dalpha = 15.f;
+ float afound = alpha;
+ int maxp = 16;
+ int curp;
+
+ if (!CheckPossiblePath(cptr, wc, mc)) { cptr->NoWayCnt=0; return; }
+
+ cptr->NoWayCnt++;
+ for (int i=0; i<12; i++) {
+ cptr->tgalpha = alpha+dalpha*pi/180.f;
+ curp=CheckPossiblePath(cptr, wc, mc) + (i>>1);
+ if (!curp) return;
+ if (curp<maxp) {
+ maxp = curp;
+ afound = cptr->tgalpha;
+ }
+
+ cptr->tgalpha = alpha-dalpha*pi/180.f;
+ curp=CheckPossiblePath(cptr, wc, mc) + (i>>1);
+ if (!curp) return;
+ if (curp<maxp) {
+ maxp = curp;
+ afound = cptr->tgalpha;
+ }
+
+ dalpha+=15.f;
+ }
+
+ cptr->tgalpha = afound;
+}
+
+
+
+
+BOOL ReplaceCharacterForward(TCharacter *cptr)
+{
+ float al = CameraAlpha + (float)siRand(2048) / 2048.f;
+ float sa = (float)f_sin(al);
+ float ca = (float)f_cos(al);
+ Vector3d p;
+ p.x = PlayerX + sa * (ctViewR+rRand(10))*256;
+ p.z = PlayerZ - ca * (ctViewR+rRand(10))*256;
+ p.y = GetLandH(p.x, p.z);
+
+ if (p.x < 16*256) return FALSE;
+ if (p.z < 16*256) return FALSE;
+ if (p.x >1000*256) return FALSE;
+ if (p.z >1000*256) return FALSE;
+
+ if (CheckPlaceCollisionP(p)) return FALSE;
+
+ cptr->State = 0;
+ cptr->pos = p;
+ //cptr->tgx = cptr->pos.x + siRand(2048);
+ //cptr->tgz = cptr->pos.z + siRand(2048);
+ SetNewTargetPlace(cptr, 2048);
+
+ if (cptr->AI==AI_ARCHEO) //===== dimor ========//
+ cptr->pos.y+=1048.f;
+ return TRUE;
+}
+
+
+void Characters_AddSecondaryOne(int ctype)
+{
+ if (ChCount>64) return;
+ Characters[ChCount].CType = ctype;
+ int tr = 0;
+replace1:
+ tr++;
+ if (tr>128) return;
+ Characters[ChCount].pos.x = PlayerX + siRand(20040);
+ Characters[ChCount].pos.z = PlayerZ + siRand(20040);
+ Characters[ChCount].pos.y = GetLandH(Characters[ChCount].pos.x,
+ Characters[ChCount].pos.z);
+
+ if (CheckPlaceCollisionP(Characters[ChCount].pos)) goto replace1;
+
+ if ( fabs(Characters[ChCount].pos.x - PlayerX) +
+ fabs(Characters[ChCount].pos.z - PlayerZ) < 256 * 40 )
+ goto replace1;
+
+ Characters[ChCount].tgx = Characters[ChCount].pos.x;
+ Characters[ChCount].tgz = Characters[ChCount].pos.z;
+ Characters[ChCount].tgtime = 0;
+
+ ResetCharacter(&Characters[ChCount]);
+ ChCount++;
+}
+
+
+
+void MoveCharacter(TCharacter *cptr, float dx, float dz, BOOL wc, BOOL mc)
+{
+ //return; //000000000000000000000000000000000000000000000
+ //000000000000000000000000000000000000000000000
+//000000000000000000000000000000000000000000000//000000000000000000000000000000000000000000000//000000000000000000000000000000000000000000000
+
+
+ Vector3d p = cptr->pos;
+
+ if (CheckPlaceCollision2(p, wc)) {
+ cptr->pos.x+=dx / 2;
+ cptr->pos.z+=dz / 2;
+ return;
+ }
+
+ p.x+=dx;
+ p.z+=dz;
+
+ if (!CheckPlaceCollision2(p, wc)) {
+ cptr->pos = p;
+ return;
+ }
+
+ p = cptr->pos;
+ p.x+=dx/2;
+ p.z+=dz/2;
+ if (!CheckPlaceCollision2(p, wc)) cptr->pos = p;
+ p = cptr->pos;
+
+ p.x+=dx/4;
+ //if (!CheckPlaceCollision2(p)) cptr->pos = p;
+ p.z+=dz/4;
+ //if (!CheckPlaceCollision2(p)) cptr->pos = p;
+ cptr->pos = p;
+}
+
+
+
+
+void MoveCharacter2(TCharacter *cptr, float dx, float dz)
+{
+ cptr->pos.x+=dx;
+ cptr->pos.z+=dz;
+}
+
+
+
+
+void SetNewTargetPlace(TCharacter *cptr, float R)
+{
+ Vector3d p;
+ int tr = 0;
+replace:
+ p.x = cptr->pos.x + siRand((int)R); if (p.x<512) p.x = 512; if (p.x>1018*256) p.x = 1018*256;
+ p.z = cptr->pos.z + siRand((int)R); if (p.z<512) p.z = 512; if (p.z>1018*256) p.z = 1018*256;
+ p.y = GetLandH(p.x, p.z);
+ tr++;
+ if (tr<128)
+ if ( fabs(p.x - cptr->pos.x) + fabs(p.z - cptr->pos.z) < R / 2.f) goto replace;
+
+ R+=512;
+
+ if (tr<256)
+ if (CheckPlaceCollisionP(p)) goto replace;
+
+ cptr->tgtime = 0;
+ cptr->tgx = p.x;
+ cptr->tgz = p.z;
+}
+
+
+
+void SetNewTargetPlace_Brahi(TCharacter *cptr, float R)
+{
+ Vector3d p;
+ int tr = 0;
+replace:
+ p.x = cptr->pos.x + siRand((int)R); if (p.x<512) p.x = 512; if (p.x>1018*256) p.x = 1018*256;
+ p.z = cptr->pos.z + siRand((int)R); if (p.z<512) p.z = 512; if (p.z>1018*256) p.z = 1018*256;
+ tr++;
+ if (tr<16)
+ if ( fabs(p.x - cptr->pos.x) + fabs(p.z - cptr->pos.z) < R / 2.f) goto replace;
+
+ p.y = GetLandH(p.x, p.z);
+ float wy = GetLandUpH(p.x, p.z) - p.y;
+
+ if (tr<128) {
+ if (wy > 400) goto replace;
+ if (wy < 200) goto replace;
+ }
+
+ cptr->tgtime = 0;
+ cptr->tgx = p.x;
+ cptr->tgz = p.z;
+}
+
+
+
+void AnimateHuntDead(TCharacter *cptr)
+{
+
+ //if (!cptr->FTime) ActivateCharacterFx(cptr);
+
+ ProcessPrevPhase(cptr);
+ BOOL NewPhase = FALSE;
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ NewPhase = TRUE;
+ if (cptr->Phase==2)
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ else
+ cptr->FTime = 0;
+
+ if (cptr->Phase==1) {
+ cptr->FTime=0;
+ cptr->Phase=2;
+ }
+
+ ActivateCharacterFx(cptr);
+ }
+
+
+ float h = GetLandH(cptr->pos.x, cptr->pos.z);
+ DeltaFunc(cptr->pos.y, h, TimeDt / 5.f);
+
+ if (cptr->Phase==2)
+ if (cptr->pos.y > h+3) {
+ cptr->FTime = 0;
+ //MessageBeep(0xFFFFFFFF);
+ }
+
+
+ if (cptr->pos.y < h + 256) {
+ //=== beta ===//
+ float blook = 256;
+ float hlook = GetLandH(cptr->pos.x + cptr->lookx * blook, cptr->pos.z + cptr->lookz * blook);
+ float hlook2 = GetLandH(cptr->pos.x - cptr->lookx * blook, cptr->pos.z - cptr->lookz * blook);
+ DeltaFunc(cptr->beta, (hlook2 - hlook) / (blook * 3.2f), TimeDt / 1800.f);
+
+ if (cptr->beta > 0.4f) cptr->beta = 0.4f;
+ if (cptr->beta <-0.4f) cptr->beta =-0.4f;
+
+ //=== gamma ===//
+ float glook = 256;
+ hlook = GetLandH(cptr->pos.x + cptr->lookz * glook, cptr->pos.z - cptr->lookx*glook);
+ hlook2 = GetLandH(cptr->pos.x - cptr->lookz * glook, cptr->pos.z + cptr->lookx*glook);
+ cptr->tggamma =(hlook - hlook2) / (glook * 3.2f);
+ if (cptr->tggamma > 0.4f) cptr->tggamma = 0.4f;
+ if (cptr->tggamma <-0.4f) cptr->tggamma =-0.4f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1800.f);
+ }
+
+
+ TCharacter *cptr2 = &Characters[DemoPoint.CIndex];
+}
+
+
+
+
+
+
+
+
+
+
+
+void AnimateDiatrDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=DIA_DIE && cptr->Phase!=DIA_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = DIA_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = DIA_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+void AnimatePigDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=PIG_DIE && cptr->Phase!=PIG_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = PIG_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = PIG_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+
+
+
+
+
+
+void AnimateDimorDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=DIM_FALL && cptr->Phase!=DIM_DIE) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = DIM_FALL;
+ cptr->rspeed = 0;
+ ActivateCharacterFx(cptr);
+ return;
+ }
+
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (cptr->Phase == DIM_DIE)
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ else
+ cptr->FTime%= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+//======= movement ===========//
+ if (cptr->Phase == DIM_DIE)
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 400.f);
+ else
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 1200.f);
+
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ if (cptr->Phase == DIM_FALL) {
+ float wh = GetLandUpH(cptr->pos.x, cptr->pos.z);
+ float lh = GetLandH (cptr->pos.x, cptr->pos.z);
+ BOOL OnWater = (wh > lh);
+ if (OnWater)
+ if (cptr->pos.y>=wh && (cptr->pos.y+cptr->rspeed * TimeDt / 1024) <wh) {
+ AddWCircle(cptr->pos.x+siRand(128), cptr->pos.z+siRand(128), 2.0);
+ AddWCircle(cptr->pos.x+siRand(128), cptr->pos.z+siRand(128), 2.5);
+ AddWCircle(cptr->pos.x+siRand(128), cptr->pos.z+siRand(128), 3.0);
+ AddWCircle(cptr->pos.x+siRand(128), cptr->pos.z+siRand(128), 3.5);
+ AddWCircle(cptr->pos.x+siRand(128), cptr->pos.z+siRand(128), 3.0);
+ }
+ cptr->pos.y+=cptr->rspeed * TimeDt / 1024;
+ cptr->rspeed-=TimeDt*2.56f;
+
+ if (cptr->pos.y<lh) {
+ cptr->pos.y = lh;
+ if (OnWater) {
+ AddElements(cptr->pos.x+siRand(128), lh, cptr->pos.z+siRand(128), 4, 10);
+ AddElements(cptr->pos.x+siRand(128), lh, cptr->pos.z+siRand(128), 4, 10);
+ AddElements(cptr->pos.x+siRand(128), lh, cptr->pos.z+siRand(128), 4, 10);
+ }
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->Phase = DIM_DIE;
+ cptr->FTime = 0;
+ ActivateCharacterFx(cptr);
+ }
+ } else {
+ ThinkY_Beta_Gamma(cptr, 140, 126, 0.6f, 0.5f);
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+ }
+}
+
+
+
+
+
+
+
+
+
+void AnimateBronDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=BRO_DIE && cptr->Phase!=BRO_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = BRO_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = BRO_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+void AnimateHogDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=BRO_DIE && cptr->Phase!=BRO_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = BRO_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = BRO_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+void AnimateRhinoDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=BRO_DIE && cptr->Phase!=BRO_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = BRO_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = BRO_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+void AnimateSmiloDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=BRO_DIE && cptr->Phase!=BRO_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = BRO_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = BRO_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+
+
+
+
+
+
+
+void AnimateDeerDead(TCharacter *cptr)
+{
+
+ if (cptr->Phase!=DER_DIE && cptr->Phase!=DER_SLP) {
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = cptr->Phase;
+ cptr->PrevPFTime = cptr->FTime;
+ cptr->PPMorphTime = 0; }
+
+ cptr->FTime = 0;
+ cptr->Phase = DER_DIE;
+ ActivateCharacterFx(cptr);
+ } else {
+ ProcessPrevPhase(cptr);
+
+ cptr->FTime+=TimeDt;
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime)
+ if (Tranq) {
+ cptr->FTime=0;
+ cptr->Phase = DER_SLP;
+ ActivateCharacterFx(cptr);
+ } else
+ cptr->FTime = cptr->pinfo->Animation[cptr->Phase].AniTime-1;
+ }
+
+//======= movement ===========//
+ DeltaFunc(cptr->vspeed, 0, TimeDt / 800.f);
+ cptr->pos.x+=cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+=cptr->lookz * cptr->vspeed * TimeDt;
+
+ ThinkY_Beta_Gamma(cptr, 100, 96, 0.6f, 0.5f);
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1600.f);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void AnimateDiatr(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 108;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 108;
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+ if (cptr->State==2) { if (cptr->Phase!=DIA_JUMP) NewPhase=TRUE; cptr->State=1; cptr->Phase=DIA_RUN;}
+
+
+ if (GetLandUpH(cptr->pos.x, cptr->pos.z) - GetLandH(cptr->pos.x, cptr->pos.z) > 140 * cptr->scale)
+ cptr->StateF |= csONWATER; else
+ cptr->StateF &= (!csONWATER);
+
+ if (cptr->Phase == DIA_EAT) goto NOTHINK;
+
+//============================================//
+ if (!MyHealth) cptr->State = 0;
+ if (cptr->State) {
+ if (pdist > ctViewR*140+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ cptr->AfraidTime-=TimeDt;
+ if (cptr->AfraidTime<=0) {
+ cptr->AfraidTime=0; cptr->State = 0;
+ }
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+
+ if (!(cptr->StateF & csONWATER))
+ if (pdist<1324 * cptr->scale && pdist>900 * cptr->scale)
+ if (AngleDifference(cptr->alpha, FindVectorAlpha(playerdx, playerdz)) < 0.2f)
+ cptr->Phase = DIA_JUMP;
+
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 120) < 256) {
+ if (!(cptr->StateF & csONWATER)) {
+ cptr->vspeed/= 8.0f;
+ cptr->State = 1;
+ cptr->Phase = DIA_EAT;
+ }
+
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+ }
+
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+NOTHINK:
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--; else
+ {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->State && pdist>1648) {
+ cptr->tgalpha += (float)f_sin(RealTime/824.f) / 4.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+ LookForAWay(cptr, FALSE, TRUE);
+ if (cptr->NoWayCnt>12) { cptr->NoWayCnt=0; cptr->NoFindCnt = 16 + rRand(20); }
+
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (cptr->Phase==DIA_EAT) goto ENDPSELECT;
+ if (NewPhase && _Phase==DIA_JUMP) { cptr->Phase = DIA_RUN; goto ENDPSELECT; }
+
+ if (cptr->Phase== DIA_JUMP) goto ENDPSELECT;
+
+ if (NewPhase)
+ if (!cptr->State)
+ if (rRand(128)>110) {
+ cptr->Phase = DIA_IDLE1 + rRand(1);
+ goto ENDPSELECT;
+ } else cptr->Phase = DIA_WALK; else cptr->Phase = DIA_RUN;
+
+ if (cptr->Phase!=DIA_IDLE1 && cptr->Phase!=DIA_IDLE2)
+ if (!cptr->State) cptr->Phase=DIA_WALK; else
+ if (fabs(cptr->tgalpha - cptr->alpha)<1.0 ||
+ fabs(cptr->tgalpha - cptr->alpha)>2*pi-1.0)
+ cptr->Phase = DIA_RUN; else cptr->Phase=DIA_WALK;
+
+ if (cptr->StateF & csONWATER) cptr->Phase = DIA_SWIM;
+ if (cptr->Slide>40) cptr->Phase = DIA_SLIDE;
+
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ //==== set proportional FTime for better morphing =//
+ if (MORPHP)
+ if (_Phase<=3 && cptr->Phase<=3)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+ if (cptr->Phase==DIA_JUMP || cptr->Phase==DIA_EAT ||
+ cptr->Phase==DIA_IDLE1 || cptr->Phase==DIA_IDLE2) goto SKIPROT;
+
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.6f + drspd*1.2f;
+ else currspeed =-0.6f - drspd*1.2f;
+ else currspeed = 0;
+ if (cptr->AfraidTime) currspeed*=2.5;
+
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->StateF & csONWATER) || cptr->Phase==DIA_WALK) currspeed/=1.4f;
+
+ if (cptr->AfraidTime) DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 160.f);
+ else DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 180.f);
+
+ tgbend = drspd/3;
+ if (tgbend>pi/5) tgbend = pi/5;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 800.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 600.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 1024.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+ //======= set slide mode ===========//
+ if (!cptr->Slide && cptr->vspeed>0.6 && cptr->Phase!=DIA_JUMP)
+ if (AngleDifference(cptr->tgalpha, cptr->alpha)>pi*2/3.f) {
+ cptr->Slide = (int)(cptr->vspeed*700.f);
+ cptr->slidex = cptr->lookx;
+ cptr->slidez = cptr->lookz;
+ cptr->vspeed = 0;
+ }
+
+
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == DIA_RUN ) curspeed = 0.640*2;
+ if (cptr->Phase == DIA_JUMP) curspeed = 0.600*2;
+ if (cptr->Phase == DIA_WALK) curspeed = 0.224*2;
+ if (cptr->Phase == DIA_SWIM) curspeed = 0.300*2;
+ if (cptr->Phase == DIA_EAT) curspeed = 0.0f;
+
+ if (cptr->Phase == DIA_RUN && cptr->Slide) {
+ curspeed /= 8;
+ if (drspd > pi / 2.f) curspeed=0; else
+ if (drspd > pi / 4.f) curspeed*=2.f - 4.f*drspd / pi;
+ } else
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+
+ DeltaFunc(cptr->vspeed, curspeed, TimeDt / 500.f);
+
+ if (cptr->Phase==DIA_JUMP) cptr->vspeed = 1.1f;
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt * cptr->scale,
+ cptr->lookz * cptr->vspeed * TimeDt * cptr->scale, FALSE, TRUE);
+
+
+//========== slide ==============//
+ if (cptr->Slide) {
+ MoveCharacter(cptr, cptr->slidex * cptr->Slide / 600.f * TimeDt * cptr->scale,
+ cptr->slidez * cptr->Slide / 600.f * TimeDt * cptr->scale, FALSE, TRUE);
+
+ cptr->Slide-=TimeDt;
+ if (cptr->Slide<0) cptr->Slide=0;
+ }
+
+
+//============ Y movement =================//
+ if (cptr->StateF & csONWATER) {
+ cptr->pos.y = GetLandUpH(cptr->pos.x, cptr->pos.z) - 160 * cptr->scale;
+ cptr->beta/=2;
+ cptr->tggamma=0;
+ } else {
+ ThinkY_Beta_Gamma(cptr, 98, 84, 0.4f, 0.3f);
+ }
+
+ //=== process to tggamma ===//
+ if (cptr->Phase==DIA_WALK) cptr->tggamma+= cptr->rspeed / 9.0f;
+ else cptr->tggamma+= cptr->rspeed / 6.0f;
+ if (cptr->Phase==DIA_JUMP) cptr->tggamma=0;
+
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 1624.f);
+
+
+//==================================================//
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void AnimatePig(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ float playerdx = PlayerX - cptr->pos.x;
+ float playerdz = PlayerZ - cptr->pos.z;
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+ if (!cptr->AfraidTime) {
+ if (pdist<2048.f) cptr->AfraidTime = (5 + rRand(5)) * 1024;
+
+ if (!cptr->AfraidTime)
+ if (pdist > 4096.f) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 2048.f);
+ goto TBEGIN; }
+ }
+
+
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ }
+
+ if (pdist>(ctViewR+20)*256)
+ if (ReplaceCharacterForward(cptr)) goto TBEGIN;
+
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+ if (pdist<812.f) {
+ cptr->State = 1;
+ cptr->AfraidTime = (5 + rRand(5)) * 1024;
+ cptr->Phase = PIG_RUN;
+ goto TBEGIN; }
+
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 2048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 8 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == PIG_IDLE1 || cptr->Phase == PIG_IDLE2 || cptr->Phase == PIG_IDLE3) {
+ if (rRand(128)>96) cptr->Phase = PIG_WALK;
+ else cptr->Phase = PIG_IDLE1 + rRand(2);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 120) cptr->Phase=PIG_IDLE1; else cptr->Phase=PIG_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = PIG_RUN;
+ else cptr->Phase = PIG_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == PIG_IDLE1 || cptr->Phase == PIG_IDLE2 || cptr->Phase == PIG_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.8f + drspd*1.4f;
+ else currspeed =-0.8f - drspd*1.4f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==PIG_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 260.f);
+
+ tgbend = drspd/2;
+ if (tgbend>pi/2) tgbend = pi/2;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 800.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 400.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 1024.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == PIG_RUN ) curspeed = 0.6f;
+ if (cptr->Phase == PIG_WALK) curspeed = 0.2f;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 64, 32, 0.7f, 0.4f);
+ if (cptr->Phase==PIG_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void AnimateBron(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ //float playerdx = PlayerX - cptr->pos.x;
+ //float playerdz = PlayerZ - cptr->pos.z;
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 300 * cptr->scale;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 300 * cptr->scale;
+
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+ if (pdist < 6000) cptr->AfraidTime = 8000;
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ if (pdist > 256*16+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+ }
+
+ if (MyHealth)
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 160) < 256) {
+ cptr->State = 0;
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime)
+ if (pdist>12*256) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 48 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) {
+ if (rRand(128) > 64 && cptr->Phase == BRO_IDLE3)
+ cptr->Phase = BRO_WALK;
+ else cptr->Phase = BRO_IDLE1 + rRand(2);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 124) cptr->Phase=BRO_IDLE1; else cptr->Phase=BRO_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = BRO_RUN;
+ else cptr->Phase = BRO_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.2f + drspd*1.0f;
+ else currspeed =-0.2f - drspd*1.0f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==BRO_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/3.5f;
+ if (tgbend>pi/2.f) tgbend = pi/2.f;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1600.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1200.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == BRO_RUN ) curspeed = 0.768*2;
+ if (cptr->Phase == BRO_WALK) curspeed = 0.168*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.3f);
+ if (cptr->Phase==BRO_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+
+void AnimateBear(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ //float playerdx = PlayerX - cptr->pos.x;
+ //float playerdz = PlayerZ - cptr->pos.z;
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 300 * cptr->scale;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 300 * cptr->scale;
+
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+ if (pdist < 6000) cptr->AfraidTime = 8000;
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ if (pdist > 256*20+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+ }
+
+ if (MyHealth)
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 160) < 256) {
+ cptr->State = 0;
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 48 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) {
+ if (rRand(128) > 64 && cptr->Phase == BRO_IDLE3)
+ cptr->Phase = BRO_WALK;
+ else cptr->Phase = BRO_IDLE1 + rRand(2);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 124) cptr->Phase=BRO_IDLE1; else cptr->Phase=BRO_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = BRO_RUN;
+ else cptr->Phase = BRO_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.2f + drspd*1.0f;
+ else currspeed =-0.2f - drspd*1.0f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==BRO_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/3.5f;
+ if (tgbend>pi/2.f) tgbend = pi/2.f;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1600.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1200.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == BRO_RUN ) curspeed = 0.896*2;
+ if (cptr->Phase == BRO_WALK) curspeed = 0.240*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.3f);
+ if (cptr->Phase==BRO_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+void AnimateWolf(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ //float playerdx = PlayerX - cptr->pos.x;
+ //float playerdz = PlayerZ - cptr->pos.z;
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 300 * cptr->scale;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 300 * cptr->scale;
+
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (!MyHealth) cptr->State = 0;
+ if (cptr->State) {
+ if (pdist > ctViewR*140+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ cptr->AfraidTime-=TimeDt;
+ if (cptr->AfraidTime<=0) {
+ cptr->AfraidTime=0; cptr->State = 0;
+ }
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+ }
+
+
+ if (MyHealth)
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 160) < 256) {
+ cptr->State = 0;
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime)
+ if (pdist>12*256) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 48 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) {
+ if (rRand(128) > 64)
+ cptr->Phase = BRO_WALK;
+ else
+ cptr->Phase = BRO_IDLE1 + rRand(2);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 124) cptr->Phase=BRO_IDLE1 + rRand(2); else cptr->Phase=BRO_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = BRO_RUN;
+ else cptr->Phase = BRO_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.4f + drspd*1.5f;
+ else currspeed =-0.4f - drspd*1.5f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==BRO_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/3.5f;
+ if (tgbend>pi/2.f) tgbend = pi/2.f;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1600.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1200.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == BRO_RUN ) curspeed = 1.024*2;
+ if (cptr->Phase == BRO_WALK) curspeed = 0.160*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.3f);
+ if (cptr->Phase==BRO_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+void AnimateHog(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ //float playerdx = PlayerX - cptr->pos.x;
+ //float playerdz = PlayerZ - cptr->pos.z;
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 300 * cptr->scale;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 300 * cptr->scale;
+
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+ if (pdist < 6000) cptr->AfraidTime = 8000;
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ if (pdist > 256*20+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+ }
+
+ if (MyHealth)
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 160) < 256) {
+ cptr->State = 0;
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime)
+ if (pdist>12*256) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 48 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) {
+ if (rRand(128) > 64 && cptr->Phase == BRO_IDLE3)
+ cptr->Phase = BRO_WALK;
+ else cptr->Phase = BRO_IDLE1 + rRand(2);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 124) cptr->Phase=BRO_IDLE1; else cptr->Phase=BRO_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = BRO_RUN;
+ else cptr->Phase = BRO_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.3f + drspd*1.4f;
+ else currspeed =-0.3f - drspd*1.4f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==BRO_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/3.5f;
+ if (tgbend>pi/2.f) tgbend = pi/2.f;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1600.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1200.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == BRO_RUN ) curspeed = 0.576*2;
+ if (cptr->Phase == BRO_WALK) curspeed = 0.112*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.3f);
+ if (cptr->Phase==BRO_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+void AnimateRhino(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ //float playerdx = PlayerX - cptr->pos.x;
+ //float playerdz = PlayerZ - cptr->pos.z;
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 300 * cptr->scale;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 300 * cptr->scale;
+
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+ if (pdist < 6000) cptr->AfraidTime = 8000;
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ if (pdist > 256*18+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+ }
+
+ if (MyHealth)
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 160) < 256) {
+ cptr->State = 0;
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime)
+ if (pdist>12*256) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 48 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) {
+ if (rRand(128) > 64 && cptr->Phase == BRO_IDLE3)
+ cptr->Phase = BRO_WALK;
+ else cptr->Phase = BRO_IDLE1 + rRand(2);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 124) cptr->Phase=BRO_IDLE1; else cptr->Phase=BRO_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = BRO_RUN;
+ else cptr->Phase = BRO_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.3f + drspd*1.2f;
+ else currspeed =-0.3f - drspd*1.2f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==BRO_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/3.5f;
+ if (tgbend>pi/2.f) tgbend = pi/2.f;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1600.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1200.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == BRO_RUN ) curspeed = 0.576*2;
+ if (cptr->Phase == BRO_WALK) curspeed = 0.168*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.3f);
+ if (cptr->Phase==BRO_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+void AnimateSmilo(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ //float playerdx = PlayerX - cptr->pos.x;
+ //float playerdz = PlayerZ - cptr->pos.z;
+
+ float playerdx = PlayerX - cptr->pos.x - cptr->lookx * 300 * cptr->scale;
+ float playerdz = PlayerZ - cptr->pos.z - cptr->lookz * 300 * cptr->scale;
+
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+ if (pdist < 6000) cptr->AfraidTime = 8000;
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ if (pdist > 256*16+OptAgres/8) {
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ } else {
+ cptr->tgx = PlayerX;
+ cptr->tgz = PlayerZ;
+ cptr->tgtime = 0;
+ }
+ }
+
+ if (MyHealth)
+ if (pdist<300)
+ if (fabs(PlayerY - cptr->pos.y - 160) < 256) {
+ cptr->State = 0;
+ AddDeadBody(cptr, HUNT_EAT);
+ }
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime)
+ if (pdist>12*256) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>8) { cptr->NoWayCnt=0; cptr->NoFindCnt = 48 + rRand(80); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) {
+ cptr->Phase = BRO_WALK;
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 124) cptr->Phase=BRO_IDLE1 + rRand(2); else cptr->Phase=BRO_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = BRO_RUN;
+ else cptr->Phase = BRO_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=1 && cptr->Phase<=1)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == BRO_IDLE1 || cptr->Phase == BRO_IDLE2 || cptr->Phase == BRO_IDLE3) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.3f + drspd*1.5f;
+ else currspeed =-0.3f - drspd*1.5f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==BRO_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/3.5f;
+ if (tgbend>pi/2.f) tgbend = pi/2.f;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1600.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 1200.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == BRO_RUN ) curspeed = 1.024*2;
+ if (cptr->Phase == BRO_WALK) curspeed = 0.320*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.3f);
+ if (cptr->Phase==BRO_WALK) cptr->tggamma+= cptr->rspeed / 12.0f;
+ else cptr->tggamma+= cptr->rspeed / 8.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void AnimateDeer(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ float playerdx = PlayerX - cptr->pos.x;
+ float playerdz = PlayerZ - cptr->pos.z;
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ }
+
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+ if (pdist<1024.f) {
+ cptr->State = 1;
+ cptr->AfraidTime = (6 + rRand(8)) * 1024;
+ cptr->Phase = DER_RUN;
+ goto TBEGIN; }
+
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<2048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>12) { cptr->NoWayCnt=0; cptr->NoFindCnt = 32 + rRand(60); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == DER_IDLE1 || cptr->Phase == DER_IDLE2) {
+ if (rRand(128) > 64 && cptr->Phase == DER_IDLE2)
+ cptr->Phase = DER_WALK;
+ else cptr->Phase = DER_IDLE1 + rRand(1);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 120) cptr->Phase=DER_IDLE1; else cptr->Phase=DER_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = DER_RUN;
+ else cptr->Phase = DER_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=2 && cptr->Phase<=2)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == DER_IDLE1 || cptr->Phase == DER_IDLE2) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.2f + drspd*1.0f;
+ else currspeed =-0.2f - drspd*1.0f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==DER_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/2.f;
+ if (tgbend>pi/3.f) tgbend = pi/3.f;
+
+ tgbend*= SGN(currspeed);
+ DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 2000.f);
+
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == DER_RUN ) curspeed = 0.768*2;
+ if (cptr->Phase == DER_WALK) curspeed = 0.160*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.4f);
+ if (cptr->Phase==DER_WALK) cptr->tggamma+= cptr->rspeed / 16.0f;
+ else cptr->tggamma+= cptr->rspeed / 10.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+
+
+
+void AnimateMamm(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+ if (cptr->AfraidTime) cptr->AfraidTime = max(0, cptr->AfraidTime - TimeDt);
+ if (cptr->State==2) { NewPhase=TRUE; cptr->State=1; }
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ float playerdx = PlayerX - cptr->pos.x;
+ float playerdz = PlayerZ - cptr->pos.z;
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (cptr->State) {
+
+ if (!cptr->AfraidTime) {
+ cptr->State = 0;
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN;
+ }
+
+ nv.x = playerdx; nv.z = playerdz; nv.y = 0;
+ NormVector(nv, 2048.f);
+ cptr->tgx = cptr->pos.x - nv.x;
+ cptr->tgz = cptr->pos.z - nv.z;
+ cptr->tgtime = 0;
+ }
+
+
+ //======== exploring area ===============//
+ if (!cptr->State) {
+ cptr->AfraidTime = 0;
+ if (pdist<1024.f) {
+ cptr->State = 1;
+ cptr->AfraidTime = (6 + rRand(8)) * 1024;
+ cptr->Phase = MAM_RUN;
+ goto TBEGIN; }
+
+
+ if (tdist<456) {
+ SetNewTargetPlace(cptr, 8048.f);
+ goto TBEGIN; }
+ }
+
+
+//============================================//
+ if (pdist<3048) cptr->NoFindCnt = 0;
+ if (cptr->NoFindCnt) cptr->NoFindCnt--;
+ else {
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->AfraidTime) {
+ cptr->tgalpha += (float)f_sin(RealTime/1024.f) / 3.f;
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+ }
+ }
+
+
+ LookForAWay(cptr, TRUE, TRUE);
+ if (cptr->NoWayCnt>12) { cptr->NoWayCnt=0; cptr->NoFindCnt = 32 + rRand(60); }
+
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase)
+ if (!cptr->State) {
+ if (cptr->Phase == MAM_IDLE1 || cptr->Phase == MAM_IDLE2) {
+ if (rRand(128) > 64 && cptr->Phase == MAM_IDLE2)
+ cptr->Phase = MAM_WALK;
+ else cptr->Phase = MAM_IDLE1 + rRand(1);
+ goto ENDPSELECT;
+ }
+ if (rRand(128) > 120) cptr->Phase=MAM_IDLE1; else cptr->Phase=MAM_WALK;
+ } else
+ if (cptr->AfraidTime) cptr->Phase = MAM_RUN;
+ else cptr->Phase = MAM_WALK;
+
+ENDPSELECT:
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (_Phase<=2 && cptr->Phase<=2)
+ cptr->FTime = _FTime * cptr->pinfo->Animation[cptr->Phase].AniTime / cptr->pinfo->Animation[_Phase].AniTime + 64;
+ else if (!NewPhase) cptr->FTime = 0;
+
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (cptr->Phase == MAM_IDLE1 || cptr->Phase == MAM_IDLE2) goto SKIPROT;
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.2f + drspd*1.0f;
+ else currspeed =-0.2f - drspd*1.0f;
+ else currspeed = 0;
+
+ if (cptr->AfraidTime) currspeed*=1.5;
+ if (dalpha > pi) currspeed*=-1;
+ if ((cptr->State & csONWATER) || cptr->Phase==MAM_WALK) currspeed/=1.4f;
+
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 400.f);
+
+ tgbend = drspd/2.f;
+ if (tgbend>pi/3.f) tgbend = pi/3.f;
+
+ tgbend*= SGN(currspeed);
+ DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 2000.f);
+
+
+
+ rspd=cptr->rspeed * TimeDt / 612.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+SKIPROT:
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == MAM_RUN ) curspeed = 0.640*2;
+ if (cptr->Phase == MAM_WALK) curspeed = 0.320*2;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ if (curspeed>cptr->vspeed) DeltaFunc(cptr->vspeed, curspeed, TimeDt / 1024.f);
+ else DeltaFunc(cptr->vspeed, curspeed, TimeDt / 256.f);
+
+ MoveCharacter(cptr, cptr->lookx * cptr->vspeed * TimeDt,
+ cptr->lookz * cptr->vspeed * TimeDt, TRUE, TRUE);
+
+ ThinkY_Beta_Gamma(cptr, 128, 64, 0.6f, 0.4f);
+ if (cptr->Phase==MAM_WALK) cptr->tggamma+= cptr->rspeed / 16.0f;
+ else cptr->tggamma+= cptr->rspeed / 10.0f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void AnimateDimor(TCharacter *cptr)
+{
+ NewPhase = FALSE;
+ int _Phase = cptr->Phase;
+ int _FTime = cptr->FTime;
+ float _tgalpha = cptr->tgalpha;
+
+
+TBEGIN:
+ float targetx = cptr->tgx;
+ float targetz = cptr->tgz;
+ float targetdx = targetx - cptr->pos.x;
+ float targetdz = targetz - cptr->pos.z;
+
+ float tdist = (float)sqrt( targetdx * targetdx + targetdz * targetdz );
+
+ float playerdx = PlayerX - cptr->pos.x;
+ float playerdz = PlayerZ - cptr->pos.z;
+ float pdist = (float)sqrt( playerdx * playerdx + playerdz * playerdz );
+
+
+ //=========== run away =================//
+
+ if (pdist>(ctViewR+20)*256)
+ if (ReplaceCharacterForward(cptr)) goto TBEGIN;
+
+
+ //======== exploring area ===============//
+ if (tdist<1024) {
+ SetNewTargetPlace(cptr, 4048.f);
+ goto TBEGIN; }
+
+
+//============================================//
+
+
+ cptr->tgalpha = CorrectedAlpha(FindVectorAlpha(targetdx, targetdz), cptr->alpha);//FindVectorAlpha(targetdx, targetdz);
+ if (cptr->tgalpha < 0) cptr->tgalpha+=2*pi;
+ if (cptr->tgalpha > 2*pi) cptr->tgalpha-=2*pi;
+
+//===============================================//
+
+ ProcessPrevPhase(cptr);
+
+//======== select new phase =======================//
+ cptr->FTime+=TimeDt;
+
+ if (cptr->FTime >= cptr->pinfo->Animation[cptr->Phase].AniTime) {
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+ NewPhase = TRUE; }
+
+ if (NewPhase) {
+ if (cptr->Phase == DIM_FLY)
+ if (cptr->pos.y > GetLandH(cptr->pos.x, cptr->pos.z) + 2800)
+ cptr->Phase = DIM_FLYP;
+ else ;
+ else
+ if (cptr->Phase == DIM_FLYP)
+ if (cptr->pos.y < GetLandH(cptr->pos.x, cptr->pos.z) + 1800)
+ cptr->Phase = DIM_FLY;
+ }
+
+
+
+
+//====== process phase changing ===========//
+ if ( (_Phase != cptr->Phase) || NewPhase)
+ if ( (rand() & 1023) > 980 )
+ ActivateCharacterFx(cptr);
+
+ if (_Phase != cptr->Phase) {
+ if (!NewPhase) cptr->FTime = 0;
+ if (cptr->PPMorphTime>128) {
+ cptr->PrevPhase = _Phase;
+ cptr->PrevPFTime = _FTime;
+ cptr->PPMorphTime = 0; }
+ }
+
+
+ cptr->FTime %= cptr->pinfo->Animation[cptr->Phase].AniTime;
+
+
+ //========== rotation to tgalpha ===================//
+
+ float rspd, currspeed, tgbend;
+ float dalpha = (float)fabs(cptr->tgalpha - cptr->alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+ if (drspd > 0.02)
+ if (cptr->tgalpha > cptr->alpha) currspeed = 0.6f + drspd*1.2f;
+ else currspeed =-0.6f - drspd*1.2f;
+ else currspeed = 0;
+
+ if (dalpha > pi) currspeed*=-1;
+ DeltaFunc(cptr->rspeed, currspeed, (float)TimeDt / 460.f);
+
+ tgbend = drspd/2.f;
+ if (tgbend>pi/2) tgbend = pi/2;
+
+ tgbend*= SGN(currspeed);
+ if (fabs(tgbend) > fabs(cptr->bend)) DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 800.f);
+ else DeltaFunc(cptr->bend, tgbend, (float)TimeDt / 400.f);
+
+
+ rspd=cptr->rspeed * TimeDt / 1024.f;
+ if (drspd < fabs(rspd)) cptr->alpha = cptr->tgalpha;
+ else cptr->alpha+=rspd;
+
+
+ if (cptr->alpha > pi * 2) cptr->alpha-= pi * 2;
+ if (cptr->alpha < 0 ) cptr->alpha+= pi * 2;
+
+//========== movement ==============================//
+ cptr->lookx = (float)f_cos(cptr->alpha);
+ cptr->lookz = (float)f_sin(cptr->alpha);
+
+ float curspeed = 0;
+ if (cptr->Phase == DIM_FLY ) curspeed = 1.5f;
+ if (cptr->Phase == DIM_FLYP) curspeed = 1.3f;
+
+ if (drspd > pi / 2.f) curspeed*=2.f - 2.f*drspd / pi;
+
+ if (cptr->Phase == DIM_FLY)
+ DeltaFunc(cptr->pos.y, GetLandH(cptr->pos.x, cptr->pos.z)+4048, TimeDt / 6.f);
+ else
+ DeltaFunc(cptr->pos.y, GetLandH(cptr->pos.x, cptr->pos.z), TimeDt / 16.f);
+
+
+ if (cptr->pos.y < GetLandH(cptr->pos.x, cptr->pos.z) + 236)
+ cptr->pos.y = GetLandH(cptr->pos.x, cptr->pos.z) + 256;
+
+
+
+//========== process speed =============//
+ curspeed*=cptr->scale;
+ DeltaFunc(cptr->vspeed, curspeed, TimeDt / 2024.f);
+
+ cptr->pos.x+= cptr->lookx * cptr->vspeed * TimeDt;
+ cptr->pos.z+= cptr->lookz * cptr->vspeed * TimeDt;
+
+ cptr->tggamma = cptr->rspeed / 4.0f;
+ if (cptr->tggamma > pi / 6.f) cptr->tggamma = pi / 6.f;
+ if (cptr->tggamma <-pi / 6.f) cptr->tggamma =-pi / 6.f;
+ DeltaFunc(cptr->gamma, cptr->tggamma, TimeDt / 2048.f);
+}
+
+
+
+
+
+void AnimateCharacters()
+{
+ //if (!RunMode) return;
+
+ TCharacter *cptr;
+ if (TrophyMode) return;
+
+ for (CurDino=0; CurDino<ChCount; CurDino++) {
+ cptr = &Characters[CurDino];
+ if (cptr->StateF == 0xFF) continue;
+ cptr->tgtime+=TimeDt;
+
+ if (cptr->tgtime > 30*1000) SetNewTargetPlace(cptr, 2048);
+ if (cptr->Health)
+ if (cptr->BloodTTime) {
+ cptr->BloodTTime-=TimeDt;
+ if (cptr->BloodTTime<0) cptr->BloodTTime=0;
+
+ float k = (20000.f + cptr->BloodTTime) / 90000.f;
+ if (k>1.5) k = 1.5;
+ cptr->BloodTime+=(int)((float)TimeDt * k);
+ if (cptr->BloodTime>600) {
+ cptr->BloodTime=rRand(228);
+ AddBloodTrail(cptr);
+ if (rRand(128) > 96) AddBloodTrail(cptr);
+ }
+ }
+
+
+ switch (cptr->AI) {
+ case AI_PIG : if (cptr->Health) AnimatePig(cptr); else AnimatePigDead(cptr);
+ break;
+ case AI_ARCHEO : if (cptr->Health) AnimateDimor(cptr); else AnimateDimorDead(cptr);
+ break;
+ case AI_BIGFOOT:
+ break;
+ case AI_POACHER: ;
+ break;
+
+
+ case AI_BRONT: if (cptr->Health) AnimateBron(cptr); else AnimateBronDead(cptr);
+ break;
+ case AI_HOG : if (cptr->Health) AnimateHog(cptr); else AnimateHogDead(cptr);
+ break;
+ case AI_WOLF : if (cptr->Health) AnimateWolf(cptr); else AnimateBronDead(cptr);
+ break;
+ case AI_RHINO: if (cptr->Health) AnimateRhino(cptr); else AnimateRhinoDead(cptr);
+ break;
+ case AI_DIATR: if (cptr->Health) AnimateDiatr(cptr); else AnimateDiatrDead(cptr);
+ break;
+ case AI_DEER : if (cptr->Health) AnimateDeer(cptr); else AnimateDeerDead(cptr);
+ break;
+ case AI_SMILO: if (cptr->Health) AnimateSmilo(cptr); else AnimateSmiloDead(cptr);
+ break;
+ case AI_MAMM : if (cptr->Health) AnimateMamm(cptr); else AnimateDeerDead(cptr);
+ break;
+ case AI_BEAR : if (cptr->Health) AnimateBear(cptr); else AnimateBronDead(cptr);
+ break;
+
+ /*
+ case AI_ANKY : if (cptr->Health) AnimateAnky(cptr); else AnimateAnkyDead(cptr);
+ break;
+ case AI_STEGO: if (cptr->Health) AnimateSteg(cptr); else AnimateStegDead(cptr);
+ break;
+
+ case AI_ALLO : if (cptr->Health) AnimateRaptor(cptr); else AnimateRaptorDead(cptr);
+ break;
+ case AI_CHASM: if (cptr->Health) AnimateTric(cptr); else AnimateTricDead(cptr);
+ break;
+
+ case AI_VELO : if (cptr->Health) AnimateVelo(cptr); else AnimateVeloDead(cptr);
+ break;
+ case AI_SPINO: if (cptr->Health) AnimateSpin(cptr); else AnimateSpinDead(cptr);
+ break;
+ case AI_CERAT: if (cptr->Health) AnimateCera(cptr); else AnimateCeraDead(cptr);
+ break;
+ case AI_TREX : if (cptr->Health) AnimateTRex(cptr); else AnimateTRexDead(cptr);
+ break;
+ */
+ case 0 : AnimateHuntDead(cptr); break;
+ }
+ }
+}
+
+
+
+
+void MakeNoise(Vector3d pos, float range)
+{
+ for (int c=0; c<ChCount; c++) {
+ TCharacter *cptr = &Characters[c];
+ if (!cptr->Health) continue;
+ float l = VectorLength(SubVectors(cptr->pos, pos));
+ if (l>range) continue;
+
+
+
+ cptr->AfraidTime = (int) (10.f + (range-l) / 256.f) * 1024;
+ cptr->State = 2;
+ cptr->NoFindCnt = 0;
+
+ }
+}
+
+
+void CheckAfraid()
+{
+ if (!MyHealth) return;
+ if (TrophyMode) return;
+
+ Vector3d ppos, plook, clook, wlook, rlook;
+ ppos = PlayerPos;
+
+ if (DEBUG || UNDERWATER || ObservMode) return;
+
+ plook.y = 0;
+ plook.x = (float) f_sin(CameraAlpha);
+ plook.z = (float)-f_cos(CameraAlpha);
+
+ wlook = Wind.nv;
+
+ float kR, kwind, klook, kstand;
+
+ float kmask = 1.0f;
+ float kskill = 1.0f;
+ float kscent = 1.0f;
+
+ if (CamoMode) kmask *=1.5;
+ if (ScentMode) kscent*=1.5;
+
+ for (int c=0; c<ChCount; c++) {
+ TCharacter *cptr = &Characters[c];
+ if (!cptr->Health) continue;
+ if (cptr->AI<10) continue;
+ if (cptr->AfraidTime || cptr->State==1) continue;
+
+ rlook = SubVectors(ppos, cptr->pos);
+ kR = VectorLength( rlook ) / 256.f / (32.f + ctViewR/2);
+ NormVector(rlook, 1.0f);
+
+ kR *= 2.5f / (float)(1.5+OptSens/128.f );
+ if (kR > 3.0f) continue;
+
+ clook.x = cptr->lookx;
+ clook.y = 0;
+ clook.z = cptr->lookz;
+
+ MulVectorsScal(wlook, rlook, kwind); kwind*=Wind.speed / 10;
+ MulVectorsScal(clook, rlook, klook); klook*=-1.f;
+
+ if (HeadY > 180) kstand = 0.7f; else kstand = 1.2f;
+
+ //============= reasons ==============//
+
+ float kALook = kR * ((klook+3.f) / 3.f) * kstand * kmask;
+ if (klook>0.3) kALook*= 2.0;
+ if (klook>0.8) kALook*= 2.0;
+ kALook/=DinoInfo[cptr->CType].LookK;
+ if (kALook < 1.0)
+ if (TraceLook(cptr->pos.x, cptr->pos.y+220, cptr->pos.z,
+ PlayerX, PlayerY+HeadY/2.f, PlayerZ) ) kALook*=1.3f;
+
+ if (kALook < 1.0)
+ if (TraceLook(cptr->pos.x, cptr->pos.y+220, cptr->pos.z,
+ PlayerX, PlayerY+HeadY, PlayerZ) ) kALook = 2.0;
+ kALook *= (1.f + (float)ObjectsOnLook / 6.f);
+
+ /*
+ if (kR<1.0f) {
+ char t[32];
+ wsprintf(t,"%d", ObjectsOnLook);
+ AddMessage(t);
+ kALook = 20.f;
+ }
+ */
+
+ float kASmell = kR * ((kwind+2.0f) / 2.0F) * ((klook+3.f) / 3.f) * kscent;
+ if (kwind>0) kASmell*= 2.0;
+ kASmell/=DinoInfo[cptr->CType].SmellK;
+
+ float kRes = min (kALook, kASmell);
+
+ if (kRes < 1.0) {
+ /*
+ MessageBeep(0xFFFFFFFF);
+ char t[128];
+ if (kALook<kASmell)
+ sprintf(t, "LOOK: KR: %f Tr: %d K: %f", kR, ObjectsOnLook, kALook);
+ else
+ sprintf(t, "SMELL: KR: %f Tr: %d K: %f", kR, ObjectsOnLook, kASmell);
+ AddMessage(t);
+ */
+
+ kRes = min (kRes, kR);
+ cptr->AfraidTime = (int)(1.0 / (kRes+0.1) * 10.f * 1000.f);
+ cptr->State = 2;
+ cptr->NoFindCnt = 0;
+ }
+ }
+}
+
+
+
+
+
+void PlaceTrophy()
+{
+ ChCount = 0;
+
+ for (int c=0; c<24; c++) {
+ if (!TrophyRoom.Body[c].ctype) continue;
+ Characters[ChCount].CType = TrophyRoom.Body[c].ctype;
+
+ if (c<6) Characters[ChCount].alpha = pi/2; else
+ if (c<12) Characters[ChCount].alpha = pi; else
+ if (c<18) Characters[ChCount].alpha = pi*3/2; else
+ Characters[ChCount].alpha = 0;
+
+ ResetCharacter(&Characters[ChCount]);
+
+ Characters[ChCount].State = c;
+ Characters[ChCount].scale = TrophyRoom.Body[c].scale;
+ Characters[ChCount].pos.x = LandingList.list[c].x * 256.f + 128.f;
+ Characters[ChCount].pos.z = LandingList.list[c].y * 256.f + 128.f;
+
+ Characters[ChCount].pos.y = GetLandH(Characters[ChCount].pos.x,
+ Characters[ChCount].pos.z);
+ ChCount++;
+ }
+}
+
+
+
+void PlaceCharacters()
+{
+ int c, tr;
+ ChCount = 0;
+ PrintLog("Placing...");
+//return;
+ for (c=10; c<30; c++)
+ if ( (TargetDino & (1<<c))>0 ) { TargetCall=c; break; }
+
+
+ //======== lohs =========//
+
+ int MC = 5 + OptDens/80;
+ if (OptDayNight==2) MC/=2;
+
+ tr = 0;
+
+ for (c=0; c<MC; c++) {
+ Characters[ChCount].CType = 1 + c % 2;
+replace1:
+ Characters[ChCount].pos.x = PlayerX + siRand(10040);
+ Characters[ChCount].pos.z = PlayerZ + siRand(10040);
+ Characters[ChCount].pos.y = GetLandH(Characters[ChCount].pos.x,
+ Characters[ChCount].pos.z);
+ tr++;
+ if (tr>10240) break;
+
+ if (CheckPlaceCollisionP(Characters[ChCount].pos)) goto replace1;
+
+ ResetCharacter(&Characters[ChCount]);
+
+ if (Characters[ChCount].AI==AI_ARCHEO)
+ Characters[ChCount].pos.y+=2048.f;
+
+ Characters[ChCount].tgx = Characters[ChCount].pos.x;
+ Characters[ChCount].tgz = Characters[ChCount].pos.z;
+ Characters[ChCount].tgtime = 0;
+
+
+ ChCount++;
+ }
+
+
+
+ int TC = 0;
+ int TDi[10];
+ TDi[0] = 10;
+ for (c=10; c<20; c++)
+ if (TargetDino & (1<<c)) TDi[TC++]=c;
+
+ MC = 8 + OptDens/30 + rRand(6);
+ tr = 0;
+
+ //======== main =========//
+ for (c=0; c<MC; c++) {
+
+ if ((c<4) || (!TargetDino)) Characters[ChCount].CType = AI_to_CIndex[10] + rRand(6); else
+ if (c<10) Characters[ChCount].CType = AI_to_CIndex[ TDi[c % (TC)] ];
+ else Characters[ChCount].CType = AI_to_CIndex[ TDi[rRand(TC-1)] ];
+ //Characters[ChCount].CType = AI_to_CIndex[ AI_BRONT+1];
+ //Characters[ChCount].CType = AI_to_CIndex[10] + 7;//rRand(3);
+replace2:
+ Characters[ChCount].pos.x = 512*256 + siRand(50*256)*10;
+ Characters[ChCount].pos.z = 512*256 + siRand(50*256)*10;
+ Characters[ChCount].pos.y = GetLandH(Characters[ChCount].pos.x,
+ Characters[ChCount].pos.z);
+ tr++;
+ if (tr>10240) break;
+
+ if ( fabs(Characters[ChCount].pos.x - PlayerX) +
+ fabs(Characters[ChCount].pos.z - PlayerZ) < 256 * 40 )
+ goto replace2;
+
+ if (CheckPlaceCollisionP(Characters[ChCount].pos)) goto replace2;
+
+ Characters[ChCount].tgx = Characters[ChCount].pos.x;
+ Characters[ChCount].tgz = Characters[ChCount].pos.z;
+ Characters[ChCount].tgtime = 0;
+
+ ResetCharacter(&Characters[ChCount]);
+ ChCount++;
+ }
+
+ PrintLog("\n");
+ DemoPoint.DemoTime = 0;
+}
+
+
+
+
+
+
+
+
+void CreateChMorphedModel(TCharacter *cptr)
+{
+ TAni *aptr = &cptr->pinfo->Animation[cptr->Phase];
+ TAni *paptr = &cptr->pinfo->Animation[cptr->PrevPhase];
+
+ int CurFrame, SplineD, PCurFrame, PSplineD;
+ float scale = cptr->scale;
+
+ CurFrame = ( (aptr->FramesCount-1) * cptr->FTime * 256) / aptr->AniTime;
+ SplineD = CurFrame & 0xFF;
+ CurFrame = (CurFrame>>8);
+
+
+ BOOL PMorph = (cptr->Phase != cptr->PrevPhase) && (cptr->PPMorphTime < PMORPHTIME) && (MORPHP);
+
+ if (PMorph) {
+ PCurFrame = ( (paptr->FramesCount-1) * cptr->PrevPFTime * 256) / paptr->AniTime;
+ PSplineD = PCurFrame & 0xFF;
+ PCurFrame = (PCurFrame>>8);
+ }
+
+
+
+ if (!MORPHA) { SplineD = 0; PSplineD = 0; }
+
+ float k1, k2, pk1, pk2, pmk1, pmk2;
+
+ k2 = (float)(SplineD) / 256.f;
+ k1 = 1.0f - k2;
+ k1/=8.f; k2/=8.f;
+
+ if (PMorph) {
+ pk2 = (float)(PSplineD) / 256.f;
+ pk1 = 1.0f - pk2;
+ pk1/=8.f; pk2/=8.f;
+ pmk1 = (float)cptr->PPMorphTime / PMORPHTIME;
+ pmk2 = 1.f - pmk1;
+ }
+
+ int VCount = cptr->pinfo->mptr->VCount;
+ short int* adptr = aptr->aniData + CurFrame*VCount*3;
+ short int* padptr = paptr->aniData + PCurFrame*VCount*3;
+
+ float sb = (float)f_sin(cptr->beta) * scale;
+ float cb = (float)f_cos(cptr->beta) * scale;
+ float sg = (float)f_sin(cptr->gamma);
+ float cg = (float)f_cos(cptr->gamma);
+
+ for (int v=0; v<VCount; v++) {
+ float x = *(adptr+v*3+0) * k1 + *(adptr+(v+VCount)*3+0) * k2;
+ float y = *(adptr+v*3+1) * k1 + *(adptr+(v+VCount)*3+1) * k2;
+ float z = - (*(adptr+v*3+2) * k1 + *(adptr+(v+VCount)*3+2) * k2);
+
+ if (PMorph) {
+ float px = *(padptr+v*3+0) * pk1 + *(padptr+(v+VCount)*3+0) * pk2;
+ float py = *(padptr+v*3+1) * pk1 + *(padptr+(v+VCount)*3+1) * pk2;
+ float pz = - (*(padptr+v*3+2) * pk1 + *(padptr+(v+VCount)*3+2) * pk2);
+
+ x = x*pmk1 + px* pmk2;
+ y = y*pmk1 + py* pmk2;
+ z = z*pmk1 + pz* pmk2;
+ }
+
+
+ float zz = z;
+ float xx = cg * x - sg * y;
+ float yy = cg * y + sg * x;
+
+
+ //float fi = (z / 400) * (cptr->bend / 1.5f);
+ float fi;
+ if (z>0) {
+ fi = z / 240.f;
+ if (fi>1.f) fi=1.f;
+ } else {
+ fi = z / 380.f;
+ if (fi<-1.f) fi=-1.f;
+ }
+
+ fi*=cptr->bend;
+
+ float bendc = (float)f_cos(fi);
+ float bends = (float)f_sin(fi);
+
+ float bx = bendc * xx - bends * zz;
+ float bz = bendc * zz + bends * xx;
+ zz = bz;
+ xx = bx;
+
+ cptr->pinfo->mptr->gVertex[v].x = xx * scale;
+ cptr->pinfo->mptr->gVertex[v].y = cb * yy - sb * zz;
+ cptr->pinfo->mptr->gVertex[v].z = cb * zz + sb * yy;
+ }
+}
+
+
+
+void CreateMorphedModel(TModel* mptr, TAni *aptr, int FTime, float scale)
+{
+ int CurFrame = ((aptr->FramesCount-1) * FTime * 256) / aptr->AniTime;
+
+ int SplineD = CurFrame & 0xFF;
+ CurFrame = (CurFrame>>8);
+
+ float k2 = (float)(SplineD) / 256.f;
+ float k1 = 1.0f - k2;
+ k1*=scale/8.f;
+ k2*=scale/8.f;
+
+ int VCount = mptr->VCount;
+ short int* adptr = &(aptr->aniData[CurFrame*VCount*3]);
+ for (int v=0; v<VCount; v++) {
+ mptr->gVertex[v].x = *(adptr+v*3+0) * k1 + *(adptr+(v+VCount)*3+0) * k2;
+ mptr->gVertex[v].y = *(adptr+v*3+1) * k1 + *(adptr+(v+VCount)*3+1) * k2;
+ mptr->gVertex[v].z =- *(adptr+v*3+2) * k1 - *(adptr+(v+VCount)*3+2) * k2;
+ }
+}
+
+
+
+
+void CreateMorphedObject(TModel* mptr, TVTL &vtl, int FTime)
+{
+ int CurFrame = ((vtl.FramesCount-1) * FTime * 256) / vtl.AniTime;
+
+ int SplineD = CurFrame & 0xFF;
+ CurFrame = (CurFrame>>8);
+
+ float k2 = (float)(SplineD) / 256.f;
+ float k1 = 1.0f - k2;
+ k1/=8.f; k2/=8.f;
+
+ int VCount = mptr->VCount;
+ short int* adptr = &(vtl.aniData[CurFrame*VCount*3]);
+ for (int v=0; v<VCount; v++) {
+ mptr->gVertex[v].x = *(adptr+v*3+0) * k1 + *(adptr+(v+VCount)*3+0) * k2;
+ mptr->gVertex[v].y = *(adptr+v*3+1) * k1 + *(adptr+(v+VCount)*3+1) * k2;
+ mptr->gVertex[v].z =- *(adptr+v*3+2) * k1 - *(adptr+(v+VCount)*3+2) * k2;
+ }
+} \ No newline at end of file
diff --git a/Game.cpp b/Game.cpp
new file mode 100644
index 0000000..c9ddbe0
--- /dev/null
+++ b/Game.cpp
@@ -0,0 +1,1731 @@
+#include "Hunt.h"
+
+bool ShowFaces = true;
+
+void UploadGeometry()
+{
+ int x,y,xx,yy;
+ byte temp;
+
+ AudioFCount = 0;
+
+ int MaxView = 20;
+ int HalfView = (int)(MaxView/2)+1;
+
+ for (x = 0; x < MaxView; x++)
+ for (y = 0; y < MaxView; y++)
+ {
+ xx = (x - HalfView)*2;
+ yy = (y - HalfView)*2;
+ data[AudioFCount].x1 = (CCX+xx) * 256 - CameraX;
+ data[AudioFCount].y1 = HMap[CCY+yy][CCX+xx] * ctHScale - CameraY;
+ data[AudioFCount].z1 = (CCY+yy) * 256 - CameraZ;
+
+ xx = ((x+1) - HalfView)*2;
+ yy = (y - HalfView)*2;
+ data[AudioFCount].x2 = (CCX+xx) * 256 - CameraX;
+ data[AudioFCount].y2 = HMap[CCY+yy][CCX+xx] * ctHScale - CameraY;
+ data[AudioFCount].z2 = (CCY+yy) * 256 - CameraZ;
+
+ xx = ((x+1) - HalfView)*2;
+ yy = ((y+1) - HalfView)*2;
+ data[AudioFCount].x3 = (CCX+xx) * 256 - CameraX;
+ data[AudioFCount].y3 = HMap[CCY+yy][CCX+xx] * ctHScale - CameraY;
+ data[AudioFCount].z3 = (CCY+yy) * 256 - CameraZ;
+
+ xx = (x - HalfView)*2;
+ yy = ((y+1) - HalfView)*2;
+ data[AudioFCount].x4 = (CCX+xx) * 256 - CameraX;
+ data[AudioFCount].y4 = HMap[CCY+yy][CCX+xx] * ctHScale - CameraY;
+ data[AudioFCount].z4 = (CCY+yy) * 256 - CameraZ;
+
+ AudioFCount++;
+ }
+
+ if (ShowFaces)
+ { wsprintf(logt,"Audio_UpdateGeometry: %i faces uploaded\n", AudioFCount); PrintLog(logt);
+
+ ShowFaces = false;}
+}
+
+
+void SetupRes()
+{
+ if (!HARD3D)
+ if (OptRes>5) OptRes=5;
+ if (OptRes==0) { WinW = 320; WinH=240; }
+ if (OptRes==1) { WinW = 400; WinH=300; }
+ if (OptRes==2) { WinW = 512; WinH=384; }
+ if (OptRes==3) { WinW = 640; WinH=480; }
+ if (OptRes==4) { WinW = 800; WinH=600; }
+ if (OptRes==5) { WinW =1024; WinH=768; }
+ if (OptRes==6) { WinW =1280; WinH=1024; }
+ if (OptRes==7) { WinW =1600; WinH=1200; }
+}
+
+
+float GetLandOH(int x, int y)
+{
+ return (float)(HMapO[y][x]) * ctHScale;
+}
+
+
+float GetLandOUH(int x, int y)
+{
+ if (FMap[y][x] & fmReverse)
+ return (float)((int)(HMap[y][x+1]+HMap[y+1][x])/2.f)*ctHScale;
+ else
+ return (float)((int)(HMap[y][x]+HMap[y+1][x+1])/2.f)*ctHScale;
+}
+
+
+
+float GetLandUpH(float x, float y)
+{
+
+ int CX = (int)x / 256;
+ int CY = (int)y / 256;
+
+ if (!(FMap[CY][CX] & fmWaterA)) return GetLandH(x,y);
+
+ return (float)(WaterList[ WMap[CY][CX] ].wlevel * ctHScale);
+
+}
+
+
+float GetLandH(float x, float y)
+{
+ int CX = (int)x / 256;
+ int CY = (int)y / 256;
+
+ int dx = (int)x % 256;
+ int dy = (int)y % 256;
+
+ int h1 = HMap[CY][CX];
+ int h2 = HMap[CY][CX+1];
+ int h3 = HMap[CY+1][CX+1];
+ int h4 = HMap[CY+1][CX];
+
+
+ if (FMap[CY][CX] & fmReverse) {
+ if (256-dx>dy) h3 = h2+h4-h1;
+ else h1 = h2+h4-h3;
+ } else {
+ if (dx>dy) h4 = h1+h3-h2;
+ else h2 = h1+h3-h4;
+ }
+
+ float h = (float)
+ (h1 * (256-dx) + h2 * dx) * (256-dy) +
+ (h4 * (256-dx) + h3 * dx) * dy;
+
+ return (h / 256.f / 256.f) * ctHScale;
+}
+
+
+
+float GetLandLt(float x, float y)
+{
+ int CX = (int)x / 256;
+ int CY = (int)y / 256;
+
+ int dx = (int)x % 256;
+ int dy = (int)y % 256;
+
+ int h1 = LMap[CY][CX];
+ int h2 = LMap[CY][CX+1];
+ int h3 = LMap[CY+1][CX+1];
+ int h4 = LMap[CY+1][CX];
+
+ float h = (float)
+ (h1 * (256-dx) + h2 * dx) * (256-dy) +
+ (h4 * (256-dx) + h3 * dx) * dy;
+
+ return (h / 256.f / 256.f);
+}
+
+
+
+float GetLandLt2(float x, float y)
+{
+ int CX = ((int)x / 512)*2 - CCX;
+ int CY = ((int)y / 512)*2 - CCY;
+
+ int dx = (int)x % 512;
+ int dy = (int)y % 512;
+
+ int h1 = VMap[CY+128][CX+128].Light;
+ int h2 = VMap[CY+128][CX+2+128].Light;
+ int h3 = VMap[CY+2+128][CX+2+128].Light;
+ int h4 = VMap[CY+2+128][CX+128].Light;
+
+ float h = (float)
+ (h1 * (512-dx) + h2 * dx) * (512-dy) +
+ (h4 * (512-dx) + h3 * dx) * dy;
+
+ return (h / 512.f / 512.f);
+}
+
+
+
+void CalcModelGroundLight(TModel *mptr, float x0, float z0, int FI)
+{
+ float ca = (float)f_cos(FI * pi / 2);
+ float sa = (float)f_sin(FI * pi / 2);
+ for (int v=0; v<mptr->VCount; v++) {
+ float x = mptr->gVertex[v].x * ca + mptr->gVertex[v].z * sa + x0;
+ float z = mptr->gVertex[v].z * ca - mptr->gVertex[v].x * sa + z0;
+ mptr->VLight[0][v] = GetLandLt2(x, z) - 128;
+ }
+}
+
+
+BOOL PointOnBound(float &H, float px, float py, float cx, float cy, float oy, TBound *bound, int angle)
+{
+ px-=cx;
+ py-=cy;
+
+ float ca = (float) f_cos(angle*pi / 2.f);
+ float sa = (float) f_sin(angle*pi / 2.f);
+
+ BOOL _on = FALSE;
+ H=-10000;
+
+ for (int o=0; o<8; o++) {
+
+ if (bound[o].a<0) continue;
+ if (bound[o].y2 + oy > PlayerY + 128) continue;
+
+ float a,b;
+ float ccx = bound[o].cx*ca + bound[o].cy*sa;
+ float ccy = bound[o].cy*ca - bound[o].cx*sa;
+
+ if (angle & 1) {
+ a = bound[o].b;
+ b = bound[o].a;
+ } else {
+ a = bound[o].a;
+ b = bound[o].b;
+ }
+
+ if ( ( fabs(px - ccx) < a) && (fabs(py - ccy) < b) )
+ {
+ _on=TRUE;
+ if (H < bound[o].y2) H = bound[o].y2;
+ }
+ }
+
+ return _on;
+}
+
+
+
+BOOL PointUnBound(float &H, float px, float py, float cx, float cy, float oy, TBound *bound, int angle)
+{
+ px-=cx;
+ py-=cy;
+
+ float ca = (float) f_cos(angle*pi / 2.f);
+ float sa = (float) f_sin(angle*pi / 2.f);
+
+ BOOL _on = FALSE;
+ H=+10000;
+
+ for (int o=0; o<8; o++) {
+
+ if (bound[o].a<0) continue;
+ if (bound[o].y1 + oy < PlayerY + 128) continue;
+
+ float a,b;
+ float ccx = bound[o].cx*ca + bound[o].cy*sa;
+ float ccy = bound[o].cy*ca - bound[o].cx*sa;
+
+ if (angle & 1) {
+ a = bound[o].b;
+ b = bound[o].a;
+ } else {
+ a = bound[o].a;
+ b = bound[o].b;
+ }
+
+ if ( ( fabs(px - ccx) < a) && (fabs(py - ccy) < b) )
+ {
+ _on=TRUE;
+ if (H > bound[o].y1) H = bound[o].y1;
+ }
+ }
+
+ return _on;
+}
+
+
+
+
+
+float GetLandCeilH(float CameraX, float CameraZ)
+{
+ float h,hh;
+
+ h = GetLandH(CameraX, CameraZ) + 20480;
+
+ int ccx = (int)CameraX / 256;
+ int ccz = (int)CameraZ / 256;
+
+ for (int z=-4; z<=4; z++)
+ for (int x=-4; x<=4; x++)
+ if (OMap[ccz+z][ccx+x]!=255) {
+ int ob = OMap[ccz+z][ccx+x];
+
+ float CR = (float)MObjects[ob].info.Radius - 1.f;
+
+ float oz = (ccz+z) * 256.f + 128.f;
+ float ox = (ccx+x) * 256.f + 128.f;
+
+ float LandY = GetLandOH(ccx+x, ccz+z);
+
+ if (!(MObjects[ob].info.flags & ofBOUND)) {
+ if (MObjects[ob].info.YLo + LandY > h) continue;
+ if (MObjects[ob].info.YLo + LandY < PlayerY+100) continue;
+ }
+
+ float r = CR+1;
+
+ if (MObjects[ob].info.flags & ofBOUND)
+ {
+ float hh;
+ if (PointUnBound(hh, CameraX, CameraZ, ox, oz, LandY, MObjects[ob].bound, ((FMap[ccz+z][ccx+x] >> 2) & 3) ) )
+ if (h > LandY + hh) h = LandY + hh;
+ } else {
+ if (MObjects[ob].info.flags & ofCIRCLE)
+ r = (float) sqrt( (ox-CameraX)*(ox-CameraX) + (oz-CameraZ)*(oz-CameraZ) );
+ else
+ r = (float) max( fabs(ox-CameraX) , fabs(oz-CameraZ) );
+
+ if (r<CR) h = MObjects[ob].info.YLo + LandY;
+ }
+
+ }
+ return h;
+}
+
+
+
+float GetLandQH(float CameraX, float CameraZ)
+{
+ float h,hh;
+
+ h = GetLandH(CameraX, CameraZ);
+ hh = GetLandH(CameraX-90.f, CameraZ-90.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX+90.f, CameraZ-90.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX-90.f, CameraZ+90.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX+90.f, CameraZ+90.f); if (hh>h) h=hh;
+
+ hh = GetLandH(CameraX+128.f, CameraZ); if (hh>h) h=hh;
+ hh = GetLandH(CameraX-128.f, CameraZ); if (hh>h) h=hh;
+ hh = GetLandH(CameraX, CameraZ+128.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX, CameraZ-128.f); if (hh>h) h=hh;
+
+ int ccx = (int)CameraX / 256;
+ int ccz = (int)CameraZ / 256;
+
+ for (int z=-4; z<=4; z++)
+ for (int x=-4; x<=4; x++)
+ if (OMap[ccz+z][ccx+x]!=255) {
+ int ob = OMap[ccz+z][ccx+x];
+
+ float CR = (float)MObjects[ob].info.Radius - 1.f;
+
+ float oz = (ccz+z) * 256.f + 128.f;
+ float ox = (ccx+x) * 256.f + 128.f;
+
+ float LandY = GetLandOH(ccx+x, ccz+z);
+
+ if (!(MObjects[ob].info.flags & ofBOUND)) {
+ if (MObjects[ob].info.YHi + LandY < h) continue;
+ if (MObjects[ob].info.YHi + LandY > PlayerY+128) continue;
+ //if (MObjects[ob].info.YLo + LandY > PlayerY+256) continue;
+ }
+
+ float r = CR+1;
+
+ if (MObjects[ob].info.flags & ofBOUND)
+ {
+ float hh;
+ if (PointOnBound(hh, CameraX, CameraZ, ox, oz, LandY, MObjects[ob].bound, ((FMap[ccz+z][ccx+x] >> 2) & 3) ) )
+ if (h < LandY + hh) h = LandY + hh;
+ } else {
+ if (MObjects[ob].info.flags & ofCIRCLE)
+ r = (float) sqrt( (ox-CameraX)*(ox-CameraX) + (oz-CameraZ)*(oz-CameraZ) );
+ else
+ r = (float) max( fabs(ox-CameraX) , fabs(oz-CameraZ) );
+
+ if (r<CR) h = MObjects[ob].info.YHi + LandY;
+ }
+
+ }
+ return h;
+}
+
+
+float GetLandHObj(float CameraX, float CameraZ)
+{
+ float h;
+
+ h = 0;
+
+ int ccx = (int)CameraX / 256;
+ int ccz = (int)CameraZ / 256;
+
+ for (int z=-3; z<=3; z++)
+ for (int x=-3; x<=3; x++)
+ if (OMap[ccz+z][ccx+x]!=255) {
+ int ob = OMap[ccz+z][ccx+x];
+ float CR = (float)MObjects[ob].info.Radius - 1.f;
+
+ float oz = (ccz+z) * 256.f + 128.f;
+ float ox = (ccx+x) * 256.f + 128.f;
+
+ if (MObjects[ob].info.YHi + GetLandOH(ccx+x, ccz+z) < h) continue;
+ if (MObjects[ob].info.YLo + GetLandOH(ccx+x, ccz+z) > PlayerY+256) continue;
+ float r;
+ if (MObjects[ob].info.flags & ofCIRCLE)
+ r = (float) sqrt( (ox-CameraX)*(ox-CameraX) + (oz-CameraZ)*(oz-CameraZ) );
+ else
+ r = (float) max( fabs(ox-CameraX) , fabs(oz-CameraZ) );
+
+ if (r<CR)
+ h = MObjects[ob].info.YHi + GetLandOH(ccx+x, ccz+z);
+ }
+
+ return h;
+}
+
+
+float GetLandQHNoObj(float CameraX, float CameraZ)
+{
+ float h,hh;
+
+ h = GetLandH(CameraX, CameraZ);
+ hh = GetLandH(CameraX-90.f, CameraZ-90.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX+90.f, CameraZ-90.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX-90.f, CameraZ+90.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX+90.f, CameraZ+90.f); if (hh>h) h=hh;
+
+ hh = GetLandH(CameraX+128.f, CameraZ); if (hh>h) h=hh;
+ hh = GetLandH(CameraX-128.f, CameraZ); if (hh>h) h=hh;
+ hh = GetLandH(CameraX, CameraZ+128.f); if (hh>h) h=hh;
+ hh = GetLandH(CameraX, CameraZ-128.f); if (hh>h) h=hh;
+
+ return h;
+}
+
+
+void ProcessCommandLine()
+{
+ for (int a=0; a<__argc; a++) {
+ LPSTR s = __argv[a];
+ if (strstr(s,"x=")) { PlayerX = (float)atof(&s[2])*256.f; LockLanding = TRUE; }
+ if (strstr(s,"y=")) { PlayerZ = (float)atof(&s[2])*256.f; LockLanding = TRUE; }
+ if (strstr(s,"reg=")) TrophyRoom.RegNumber = atoi(&s[4]);
+ if (strstr(s,"prj=")) strcpy(ProjectName, (s+4));
+ if (strstr(s,"din=")) TargetDino = (atoi(&s[4])*1024);
+ if (strstr(s,"wep=")) WeaponPres = atoi(&s[4]);
+ if (strstr(s,"dtm=")) OptDayNight = atoi(&s[4]);
+
+ if (strstr(s,"-debug")) DEBUG = TRUE;
+ if (strstr(s,"-double")) DoubleAmmo = TRUE;
+ if (strstr(s,"-radar")) RadarMode = TRUE;
+ if (strstr(s,"-tranq")) Tranq = TRUE;
+ if (strstr(s,"-observ")) ObservMode = TRUE;
+ }
+}
+
+
+
+
+void AddWCircle(float x, float z, float scale)
+{
+ WCircles[WCCount].pos.x = x;
+ WCircles[WCCount].pos.z = z;
+ WCircles[WCCount].pos.y = GetLandUpH(x, z);
+ WCircles[WCCount].FTime = 0;
+ WCircles[WCCount].scale = scale;
+ WCCount++;
+}
+
+
+void AddShipTask(int cindex)
+{
+ TCharacter *cptr = &Characters[cindex];
+
+ BOOL TROPHYON = (GetLandUpH(cptr->pos.x, cptr->pos.z) - GetLandH(cptr->pos.x, cptr->pos.z) < 100) &&
+ (!Tranq);
+
+ if (TROPHYON) {
+ ShipTask.clist[ShipTask.tcount] = cindex;
+ ShipTask.tcount++;
+ AddVoicev(ShipModel.SoundFX[3].length,
+ ShipModel.SoundFX[3].lpData, 256);
+ }
+
+ //===== trophy =======//
+ SYSTEMTIME st;
+ GetLocalTime(&st);
+ int t=0;
+ for (t=0; t<23; t++)
+ if (!TrophyRoom.Body[t].ctype) break;
+
+ float score = (float)DinoInfo[Characters[cindex].CType].BaseScore;
+
+ if (TrophyRoom.Last.success>1)
+ score*=(1.f + TrophyRoom.Last.success / 10.f);
+
+ if (!(TargetDino & (1<<Characters[cindex].AI)) ) score/=2.f;
+
+ if (Tranq ) score *= 1.25f;
+ if (RadarMode) score *= 0.70f;
+ if (ScentMode) score *= 0.80f;
+ if (CamoMode ) score *= 0.85f;
+ TrophyRoom.Score+=(int)score;
+
+
+ if (!Tranq) {
+ TrophyTime = 20 * 1000;
+ TrophyBody = t;
+ TrophyRoom.Body[t].ctype = Characters[cindex].CType;
+ TrophyRoom.Body[t].scale = Characters[cindex].scale;
+ TrophyRoom.Body[t].weapon = CurrentWeapon;
+ TrophyRoom.Body[t].score = (int)score;
+ TrophyRoom.Body[t].phase = (RealTime & 3);
+ TrophyRoom.Body[t].time = (st.wHour<<10) + st.wMinute;
+ TrophyRoom.Body[t].date = (st.wYear<<20) + (st.wMonth<<10) + st.wDay;
+ TrophyRoom.Body[t].range = VectorLength( SubVectors(Characters[cindex].pos, PlayerPos) ) / 64.f;
+ PrintLog("Trophy added: ");
+ PrintLog(DinoInfo[Characters[cindex].CType].Name);
+ PrintLog("\n");
+ }
+}
+
+
+
+void InitShip(int cindex)
+{
+ TCharacter *cptr = &Characters[cindex];
+
+ Ship.DeltaY = 2048.f + DinoInfo[cptr->CType].ShDelta * cptr->scale;
+
+ Ship.pos.x = PlayerX - 90*256;
+ if (Ship.pos.x < 256) Ship.pos.x = PlayerX + 90*256;
+ Ship.pos.z = PlayerZ - 90*256;
+ if (Ship.pos.z < 256) Ship.pos.z = PlayerZ + 90*256;
+ Ship.pos.y = GetLandUpH(Ship.pos.x, Ship.pos.z) + Ship.DeltaY + 1024;
+
+ Ship.tgpos.x = cptr->pos.x;
+ Ship.tgpos.z = cptr->pos.z;
+ Ship.tgpos.y = GetLandUpH(Ship.tgpos.x, Ship.tgpos.z) + Ship.DeltaY;
+ Ship.State = 0;
+
+ Ship.retpos = Ship.pos;
+ Ship.cindex = cindex;
+ Ship.FTime = 0;
+}
+
+
+
+void HideWeapon()
+{
+ TWeapon *wptr = &Weapon;
+ if (UNDERWATER && !wptr->state) return;
+ if (ObservMode || TrophyMode) return;
+
+ if (wptr->state == 0) {
+ if (!ShotsLeft[CurrentWeapon]) return;
+ if (WeapInfo[CurrentWeapon].Optic) OPTICMODE = TRUE;
+ AddVoicev(wptr->chinfo[CurrentWeapon].SoundFX[0].length,
+ wptr->chinfo[CurrentWeapon].SoundFX[0].lpData, 256);
+ wptr->FTime = 0;
+ wptr->state = 1;
+ BINMODE = FALSE;
+ MapMode = FALSE;
+ wptr->shakel = 0.2f;
+ return;
+ }
+
+ if (wptr->state!=2 || wptr->FTime!=0) return;
+ AddVoicev(wptr->chinfo[CurrentWeapon].SoundFX[2].length,
+ wptr->chinfo[CurrentWeapon].SoundFX[2].lpData, 256);
+ wptr->state = 3;
+ wptr->FTime = 0;
+ OPTICMODE = FALSE;
+ return ;
+}
+
+
+
+
+
+
+
+
+void InitGameInfo()
+{
+ for (int c=0; c<32; c++) {
+ DinoInfo[c].Scale0 = 800;
+ DinoInfo[c].ScaleA = 600;
+ DinoInfo[c].ShDelta = 0;
+ }
+/*
+ WeapInfo[0].Name = "Shotgun";
+ WeapInfo[0].Power = 1.5f;
+ WeapInfo[0].Prec = 1.1f;
+ WeapInfo[0].Loud = 0.3f;
+ WeapInfo[0].Rate = 1.6f;
+ WeapInfo[0].Shots = 6;
+
+ WeapInfo[1].Name = "X-Bow";
+ WeapInfo[1].Power = 1.1f;
+ WeapInfo[1].Prec = 0.7f;
+ WeapInfo[1].Loud = 1.9f;
+ WeapInfo[1].Rate = 1.2f;
+ WeapInfo[1].Shots = 8;
+
+ WeapInfo[2].Name = "Sniper Rifle";
+ WeapInfo[2].Power = 1.0f;
+ WeapInfo[2].Prec = 1.8f;
+ WeapInfo[2].Loud = 0.6f;
+ WeapInfo[2].Rate = 1.0f;
+ WeapInfo[2].Shots = 6;
+
+
+
+
+ DinoInfo[ 0].Name = "Moschops";
+ DinoInfo[ 0].Health0 = 2;
+ DinoInfo[ 0].Mass = 0.15f;
+
+ DinoInfo[ 1].Name = "Galimimus";
+ DinoInfo[ 1].Health0 = 2;
+ DinoInfo[ 1].Mass = 0.1f;
+
+ DinoInfo[ 2].Name = "Dimorphodon";
+ DinoInfo[ 2].Health0 = 1;
+ DinoInfo[ 2].Mass = 0.05f;
+
+ DinoInfo[ 3].Name = "Dimetrodon";
+ DinoInfo[ 3].Health0 = 2;
+ DinoInfo[ 3].Mass = 0.22f;
+
+
+ DinoInfo[ 5].Name = "Parasaurolophus";
+ DinoInfo[ 5].Mass = 1.5f;
+ DinoInfo[ 5].Length = 5.8f;
+ DinoInfo[ 5].Radius = 320.f;
+ DinoInfo[ 5].Health0 = 5;
+ DinoInfo[ 5].BaseScore = 6;
+ DinoInfo[ 5].SmellK = 0.8f; DinoInfo[ 4].HearK = 1.f; DinoInfo[ 4].LookK = 0.4f;
+ DinoInfo[ 5].ShDelta = 48;
+
+ DinoInfo[ 6].Name = "Pachycephalosaurus";
+ DinoInfo[ 6].Mass = 0.8f;
+ DinoInfo[ 6].Length = 4.5f;
+ DinoInfo[ 6].Radius = 280.f;
+ DinoInfo[ 6].Health0 = 4;
+ DinoInfo[ 6].BaseScore = 8;
+ DinoInfo[ 6].SmellK = 0.4f; DinoInfo[ 5].HearK = 0.8f; DinoInfo[ 5].LookK = 0.6f;
+ DinoInfo[ 6].ShDelta = 36;
+
+ DinoInfo[ 7].Name = "Stegosaurus";
+ DinoInfo[ 7].Mass = 7.f;
+ DinoInfo[ 7].Length = 7.f;
+ DinoInfo[ 7].Radius = 480.f;
+ DinoInfo[ 7].Health0 = 5;
+ DinoInfo[ 7].BaseScore = 7;
+ DinoInfo[ 7].SmellK = 0.4f; DinoInfo[ 6].HearK = 0.8f; DinoInfo[ 6].LookK = 0.6f;
+ DinoInfo[ 7].ShDelta = 128;
+
+ DinoInfo[ 8].Name = "Allosaurus";
+ DinoInfo[ 8].Mass = 0.5;
+ DinoInfo[ 8].Length = 4.2f;
+ DinoInfo[ 8].Radius = 256.f;
+ DinoInfo[ 8].Health0 = 3;
+ DinoInfo[ 8].BaseScore = 12;
+ DinoInfo[ 8].Scale0 = 1000;
+ DinoInfo[ 8].ScaleA = 600;
+ DinoInfo[ 8].SmellK = 1.0f; DinoInfo[ 7].HearK = 0.3f; DinoInfo[ 7].LookK = 0.5f;
+ DinoInfo[ 8].ShDelta = 32;
+ DinoInfo[ 8].DangerCall = TRUE;
+
+ DinoInfo[ 9].Name = "Chasmosaurus";
+ DinoInfo[ 9].Mass = 3.f;
+ DinoInfo[ 9].Length = 5.0f;
+ DinoInfo[ 9].Radius = 400.f;
+ DinoInfo[ 9].Health0 = 8;
+ DinoInfo[ 9].BaseScore = 9;
+ DinoInfo[ 9].SmellK = 0.6f; DinoInfo[ 8].HearK = 0.5f; DinoInfo[ 8].LookK = 0.4f;
+ //DinoInfo[ 8].ShDelta = 148;
+ DinoInfo[ 9].ShDelta = 108;
+
+ DinoInfo[10].Name = "Velociraptor";
+ DinoInfo[10].Mass = 0.3f;
+ DinoInfo[10].Length = 4.0f;
+ DinoInfo[10].Radius = 256.f;
+ DinoInfo[10].Health0 = 3;
+ DinoInfo[10].BaseScore = 16;
+ DinoInfo[10].ScaleA = 400;
+ DinoInfo[10].SmellK = 1.0f; DinoInfo[ 9].HearK = 0.5f; DinoInfo[ 9].LookK = 0.4f;
+ DinoInfo[10].ShDelta =-24;
+ DinoInfo[10].DangerCall = TRUE;
+
+ DinoInfo[11].Name = "T-Rex";
+ DinoInfo[11].Mass = 6.f;
+ DinoInfo[11].Length = 12.f;
+ DinoInfo[11].Radius = 400.f;
+ DinoInfo[11].Health0 = 1024;
+ DinoInfo[11].BaseScore = 20;
+ DinoInfo[11].SmellK = 0.85f; DinoInfo[10].HearK = 0.8f; DinoInfo[10].LookK = 0.8f;
+ DinoInfo[11].ShDelta = 168;
+ DinoInfo[11].DangerCall = TRUE;
+
+ DinoInfo[ 4].Name = "Brahiosaurus";
+ DinoInfo[ 4].Mass = 9.f;
+ DinoInfo[ 4].Length = 12.f;
+ DinoInfo[ 4].Radius = 400.f;
+ DinoInfo[ 4].Health0 = 1024;
+ DinoInfo[ 4].BaseScore = 0;
+ DinoInfo[ 4].SmellK = 0.85f; DinoInfo[16].HearK = 0.8f; DinoInfo[16].LookK = 0.8f;
+ DinoInfo[ 4].ShDelta = 168;
+ DinoInfo[ 4].DangerCall = FALSE;
+*/
+ LoadResourcesScript();
+}
+
+
+
+
+void InitEngine()
+{
+ //DEBUG = TRUE;
+
+ WATERANI = TRUE;
+ NODARKBACK = TRUE;
+ LoDetailSky = TRUE;
+ CORRECTION = TRUE;
+ FOGON = TRUE;
+ FOGENABLE = TRUE;
+ Clouds = TRUE;
+ SKY = TRUE;
+ GOURAUD = TRUE;
+ MODELS = TRUE;
+ TIMER = DEBUG;
+ BITMAPP = FALSE;
+ MIPMAP = TRUE;
+ NOCLIP = FALSE;
+ CLIP3D = TRUE;
+
+
+ SLOW = FALSE;
+ LOWRESTX = FALSE;
+ MORPHP = TRUE;
+ MORPHA = TRUE;
+
+ _GameState = 0;
+
+ RadarMode = FALSE;
+
+ fnt_BIG = CreateFont(
+ 23, 10, 0, 0,
+ 600, 0,0,0,
+#ifdef __rus
+ RUSSIAN_CHARSET,
+#else
+ ANSI_CHARSET,
+#endif
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, NULL);
+
+
+
+
+ fnt_Small = CreateFont(
+ 14, 5, 0, 0,
+ 100, 0,0,0,
+#ifdef __rus
+ RUSSIAN_CHARSET,
+#else
+ ANSI_CHARSET,
+#endif
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, NULL);
+
+
+ fnt_Midd = CreateFont(
+ 16, 7, 0, 0,
+ 550, 0,0,0,
+#ifdef __rus
+ RUSSIAN_CHARSET,
+#else
+ ANSI_CHARSET,
+#endif
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, NULL);
+
+
+ Heap = HeapCreate( 0, 60000000, 64000000 );
+ if( Heap == NULL ) {
+ MessageBox(hwndMain,"Error creating heap.","Error",IDOK);
+ return; }
+
+ Textures[255] = (TEXTURE*) _HeapAlloc(Heap, 0, sizeof(TEXTURE));
+
+ WaterR = 10;
+ WaterG = 38;
+ WaterB = 46;
+ WaterA = 10;
+ TargetDino = 1<<10;
+ TargetCall = 10;
+ WeaponPres = 1;
+ MessageList.timeleft = 0;
+
+ InitGameInfo();
+
+ CreateVideoDIB();
+ CreateFadeTab();
+ CreateDivTable();
+ InitClips();
+
+ TrophyRoom.RegNumber=0;
+
+ PlayerX = (ctMapSize / 3) * 256;
+ PlayerZ = (ctMapSize / 3) * 256;
+
+ ProcessCommandLine();
+
+
+ switch (OptDayNight) {
+ case 0:
+ SunShadowK = 0.7f;
+ Sun3dPos.x = - 4048;
+ Sun3dPos.y = + 2048;
+ Sun3dPos.z = - 4048;
+ break;
+ case 1:
+ SunShadowK = 0.5f;
+ Sun3dPos.x = - 2048;
+ Sun3dPos.y = + 4048;
+ Sun3dPos.z = - 2048;
+ break;
+ case 2:
+ SunShadowK = -0.7f;
+ Sun3dPos.x = + 3048;
+ Sun3dPos.y = + 3048;
+ Sun3dPos.z = + 3048;
+ break;
+ }
+
+ LoadTrophy();
+
+ ProcessCommandLine();
+
+
+
+
+ //ctViewR = 72;
+ //ctViewR1 = 28;
+ //ctViewRM = 24;
+ ctViewR = 42 + (int)(OptViewR / 8)*2;
+ ctViewR1 = 28;
+ ctViewRM = 24;
+
+ Soft_Persp_K = 1.5f;
+ HeadY = 220;
+
+ FogsList[0].fogRGB = 0x000000;
+ FogsList[0].YBegin = 0;
+ FogsList[0].Transp = 000;
+ FogsList[0].FLimit = 000;
+
+ FogsList[127].fogRGB = 0x00504000;
+ FogsList[127].Mortal = FALSE;
+ FogsList[127].Transp = 460;
+ FogsList[127].FLimit = 200;
+
+ FillMemory( FogsMap, sizeof(FogsMap), 0);
+ PrintLog("Init Engine: Ok.\n");
+}
+
+
+
+
+
+void ShutDownEngine()
+{
+ ReleaseDC(hwndMain,hdcMain);
+}
+
+
+
+void ProcessSyncro()
+{
+ RealTime = timeGetTime();
+ srand( (unsigned) RealTime );
+ if (SLOW) RealTime/=4;
+ TimeDt = RealTime - PrevTime;
+ if (TimeDt<0) TimeDt = 10;
+ if (TimeDt>10000) TimeDt = 10;
+ if (TimeDt>1000) TimeDt = 1000;
+ PrevTime = RealTime;
+ Takt++;
+ if (!PAUSE)
+ if (MyHealth) MyHealth+=TimeDt*4;
+ if (MyHealth>MAX_HEALTH) MyHealth = MAX_HEALTH;
+}
+
+
+
+
+
+
+void AddBloodTrail(TCharacter *cptr)
+{
+ if (BloodTrail.Count>508) {
+ memcpy(&BloodTrail.Trail[0], &BloodTrail.Trail[1], 510*sizeof(TBloodP));
+ BloodTrail.Count--;
+ }
+ BloodTrail.Trail[BloodTrail.Count].LTime = 210000;
+ BloodTrail.Trail[BloodTrail.Count].pos = cptr->pos;
+ BloodTrail.Trail[BloodTrail.Count].pos.x+=siRand(32);
+ BloodTrail.Trail[BloodTrail.Count].pos.z+=siRand(32);
+ BloodTrail.Trail[BloodTrail.Count].pos.y =
+ GetLandH(BloodTrail.Trail[BloodTrail.Count].pos.x,
+ BloodTrail.Trail[BloodTrail.Count].pos.z)+4;
+ BloodTrail.Count++;
+}
+
+
+
+
+
+void MakeCall()
+{
+ if (!TargetDino) return;
+ if (UNDERWATER) return;
+ if (ObservMode || TrophyMode) return;
+ if (CallLockTime) return;
+
+ CallLockTime=1024*3;
+
+ NextCall+=(RealTime % 2)+1;
+ NextCall%=3;
+
+ AddVoicev(fxCall[TargetCall-10][NextCall].length,
+ fxCall[TargetCall-10][NextCall].lpData, 256);
+
+ float dmin = 512*256;
+ int ai = -1;
+
+ for (int c=0; c<ChCount; c++) {
+ TCharacter *cptr = &Characters[c];
+
+ if (DinoInfo[AI_to_CIndex[TargetCall] ].DangerCall)
+ if (cptr->AI<10) {
+ cptr->State=2;
+ cptr->AfraidTime = (10 + rRand(5)) * 1024;
+ }
+
+ if (cptr->AI!=TargetCall) continue;
+ if (cptr->AfraidTime) continue;
+ if (cptr->State) continue;
+
+ float d = VectorLength(SubVectors(PlayerPos, cptr->pos));
+ if (d < ctViewR * 400) {
+ if (rRand(128) > 32)
+ if (d<dmin) { dmin = d; ai = c; }
+ cptr->tgx = PlayerX + siRand(1800);
+ cptr->tgz = PlayerZ + siRand(1800);
+ }
+ }
+
+ if (ai!=-1) {
+ answpos = SubVectors(Characters[ai].pos, PlayerPos);
+ answpos.x/=-3.f; answpos.y/=-3.f; answpos.z/=-3.f;
+ answpos = SubVectors(PlayerPos, answpos);
+ answtime = 2000 + rRand(2000);
+ answcall = TargetCall;
+ }
+
+}
+
+
+
+DWORD ColorSum(DWORD C1, DWORD C2)
+{
+ DWORD R,G,B;
+ R = min(255, ((C1>> 0) & 0xFF) + ((C2>> 0) & 0xFF));
+ G = min(255, ((C1>> 8) & 0xFF) + ((C2>> 8) & 0xFF));
+ B = min(255, ((C1>>16) & 0xFF) + ((C2>>16) & 0xFF));
+ return R + (G<<8) + (B<<16);
+}
+
+
+#define partBlood 1
+#define partWater 2
+#define partGround 3
+#define partBubble 4
+
+void AddElements(float x, float y, float z, int etype, int cnt)
+{
+ if (ElCount > 30) {
+ memcpy(&Elements[0], &Elements[1], (ElCount-1) * sizeof(TElements));
+ ElCount--;
+ }
+
+ Elements[ElCount].EDone = 0;
+ Elements[ElCount].Type = etype;
+ Elements[ElCount].ECount = min(30, cnt);
+ int c;
+
+ switch (etype) {
+ case partBlood:
+#ifdef _d3d
+ Elements[ElCount].RGBA = 0xE0600000;
+ Elements[ElCount].RGBA2= 0x20300000;
+#else
+ Elements[ElCount].RGBA = 0xE0000060;
+ Elements[ElCount].RGBA2= 0x20000030;
+#endif
+ break;
+
+ case partGround:
+#ifdef _d3d
+ Elements[ElCount].RGBA = 0xF0F09E55;
+ Elements[ElCount].RGBA2= 0x10F09E55;
+#else
+ Elements[ElCount].RGBA = 0xF0559EF0;
+ Elements[ElCount].RGBA2= 0x10559EF0;
+#endif
+ break;
+
+
+ case partBubble:
+ c = WaterList[ WMap[ (int)z / 256][ (int)x / 256] ].fogRGB;
+#ifdef _d3d
+ c = ColorSum( ((c & 0xFEFEFE)>>1) , 0x152020);
+#else
+ c = ColorSum( ((c & 0xFEFEFE)>>1) , 0x202015);
+#endif
+ Elements[ElCount].RGBA = 0x70000000 + (ColorSum(c, ColorSum(c,c)));
+ Elements[ElCount].RGBA2= 0x40000000 + (ColorSum(c, c));
+ break;
+
+ case partWater:
+ c = WaterList[ WMap[ (int)z / 256][ (int)x / 256] ].fogRGB;
+#ifdef _d3d
+ c = ColorSum( ((c & 0xFEFEFE)>>1) , 0x152020);
+#else
+ c = ColorSum( ((c & 0xFEFEFE)>>1) , 0x202015);
+#endif
+ Elements[ElCount].RGBA = 0xB0000000 + ( ColorSum(c, ColorSum(c,c)) );
+ Elements[ElCount].RGBA2 = 0x40000000 + (c);
+ break;
+ }
+
+ Elements[ElCount].RGBA = conv_xGx(Elements[ElCount].RGBA);
+ Elements[ElCount].RGBA2 = conv_xGx(Elements[ElCount].RGBA2);
+
+ float al = siRand(128) / 128.f * pi / 4.f;
+ float ss = f_sin(al);
+ float cc = f_cos(al);
+
+ for (int e=0; e<Elements[ElCount].ECount; e++) {
+ Elements[ElCount].EList[e].pos.x = x;
+ Elements[ElCount].EList[e].pos.y = y;
+ Elements[ElCount].EList[e].pos.z = z;
+ Elements[ElCount].EList[e].R = 6 + rRand(5);
+ Elements[ElCount].EList[e].Flags = 0;
+ float v;
+
+ switch (etype) {
+ case partBlood:
+ v = e * 6 + rRand(96) + 220;
+ Elements[ElCount].EList[e].speed.x =ss*ca*v + siRand(32);
+ Elements[ElCount].EList[e].speed.y =cc * (v * 3);
+ Elements[ElCount].EList[e].speed.z =ss*sa*v + siRand(32);
+ break;
+ case partGround:
+ Elements[ElCount].EList[e].speed.x =siRand(52)-sa*64;
+ Elements[ElCount].EList[e].speed.y =rRand(100) + 600 + e * 20;
+ Elements[ElCount].EList[e].speed.z =siRand(52)+ca*64;
+ break;
+ case partWater:
+ Elements[ElCount].EList[e].speed.x =siRand(32);
+ Elements[ElCount].EList[e].speed.y =rRand(80) + 400 + e * 40;
+ Elements[ElCount].EList[e].speed.z =siRand(32);
+ break;
+ case partBubble:
+ Elements[ElCount].EList[e].speed.x =siRand(40);
+ Elements[ElCount].EList[e].speed.y =rRand(140) + 20;
+ Elements[ElCount].EList[e].speed.z =siRand(40);
+ break;
+ }
+ }
+
+ ElCount++;
+}
+
+
+void MakeShot(float ax, float ay, float az,
+ float bx, float by, float bz)
+{
+ int sres;
+ if (!WeapInfo[CurrentWeapon].Fall)
+ sres = TraceShot(ax, ay, az, bx, by, bz);
+ else {
+ Vector3d dl;
+ float dy = 40.f * ctViewR / 36.f;
+ dl.x = (bx-ax) / 3;
+ dl.y = (by-ay) / 3;
+ dl.z = (bz-az) / 3;
+ bx = ax + dl.x;
+ by = ay + dl.y - dy / 2;
+ bz = az + dl.z;
+ sres = TraceShot(ax, ay, az, bx, by, bz);
+ if (sres!=-1) goto ENDTRACE;
+ ax = bx; ay = by; az = bz;
+
+ bx = ax + dl.x;
+ by = ay + dl.y - dy * 3;
+ bz = az + dl.z;
+ sres = TraceShot(ax, ay, az, bx, by, bz);
+ if (sres!=-1) goto ENDTRACE;
+ ax = bx; ay = by; az = bz;
+
+ bx = ax + dl.x;
+ by = ay + dl.y - dy * 5;
+ bz = az + dl.z;
+ sres = TraceShot(ax, ay, az, bx, by, bz);
+ if (sres!=-1) goto ENDTRACE;
+ ax = bx; ay = by; az = bz;
+ }
+
+ENDTRACE:
+ if (sres==-1) return;
+
+ int mort = (sres & 0xFF00) && (Characters[ShotDino].Health);
+ sres &= 0xFF;
+
+ if (sres == tresGround)
+ AddElements(bx, by, bz, partGround, 6 + WeapInfo[CurrentWeapon].Power*4);
+ if (sres == tresModel)
+ AddElements(bx, by, bz, partGround, 6 + WeapInfo[CurrentWeapon].Power*4);
+
+
+ if (sres == tresWater) {
+ AddElements(bx, by, bz, partWater, 4 + WeapInfo[CurrentWeapon].Power*3);
+ //AddElements(bx, GetLandH(bx, bz), bz, partBubble);
+ AddWCircle(bx, bz, 1.2);
+ AddWCircle(bx, bz, 1.2);
+ }
+
+
+ if (sres!=tresChar) return;
+ AddElements(bx, by, bz, partBlood, 4 + WeapInfo[CurrentWeapon].Power*4);
+ if (!Characters[ShotDino].Health) return;
+
+//======= character damage =========//
+
+
+ if (mort) Characters[ShotDino].Health = 0;
+ else Characters[ShotDino].Health-=WeapInfo[CurrentWeapon].Power;
+ if (Characters[ShotDino].Health<0) Characters[ShotDino].Health=0;
+
+
+ if (!Characters[ShotDino].Health) {
+ if (Characters[ShotDino].AI>=10) {
+ TrophyRoom.Last.success++;
+ AddShipTask(ShotDino);
+ }
+
+ if (Characters[ShotDino].AI<10)
+ Characters_AddSecondaryOne(Characters[ShotDino].CType);
+
+ }
+ else {
+ Characters[ShotDino].AfraidTime = 60*1000;
+ if (Characters[ShotDino].State==0)
+ Characters[ShotDino].State = 2;
+
+ Characters[ShotDino].BloodTTime+=90000;
+
+ }
+
+}
+
+
+void RemoveCharacter(int index)
+{
+ if (index==-1) return;
+ memcpy( &Characters[index], &Characters[index+1], (255 - index) * sizeof(TCharacter) );
+ ChCount--;
+
+ if (DemoPoint.CIndex > index) DemoPoint.CIndex--;
+
+ for (int c=0; c<ShipTask.tcount; c++)
+ if (ShipTask.clist[c]>index) ShipTask.clist[c]--;
+}
+
+
+void AnimateShip()
+{
+ if (Ship.State==-1) {
+ SetAmbient3d(0,0, 0,0,0);
+ if (!ShipTask.tcount) return;
+ InitShip(ShipTask.clist[0]);
+ memcpy(&ShipTask.clist[0], &ShipTask.clist[1], 250*4);
+ ShipTask.tcount--;
+ return;
+ }
+
+ SetAmbient3d(ShipModel.SoundFX[0].length,
+ ShipModel.SoundFX[0].lpData,
+ Ship.pos.x, Ship.pos.y, Ship.pos.z);
+
+ int _TimeDt = TimeDt;
+
+//====== get up/down time acceleration ===========//
+ if (Ship.FTime) {
+ int am = ShipModel.Animation[0].AniTime;
+ if (Ship.FTime < 500) _TimeDt = TimeDt * (Ship.FTime + 48) / 548;
+ if (am-Ship.FTime < 500) _TimeDt = TimeDt * (am-Ship.FTime + 48) / 548;
+ if (_TimeDt<2) _TimeDt=2;
+ }
+//===================================
+
+ float L = VectorLength( SubVectors(Ship.tgpos, Ship.pos) );
+ float L2 = sqrt ( (Ship.tgpos.x - Ship.pos.x) * (Ship.tgpos.x - Ship.pos.x) +
+ (Ship.tgpos.x - Ship.pos.x) * (Ship.tgpos.x - Ship.pos.x) );
+
+ Ship.pos.y+=0.3f*(float)f_cos(RealTime / 256.f);
+
+
+
+ Ship.tgalpha = FindVectorAlpha(Ship.tgpos.x - Ship.pos.x, Ship.tgpos.z - Ship.pos.z);
+ float currspeed;
+ float dalpha = (float)fabs(Ship.tgalpha - Ship.alpha);
+ float drspd = dalpha; if (drspd>pi) drspd = 2*pi - drspd;
+
+
+//====== fly more away if I near =============//
+ if (Ship.State)
+ if (Ship.speed>1)
+ if (L<4000)
+ if (VectorLength(SubVectors(PlayerPos, Ship.pos))<(ctViewR+2)*256) {
+ Ship.tgpos.x += (float)f_cos(Ship.alpha) * 256*6.f;
+ Ship.tgpos.z += (float)f_sin(Ship.alpha) * 256*6.f;
+ Ship.tgpos.y = GetLandUpH(Ship.tgpos.x, Ship.tgpos.z) + Ship.DeltaY;
+ Ship.tgpos.y = max(Ship.tgpos.y, GetLandUpH(Ship.pos.x, Ship.pos.z) + Ship.DeltaY);
+ }
+//==============================//
+
+
+
+//========= animate down ==========//
+ if (Ship.State==3) {
+ Ship.FTime+=_TimeDt;
+ if (Ship.FTime>=ShipModel.Animation[0].AniTime) {
+ Ship.FTime=ShipModel.Animation[0].AniTime-1;
+ Ship.State=2;
+ AddVoicev(ShipModel.SoundFX[4].length,
+ ShipModel.SoundFX[4].lpData, 256);
+ AddVoice3d(ShipModel.SoundFX[1].length, ShipModel.SoundFX[1].lpData,
+ Ship.pos.x, Ship.pos.y, Ship.pos.z);
+ }
+ return;
+ }
+
+
+//========= get body on board ==========//
+ if (Ship.State) {
+ if (Ship.cindex!=-1) {
+ DeltaFunc(Characters[Ship.cindex].pos.y, Ship.pos.y-650 - (Ship.DeltaY-2048), _TimeDt / 3.f);
+ DeltaFunc(Characters[Ship.cindex].beta, 0, TimeDt / 4048.f);
+ DeltaFunc(Characters[Ship.cindex].gamma, 0, TimeDt / 4048.f);
+ }
+
+ if (Ship.State==2) {
+ Ship.FTime-=_TimeDt;
+ if (Ship.FTime<0) Ship.FTime=0;
+
+ if (Ship.FTime==0)
+ if (fabs(Characters[Ship.cindex].pos.y - (Ship.pos.y-650 - (Ship.DeltaY-2048))) < 1.f) {
+ Ship.State = 1;
+ AddVoicev(ShipModel.SoundFX[5].length,
+ ShipModel.SoundFX[5].lpData, 256);
+ AddVoice3d(ShipModel.SoundFX[2].length, ShipModel.SoundFX[2].lpData,
+ Ship.pos.x, Ship.pos.y, Ship.pos.z);
+ }
+ return;
+ }
+ }
+//=====================================//
+
+
+//====== speed ===============//
+ float vspeed = 1.f + L / 128.f;
+ if (vspeed > 24) vspeed = 24;
+ if (Ship.State) vspeed = 24;
+ if (fabs(dalpha) > 0.4) vspeed = 0.f;
+ float _s = Ship.speed;
+ if (vspeed>Ship.speed) DeltaFunc(Ship.speed, vspeed, TimeDt / 200.f);
+ else Ship.speed = vspeed;
+
+ if (Ship.speed>0 && _s==0)
+ AddVoice3d(ShipModel.SoundFX[2].length, ShipModel.SoundFX[2].lpData,
+ Ship.pos.x, Ship.pos.y, Ship.pos.z);
+
+//====== fly ===========//
+ float l = TimeDt * Ship.speed / 16.f;
+
+ if (fabs(dalpha) < 0.4)
+ if (l<L) {
+ if (l>L2) l = L2 * 0.5f;
+ if (L2<0.1) l = 0;
+ Ship.pos.x += (float)f_cos(Ship.alpha)*l;
+ Ship.pos.z += (float)f_sin(Ship.alpha)*l;
+ } else {
+ if (Ship.State) {
+ Ship.State = -1;
+ RemoveCharacter(Ship.cindex);
+ return;
+ } else {
+ Ship.pos = Ship.tgpos;
+ Ship.State = 3;
+ Ship.FTime = 1;
+ Ship.tgpos = Ship.retpos;
+ Ship.tgpos.y = GetLandUpH(Ship.tgpos.x, Ship.tgpos.z) + Ship.DeltaY;
+ Ship.tgpos.y = max(Ship.tgpos.y, GetLandUpH(Ship.pos.x, Ship.pos.z) + Ship.DeltaY);
+ Characters[Ship.cindex].StateF = 0xFF;
+ AddVoice3d(ShipModel.SoundFX[1].length, ShipModel.SoundFX[1].lpData,
+ Ship.pos.x, Ship.pos.y, Ship.pos.z);
+ }
+ }
+
+//======= y movement ============//
+ float h = GetLandUpH(Ship.pos.x, Ship.pos.z);
+ DeltaFunc(Ship.pos.y, Ship.tgpos.y, TimeDt / 4.f);
+ if (Ship.pos.y < h + 1024) {
+ if (Ship.State)
+ if (Ship.cindex!=-1)
+ Characters[Ship.cindex].pos.y+= h + 1024 - Ship.pos.y;
+ Ship.pos.y = h + 1024;
+ }
+
+
+
+//======= rotation ============//
+
+ if (Ship.tgalpha > Ship.alpha) currspeed = 0.1f + (float)fabs(drspd)/2.f;
+ else currspeed =-0.1f - (float)fabs(drspd)/2.f;
+
+ if (fabs(dalpha) > pi) currspeed=-currspeed;
+
+
+ DeltaFunc(Ship.rspeed, currspeed, (float)TimeDt / 420.f);
+
+ float rspd=Ship.rspeed * TimeDt / 1024.f;
+ if (fabs(drspd) < fabs(rspd)) { Ship.alpha = Ship.tgalpha; Ship.rspeed/=2; }
+ else {
+ Ship.alpha+=rspd;
+ if (Ship.State)
+ if (Ship.cindex!=-1)
+ Characters[Ship.cindex].alpha+=rspd;
+ }
+
+ if (Ship.alpha<0) Ship.alpha+=pi*2;
+ if (Ship.alpha>pi*2) Ship.alpha-=pi*2;
+
+//======== move body ===========//
+ if (Ship.State) {
+ if (Ship.cindex!=-1) {
+ Characters[Ship.cindex].pos.x = Ship.pos.x;
+ Characters[Ship.cindex].pos.z = Ship.pos.z;
+ }
+ if (L>1000) Ship.tgpos.y+=TimeDt / 12.f;
+ } else {
+ Ship.tgpos.x = Characters[Ship.cindex].pos.x;
+ Ship.tgpos.z = Characters[Ship.cindex].pos.z;
+ Ship.tgpos.y = GetLandUpH(Ship.tgpos.x, Ship.tgpos.z) + Ship.DeltaY;
+ Ship.tgpos.y = max(Ship.tgpos.y, GetLandUpH(Ship.pos.x, Ship.pos.z) + Ship.DeltaY);
+ }
+
+
+
+}
+
+
+
+void ProcessTrophy()
+{
+ TrophyBody = -1;
+
+ for (int c=0; c<ChCount; c++) {
+ Vector3d p = Characters[c].pos;
+ p.x+=Characters[c].lookx * 256*2.5f;
+ p.z+=Characters[c].lookz * 256*2.5f;
+
+ if (VectorLength( SubVectors(p, PlayerPos) ) < 148)
+ TrophyBody = c;
+ }
+
+ if (TrophyBody==-1) return;
+
+ TrophyBody = Characters[TrophyBody].State;
+}
+
+
+
+void RespawnSnow(int s, BOOL rand)
+{
+ Snow[s].pos.x = PlayerX + siRand(12*256);
+ Snow[s].pos.z = PlayerZ + siRand(12*256);
+ Snow[s].hl = GetLandUpH(Snow[s].pos.x, Snow[s].pos.z);
+ Snow[s].ftime = 0;
+ if (rand) Snow[s].pos.y = Snow[s].hl + 256+rRand(12*256);
+ else Snow[s].pos.y = Snow[s].hl + (8+rRand(5))*256;
+}
+
+
+
+
+void AnimateElements()
+{
+for (int eg=0; eg<ElCount; eg++) {
+
+ if (Elements[eg].Type == partGround) {
+ int a1 = Elements[eg].RGBA >> 24; a1-=TimeDt/4; if (a1<0) a1=0; Elements[eg].RGBA = (Elements[eg].RGBA & 0x00FFFFFF) + (a1<<24);
+ int a2 = Elements[eg].RGBA2>> 24; a2-=TimeDt/4; if (a2<0) a2=0; Elements[eg].RGBA2= (Elements[eg].RGBA2 & 0x00FFFFFF) + (a2<<24);
+ if (a1 == 0 && a2==0) Elements[eg].ECount = 0;
+ }
+
+ if (Elements[eg].Type == partWater)
+ if (Elements[eg].EDone == Elements[eg].ECount)
+ Elements[eg].ECount = 0;
+
+ if (Elements[eg].Type == partBubble)
+ if (Elements[eg].EDone == Elements[eg].ECount)
+ Elements[eg].ECount = 0;
+
+ if (Elements[eg].Type == partBlood)
+ if ((Takt & 3)==0)
+ if (Elements[eg].EDone == Elements[eg].ECount) {
+ int a1 = Elements[eg].RGBA >> 24; a1--; if (a1<0) a1=0; Elements[eg].RGBA = (Elements[eg].RGBA & 0x00FFFFFF) + (a1<<24);
+ int a2 = Elements[eg].RGBA2>> 24; a2--; if (a2<0) a2=0; Elements[eg].RGBA2= (Elements[eg].RGBA2 & 0x00FFFFFF) + (a2<<24);
+ if (a1 == 0 && a2==0) Elements[eg].ECount = 0;
+ }
+
+
+
+//====== remove finished process =========//
+ if (!Elements[eg].ECount) {
+ memcpy(&Elements[eg], &Elements[eg+1], (ElCount+1-eg) * sizeof(TElements));
+ ElCount--;
+ eg--;
+ continue;
+ }
+
+
+ for (int e=0; e<Elements[eg].ECount; e++) {
+ if (Elements[eg].EList[e].Flags) continue;
+ Elements[eg].EList[e].pos.x+=Elements[eg].EList[e].speed.x * TimeDt / 1000.f;
+ Elements[eg].EList[e].pos.y+=Elements[eg].EList[e].speed.y * TimeDt / 1000.f;
+ Elements[eg].EList[e].pos.z+=Elements[eg].EList[e].speed.z * TimeDt / 1000.f;
+
+ float h;
+ h = GetLandUpH(Elements[eg].EList[e].pos.x, Elements[eg].EList[e].pos.z);
+ BOOL OnWater = GetLandH(Elements[eg].EList[e].pos.x, Elements[eg].EList[e].pos.z) < h;
+
+ switch (Elements[eg].Type) {
+ case partBubble:
+ Elements[eg].EList[e].speed.y += 2.0 * 256 * TimeDt / 1000.f;
+ if (Elements[eg].EList[e].speed.y > 824) Elements[eg].EList[e].speed.y = 824;
+ if (Elements[eg].EList[e].pos.y > h) {
+ AddWCircle(Elements[eg].EList[e].pos.x, Elements[eg].EList[e].pos.z, 0.6);
+ Elements[eg].EDone++;
+ Elements[eg].EList[e].Flags = 1;
+ if (OnWater) Elements[eg].EList[e].pos.y-= 10240;
+ }
+ break;
+
+ default:
+ Elements[eg].EList[e].speed.y -= 9.8 * 256 * TimeDt / 1000.f;
+ if (Elements[eg].EList[e].pos.y < h) {
+ if (OnWater) AddWCircle(Elements[eg].EList[e].pos.x, Elements[eg].EList[e].pos.z, 0.6);
+ Elements[eg].EDone++;
+ Elements[eg].EList[e].Flags = 1;
+ if (OnWater) Elements[eg].EList[e].pos.y-= 10240;
+ else Elements[eg].EList[e].pos.y = h + 4;
+ }
+ break;
+
+ } //== switch ==//
+
+ } // for(e) //
+ } // for(eg) //
+
+ for (int b=0; b<BloodTrail.Count; b++) {
+ BloodTrail.Trail[b].LTime-=TimeDt;
+ if (BloodTrail.Trail[b].LTime<=0) {
+ memcpy(&BloodTrail.Trail[b], &BloodTrail.Trail[b+1], (511-b)*sizeof(TBloodP));
+ BloodTrail.Count--;
+ b--;
+ }
+ }
+
+ if (!SNOW) return;
+ while (SnCount<2000) {
+ RespawnSnow(SnCount, TRUE);
+ SnCount++;
+ }
+
+ nv = Wind.nv;
+ NormVector(nv, (4+Wind.speed)*4*TimeDt/1000);
+
+ for (int s=0; s<SnCount; s++) {
+
+ if ( (fabs(Snow[s].pos.x - PlayerX) > 14*256) ||
+ (fabs(Snow[s].pos.z - PlayerZ) > 14*256) ) {
+ Snow[s].pos.x = PlayerX + siRand(12*256);
+ Snow[s].pos.z = PlayerZ + siRand(12*256);
+ Snow[s].pos.y = Snow[s].pos.y - Snow[s].hl;
+ Snow[s].hl = GetLandUpH(Snow[s].pos.x, Snow[s].pos.z);
+ Snow[s].pos.y+=Snow[s].hl;
+ }
+
+ if (!Snow[s].ftime) {
+ float v = ( ((RealTime + s * 23) % 800) - 400) * TimeDt / 16000;
+ Snow[s].pos.x+=ca*v;
+ Snow[s].pos.z+=sa*v;
+
+ Snow[s].pos = AddVectors(Snow[s].pos, nv);
+ Snow[s].hl = GetLandUpH(Snow[s].pos.x, Snow[s].pos.z);
+ Snow[s].pos.y-=TimeDt*192/1000.f;
+ if (Snow[s].pos.y < Snow[s].hl+8) {
+ Snow[s].pos.y = Snow[s].hl+8;
+ Snow[s].ftime = 1;
+ }
+ } else {
+ Snow[s].ftime+=TimeDt;
+ Snow[s].pos.y-=TimeDt*3/1000.f;
+ if (Snow[s].ftime>2000) RespawnSnow(s, FALSE);
+ }
+
+ }
+}
+
+
+void AnimateProcesses()
+{
+ AnimateElements();
+
+ if ((Takt & 63)==0) {
+ float al2 = CameraAlpha + siRand(60) * pi / 180.f;
+ float c2 = f_cos(al2);
+ float s2 = f_sin(al2);
+ float l = 1024 + rRand(3120);
+ float xx = CameraX + s2 * l;
+ float zz = CameraZ - c2 * l;
+ if (GetLandUpH(xx,zz) > GetLandH(xx,zz)+256)
+ AddElements(xx, GetLandH(xx,zz), zz, 4, 6 + rRand(6));
+ }
+
+ if (Takt & 1) {
+ Wind.alpha+=siRand(16) / 4096.f;
+ Wind.speed+=siRand(400) / 6400.f;
+ }
+
+ if (Wind.speed< 4.f) Wind.speed=4.f;
+ if (Wind.speed>18.f) Wind.speed=18.f;
+
+ Wind.nv.x = (float) f_sin(Wind.alpha);
+ Wind.nv.z = (float)-f_cos(Wind.alpha);
+ Wind.nv.y = 0.f;
+
+
+ if (answtime) {
+ answtime-=TimeDt;
+ if (answtime<=0) {
+ answtime = 0;
+ int r = rRand(128) % 3;
+ AddVoice3d(fxCall[answcall-10][r].length, fxCall[answcall-10][r].lpData,
+ answpos.x, answpos.y, answpos.z);
+ }
+ }
+
+
+
+ if (CallLockTime) {
+ CallLockTime-=TimeDt;
+ if (CallLockTime<0) CallLockTime=0;
+ }
+
+ CheckAfraid();
+ AnimateShip();
+ if (TrophyMode)
+ ProcessTrophy();
+
+ for (int w=0; w<WCCount; w++) {
+ if (WCircles[w].scale > 1)
+ WCircles[w].FTime+=(int)(TimeDt*3 / WCircles[w].scale);
+ else
+ WCircles[w].FTime+=TimeDt*3;
+ if (WCircles[w].FTime >= 2000) {
+ memcpy(&WCircles[w], &WCircles[w+1], sizeof(TWCircle) * (WCCount+1-w) );
+ w--;
+ WCCount--;
+ }
+ }
+
+
+
+ if (ExitTime) {
+ ExitTime-=TimeDt;
+ if (ExitTime<=0) {
+ TrophyRoom.Total.time +=TrophyRoom.Last.time;
+ TrophyRoom.Total.smade +=TrophyRoom.Last.smade;
+ TrophyRoom.Total.success+=TrophyRoom.Last.success;
+ TrophyRoom.Total.path +=TrophyRoom.Last.path;
+
+ if (MyHealth) SaveTrophy();
+ else LoadTrophy();
+ DoHalt("");
+ }
+ }
+}
+
+
+
+void RemoveCurrentTrophy()
+{
+ int p = 0;
+ if (!TrophyMode) return;
+ if (!TrophyRoom.Body[TrophyBody].ctype) return;
+
+ PrintLog("Trophy removed: ");
+ PrintLog(DinoInfo[TrophyRoom.Body[TrophyBody].ctype].Name);
+ PrintLog("\n");
+
+ for (int c=0; c<TrophyBody; c++)
+ if (TrophyRoom.Body[c].ctype) p++;
+
+
+ TrophyRoom.Body[TrophyBody].ctype = 0;
+
+ if (TrophyMode) {
+ memcpy(&Characters[p],
+ &Characters[p+1],
+ (250-p) * sizeof(TCharacter) );
+ ChCount--;
+ }
+
+ TrophyTime = 0;
+ TrophyBody = -1;
+}
+
+
+void LoadTrophy()
+{
+ int pr = TrophyRoom.RegNumber;
+ FillMemory(&TrophyRoom, sizeof(TrophyRoom), 0);
+ TrophyRoom.RegNumber = pr;
+ DWORD l;
+ char fname[128];
+ int rn = TrophyRoom.RegNumber;
+ wsprintf(fname, "trophy0%d.sav", TrophyRoom.RegNumber);
+ HANDLE hfile = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hfile==INVALID_HANDLE_VALUE) {
+ PrintLog("===> Error loading trophy!\n");
+ return;
+ }
+ ReadFile(hfile, &TrophyRoom, sizeof(TrophyRoom), &l, NULL);
+
+ ReadFile(hfile, &OptAgres, 4, &l, NULL);
+ ReadFile(hfile, &OptDens , 4, &l, NULL);
+ ReadFile(hfile, &OptSens , 4, &l, NULL);
+
+ ReadFile(hfile, &OptRes, 4, &l, NULL);
+ ReadFile(hfile, &FOGENABLE, 4, &l, NULL);
+ ReadFile(hfile, &OptText , 4, &l, NULL);
+ ReadFile(hfile, &OptViewR, 4, &l, NULL);
+ ReadFile(hfile, &SHADOWS3D, 4, &l, NULL);
+ ReadFile(hfile, &OptMsSens, 4, &l, NULL);
+ ReadFile(hfile, &OptBrightness, 4, &l, NULL);
+
+
+ ReadFile(hfile, &KeyMap, sizeof(KeyMap), &l, NULL);
+ ReadFile(hfile, &REVERSEMS, 4, &l, NULL);
+
+ ReadFile(hfile, &ScentMode, 4, &l, NULL);
+ ReadFile(hfile, &CamoMode, 4, &l, NULL);
+ ReadFile(hfile, &RadarMode, 4, &l, NULL);
+ ReadFile(hfile, &Tranq , 4, &l, NULL);
+ ReadFile(hfile, &OPT_ALPHA_COLORKEY, 4, &l, NULL);
+
+ ReadFile(hfile, &OptSys , 4, &l, NULL);
+ ReadFile(hfile, &OptSound , 4, &l, NULL);
+ ReadFile(hfile, &OptRender, 4, &l, NULL);
+
+
+ SetupRes();
+
+ CloseHandle(hfile);
+ TrophyRoom.RegNumber = rn;
+ PrintLog("Trophy Loaded.\n");
+// TrophyRoom.Score = 299;
+}
+
+
+
+
+void SaveTrophy()
+{
+ DWORD l;
+ char fname[128];
+ wsprintf(fname, "trophy0%d.sav", TrophyRoom.RegNumber);
+
+ int r = TrophyRoom.Rank;
+ TrophyRoom.Rank = 0;
+ if (TrophyRoom.Score >= 100) TrophyRoom.Rank = 1;
+ if (TrophyRoom.Score >= 300) TrophyRoom.Rank = 2;
+
+
+ HANDLE hfile = CreateFile(fname, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hfile == INVALID_HANDLE_VALUE) {
+ PrintLog("==>> Error saving trophy!\n");
+ return;
+ }
+ WriteFile(hfile, &TrophyRoom, sizeof(TrophyRoom), &l, NULL);
+
+ WriteFile(hfile, &OptAgres, 4, &l, NULL);
+ WriteFile(hfile, &OptDens , 4, &l, NULL);
+ WriteFile(hfile, &OptSens , 4, &l, NULL);
+
+ WriteFile(hfile, &OptRes, 4, &l, NULL);
+ WriteFile(hfile, &FOGENABLE, 4, &l, NULL);
+ WriteFile(hfile, &OptText , 4, &l, NULL);
+ WriteFile(hfile, &OptViewR, 4, &l, NULL);
+ WriteFile(hfile, &SHADOWS3D, 4, &l, NULL);
+ WriteFile(hfile, &OptMsSens, 4, &l, NULL);
+ WriteFile(hfile, &OptBrightness, 4, &l, NULL);
+
+ WriteFile(hfile, &KeyMap, sizeof(KeyMap), &l, NULL);
+ WriteFile(hfile, &REVERSEMS, 4, &l, NULL);
+
+ WriteFile(hfile, &ScentMode, 4, &l, NULL);
+ WriteFile(hfile, &CamoMode , 4, &l, NULL);
+ WriteFile(hfile, &RadarMode, 4, &l, NULL);
+ WriteFile(hfile, &Tranq , 4, &l, NULL);
+ WriteFile(hfile, &OPT_ALPHA_COLORKEY, 4, &l, NULL);
+
+ WriteFile(hfile, &OptSys , 4, &l, NULL);
+ WriteFile(hfile, &OptSound , 4, &l, NULL);
+ WriteFile(hfile, &OptRender, 4, &l, NULL);
+ CloseHandle(hfile);
+ PrintLog("Trophy Saved.\n");
+}
+
diff --git a/Hunt.h b/Hunt.h
new file mode 100644
index 0000000..3a3a4fb
--- /dev/null
+++ b/Hunt.h
@@ -0,0 +1,1114 @@
+#include "math.h"
+#include "windows.h"
+#include "winuser.h"
+
+#include "resource.h"
+
+#include "ddraw.h"
+
+#ifdef _d3d
+#include <d3d.h>
+#endif
+
+#define ctHScale 64
+#define PMORPHTIME 256
+#define HiColor(R,G,B) ( ((R)<<10) + ((G)<<5) + (B) )
+
+
+#define TCMAX ((128<<16)-62024)
+#define TCMIN ((000<<16)+62024)
+
+
+#ifdef _MAIN_
+ #define _EXTORNOT
+#else
+ #define _EXTORNOT extern
+#endif
+
+#define pi 3.1415926535f
+#define ctMapSize 1024
+
+
+
+
+typedef struct tagMessageList {
+ int timeleft;
+ char mtext[256];
+} TMessageList;
+
+typedef struct tagTRGB {
+ BYTE B;
+ BYTE G;
+ BYTE R;
+} TRGB;
+
+typedef struct _Animation {
+ char aniName[32];
+ int aniKPS, FramesCount, AniTime;
+ short int* aniData;
+} TAni;
+
+typedef struct _VTLdata {
+ int aniKPS, FramesCount, AniTime;
+ short int* aniData;
+} TVTL;
+
+typedef struct _SoundFX {
+ int length;
+ short int* lpData;
+} TSFX;
+
+
+
+typedef struct _TRD {
+ int RNumber, RVolume, RFreq;
+ WORD REnvir, Flags;
+} TRD;
+
+typedef struct _TAmbient {
+ TSFX sfx;
+ TRD rdata[16];
+ int RSFXCount;
+ int AVolume;
+ int RndTime;
+} TAmbient;
+
+
+typedef struct TagTEXTURE {
+ WORD DataA[128*128];
+ WORD DataB[64*64];
+ WORD DataC[32*32];
+ WORD DataD[16*16];
+ WORD SDataC[2][32*32];
+ int mR, mG, mB;
+} TEXTURE;
+
+
+
+typedef struct _TPicture {
+ int W,H;
+ WORD* lpImage;
+} TPicture;
+
+
+typedef struct TagVector3d {
+ float x,y,z;
+} Vector3d;
+
+typedef struct TagPoint3di {
+ int x,y,z;
+} TPoint3di;
+
+typedef struct TagVector2di {
+ int x,y;
+} Vector2di;
+
+typedef struct TagVector2df {
+ float x,y;
+} Vector2df;
+
+
+typedef struct TagScrPoint {
+#ifdef _soft
+ int x,y, tx,ty;
+#else
+ float x,y, tx,ty;
+#endif
+
+ int Light, z, r2, r3;
+} ScrPoint;
+
+typedef struct TagMScrPoint {
+ int x,y, tx,ty;
+} MScrPoint;
+
+typedef struct tagClipPlane {
+ Vector3d v1,v2,nv;
+} CLIPPLANE;
+
+
+
+
+
+typedef struct TagEPoint {
+ Vector3d v;
+ WORD DFlags;
+ short int ALPHA;
+#ifdef _d3d
+ float scrx, scry;
+#else
+ int scrx, scry;
+#endif
+ int Light;
+ float Fog;
+} EPoint;
+
+
+typedef struct TagClipPoint {
+ EPoint ev;
+ float tx, ty;
+} ClipPoint;
+
+
+//================= MODEL ========================
+typedef struct _Point3d {
+ float x;
+ float y;
+ float z;
+ short owner;
+ short hide;
+} TPoint3d;
+
+
+
+typedef struct _Face {
+ int v1, v2, v3;
+#ifdef _soft
+ int tax, tbx, tcx, tay, tby, tcy;
+#else
+ float tax, tbx, tcx, tay, tby, tcy;
+#endif
+ WORD Flags,DMask;
+ int Distant, Next, group;
+ char reserv[12];
+} TFace;
+
+
+typedef struct _Facef {
+ int v1, v2, v3;
+ float tax, tbx, tcx, tay, tby, tcy;
+ WORD Flags,DMask;
+ int Distant, Next, group;
+ char reserv[12];
+} TFacef;
+
+
+
+typedef struct _Obj {
+ char OName [32];
+ float ox;
+ float oy;
+ float oz;
+ short owner;
+ short hide;
+} TObj;
+
+
+typedef struct TagMODEL {
+ int VCount, FCount, TextureSize, TextureHeight;
+ TPoint3d gVertex[1024];
+ union {
+ TFace gFace [1024];
+ TFacef gFacef [1024];
+ };
+ WORD *lpTexture, *lpTexture2, *lpTexture3;
+#ifdef _d3d
+ int VLight[4][1024];
+#else
+ float VLight[4][1024];
+#endif
+} TModel;
+
+
+//=========== END MODEL ==============================//
+
+
+typedef struct _ObjInfo {
+ int Radius;
+ int YLo, YHi;
+ int linelenght, lintensity;
+ int circlerad, cintensity;
+ int flags;
+ int GrRad;
+ int DefLight;
+ int LastAniTime;
+ float BoundR;
+ BYTE res[16];
+} TObjInfo;
+
+typedef struct _TBMPModel {
+ Vector3d gVertex[4];
+ WORD *lpTexture;
+} TBMPModel;
+
+typedef struct _TBound {
+ float cx, cy, a, b, y1, y2;
+} TBound;
+
+typedef struct TagObject {
+ TObjInfo info;
+ TBound bound[8];
+ TBMPModel bmpmodel;
+ TModel *model;
+ TVTL vtl;
+} TObject;
+
+
+typedef struct _TCharacterInfo {
+ char ModelName[32];
+ int AniCount,SfxCount;
+ TModel* mptr;
+ TAni Animation[64];
+ TSFX SoundFX[64];
+ int Anifx[64];
+} TCharacterInfo;
+
+typedef struct _TWeapon {
+ TCharacterInfo chinfo[10];
+ TPicture BulletPic[10];
+ Vector3d normals[1024];
+ int state, FTime;
+ float shakel;
+} TWeapon;
+
+
+
+typedef struct _TWCircle {
+ Vector3d pos;
+ float scale;
+ int FTime;
+} TWCircle;
+
+
+typedef struct _TSnowElement {
+ Vector3d pos;
+ float hl, ftime;
+} TSnowElement;
+
+
+
+
+typedef struct _TCharacter {
+ int CType, AI;
+ TCharacterInfo *pinfo;
+ int StateF;
+ int State;
+ int NoWayCnt, NoFindCnt, AfraidTime, tgtime;
+ int PPMorphTime, PrevPhase,PrevPFTime, Phase, FTime;
+
+ float vspeed, rspeed, bend, scale;
+ int Slide;
+ float slidex, slidez;
+ float tgx, tgz;
+
+ Vector3d pos, rpos;
+ float tgalpha, alpha, beta,
+ tggamma,gamma,
+ lookx, lookz;
+ int Health, BloodTime, BloodTTime;
+} TCharacter;
+
+
+
+typedef struct tagPlayer {
+ BOOL Active;
+ unsigned int IPaddr;
+ Vector3d pos;
+ float alpha, beta, vspeed;
+ int kbState;
+ char NickName[16];
+} TPlayer;
+
+
+typedef struct _TDemoPoint {
+ Vector3d pos;
+ int DemoTime, CIndex;
+} TDemoPoint;
+
+typedef struct tagLevelDef {
+ char FileName[64];
+ char MapName[128];
+ DWORD DinosAvail;
+ WORD *lpMapImage;
+} TLevelDef;
+
+
+typedef struct tagShipTask {
+ int tcount;
+ int clist[255];
+} TShipTask;
+
+typedef struct tagShip {
+ Vector3d pos, rpos, tgpos, retpos;
+ float alpha, tgalpha, speed, rspeed, DeltaY;
+ int State, cindex, FTime;
+} TShip;
+
+
+typedef struct tagLandingList {
+ int PCount;
+ Vector2di list[64];
+} TLandingList;
+
+
+typedef struct _TPlayerR {
+ char PName[128];
+ int RegNumber;
+ int Score, Rank;
+} TPlayerR;
+
+typedef struct _TTrophyItem {
+ int ctype, weapon, phase,
+ height, weight, score,
+ date, time;
+ float scale, range;
+ int r1, r2, r3, r4;
+} TTrophyItem;
+
+
+typedef struct _TStats {
+ int smade, success;
+ float path, time;
+} TStats;
+
+
+typedef struct _TTrophyRoom {
+ char PlayerName[128];
+ int RegNumber;
+ int Score, Rank;
+
+ TStats Last, Total;
+
+ TTrophyItem Body[24];
+} TTrophyRoom;
+
+
+
+typedef struct _TDinoInfo {
+ char Name[48], FName[48], PName[48];
+ int Health0, AI;
+ BOOL DangerCall;
+ float Mass, Length, Radius,
+ SmellK, HearK, LookK,
+ ShDelta;
+ int Scale0, ScaleA, BaseScore;
+ TPicture CallIcon;
+} TDinoInfo;
+
+
+typedef struct _TWeapInfo {
+ char Name[48], FName[48], BFName[48];
+ float Power, Prec, Loud, Rate;
+ int Shots, Optic, Fall, TraceC, Reload;
+} TWeapInfo;
+
+
+typedef struct _TFogEntity {
+ int fogRGB;
+ float YBegin;
+ BOOL Mortal;
+ float Transp, FLimit;
+} TFogEntity;
+
+
+typedef struct _TWaterEntity {
+ int tindex, wlevel;
+ float transp;
+ int fogRGB;
+} TWaterEntity;
+
+
+typedef struct _TWind {
+ float alpha;
+ float speed;
+ Vector3d nv;
+} TWind;
+
+
+
+
+typedef struct _TElement {
+ Vector3d pos, speed;
+ int Flags;
+ float R;
+} TElement;
+
+typedef struct _TElements {
+ int Type, ECount, EDone, LifeTime;
+ int Param1, Param2, Param3;
+ DWORD RGBA, RGBA2;
+ Vector3d pos;
+ TElement EList[32];
+} TElements;
+
+
+typedef struct _TBloodP {
+ int LTime;
+ Vector3d pos;
+} TBloodP;
+
+typedef struct _TBTrail {
+ int Count;
+ TBloodP Trail[512];
+} TBTrail;
+
+
+//============= functions ==========================//
+
+void HLineTxB( void );
+void HLineTxC( void );
+void HLineTxGOURAUD( void );
+
+
+void HLineTxModel25( void );
+void HLineTxModel75( void );
+void HLineTxModel50( void );
+
+void HLineTxModel3( void );
+void HLineTxModel2( void );
+void HLineTxModel( void );
+
+void HLineTDGlass75( void );
+void HLineTDGlass50( void );
+void HLineTDGlass25( void );
+void HLineTBGlass25( void );
+
+
+void SetVideoMode(int, int);
+
+void CreateDivTable();
+void DrawTexturedFace();
+int GetTextW(HDC, LPSTR);
+void wait_mouse_release();
+
+//============================== render =================================//
+void ShowControlElements();
+void InsertModelList(TModel* mptr, float x0, float y0, float z0, int light, float al, float bt);
+void RenderGround();
+void RenderWater();
+void RenderElements();
+void CreateChRenderList();
+void RenderModelsList();
+void ProcessMap (int x, int y, int r);
+void ProcessMap2 (int x, int y, int r);
+void ProcessMapW (int x, int y, int r);
+void ProcessMapW2(int x, int y, int r);
+
+void DrawTPlane(BOOL);
+void DrawTPlaneClip(BOOL);
+void ClearVideoBuf();
+void DrawTrophyText(int, int);
+void DrawHMap();
+void RenderCharacter(int);
+void RenderShip();
+void RenderPlayer(int);
+void RenderSkyPlane();
+void RenderHealthBar();
+void Render_Cross(int, int);
+void Render_LifeInfo(int);
+
+void RenderModelClipEnvMap(TModel*, float, float, float, float, float);
+void RenderModelClipPhongMap(TModel*, float, float, float, float, float);
+
+void RenderModel (TModel*, float, float, float, int, int, float, float);
+void RenderBMPModel (TBMPModel*, float, float, float, int);
+void RenderModelClipWater(TModel*, float, float, float, int, int, float, float);
+void RenderModelClip (TModel*, float, float, float, int, int, float, float);
+void RenderNearModel (TModel*, float, float, float, int, float, float);
+void DrawPicture (int x, int y, TPicture &pic);
+
+void InitClips();
+void InitDirectDraw();
+void WaitRetrace();
+
+//============= Characters =======================
+void Characters_AddSecondaryOne(int ctype);
+void AddDeadBody(TCharacter *cptr, int);
+void PlaceCharacters();
+void PlaceTrophy();
+void AnimateCharacters();
+void MakeNoise(Vector3d, float);
+void CheckAfraid();
+void CreateChMorphedModel(TCharacter* cptr);
+void CreateMorphedObject(TModel* mptr, TVTL &vtl, int FTime);
+void CreateMorphedModel(TModel* mptr, TAni *aptr, int FTime, float scale);
+
+//=============================== Math ==================================//
+
+void CalcLights (TModel* mptr);
+void CalcModelGroundLight(TModel *mptr, float x0, float z0, int FI);
+void CalcNormals (TModel* mptr, Vector3d *nvs);
+void CalcGouraud (TModel* mptr, Vector3d *nvs);
+
+void CalcPhongMapping(TModel* mptr, Vector3d *nv);
+void CalcEnvMapping(TModel* mptr, Vector3d *nv);
+
+void CalcBoundBox(TModel* mptr, TBound *bound);
+void NormVector(Vector3d&, float);
+float SGN(float);
+void DeltaFunc(float &a, float b, float d);
+void MulVectorsScal(Vector3d&, Vector3d&, float&);
+void MulVectorsVect(Vector3d&, Vector3d&, Vector3d&);
+Vector3d SubVectors( Vector3d&, Vector3d& );
+Vector3d AddVectors( Vector3d&, Vector3d& );
+Vector3d RotateVector(Vector3d&);
+float VectorLength(Vector3d);
+int siRand(int);
+int rRand(int);
+void CalcHitPoint(CLIPPLANE&, Vector3d&, Vector3d&, Vector3d&);
+void ClipVector(CLIPPLANE& C, int vn);
+float FindVectorAlpha(float, float);
+float AngleDifference(float a, float b);
+
+int TraceShot(float ax, float ay, float az,
+ float &bx, float &by, float &bz);
+int TraceLook(float ax, float ay, float az,
+ float bx, float by, float bz);
+
+
+void CheckCollision(float&, float&);
+float CalcFogLevel(Vector3d v);
+//=================================================================//
+void AddMessage(LPSTR mt);
+void CreateTMap();
+
+
+void LoadSky();
+void LoadSkyMap();
+void LoadTexture(TEXTURE*&);
+void LoadWav(char* FName, TSFX &sfx);
+
+
+void ApplyAlphaFlags(WORD*, int);
+WORD conv_565(WORD c);
+int conv_xGx(int);
+void conv_pic(TPicture &pic);
+void LoadPicture(TPicture &pic, LPSTR pname);
+void LoadPictureTGA(TPicture &pic, LPSTR pname);
+void LoadCharacterInfo(TCharacterInfo&, char*);
+void LoadModelEx(TModel* &mptr, char* FName);
+void LoadModel(TModel*&);
+void LoadResources();
+void ReInitGame();
+
+
+void SaveScreenShot();
+void CreateWaterTab();
+void CreateFadeTab();
+void CreateVideoDIB();
+void RenderLightMap();
+
+void MulVectorsVect(Vector3d& v1, Vector3d& v2, Vector3d& r );
+void MulVectorsScal(Vector3d& v1,Vector3d& v2, float& r);
+Vector3d SubVectors( Vector3d& v1, Vector3d& v2 );
+void NormVector(Vector3d& v, float Scale);
+
+LPVOID _HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes);
+BOOL _HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
+
+//============ game ===========================//
+float GetLandCeilH(float, float);
+float GetLandH(float, float);
+float GetLandOH(int, int);
+float GetLandLt(float, float);
+float GetLandUpH(float, float);
+float GetLandQH(float, float);
+float GetLandQHNoObj(float, float);
+float GetLandHObj(float, float);
+
+void LoadResourcesScript();
+void InitEngine();
+void ShutDownEngine();
+void ProcessSyncro();
+void AddShipTask(int);
+void LoadTrophy();
+//void LoadPlayersInfo();
+void SaveTrophy();
+void RemoveCurrentTrophy();
+void MakeCall();
+void MakeShot(float ax, float ay, float az,
+ float bx, float by, float bz);
+
+void AddBloodTrail(TCharacter *cptr);
+void AddElements(float, float, float, int, int);
+void AddWCircle(float, float, float);
+void AnimateProcesses();
+void DoHalt(LPSTR);
+
+_EXTORNOT char logt[128];
+void CreateLog();
+void PrintLog(LPSTR l);
+void CloseLog();
+
+_EXTORNOT float BackViewR;
+_EXTORNOT int BackViewRR;
+_EXTORNOT int UnderWaterT;
+_EXTORNOT int TotalC, TotalW;
+
+
+//========== common ==================//
+_EXTORNOT HWND hwndMain;
+_EXTORNOT HINSTANCE hInst;
+_EXTORNOT HANDLE Heap;
+_EXTORNOT HDC hdcMain, hdcCMain;
+_EXTORNOT BOOL blActive;
+_EXTORNOT BYTE KeyboardState[256];
+_EXTORNOT int KeyFlags, _shotcounter;
+
+_EXTORNOT TMessageList MessageList;
+_EXTORNOT char ProjectName[128];
+_EXTORNOT int _GameState;
+_EXTORNOT TSFX fxCall[10][3], fxScream[4];
+_EXTORNOT TSFX fxUnderwater, fxWaterIn, fxWaterOut, fxJump, fxStep[3], fxStepW[3];
+//========== map =====================//
+_EXTORNOT byte HMap[ctMapSize][ctMapSize];
+_EXTORNOT byte WMap[ctMapSize][ctMapSize];
+_EXTORNOT byte HMapO[ctMapSize][ctMapSize];
+_EXTORNOT WORD FMap[ctMapSize][ctMapSize];
+_EXTORNOT byte LMap[ctMapSize][ctMapSize];
+_EXTORNOT WORD TMap1[ctMapSize][ctMapSize];
+_EXTORNOT WORD TMap2[ctMapSize][ctMapSize];
+_EXTORNOT byte OMap[ctMapSize][ctMapSize];
+
+_EXTORNOT byte FogsMap[512][512];
+_EXTORNOT byte AmbMap[512][512];
+
+_EXTORNOT TFogEntity FogsList[256];
+_EXTORNOT TWaterEntity WaterList[256];
+_EXTORNOT TWind Wind;
+_EXTORNOT TShip Ship;
+_EXTORNOT TShipTask ShipTask;
+
+_EXTORNOT int SkyR, SkyG, SkyB, WaterR, WaterG, WaterB, WaterA,
+ SkyTR,SkyTG,SkyTB, CurFogColor;
+_EXTORNOT int RandomMap[32][32];
+
+_EXTORNOT Vector2df PhongMapping[1024];
+_EXTORNOT TPicture TFX_SPECULAR, TFX_ENVMAP;
+_EXTORNOT WORD SkyPic[256*256];
+_EXTORNOT WORD SkyFade[9][128*128];
+_EXTORNOT BYTE SkyMap[128*128];
+
+_EXTORNOT TEXTURE* Textures[1024];
+_EXTORNOT TAmbient Ambient[256];
+_EXTORNOT TSFX RandSound[256];
+
+//========= GAME ====================//
+_EXTORNOT int TargetDino, TargetArea, TargetWeapon, WeaponPres, TargetCall,
+ TrophyTime, ObservMode, Tranq, ObjectsOnLook,
+ CurrentWeapon, ShotsLeft[10], AmmoMag[10];
+
+_EXTORNOT Vector3d answpos;
+_EXTORNOT int answtime, answcall;
+
+_EXTORNOT BOOL ScentMode, CamoMode,
+ RadarMode, LockLanding,
+ TrophyMode, DoubleAmmo;
+
+_EXTORNOT TTrophyRoom TrophyRoom;
+//_EXTORNOT TPlayerR PlayerR[16];
+_EXTORNOT TPicture LandPic,DinoPic,DinoPicM, MapPic, WepPic;
+_EXTORNOT HFONT fnt_BIG, fnt_Small, fnt_Midd;
+_EXTORNOT TLandingList LandingList;
+
+//======== MODEL ======================//
+_EXTORNOT TObject MObjects[256];
+_EXTORNOT TModel* mptr;
+_EXTORNOT TWeapon Weapon;
+
+
+_EXTORNOT int OCount, iModelFade, iModelBaseFade, Current;
+_EXTORNOT Vector3d rVertex[1024];
+_EXTORNOT TObj gObj[1024];
+_EXTORNOT Vector2di gScrp[1024];
+_EXTORNOT Vector2df gScrpf[1024];
+
+//============= Characters ==============//
+_EXTORNOT TPicture PausePic, ExitPic, TrophyExit, TrophyPic;
+_EXTORNOT TModel *SunModel;
+_EXTORNOT TCharacterInfo WCircleModel;
+_EXTORNOT TModel *CompasModel;
+_EXTORNOT TModel *Binocular;
+_EXTORNOT TDinoInfo DinoInfo[32];
+_EXTORNOT TWeapInfo WeapInfo[8];
+_EXTORNOT TCharacterInfo ShipModel;
+_EXTORNOT int AI_to_CIndex[32];
+_EXTORNOT int ChCount, WCCount, ElCount, SnCount,
+ ShotDino, TrophyBody;
+_EXTORNOT TCharacterInfo WindModel;
+_EXTORNOT TCharacterInfo PlayerInfo;
+_EXTORNOT TCharacterInfo ChInfo[32];
+_EXTORNOT TCharacter Characters[256];
+_EXTORNOT TWCircle WCircles[128];
+_EXTORNOT TSnowElement Snow[8024];
+_EXTORNOT TDemoPoint DemoPoint;
+
+_EXTORNOT TPlayer Players[16];
+_EXTORNOT Vector3d PlayerPos, CameraPos;
+
+//========== Render ==================//
+_EXTORNOT LPDIRECTDRAW lpDD;
+_EXTORNOT LPDIRECTDRAW2 lpDD2;
+//_EXTORNOT LPDIRECTINPUT lpDI;
+
+_EXTORNOT void* lpVideoRAM;
+_EXTORNOT LPDIRECTDRAWSURFACE lpddsPrimary;
+_EXTORNOT BOOL DirectActive, RestartMode;
+_EXTORNOT BOOL LoDetailSky;
+_EXTORNOT int WinW,WinH,WinEX,WinEY,VideoCX,VideoCY,VideoCX16,VideoCY16,iBytesPerLine,ts,r,MapMinY;
+_EXTORNOT float VideoCXf, VideoCYf, CameraW,CameraH,CameraW16,CameraH16,Soft_Persp_K, stepdy, stepdd, SunShadowK, FOVK;
+_EXTORNOT CLIPPLANE ClipA,ClipB,ClipC,ClipD,ClipZ,ClipW;
+_EXTORNOT int u,vused, CCX, CCY;
+
+_EXTORNOT DWORD Mask1,Mask2;
+_EXTORNOT DWORD HeapAllocated, HeapReleased;
+
+
+_EXTORNOT EPoint VMap[256][256];
+_EXTORNOT EPoint VMap2[256][256];
+_EXTORNOT EPoint ev[3];
+
+_EXTORNOT ClipPoint cp[16];
+_EXTORNOT ClipPoint hleft,hright;
+
+
+_EXTORNOT void *HLineT;
+_EXTORNOT int rTColor;
+_EXTORNOT int SKYMin, SKYDTime, GlassL, ctViewR, ctViewR1, ctViewRM,
+ dFacesCount, ReverseOn, TDirection;
+_EXTORNOT WORD FadeTab[65][0x8000];
+_EXTORNOT TElements Elements[32];
+_EXTORNOT TBTrail BloodTrail;
+
+_EXTORNOT int PrevTime, TimeDt, T, Takt, RealTime, StepTime, MyHealth, ExitTime,
+ ChCallTime, CallLockTime, NextCall;
+_EXTORNOT float DeltaT;
+_EXTORNOT float CameraX, CameraY, CameraZ, CameraAlpha, CameraBeta;
+_EXTORNOT float PlayerX, PlayerY, PlayerZ, PlayerAlpha, PlayerBeta,
+ HeadY, HeadBackR, HeadBSpeed, HeadAlpha, HeadBeta,
+ SSpeed,VSpeed,RSpeed,YSpeed;
+_EXTORNOT Vector3d PlayerNv;
+
+_EXTORNOT float ca,sa,cb,sb, wpnDAlpha, wpnDBeta;
+_EXTORNOT void *lpVideoBuf, *lpTextureAddr;
+_EXTORNOT HBITMAP hbmpVideoBuf;
+_EXTORNOT HCURSOR hcArrow;
+_EXTORNOT int DivTbl[10240];
+
+_EXTORNOT Vector3d v[3];
+_EXTORNOT ScrPoint scrp[3];
+_EXTORNOT MScrPoint mscrp[3];
+_EXTORNOT Vector3d nv, waterclipbase, Sun3dPos;
+
+
+_EXTORNOT struct _t {
+ int fkForward, fkBackward, fkUp, fkDown, fkLeft, fkRight, fkFire, fkShow, fkSLeft, fkSRight, fkStrafe, fkJump, fkRun, fkCrouch, fkCall, fkCCall, fkBinoc;
+ } KeyMap;
+
+
+#define kfForward 0x00000001
+#define kfBackward 0x00000002
+#define kfLeft 0x00000004
+#define kfRight 0x00000008
+#define kfLookUp 0x00000010
+#define kfLookDn 0x00000020
+#define kfJump 0x00000040
+#define kfCall 0x00000100
+
+#define kfSLeft 0x00001000
+#define kfSRight 0x00002000
+#define kfStrafe 0x00004000
+
+#define fmWater 0x0080
+#define fmWater2 0x8000
+#define fmNOWAY 0x0020
+#define fmReverse 0x0010
+
+#define fmWaterA 0x8080
+
+
+#define tresGround 1
+#define tresWater 2
+#define tresModel 3
+#define tresChar 4
+
+#define sfDoubleSide 1
+#define sfDarkBack 2
+#define sfOpacity 4
+#define sfTransparent 8
+#define sfMortal 0x0010
+#define sfPhong 0x0030
+#define sfEnvMap 0x0050
+
+#define sfNeedVC 0x0080
+#define sfDark 0x8000
+
+#define ofPLACEWATER 1
+#define ofPLACEGROUND 2
+#define ofPLACEUSER 4
+#define ofCIRCLE 8
+#define ofBOUND 16
+#define ofNOBMP 32
+#define ofNOLIGHT 64
+#define ofDEFLIGHT 128
+#define ofGRNDLIGHT 256
+#define ofNOSOFT 512
+#define ofNOSOFT2 1024
+#define ofANIMATED 0x80000000
+
+#define csONWATER 0x00010000
+#define MAX_HEALTH 128000
+
+#define HUNT_EAT 0
+#define HUNT_BREATH 1
+#define HUNT_FALL 2
+#define HUNT_KILL 3
+
+
+
+#define AI_PIG 1
+#define AI_ARCHEO 2
+#define AI_BIGFOOT 3
+#define AI_POACHER 4
+
+#define AI_BRONT 10
+#define AI_HOG 11
+#define AI_WOLF 12
+#define AI_RHINO 13
+#define AI_DIATR 14
+#define AI_DEER 15
+#define AI_SMILO 16
+#define AI_MAMM 17
+#define AI_BEAR 18
+
+
+
+_EXTORNOT BOOL WATERANI,Clouds,SKY,GOURAUD,
+ MODELS,TIMER,BITMAPP,MIPMAP,
+ NOCLIP,CLIP3D,NODARKBACK,CORRECTION, LOWRESTX,
+ FOGENABLE, FOGON, CAMERAINFOG,
+ WATERREVERSE,waterclip,UNDERWATER, ONWATER, NeedWater,
+ SNOW, SWIM, FLY, PAUSE, OPTICMODE, BINMODE, EXITMODE, MapMode, RunMode, CrouchMode;
+_EXTORNOT int CameraFogI, QUITMODE;
+_EXTORNOT int OptDayNight, OptAgres, OptDens, OptSens, OptRes, OptViewR,
+ OptMsSens, OptBrightness, OptSound, OptRender,
+ OptText, OptSys, WaitKey, OPT_ALPHA_COLORKEY;
+_EXTORNOT BOOL SHADOWS3D,REVERSEMS;
+
+_EXTORNOT BOOL SLOW, DEBUG, MORPHP, MORPHA;
+_EXTORNOT HANDLE hlog;
+
+
+//========== for audio ==============//
+void AddVoicev (int, short int*, int);
+void AddVoice3dv(int, short int*, float, float, float, int);
+void AddVoice3d (int, short int*, float, float, float);
+
+void SetAmbient3d(int, short int*, float, float, float);
+void SetAmbient(int, short int*, int);
+void AudioSetCameraPos(float, float, float, float, float);
+void InitAudioSystem(HWND, HANDLE, int);
+void Audio_Restore();
+void AudioStop();
+void Audio_Shutdown();
+void Audio_SetEnvironment(int, float);
+void Audio_UploadGeometry();
+//=================================
+typedef struct tagAudioQuad
+{
+ float x1,y1,z1;
+ float x2,y2,z2;
+ float x3,y3,z3;
+ float x4,y4,z4;
+} AudioQuad;
+_EXTORNOT int AudioFCount;
+_EXTORNOT AudioQuad data[8192];
+_EXTORNOT void UploadGeometry();
+_EXTORNOT int Env;
+
+__inline float f_cos(float x)
+{
+ return (float) cos(x);
+}
+
+__inline float f_sin(float x)
+{
+ return (float) sin(x);
+}/**/
+//_EXTORNOT float f_sin(double);
+//_EXTORNOT float f_cos(double);
+
+/*__inline float f_cos(float x)
+{
+ static float y;
+__asm
+{
+fld [x]
+fcos
+fstp [y]
+}
+return y;
+}
+
+__inline float f_sin(float x)
+{
+ static float y;
+__asm
+{
+fld [x]
+fsin
+fstp [y]
+}
+return y;
+}/**/
+
+//========== for 3d hardware =============//
+//========== for 3d hardware =============//
+_EXTORNOT BOOL HARD3D;
+void ShowVideo();
+void Init3DHardware();
+void Activate3DHardware();
+void ShutDown3DHardware();
+void Render3DHardwarePosts();
+void CopyBackToDIB();
+void CopyHARDToDIB();
+void Hardware_ZBuffer(BOOL zb);
+
+
+//=========== loading =============
+void StartLoading();
+void EndLoading();
+void PrintLoad(char *t);
+
+#ifdef _MAIN_
+_EXTORNOT char KeysName[256][24] = {
+"...",
+"Esc",
+"1",
+"2",
+"3",
+"4",
+"5",
+"6",
+"7",
+"8",
+"9",
+"0",
+"-",
+"=",
+"BSpace",
+"Tab",
+"Q",
+"W",
+"E",
+"R",
+"T",
+"Y",
+"U",
+"I",
+"O",
+"P",
+"[",
+"]",
+"Enter",
+"Ctrl",
+"A",
+"S",
+"D",
+"F",
+"G",
+"H",
+"J",
+"K",
+"L",
+";",
+"'",
+"~",
+"Shift",
+"\\",
+"Z",
+"X",
+"C",
+"V",
+"B",
+"N",
+"M",
+",",
+".",
+"/",
+"Shift",
+"*",
+"Alt",
+"Space",
+"CLock",
+"F1",
+"F2",
+"F3",
+"F4",
+"F5",
+"F6",
+"F7",
+"F8",
+"F9",
+"F10",
+"NLock",
+"SLock",
+"Home",
+"Up",
+"PgUp",
+"-",
+"Left",
+"Midle",
+"Right",
+"+",
+"End",
+"Down",
+"PgDn",
+"Ins",
+"Del",
+"",
+"",
+"",
+"F11",
+"F12",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Mouse1",
+"Mouse2",
+"Mouse3",
+"<?>",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
+ };
+#else
+ _EXTORNOT char KeysName[128][24];
+#endif \ No newline at end of file
diff --git a/Hunt2.cpp b/Hunt2.cpp
new file mode 100644
index 0000000..2b28166
--- /dev/null
+++ b/Hunt2.cpp
@@ -0,0 +1,1718 @@
+#define _MAIN_
+#include "Hunt.h"
+#include "stdio.h"
+
+float rav=0;
+float rbv=0;
+
+#ifdef _soft
+BOOL PHONG = FALSE;
+BOOL GOUR = FALSE;
+BOOL ENVMAP = FALSE;
+#else
+BOOL PHONG = TRUE;
+BOOL GOUR = TRUE;
+BOOL ENVMAP = TRUE;
+#endif
+
+BOOL NeedRVM = TRUE;
+float BinocularPower = 2.5;
+float wpshy = 0;
+float wpshz = 0;
+float wpnb = 0;
+int wpnlight;
+
+void HideWeapon();
+
+char cheatcode[16] = "DEBUGUP";
+int cheati = 0;
+
+
+void ResetMousePos()
+{
+ SetCursorPos(VideoCX, VideoCY);
+}
+
+
+
+float CalcFogLevel(Vector3d v)
+{
+ if (!FOGON) return 0;
+ BOOL vinfog = TRUE;
+ int cf;
+ if (!UNDERWATER) {
+ cf = FogsMap[ ((int)(v.z + CameraZ))>>9 ][ ((int)(v.x + CameraX))>>9 ];
+ if ((!cf) && CAMERAINFOG) { cf = CameraFogI; vinfog = FALSE; }
+ } else cf = 127;
+
+
+ if (! (CAMERAINFOG | cf) ) return 0;
+ TFogEntity *fptr;
+ fptr = &FogsList[cf];
+ CurFogColor = fptr->fogRGB;
+
+ float d = VectorLength(v);
+
+ v.y+=CameraY;
+
+ float fla= -(v.y - fptr->YBegin*ctHScale) / ctHScale;
+ if (!vinfog) if (fla>0) fla=0;
+
+ float flb = -(CameraY - fptr->YBegin*ctHScale) / ctHScale;
+ if (!CAMERAINFOG) if (flb>0) flb=0;
+
+ if (fla<0 && flb<0) return 0;
+
+ if (fla<0) { d*= flb / (flb-fla); fla = 0; }
+ if (flb<0) { d*= fla / (fla-flb); flb = 0; }
+
+ float fl = (fla + flb);
+
+ fl *= (d+(fptr->Transp/2)) / fptr->Transp;
+
+ return min(fl, fptr->FLimit);
+}
+
+
+
+void PreCashGroundModel()
+{
+ SKYDTime = RealTime>>1;
+ int x,y;
+
+ int kx = SKYDTime & 255;
+ int ky = SKYDTime & 255;
+ int SKYDT = SKYDTime>>8;
+
+ VideoCX16 = VideoCX * 16;
+ VideoCY16 = VideoCY * 16;
+ VideoCXf = VideoCX;
+ VideoCYf = VideoCY;
+ CameraW16 = CameraW * 16;
+ CameraH16 = CameraH * 16;
+
+ BOOL FogFound = FALSE;
+ NeedWater = FALSE;
+
+ MapMinY = 10241024;
+ Vector3d rv;
+
+
+ for (y=-(ctViewR+3); y<(ctViewR+3); y++)
+ for (x=-(ctViewR+3); x<(ctViewR+3); x++) {
+
+ int r = max((max(y,-y)), (max(x,-x)));
+ if ( r>ctViewR1+4 )
+ if ( (x & 1) + (y & 1) > 0) continue;
+
+ int xx = (CCX + x) & 1023;
+ int yy = (CCY + y) & 1023;
+
+ v[0].x = xx*256 - CameraX;
+ v[0].z = yy*256 - CameraZ;
+ v[0].y = (float)((int)HMap[yy][xx])*ctHScale - CameraY;
+
+
+//========= water section ===========//
+
+ //if (RunMode)
+ if ((FMap[yy][xx] & fmWaterA)>0) {
+ rv = v[0];
+ rv.y = WaterList[ WMap[yy][xx] ].wlevel*ctHScale - CameraY;
+
+ float wdelta = (float)f_sin(-pi/2 + RandomMap[yy & 31][xx & 31]/128+RealTime/200.f);
+
+ if ( (FMap[yy][xx] & fmWater) && (r < ctViewR1-4)) {
+ rv.x+=(float)f_sin(xx+yy + RealTime/200.f) * 16.f;
+ rv.z+=(float)f_sin(pi/2.f + xx+yy + RealTime/200.f) * 16.f;
+ }
+
+ rv = RotateVector(rv);
+ VMap2[128+y][128+x].v = rv;
+
+ if (fabs(rv.x) > -rv.z + 1524) {
+ VMap2[128+y][128+x].DFlags = 128;
+ } else {
+ NeedWater = TRUE;
+ VMap2[128+y][128+x].Light = 168-(int)(wdelta*24);
+
+ float Alpha;
+ if (UNDERWATER) {
+ Alpha = 160 - VectorLength(rv)* 160 / 220 / ctViewR;
+ if (Alpha<10) Alpha=10;
+ } else
+ if (r < ctViewR1+2) {
+ int wi = WMap[yy][xx];
+ Alpha = (float)((WaterList[wi].wlevel - HMap[yy][xx])*2+4)*WaterList[wi].transp;
+ Alpha+=VectorLength(rv) / 256;
+ Alpha+=wdelta*2;
+ if (Alpha<0) Alpha=0;
+ Vector3d va = v[0];
+ NormVector(va,1.0f); va.y=-va.y;
+ if (va.y<0) va.y=0;
+ Alpha*=6.f/(va.y+0.1f);
+ if (Alpha>255) Alpha=255.f;
+ } else Alpha = 255.f;
+
+ VMap2[128+y][128+x].ALPHA=(int)Alpha;
+ VMap2[128+y][128+x].Fog = 0;
+
+ if (rv.z>-256.0) VMap2[128+y][128+x].DFlags=128; else {
+#ifdef _soft
+ VMap2[128+y][128+x].scrx = VideoCX - (int)(rv.x / rv.z * CameraW);
+ VMap2[128+y][128+x].scry = VideoCY + (int)(rv.y / rv.z * CameraH);
+
+ int DF = 0;
+ if (VMap2[128+y][128+x].scrx < 0) DF+=1;
+ if (VMap2[128+y][128+x].scrx > WinEX) DF+=2;
+ if (VMap2[128+y][128+x].scry < 0) DF+=4;
+ if (VMap2[128+y][128+x].scry > WinEY) DF+=8;
+#endif
+#ifdef _3dfx
+ VMap2[128+y][128+x].scrx = VideoCX16 - (int)(rv.x / rv.z * CameraW16);
+ VMap2[128+y][128+x].scry = VideoCY16 + (int)(rv.y / rv.z * CameraH16);
+
+ int DF = 0;
+ if (VMap2[128+y][128+x].scrx < 0) DF+=1;
+ if (VMap2[128+y][128+x].scrx > WinEX*16) DF+=2;
+ if (VMap2[128+y][128+x].scry < 0) DF+=4;
+ if (VMap2[128+y][128+x].scry > WinEY*16) DF+=8;
+#endif
+#ifdef _d3d
+ VMap2[128+y][128+x].scrx = VideoCXf - (rv.x / rv.z * CameraW);
+ VMap2[128+y][128+x].scry = VideoCYf + (rv.y / rv.z * CameraH);
+
+ int DF = 0;
+ if (VMap2[128+y][128+x].scrx < 0) DF+=1;
+ if (VMap2[128+y][128+x].scrx > WinEX) DF+=2;
+ if (VMap2[128+y][128+x].scry < 0) DF+=4;
+ if (VMap2[128+y][128+x].scry > WinEY) DF+=8;
+#endif
+
+
+ VMap2[128+y][128+x].DFlags = DF;
+
+ }
+ }
+ }
+
+
+
+#ifdef _soft
+#else
+ if (r>ctViewR1-20 && r<ctViewR1+8)
+ if ( (x & 1) + (y & 1) > 0)
+ {
+ float y1;
+ float zd = (float)sqrt(v[0].x*v[0].x + v[0].z*v[0].z) / 256.f;
+ float k = (zd - (ctViewR1-8)) / 4.f;
+ if (k<0) k=0;
+ if (k>1) k=1;
+
+ if ((y & 1)==0) y1 = (float)((int)HMap[yy][xx-1]+HMap[yy][xx+1])*ctHScale/2 - CameraY; else
+ if ((x & 1)==0) y1 = (float)((int)HMap[yy-1][xx]+HMap[yy+1][xx])*ctHScale/2 - CameraY; else
+ y1 = (float)((int)HMap[yy-1][xx-1]+HMap[yy+1][xx+1])*ctHScale/2 - CameraY;
+
+ v[0].y = ((v[0].y+2) * (1-k) + (y1+8) * k);
+ }
+#endif
+
+ if ( (x & 1) + (y & 1) > 0)
+ if (RunMode) {
+ float y1;
+ if ((y & 1)==0) y1 = (float)((int)HMap[yy][xx-1]+HMap[yy][xx+1])*ctHScale/2 - CameraY; else
+ if ((x & 1)==0) y1 = (float)((int)HMap[yy-1][xx]+HMap[yy+1][xx])*ctHScale/2 - CameraY; else
+ y1 = (float)((int)HMap[yy-1][xx-1]+HMap[yy+1][xx+1])*ctHScale/2 - CameraY;
+ v[0].y = y1;
+ }
+
+
+ rv = RotateVector(v[0]);
+
+
+ if (fabs(rv.x * FOVK) > -rv.z + 1600) {
+ VMap[128+y][128+x].v = rv;
+ VMap[128+y][128+x].DFlags = 128;
+ continue;
+ }
+
+
+ if (HARD3D)
+ if ( ((FMap[yy][xx] & fmWater)==0) || UNDERWATER)
+ VMap[128+y][128+x].Fog = CalcFogLevel(v[0]); else
+ VMap[128+y][128+x].Fog = 0;
+
+ VMap[128+y][128+x].ALPHA = 255;
+
+ v[0]=rv;
+
+ if (v[0].z<1024)
+ if (FOGENABLE)
+ if (FogsMap[yy>>1][xx>>1]) FogFound = TRUE;
+
+ VMap[128+y][128+x].v = v[0];
+
+ int DF = 0;
+ int db = 0;
+
+ if (v[0].z<256) {
+ if (Clouds) {
+ int shmx = (xx + SKYDT) & 127;
+ int shmy = (yy + SKYDT) & 127;
+
+ int db1 = SkyMap[shmy * 128 + shmx ];
+ int db2 = SkyMap[shmy * 128 + ((shmx+1) & 127) ];
+ int db3 = SkyMap[((shmy+1) & 127) * 128 + shmx ];
+ int db4 = SkyMap[((shmy+1) & 127) * 128 + ((shmx+1) & 127) ];
+ db = (db1 * (256 - kx) + db2 * kx) * (256-ky) +
+ (db3 * (256 - kx) + db4 * kx) * ky;
+ db>>=17;
+ db = db - 40;
+ if (db<0) db=0;
+ if (db>48) db=48;
+ }
+
+ int clt = LMap[yy][xx];
+ clt= max(64, clt-db);
+ VMap[128+y][128+x].Light = clt;
+ }
+
+
+
+ if (v[0].z>-256.0) DF+=128; else {
+
+#ifdef _soft
+ VMap[128+y][128+x].scrx = VideoCX - (int)(v[0].x / v[0].z * CameraW);
+ VMap[128+y][128+x].scry = VideoCY + (int)(v[0].y / v[0].z * CameraH);
+
+ if (VMap[128+y][128+x].scrx < 0) DF+=1;
+ if (VMap[128+y][128+x].scrx > WinEX) DF+=2;
+ if (VMap[128+y][128+x].scry < 0) DF+=4;
+ if (VMap[128+y][128+x].scry > WinEY) DF+=8;
+#endif
+#ifdef _3dfx
+ VMap[128+y][128+x].scrx = VideoCX16 - (int)(v[0].x / v[0].z * CameraW16);
+ VMap[128+y][128+x].scry = VideoCY16 + (int)(v[0].y / v[0].z * CameraH16);
+
+ if (VMap[128+y][128+x].scrx < 0) DF+=1;
+ if (VMap[128+y][128+x].scrx > WinEX*16) DF+=2;
+ if (VMap[128+y][128+x].scry < 0) DF+=4;
+ if (VMap[128+y][128+x].scry > WinEY*16) DF+=8;
+#endif
+#ifdef _d3d
+ VMap[128+y][128+x].scrx = VideoCXf - (v[0].x / v[0].z * CameraW);
+ VMap[128+y][128+x].scry = VideoCYf + (v[0].y / v[0].z * CameraH);
+
+ if (VMap[128+y][128+x].scrx < 0) DF+=1;
+ if (VMap[128+y][128+x].scrx > WinEX) DF+=2;
+ if (VMap[128+y][128+x].scry < 0) DF+=4;
+ if (VMap[128+y][128+x].scry > WinEY) DF+=8;
+#endif
+ }
+
+ VMap[128+y][128+x].DFlags = DF;
+ }
+
+ FOGON = FogFound || UNDERWATER;
+}
+
+
+
+
+void AddShadowCircle(int x, int y, int R, int D)
+{
+ if (UNDERWATER) return;
+
+ int cx = x / 256;
+ int cy = y / 256;
+ int cr = 1 + R / 256;
+ for (int yy=-cr; yy<=cr; yy++)
+ for (int xx=-cr; xx<=cr; xx++) {
+ int tx = (cx+xx)*256;
+ int ty = (cy+yy)*256;
+ int r = (int)sqrt( (tx-x)*(tx-x) + (ty-y)*(ty-y) );
+ if (r>R) continue;
+ VMap[cy+yy - CCY + 128][cx+xx - CCX + 128].Light-= D * (R-r) / R;
+ if (VMap[cy+yy - CCY + 128][cx+xx - CCX + 128].Light < 32)
+ VMap[cy+yy - CCY + 128][cx+xx - CCX + 128].Light = 32;
+ }
+}
+
+
+
+
+
+void DrawScene()
+{
+ dFacesCount = 0;
+
+ ca = (float)f_cos(CameraAlpha);
+ sa = (float)f_sin(CameraAlpha);
+
+ cb = (float)f_cos(CameraBeta);
+ sb = (float)f_sin(CameraBeta);
+
+ CCX = ((int)CameraX / 512) * 2;
+ CCY = ((int)CameraZ / 512) * 2;
+
+ PreCashGroundModel();
+
+#ifdef _soft
+ CreateChRenderList();
+#endif
+
+ RenderSkyPlane();
+
+ cb = (float)f_cos(CameraBeta);
+ sb = (float)f_sin(CameraBeta);
+
+
+ RenderGround();
+
+ RenderModelsList();
+
+ Render3DHardwarePosts();
+
+ if (NeedWater) RenderWater();
+
+ RenderElements();
+}
+
+
+
+
+void DrawOpticCross( int v)
+{
+ int sx = VideoCX + (int)(rVertex[v].x / (-rVertex[v].z) * CameraW);
+ int sy = VideoCY - (int)(rVertex[v].y / (-rVertex[v].z) * CameraH);
+
+ if ( (fabs(VideoCX - sx) > WinW / 2) ||
+ (fabs(VideoCY - sy) > WinH / 4) ) return;
+
+ Render_Cross(sx, sy);
+}
+
+
+
+void ScanLifeForms()
+{
+ int li = -1;
+ float dm = (float)(ctViewR+2)*256;
+ for (int c=0; c<ChCount; c++) {
+ TCharacter *cptr = &Characters[c];
+ if (!cptr->Health) continue;
+ if (cptr->rpos.z > -512) continue;
+ float d = (float)sqrt( cptr->rpos.x*cptr->rpos.x + cptr->rpos.y*cptr->rpos.y + cptr->rpos.z*cptr->rpos.z );
+ if (d > ctViewR*256) continue;
+ float r = (float)(fabs(cptr->rpos.x) + fabs(cptr->rpos.y)) / d;
+ if (r > 0.15) continue;
+ if (d<dm)
+ if (!TraceLook(cptr->pos.x, cptr->pos.y+220, cptr->pos.z,
+ CameraX, CameraY, CameraZ) ) {
+
+ dm = d;
+ li = c;
+ }
+
+ }
+
+ if (li==-1) return;
+ Render_LifeInfo(li);
+}
+
+
+void DrawPostObjects()
+{
+ float b;
+ TWeapon* wptr = &Weapon;
+
+ Hardware_ZBuffer(FALSE);
+
+ if (DemoPoint.DemoTime) goto SKIPWEAPON;
+
+ GlassL = 0;
+ if (BINMODE) {
+ RenderNearModel(Binocular, 0, 0, 2*(216-72 * BinocularPower), 192, 0,0);
+ ScanLifeForms();
+ MapMode = FALSE;
+ }
+
+ //goto SKIPWIND;
+ if (BINMODE || OPTICMODE) goto SKIPWIND;
+
+ if (!TrophyMode)
+ if (!KeyboardState[VK_CAPITAL] & 1) {
+ BOOL lr = LOWRESTX;
+ LOWRESTX = TRUE;
+ VideoCX = WinW / 5;
+ VideoCY = WinH - (WinH * 10 / 23);
+ VideoCXf= VideoCX;
+ VideoCYf= VideoCY;
+ VideoCX16 = VideoCX * 16;
+ VideoCY16 = VideoCY * 16;
+ CreateMorphedModel(WindModel.mptr, &WindModel.Animation[0], (int)(Wind.speed*50.f), 1.0);
+ RenderNearModel(WindModel.mptr, -10, -37, -96, 192, CameraAlpha-Wind.alpha,0);
+
+ VideoCX = WinW - (WinW / 5);
+ VideoCY = WinH - (WinH * 10 / 23);
+ VideoCXf= VideoCX;
+ VideoCYf= VideoCY;
+ VideoCX16 = VideoCX * 16;
+ VideoCY16 = VideoCY * 16;
+ RenderNearModel(CompasModel, +8, -38, -96, 192, CameraAlpha,0);
+
+ VideoCX = WinW / 2;
+ VideoCY = WinH / 2;
+ VideoCXf= VideoCX;
+ VideoCYf= VideoCY;
+ VideoCX16 = VideoCX * 16;
+ VideoCY16 = VideoCY * 16;
+ LOWRESTX = lr;
+ }
+
+SKIPWIND:
+
+
+ if (wptr->state == 0) goto SKIPWEAPON;
+
+ MapMode = FALSE;
+
+ wptr->shakel+= TimeDt / 10000.f;
+ //wptr->shakel = 0;
+ if (wptr->shakel > 4.0f) wptr->shakel = 4.0f;
+
+ if (wptr->state == 1) {
+ wptr->FTime+=TimeDt;
+ if (wptr->FTime >= wptr->chinfo[CurrentWeapon].Animation[0].AniTime) {
+ wptr->FTime = 0;
+ wptr->state = 2;
+ }
+ }
+
+ if (wptr->state == 4) {
+ wptr->FTime+=TimeDt;
+ if (wptr->FTime >= wptr->chinfo[CurrentWeapon].Animation[3].AniTime) {
+ wptr->FTime = 0;
+ wptr->state = 2;
+ }
+ }
+
+ if (wptr->state == 2 && wptr->FTime>0) {
+ wptr->FTime+=TimeDt;
+ if (wptr->FTime >= wptr->chinfo[CurrentWeapon].Animation[1].AniTime) {
+ wptr->FTime = 0;
+ wptr->state = 2;
+
+
+ if (WeapInfo[CurrentWeapon].Reload)
+ if ( (ShotsLeft[CurrentWeapon] % WeapInfo[CurrentWeapon].Reload) == 0 )
+ if ( (ShotsLeft[CurrentWeapon]>0) || (AmmoMag[CurrentWeapon]>0) )
+ {
+ wptr->state = 4;
+ wptr->FTime = 1;
+ AddVoicev(wptr->chinfo[CurrentWeapon].SoundFX[3].length,
+ wptr->chinfo[CurrentWeapon].SoundFX[3].lpData, 256);
+ }
+
+
+ if (!ShotsLeft[CurrentWeapon])
+ if (AmmoMag[CurrentWeapon]) {
+ AmmoMag[CurrentWeapon]--;
+ ShotsLeft[CurrentWeapon] = WeapInfo[CurrentWeapon].Shots;
+ if (wptr->chinfo[CurrentWeapon].Animation[3].AniTime) {
+ wptr->state = 4;
+ wptr->FTime = 1;
+ AddVoicev(wptr->chinfo[CurrentWeapon].SoundFX[3].length,
+ wptr->chinfo[CurrentWeapon].SoundFX[3].lpData, 256);
+ }
+ }
+ }
+ }
+
+ if (wptr->state == 3) {
+ wptr->FTime+=TimeDt;
+ if (wptr->FTime >= wptr->chinfo[CurrentWeapon].Animation[2].AniTime) {
+ wptr->FTime = 0;
+ wptr->state = 0;
+ if (CurrentWeapon != TargetWeapon) {
+ CurrentWeapon = TargetWeapon;
+ HideWeapon();
+ }
+ goto SKIPWEAPON;
+ }
+ }
+
+
+
+ if (!ShotsLeft[CurrentWeapon]) {
+ HideWeapon();
+ for (int w=0; w<10; w++)
+ if (ShotsLeft[w]) { TargetWeapon=w; break; }
+ }
+
+ CreateMorphedModel(wptr->chinfo[CurrentWeapon].mptr,
+ &wptr->chinfo[CurrentWeapon].Animation[wptr->state-1], wptr->FTime, 1.0);
+
+ b = (float)f_sin((float)RealTime / 300.f) / 100.f;
+ wpnDAlpha = wptr->shakel * (float)f_sin((float)RealTime / 300.f+pi/2) / 200.f;
+ wpnDBeta = wptr->shakel * (float)f_sin((float)RealTime / 300.f) / 400.f;
+ nv.z = 0;
+
+ //==================== render weapon ===================//
+
+
+ Vector3d v = Sun3dPos;
+ Sun3dPos = RotateVector(Sun3dPos);
+ CalcNormals(wptr->chinfo[CurrentWeapon].mptr, wptr->normals);
+
+
+ if (GOUR)
+ CalcGouraud(wptr->chinfo[CurrentWeapon].mptr, wptr->normals);
+ else
+ for (int c=0; c<1000; c++)
+ wptr->chinfo[CurrentWeapon].mptr->VLight[0][c] = 0;
+
+ if (HARD3D) wpnlight = 96 + GetLandLt(PlayerX, PlayerZ) / 4;
+ else wpnlight = 200;
+
+ RenderNearModel(wptr->chinfo[CurrentWeapon].mptr, 0, wpshy, wpshz, wpnlight,
+ -wpnDAlpha, -wpnDBeta + wpnb);
+
+
+#ifdef _soft
+#else
+ if (PHONG) {
+ CalcPhongMapping(wptr->chinfo[CurrentWeapon].mptr, wptr->normals);
+ RenderModelClipPhongMap(wptr->chinfo[CurrentWeapon].mptr, 0, wpshy, wpshz, -wpnDAlpha, -wpnDBeta+wpnb);
+ }
+
+ if (ENVMAP) {
+ CalcEnvMapping(wptr->chinfo[CurrentWeapon].mptr, wptr->normals);
+ RenderModelClipEnvMap(wptr->chinfo[CurrentWeapon].mptr, 0, wpshy, wpshz, -wpnDAlpha, -wpnDBeta+wpnb);
+ }
+#endif
+
+ Sun3dPos = v;
+
+
+ //Render_Cross(VideoCX, VideoCY);
+ if (OPTICMODE) DrawOpticCross(wptr->chinfo[CurrentWeapon].mptr->VCount-1);
+
+
+
+SKIPWEAPON:
+
+ if (ChCallTime) {
+ ChCallTime-=TimeDt;
+ if (ChCallTime<0) ChCallTime=0;
+ DrawPicture(WinW - 10 - DinoInfo[ AI_to_CIndex[TargetCall] ].CallIcon.W, 7,
+ DinoInfo[ AI_to_CIndex[TargetCall] ].CallIcon);
+ }
+
+ Hardware_ZBuffer(TRUE);
+
+ if (Weapon.state) {
+ int y0 = 5;
+ if (AmmoMag[CurrentWeapon]) {
+ for (int bl=0; bl<WeapInfo[CurrentWeapon].Shots; bl++)
+ DrawPicture(6 + bl*Weapon.BulletPic[CurrentWeapon].W, y0, Weapon.BulletPic[CurrentWeapon]);
+ y0+=Weapon.BulletPic[CurrentWeapon].H+4;
+ }
+
+ for (int bl=0; bl<ShotsLeft[CurrentWeapon]; bl++)
+ DrawPicture(6 + bl*Weapon.BulletPic[CurrentWeapon].W, y0, Weapon.BulletPic[CurrentWeapon]);
+ }
+
+
+ if (TrophyMode)
+ DrawPicture( VideoCX - TrophyExit.W / 2, 2, TrophyExit);
+
+ if (EXITMODE)
+ DrawPicture( (WinW - ExitPic.W) / 2, (WinH - ExitPic.H) / 2, ExitPic);
+
+ if (PAUSE)
+ DrawPicture( (WinW - PausePic.W) / 2, (WinH - PausePic.H) / 2, PausePic);
+
+ if (TrophyMode || TrophyTime)
+ if (TrophyBody!=-1) {
+ int x0 = WinW - TrophyPic.W - 16;
+ int y0 = WinH - TrophyPic.H - 12;
+ if (!TrophyMode)
+ x0 = VideoCX - TrophyPic.W / 2;
+
+ DrawPicture( x0, y0, TrophyPic);
+ DrawTrophyText(x0, y0);
+
+ if (TrophyTime) {
+ TrophyTime-=TimeDt;
+ if (TrophyTime<0) {
+ TrophyTime=0;
+ TrophyBody = -1;
+ }
+ }
+ }
+}
+
+
+
+
+
+void SwitchMode(LPSTR lps, BOOL& b)
+{
+ b = !b;
+ char buf[200];
+ if (b) wsprintf(buf,"%s is ON", lps);
+ else wsprintf(buf,"%s is OFF", lps);
+ MessageBeep(0xFFFFFFFF);
+ AddMessage(buf);
+}
+
+
+void ChangeViewR(int d1, int d2, int d3)
+{
+ char buf[200];
+ ctViewR +=d1;
+ ctViewR1+=d2;
+ ctViewRM+=d3;
+ if (ctViewR<20) ctViewR = 20;
+ if (ctViewR>122) ctViewR = 122;
+
+ if (ctViewR1 < 12) ctViewR1=12;
+ if (ctViewR1 > ctViewR-10) ctViewR1=ctViewR-10;
+ if (ctViewRM < 4) ctViewRM = 4;
+ if (ctViewRM > 60) ctViewRM = 60;
+
+ wsprintf(buf,"ViewR = %d (%d + %d) BMP at %d", ctViewR, ctViewR1, ctViewR-ctViewR1, ctViewRM);
+ //MessageBeep(0xFFFFFFFF);
+ AddMessage(buf);
+
+}
+
+
+void ChangeCall()
+{
+ if (!TargetDino) return;
+ if (ChCallTime)
+ for (int t=0; t<32; t++) {
+ TargetCall++;
+ if (TargetCall>32) TargetCall=10;
+ if (TargetDino & (1<<TargetCall)) break;
+ }
+ //wsprintf(logt,"Call: %s", DinoInfo[ AI_to_CIndex[TargetCall] ].Name);
+ //AddMessage(logt);
+ //CallLockTime+= 1024;
+ ChCallTime = 2048;
+}
+
+void ToggleBinocular()
+{
+ if (Weapon.state) return;
+ if (UNDERWATER) return;
+ if (!MyHealth) return;
+ BINMODE = !BINMODE;
+ MapMode = FALSE;
+}
+
+
+void ToggleRunMode()
+{
+ RunMode = !RunMode;
+ if (RunMode) AddMessage("Run mode is ON");
+ else AddMessage("Run mode is OFF");
+}
+
+
+
+void ToggleCrouchMode()
+{
+ CrouchMode = !CrouchMode;
+ if (CrouchMode) AddMessage("Crouch mode is ON");
+ else AddMessage("Crouch mode is OFF");
+}
+
+
+void ToggleMapMode()
+{
+ if (!MyHealth) return;
+ if (BINMODE) return;
+ if (Weapon.state) return;
+ MapMode = !MapMode;
+}
+
+
+
+
+void ShowShifts()
+{
+ sprintf(logt, "Y=%3.4f Z=%3.4f A=%3.4f", wpshy/2, wpshz/2, wpnb*180/3.1415);
+ AddMessage(logt);
+}
+
+LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam)
+{
+ BOOL A = (GetActiveWindow() == hWnd);
+
+ if (A!=blActive) {
+ blActive = A;
+
+ if (blActive) SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+ else SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS);
+
+ if (!blActive) {
+ ShutDown3DHardware();
+ NeedRVM = TRUE;
+ }
+
+ if (blActive) {
+ Audio_Restore();
+ NeedRVM = TRUE;
+ }
+
+ }
+
+ if (message == WM_KEYDOWN) {
+ if ((int)wParam == KeyMap.fkBinoc) ToggleBinocular();
+ if ((int)wParam == KeyMap.fkCCall) ChangeCall();
+ if ((int)wParam == KeyMap.fkRun ) ToggleRunMode();
+ if ((int)wParam == KeyMap.fkCrouch) ToggleCrouchMode();
+ if ((int)wParam == cheatcode[cheati]) {
+ cheati++;
+ if (cheati>6) { cheati=0; SwitchMode("Debug mode",DEBUG); }
+ } else cheati=0;
+ }
+
+
+ switch (message) {
+ case WM_CREATE: return 0;
+
+
+ case WM_KEYDOWN: {
+ BOOL CTRL = (GetKeyState(VK_SHIFT) & 0x8000);
+ switch( (int)wParam ) {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6': {
+ if (Weapon.FTime) break;
+ int w = ((int)wParam ) - '1';
+ if (!ShotsLeft[w]) {
+ AddMessage("No weapon");
+ break;
+ }
+ TargetWeapon = w;
+ if (!Weapon.state)
+ CurrentWeapon = TargetWeapon;
+ HideWeapon();
+ break;
+ }
+
+ case 'U': if (DEBUG) ChangeViewR(0, 0, -2); break;
+ case 'I': if (DEBUG) ChangeViewR(0, 0, +2); break;
+ case 'O': if (DEBUG) ChangeViewR(0, -2, 0); break;
+ //case 'P': if (DEBUG) ChangeViewR(0, +2, 0); break;
+ case 219: if (DEBUG) ChangeViewR(-2, 0, 0); break;
+ case 221: if (DEBUG) ChangeViewR(+2, 0, 0); break;
+
+ /*
+ case '0': wpshy=0; wpshz=0; wpnb=0; break;
+ case '7': if (CTRL) wpshy-=0.25; else wpshy+=0.25;
+ ShowShifts();
+ break;
+ case '8': if (CTRL) wpshz-=0.25; else wpshz+=0.25;
+ ShowShifts();
+ break;
+ case '9': if (CTRL) wpnb-=0.005; else wpnb+=0.005;
+ ShowShifts();
+ break;*/
+
+
+ case 'S': if (DEBUG && CTRL) SwitchMode("Slow mode",SLOW);
+ break;
+ case 'T': if (DEBUG && CTRL) SwitchMode("Timer",TIMER);
+ break;
+
+
+ case 'M': if (CTRL) SwitchMode("Draw 3D models",MODELS);
+ break;
+ case 'F': if (CTRL) SwitchMode("V.Fog",FOGENABLE);
+ break;
+ case 'L': if (CTRL) SwitchMode("Fly",FLY);
+ break;
+ case 'C': if (CTRL) SwitchMode("Clouds shadow",Clouds);
+ break;
+
+ case 'E': if (CTRL) SwitchMode("Env.Mapping",ENVMAP);
+ break;
+ case 'G': if (CTRL) SwitchMode("Gour.Mapping",GOUR);
+ break;
+ case 'P': if (CTRL) SwitchMode("Phong Mapping",PHONG);
+ else if (DEBUG) ChangeViewR(0, +2, 0);
+ break;
+
+ case VK_TAB:
+ if (!TrophyMode) ToggleMapMode();
+ break;
+
+ case VK_PAUSE:
+ PAUSE = !PAUSE; EXITMODE = FALSE; ResetMousePos();
+ break;
+
+ case 'N':
+ if (EXITMODE) EXITMODE = FALSE;
+ break;
+
+ case VK_ESCAPE:
+ if (TrophyMode)
+ {
+ SaveTrophy();
+ ExitTime = 1;
+ } else {
+ if (PAUSE) PAUSE = FALSE;
+ else EXITMODE = !EXITMODE;
+ if (ExitTime) EXITMODE = FALSE;
+ ResetMousePos();
+ }
+ break;
+
+ case 'Y':
+ case VK_RETURN:
+ if (EXITMODE ) {
+ if (MyHealth) ExitTime = 4000; else ExitTime = 1;
+ EXITMODE = FALSE;
+ }
+ break;
+
+ case 'R':
+ if (TrophyBody!=-1) RemoveCurrentTrophy();
+ if (EXITMODE) {
+ LoadTrophy();
+ RestartMode = TRUE;
+ _GameState = 0;
+ //DoHalt("");
+ }
+ break;
+
+ case VK_F9:
+ ShutDown3DHardware();
+ AudioStop();
+ DoHalt("");
+ break;
+
+ case VK_F12: SaveScreenShot(); break;
+
+ } // switch
+ break; }
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ /*
+ case WM_PAINT:
+ case WM_ERASEBKGND:
+ case WM_NCPAINT : break;
+ */
+ /*case WM_PAINT: {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hWnd, &ps );
+ EndPaint(hWnd, &ps);
+ return 0;
+ } */
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ return 0;
+}
+
+
+
+
+BOOL CreateMainWindow()
+{
+ PrintLog("Creating main window...");
+ WNDCLASS wc;
+ wc.style = CS_OWNDC;
+ wc.lpfnWndProc = (WNDPROC)MainWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInst;
+ wc.hIcon = wc.hIcon = LoadIcon(hInst,"ACTION");
+ wc.hCursor = NULL;
+ wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
+ wc.lpszMenuName = NULL;
+ //wc.lpfnWndProc = NULL;
+ wc.lpszClassName = "HuntRenderWindow";
+ if (!RegisterClass(&wc)) return FALSE;
+
+ hwndMain = CreateWindow(
+ "HuntRenderWindow","Carnivores 2 Renderer",
+ WS_VISIBLE | WS_POPUP,
+ 0, 0, 0, 0, NULL, NULL, hInst, NULL );
+
+ if (hwndMain)
+ PrintLog("Ok.\n");
+
+ return TRUE;
+}
+
+
+
+
+
+
+
+
+
+void ProcessShoot()
+{
+ //if (HeadBackR) return;
+ if (!ShotsLeft[CurrentWeapon]) return;
+ TWeapon *wptr = &Weapon;
+ if (UNDERWATER) {
+ HideWeapon();
+ return; }
+
+ if (wptr->state == 2 && wptr->FTime==0) {
+ wptr->FTime = 1;
+ HeadBackR=64;
+ //if (HeadBackR>64) HeadBackR=64;
+
+ AddVoicev(wptr->chinfo[CurrentWeapon].SoundFX[1].length,
+ wptr->chinfo[CurrentWeapon].SoundFX[1].lpData, 256);
+ TrophyRoom.Last.smade++;
+
+for (int s=0; s<=WeapInfo[CurrentWeapon].TraceC; s++) {
+ float rA = 0;
+ float rB = 0;
+
+ rA = siRand(128) * 0.00010 * (2.f - WeapInfo[CurrentWeapon].Prec);
+ rB = siRand(128) * 0.00010 * (2.f - WeapInfo[CurrentWeapon].Prec);
+
+
+ float ca = (float)f_cos(PlayerAlpha + wpnDAlpha + rA);
+ float sa = (float)f_sin(PlayerAlpha + wpnDAlpha + rA);
+ float cb = (float)f_cos(PlayerBeta + wpnDBeta + rB);
+ float sb = (float)f_sin(PlayerBeta + wpnDBeta + rB);
+
+ nv.x=sa;
+ nv.y=0;
+ nv.z=-ca;
+
+ nv.x*=cb;
+ nv.y=-sb;
+ nv.z*=cb;
+
+ MakeShot(PlayerX, PlayerY+HeadY, PlayerZ,
+ PlayerX+nv.x * 256*ctViewR,
+ PlayerY+nv.y * 256*ctViewR + HeadY,
+ PlayerZ+nv.z * 256*ctViewR);
+}
+
+ Vector3d v;
+ v.x = PlayerX;
+ v.y = PlayerY;
+ v.z = PlayerZ;
+ MakeNoise(v, ctViewR*200 * WeapInfo[CurrentWeapon].Loud);
+ ShotsLeft[CurrentWeapon]--;
+ }
+}
+
+
+void ProcessSlide()
+{
+ if (NOCLIP || UNDERWATER) return;
+ float ch = GetLandQHNoObj(PlayerX, PlayerZ);
+ float mh = ch;
+ float chh;
+ int sd = 0;
+
+ chh=GetLandQHNoObj(PlayerX - 16, PlayerZ); if (chh<mh) { mh = chh; sd = 1; }
+ chh=GetLandQHNoObj(PlayerX + 16, PlayerZ); if (chh<mh) { mh = chh; sd = 2; }
+ chh=GetLandQHNoObj(PlayerX, PlayerZ - 16); if (chh<mh) { mh = chh; sd = 3; }
+ chh=GetLandQHNoObj(PlayerX, PlayerZ + 16); if (chh<mh) { mh = chh; sd = 4; }
+
+ chh=GetLandQHNoObj(PlayerX - 12, PlayerZ - 12); if (chh<mh) { mh = chh; sd = 5; }
+ chh=GetLandQHNoObj(PlayerX + 12, PlayerZ - 12); if (chh<mh) { mh = chh; sd = 6; }
+ chh=GetLandQHNoObj(PlayerX - 12, PlayerZ + 12); if (chh<mh) { mh = chh; sd = 7; }
+ chh=GetLandQHNoObj(PlayerX + 12, PlayerZ + 12); if (chh<mh) { mh = chh; sd = 8; }
+
+ if (!NOCLIP)
+ if (mh<ch-16) {
+ float delta = (ch-mh) / 4;
+ if (sd == 1) { PlayerX -= delta; }
+ if (sd == 2) { PlayerX += delta; }
+ if (sd == 3) { PlayerZ -= delta; }
+ if (sd == 4) { PlayerZ += delta; }
+
+ delta*=0.7f;
+ if (sd == 5) { PlayerX -= delta; PlayerZ -= delta; }
+ if (sd == 6) { PlayerX += delta; PlayerZ -= delta; }
+ if (sd == 7) { PlayerX -= delta; PlayerZ += delta; }
+ if (sd == 8) { PlayerX += delta; PlayerZ += delta; }
+ }
+}
+
+
+
+void ProcessPlayerMovement()
+{
+
+ POINT ms;
+
+ GetCursorPos(&ms);
+ if (REVERSEMS) ms.y = -ms.y+VideoCY*2;
+ rav += (float)(ms.x-VideoCX) * (OptMsSens+64) / 600.f / 192.f;
+ rbv += (float)(ms.y-VideoCY) * (OptMsSens+64) / 600.f / 192.f;
+ if (KeyFlags & kfStrafe)
+ SSpeed+= (float)rav * 10; else
+ PlayerAlpha += rav;
+ PlayerBeta += rbv;
+
+ rav/=(2.f + (float)TimeDt/20.f);
+ rbv/=(2.f + (float)TimeDt/20.f);
+ ResetMousePos();
+
+
+
+ if ( !(KeyFlags & (kfForward | kfBackward)))
+ if (VSpeed>0) VSpeed=max(0,VSpeed-DeltaT*2);
+ else VSpeed=min(0,VSpeed+DeltaT*2);
+
+ if ( !(KeyFlags & (kfSLeft | kfSRight)))
+ if (SSpeed>0) SSpeed=max(0,SSpeed-DeltaT*2);
+ else SSpeed=min(0,SSpeed+DeltaT*2);
+
+ if (KeyFlags & kfForward) if (VSpeed>0) VSpeed+=DeltaT; else VSpeed+=DeltaT*4;
+ if (KeyFlags & kfBackward) if (VSpeed<0) VSpeed-=DeltaT; else VSpeed-=DeltaT*4;
+
+ if (KeyFlags & kfSRight ) if (SSpeed>0) SSpeed+=DeltaT; else SSpeed+=DeltaT*4;
+ if (KeyFlags & kfSLeft ) if (SSpeed<0) SSpeed-=DeltaT; else SSpeed-=DeltaT*4;
+
+
+ if (SWIM) {
+ if (VSpeed > 0.25f) VSpeed = 0.25f;
+ if (VSpeed <-0.25f) VSpeed =-0.25f;
+ if (SSpeed > 0.25f) SSpeed = 0.25f;
+ if (SSpeed <-0.25f) SSpeed =-0.25f;
+ }
+ if ( RunMode && (HeadY > 190.f) && (Weapon.state==0)) {
+ if (VSpeed > 0.7f) VSpeed = 0.7f;
+ if (VSpeed <-0.7f) VSpeed =-0.7f;
+ if (SSpeed > 0.7f) SSpeed = 0.7f;
+ if (SSpeed <-0.7f) SSpeed =-0.7f;
+ } else {
+ if (VSpeed > 0.3f) VSpeed = 0.3f;
+ if (VSpeed <-0.3f) VSpeed =-0.3f;
+ if (SSpeed > 0.30f) SSpeed = 0.30f;
+ if (SSpeed <-0.30f) SSpeed =-0.30f;
+ }
+
+ if (KeyboardState [KeyMap.fkFire] & 128) ProcessShoot();
+
+
+ if (KeyboardState [KeyMap.fkShow] & 128) HideWeapon();
+
+ if (BINMODE) {
+ if (KeyboardState[VK_ADD ] & 128) BinocularPower+=BinocularPower * TimeDt / 4000.f;
+ if (KeyboardState[VK_SUBTRACT] & 128) BinocularPower-=BinocularPower * TimeDt / 4000.f;
+ if (BinocularPower < 1.5f) BinocularPower = 1.5f;
+ if (BinocularPower > 3.0f) BinocularPower = 3.0f;
+ }
+
+ if (KeyFlags & kfCall) MakeCall();
+
+ if (DEBUG)
+ if (KeyboardState [VK_CONTROL] & 128)
+ if (KeyFlags & kfBackward) VSpeed =-8; else VSpeed = 8;
+
+ if (KeyFlags & kfJump)
+ if (YSpeed == 0 && !SWIM) {
+ YSpeed = 600 + (float)fabs(VSpeed) * 600;
+ AddVoicev(fxJump.length, fxJump.lpData, 256);
+ }
+
+//========= rotation =========//
+ if (KeyFlags & kfRight) PlayerAlpha+=DeltaT*1.5f;
+ if (KeyFlags & kfLeft ) PlayerAlpha-=DeltaT*1.5f;
+ if (KeyFlags & kfLookUp) PlayerBeta-=DeltaT;
+ if (KeyFlags & kfLookDn) PlayerBeta+=DeltaT;
+
+
+//========= movement ==========//
+
+ ca = (float)f_cos(PlayerAlpha);
+ sa = (float)f_sin(PlayerAlpha);
+ cb = (float)f_cos(PlayerBeta);
+ sb = (float)f_sin(PlayerBeta);
+
+ nv.x=sa;
+ nv.y=0;
+ nv.z=-ca;
+
+
+ PlayerNv = nv;
+ if (UNDERWATER || FLY) {
+ nv.x*=cb;
+ nv.y=-sb;
+ nv.z*=cb;
+ PlayerNv = nv;
+ } else {
+ PlayerNv.x*=cb;
+ PlayerNv.y=-sb;
+ PlayerNv.z*=cb;
+ }
+
+ Vector3d sv = nv;
+ nv.x*=(float)TimeDt*VSpeed;
+ nv.y*=(float)TimeDt*VSpeed;
+ nv.z*=(float)TimeDt*VSpeed;
+
+ sv.x*=(float)TimeDt*SSpeed;
+ sv.y=0;
+ sv.z*=(float)TimeDt*SSpeed;
+
+ if (!TrophyMode) {
+ TrophyRoom.Last.path+=(TimeDt*VSpeed) / 128.f;
+ TrophyRoom.Last.time+=TimeDt/1000.f;
+ }
+
+ //if (SWIM & (VSpeed>0.1) & (sb>0.60)) HeadY-=40;
+
+ int mvi = 1 + TimeDt / 16;
+
+ for (int mvc = 0; mvc<mvi; mvc++) {
+ PlayerX+=nv.x / mvi;
+ PlayerY+=nv.y / mvi;
+ PlayerZ+=nv.z / mvi;
+
+ PlayerX-=sv.z / mvi;
+ PlayerZ+=sv.x / mvi;
+
+ if (!NOCLIP) CheckCollision(PlayerX, PlayerZ);
+
+ if (PlayerY <= GetLandQHNoObj(PlayerX, PlayerZ)+16) {
+ ProcessSlide();
+ ProcessSlide(); }
+ }
+
+ if (PlayerY <= GetLandQHNoObj(PlayerX, PlayerZ)+16) {
+ ProcessSlide();
+ ProcessSlide(); }
+//===========================================================
+}
+
+
+void ProcessDemoMovement()
+{
+ BINMODE = FALSE;
+
+ PAUSE = FALSE;
+ MapMode = FALSE;
+
+ if (DemoPoint.DemoTime>6*1000)
+ if (!PAUSE) {
+ EXITMODE = TRUE;
+ ResetMousePos();
+ }
+
+ if (DemoPoint.DemoTime>12*1000) {
+ //ResetMousePos();
+ //DemoPoint.DemoTime = 0;
+ //LoadTrophy();
+ DoHalt("");
+ return; }
+
+ VSpeed = 0.f;
+
+ DemoPoint.pos = Characters[DemoPoint.CIndex].pos;
+ DemoPoint.pos.y+=256;
+
+ Vector3d nv = SubVectors(DemoPoint.pos, CameraPos);
+ Vector3d pp = DemoPoint.pos;
+ pp.y = CameraPos.y;
+ float l = VectorLength( SubVectors(pp, CameraPos) );
+ float base = 824;
+
+ if (DemoPoint.DemoTime==1)
+ if (l < base) DemoPoint.DemoTime = 2;
+ NormVector(nv, 1.0f);
+
+ if (DemoPoint.DemoTime == 1) {
+ DeltaFunc(CameraX, DemoPoint.pos.x, (float)fabs(nv.x) * TimeDt * 3.f);
+ DeltaFunc(CameraZ, DemoPoint.pos.z, (float)fabs(nv.z) * TimeDt * 3.f);
+ } else {
+ DemoPoint.DemoTime+=TimeDt;
+ CameraAlpha+=TimeDt / 1224.f;
+ ca = (float)f_cos(CameraAlpha);
+ sa = (float)f_sin(CameraAlpha);
+ //float k = (base - l) / 350.f;
+ DeltaFunc(CameraX, DemoPoint.pos.x - sa * base, (float)TimeDt );
+ DeltaFunc(CameraZ, DemoPoint.pos.z + ca * base, (float)TimeDt );
+ }
+
+ float b = FindVectorAlpha( (float)
+ sqrt ( (DemoPoint.pos.x - CameraX)*(DemoPoint.pos.x - CameraX) +
+ (DemoPoint.pos.z - CameraZ)*(DemoPoint.pos.z - CameraZ) ),
+ DemoPoint.pos.y - CameraY - 400.f);
+ if (b>pi) b = b - 2*pi;
+ DeltaFunc(CameraBeta, -b , TimeDt / 4000.f);
+
+
+
+ float h = GetLandQH(CameraX, CameraZ);
+ DeltaFunc(CameraY, h+128, TimeDt / 8.f);
+ if (CameraY < h + 80) CameraY = h + 80;
+}
+
+
+
+
+void ProcessControls()
+{
+ int _KeyFlags = KeyFlags;
+ KeyFlags = 0;
+ GetKeyboardState(KeyboardState);
+
+
+ if (KeyboardState [KeyMap.fkStrafe] & 128) KeyFlags+=kfStrafe;
+
+ if (KeyboardState [KeyMap.fkForward ] & 128) KeyFlags+=kfForward;
+ if (KeyboardState [KeyMap.fkBackward] & 128) KeyFlags+=kfBackward;
+
+ if (KeyboardState [KeyMap.fkUp ] & 128) KeyFlags+=kfLookUp;
+ if (KeyboardState [KeyMap.fkDown ] & 128) KeyFlags+=kfLookDn;
+
+ if (KeyFlags & kfStrafe) {
+ if (KeyboardState [KeyMap.fkLeft ] & 128) KeyFlags+=kfSLeft;
+ if (KeyboardState [KeyMap.fkRight] & 128) KeyFlags+=kfSRight;
+ } else {
+ if (KeyboardState [KeyMap.fkLeft ] & 128) KeyFlags+=kfLeft;
+ if (KeyboardState [KeyMap.fkRight] & 128) KeyFlags+=kfRight;
+ }
+
+ if (KeyboardState [KeyMap.fkSLeft] & 128) KeyFlags+=kfSLeft;
+ if (KeyboardState [KeyMap.fkSRight] & 128) KeyFlags+=kfSRight;
+
+
+ if (KeyboardState [KeyMap.fkJump] & 128) KeyFlags+=kfJump;
+
+ if (KeyboardState [KeyMap.fkCall] & 128)
+ if (!(_KeyFlags & kfCall)) KeyFlags+=kfCall;
+
+ DeltaT = (float)TimeDt / 1000.f;
+
+ if ( DemoPoint.DemoTime) ProcessDemoMovement();
+ if (!DemoPoint.DemoTime) ProcessPlayerMovement();
+
+
+//======= Y movement ===========//
+ HeadAlpha = HeadBackR / 20000;
+ HeadBeta =-HeadBackR / 10000;
+ if (HeadBackR) {
+ HeadBackR-=DeltaT*(80 + (32-(float)fabs(HeadBackR - 32))*4);
+ if (HeadBackR<=0) { HeadBackR = 0; HeadBSpeed = 0; }
+ }
+
+ if (CrouchMode | (UNDERWATER) ) {
+ if (HeadY<110.f) HeadY = 110.f;
+ HeadY-=DeltaT*(60 + (HeadY-110)*5);
+ if (HeadY<110.f) HeadY = 110.f;
+ } else {
+ if (HeadY>220.f) HeadY = 220.f;
+ HeadY+=DeltaT*(60 + (220 - HeadY) * 5);
+ if (HeadY>220.f) HeadY = 220.f;
+ }
+
+
+ float h = GetLandQH(PlayerX, PlayerZ);
+ float hu = GetLandCeilH(PlayerX, PlayerZ)-64;
+ float hwater = GetLandUpH(PlayerX, PlayerZ);
+
+ if (DemoPoint.DemoTime) goto SKIPYMOVE;
+
+ if (!UNDERWATER) {
+ if (PlayerY>h) YSpeed-=DeltaT*3000;
+ } else
+ if (YSpeed<0) {
+ YSpeed+=DeltaT*4000;
+ if (YSpeed>0) YSpeed=0;
+ }
+
+ if (FLY) YSpeed=0;
+ PlayerY+=YSpeed*DeltaT;
+
+
+ if (PlayerY+HeadY>hu) {
+ if (YSpeed>0) YSpeed=-1;
+ PlayerY = hu - HeadY;
+ if (PlayerY<h) {
+ PlayerY = h;
+ HeadY = hu - PlayerY;
+ if (HeadY<110) HeadY = 110;
+ }
+ }
+
+ if (PlayerY<h) {
+ if (YSpeed<-800) HeadY+=YSpeed/100;
+ if (PlayerY < h-80) PlayerY = h - 80;
+ PlayerY+=(h-PlayerY+32)*DeltaT*4;
+ if (PlayerY>h) PlayerY = h;
+ if (YSpeed<-600)
+ AddVoicev(fxStep[(RealTime % 3)].length,
+ fxStep[(RealTime % 3)].lpData, 64);
+ YSpeed = 0;
+ }
+
+SKIPYMOVE:
+
+ SWIM = FALSE;
+ if (!UNDERWATER && (KeyFlags & kfJump) )
+ if (PlayerY<hwater-148) { SWIM = TRUE; PlayerY = hwater-148; YSpeed = 0; }
+
+ float _s = stepdy;
+
+ if (SWIM) stepdy = (float)f_sin((float)RealTime / 360) * 20;
+ else stepdy = (float)min(1.f,fabs(VSpeed) + (float)fabs(SSpeed)) * (float)f_sin((float)RealTime / 80.f) * 22.f;
+ float d = stepdy - _s;
+
+ if (!UNDERWATER)
+ if (PlayerY<h+64)
+ if (d<0 && stepdd >= 0)
+ if (ONWATER) {
+ AddWCircle(CameraX, CameraZ, 1.2);
+ AddVoicev(fxStepW[(RealTime % 3)].length,
+ fxStepW[(RealTime % 3)].lpData, 64+(int)(VSpeed*30.f));
+ }
+ else
+ AddVoicev(fxStep[(RealTime % 3)].length,
+ fxStep[(RealTime % 3)].lpData, 24+(int)(VSpeed*50.f));
+ stepdd = d;
+
+ if (PlayerBeta> 1.46f) PlayerBeta= 1.46f;
+ if (PlayerBeta<-1.26f) PlayerBeta=-1.26f;
+
+
+//======== set camera pos ===================//
+
+ if (!DemoPoint.DemoTime) {
+ CameraAlpha = PlayerAlpha + HeadAlpha;
+ CameraBeta = PlayerBeta + HeadBeta;
+
+ CameraX = PlayerX - sa * HeadBackR;
+ CameraY = PlayerY + HeadY + stepdy;// + 2024;
+ CameraZ = PlayerZ + ca * HeadBackR;
+ }
+
+ if (CLIP3D) {
+ if (sb<0) BackViewR = 320.f - 1024.f * sb;
+ else BackViewR = 320.f + 512.f * sb;
+ BackViewRR = 380 + (int)(1024 * fabs(sb));
+ if (UNDERWATER) BackViewR -= 512.f * (float)min(0,sb);
+ } else {
+ BackViewR = 300;
+ BackViewRR = 380;
+ }
+
+
+//==================== SWIM & UNDERWATER =========================//
+ ONWATER = (GetLandUpH(CameraX, CameraZ) > GetLandH(CameraX, CameraZ)) &&
+ (PlayerY < GetLandUpH(CameraX, CameraZ));
+
+ if (UNDERWATER) {
+ UNDERWATER = (GetLandUpH(CameraX, CameraZ)-4>= CameraY);
+ if (!UNDERWATER) {
+ HeadY+=20; CameraY+=20;
+ AddVoicev(fxWaterOut.length, fxWaterOut.lpData, 256);
+ AddWCircle(CameraX, CameraZ, 2.0);
+ }
+ } else {
+ UNDERWATER = (GetLandUpH(CameraX, CameraZ)+28 >= CameraY);
+ if (UNDERWATER) {
+ HeadY-=20; CameraY-=20;
+ BINMODE = FALSE;
+ AddVoicev(fxWaterIn.length, fxWaterIn.lpData, 256);
+ AddWCircle(CameraX, CameraZ, 2.0);
+ }
+ }
+
+ if (MyHealth)
+ if (UNDERWATER) {
+ MyHealth-=TimeDt*12;
+ //if ( !(Takt & 31)) AddElements(CameraX + sa*64*cb, CameraY - 32 - sb*64, CameraZ - ca*64*cb, 4);
+ if (MyHealth<=0)
+ AddDeadBody(NULL, HUNT_BREATH);
+ }
+
+ if (UNDERWATER)
+ if (Weapon.state) HideWeapon();
+
+ if (!UNDERWATER) UnderWaterT = 0;
+ else if (UnderWaterT<512) UnderWaterT += TimeDt; else UnderWaterT = 512;
+
+ if (UNDERWATER) {
+ CameraW = (float)VideoCX*(1.25f + (1.f+(float)f_cos(RealTime/180.f)) / 30 + (1.f - (float)f_sin(UnderWaterT/512.f*pi/2)) / 1.5f );
+ CameraH = (float)VideoCX*(1.25f + (1.f+(float)f_sin(RealTime/180.f)) / 30 - (1.f - (float)f_sin(UnderWaterT/512.f*pi/2)) / 16.f );
+ CameraH *=(WinH*1.3333f / WinW);
+
+ CameraAlpha+=(float)f_cos(RealTime/360.f) / 120;
+ CameraBeta +=(float)f_sin(RealTime/360.f) / 100;
+ CameraY-=(float)f_sin(RealTime/360.f) * 4;
+ int w = WMap[(((int)(CameraZ))>>8) ][ (((int)(CameraX))>>8) ];
+ FogsList[127].YBegin = (float)WaterList[w].wlevel;
+ FogsList[127].fogRGB = WaterList[w].fogRGB;
+ } else {
+ CameraW = (float)VideoCX*1.25f;
+ CameraH = CameraW * (WinH*1.3333f / WinW);
+ }
+
+
+ if (BINMODE) {
+ CameraW*=BinocularPower;
+ CameraH*=BinocularPower;
+ } else if (OPTICMODE) {
+ CameraW*=3.0f;
+ CameraH*=3.0f;
+ }
+
+ FOVK = CameraW / (VideoCX*1.25f);
+
+ InitClips();
+
+ if (SWIM) {
+ if (!(Takt & 31)) AddWCircle(CameraX, CameraZ, 1.5);
+ CameraBeta -=(float)f_cos(RealTime/360.f) / 80;
+ PlayerX+=DeltaT*32;
+ PlayerZ+=DeltaT*32;
+ }
+
+
+ CameraFogI = FogsMap [((int)CameraZ)>>9][((int)CameraX)>>9];
+ if (UNDERWATER) CameraFogI=127;
+ if (FogsList[CameraFogI].YBegin*ctHScale> CameraY)
+ CAMERAINFOG = (CameraFogI>0);
+ else
+ CAMERAINFOG = FALSE;
+
+ if (CAMERAINFOG)
+ if (MyHealth)
+ if (FogsList[CameraFogI].Mortal) {
+ if (MyHealth>100000) MyHealth = 100000;
+ MyHealth-=TimeDt*64;
+ if (MyHealth<=0)
+ AddDeadBody(NULL, HUNT_EAT);
+ }
+
+ int CameraAmb = AmbMap [((int)CameraZ)>>9][((int)CameraX)>>9];
+
+
+ if (UNDERWATER) {
+ SetAmbient(fxUnderwater.length,
+ fxUnderwater.lpData,
+ 240);
+ Audio_SetEnvironment(8, ctViewR*256);
+ } else {
+ SetAmbient(Ambient[CameraAmb].sfx.length,
+ Ambient[CameraAmb].sfx.lpData,
+ Ambient[CameraAmb].AVolume);
+ Audio_SetEnvironment(Ambient[CameraAmb].rdata[0].REnvir, ctViewR*256);
+
+
+ Env = Ambient[CameraAmb].rdata[0].REnvir;
+
+ if (Ambient[CameraAmb].RSFXCount) {
+ Ambient[CameraAmb].RndTime-=TimeDt;
+ if (Ambient[CameraAmb].RndTime<=0) {
+ Ambient[CameraAmb].RndTime = (Ambient[CameraAmb].rdata[0].RFreq / 2 + rRand(Ambient[CameraAmb].rdata[0].RFreq)) * 1000;
+ int rr = (rand() % Ambient[CameraAmb].RSFXCount);
+ int r = Ambient[CameraAmb].rdata[rr].RNumber;
+ AddVoice3dv(RandSound[r].length, RandSound[r].lpData,
+ CameraX + siRand(4096),
+ CameraY + siRand(256),
+ CameraZ + siRand(4096) ,
+ Ambient[CameraAmb].rdata[rr].RVolume);
+ }
+ }
+ }
+
+
+ if (NOCLIP) CameraY+=1024;
+ //======= results ==========//
+ if (CameraBeta> 1.46f) CameraBeta= 1.46f;
+ if (CameraBeta<-1.26f) CameraBeta=-1.26f;
+
+ PlayerPos.x = PlayerX;
+ PlayerPos.y = PlayerY;
+ PlayerPos.z = PlayerZ;
+
+ CameraPos.x = CameraX;
+ CameraPos.y = CameraY;
+ CameraPos.z = CameraZ;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void ProcessGame()
+{
+ if (RestartMode) {
+ ShutDown3DHardware();
+ AudioStop();
+ NeedRVM = TRUE;
+ }
+
+ if (!_GameState) {
+ PrintLog("Entered game\n");
+ ReInitGame();
+ while (ShowCursor(FALSE)>=0);
+ }
+
+ _GameState = 1;
+
+ if (NeedRVM) {
+ SetWindowPos(hwndMain, HWND_TOP, 0,0,0,0, SWP_SHOWWINDOW);
+ SetFocus(hwndMain);
+ Activate3DHardware();
+ NeedRVM = FALSE;
+ }
+
+ ProcessSyncro();
+
+ if (!PAUSE || !MyHealth) {
+ ProcessControls();
+ AudioSetCameraPos(CameraX, CameraY, CameraZ, CameraAlpha, CameraBeta);
+ Audio_UploadGeometry();
+// AnimateCharacters();
+ AnimateProcesses();
+ }
+
+ if (DEBUG || ObservMode || TrophyMode)
+ if (MyHealth) MyHealth = MAX_HEALTH;
+ if (DEBUG) ShotsLeft[CurrentWeapon] = WeapInfo[CurrentWeapon].Shots;
+
+ DrawScene();
+
+ if (!TrophyMode)
+ if (MapMode) DrawHMap();
+
+ DrawPostObjects();
+
+ ShowControlElements();
+
+ ShowVideo();
+}
+
+
+
+int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine, int nCmdShow)
+{
+ MSG msg;
+
+ hInst = hInstance;
+ CreateLog();
+
+ CreateMainWindow();
+
+ Init3DHardware();
+ InitEngine();
+ InitAudioSystem(hwndMain, hlog, OptSound);
+
+ StartLoading();
+ PrintLoad("Loading...");
+
+ PrintLog("== Loading resources ==\n");
+ hcArrow = LoadCursor(NULL, IDC_ARROW);
+
+
+ PrintLog("Loading common resources:");
+ PrintLoad("Loading common resources...");
+
+ if (OptDayNight==2)
+ LoadModelEx(SunModel, "HUNTDAT\\MOON.3DF");
+ else
+ LoadModelEx(SunModel, "HUNTDAT\\SUN2.3DF");
+ LoadModelEx(CompasModel, "HUNTDAT\\COMPAS.3DF");
+ LoadModelEx(Binocular, "HUNTDAT\\BINOCUL.3DF");
+
+ LoadCharacterInfo(WCircleModel , "HUNTDAT\\WCIRCLE2.CAR");
+ LoadCharacterInfo(ShipModel, "HUNTDAT\\ship2a.car");
+ LoadCharacterInfo(WindModel, "HUNTDAT\\WIND.CAR");
+
+
+ LoadWav("HUNTDAT\\SOUNDFX\\a_underw.wav", fxUnderwater);
+
+ LoadWav("HUNTDAT\\SOUNDFX\\STEPS\\hwalk1.wav", fxStep[0]);
+ LoadWav("HUNTDAT\\SOUNDFX\\STEPS\\hwalk2.wav", fxStep[1]);
+ LoadWav("HUNTDAT\\SOUNDFX\\STEPS\\hwalk3.wav", fxStep[2]);
+
+ LoadWav("HUNTDAT\\SOUNDFX\\STEPS\\footw1.wav", fxStepW[0]);
+ LoadWav("HUNTDAT\\SOUNDFX\\STEPS\\footw2.wav", fxStepW[1]);
+ LoadWav("HUNTDAT\\SOUNDFX\\STEPS\\footw3.wav", fxStepW[2]);
+
+ LoadWav("HUNTDAT\\SOUNDFX\\hum_die1.wav", fxScream[0]);
+ LoadWav("HUNTDAT\\SOUNDFX\\hum_die2.wav", fxScream[1]);
+ LoadWav("HUNTDAT\\SOUNDFX\\hum_die3.wav", fxScream[2]);
+ LoadWav("HUNTDAT\\SOUNDFX\\hum_die4.wav", fxScream[3]);
+
+ LoadPictureTGA(PausePic, "HUNTDAT\\MENU\\pause.tga"); conv_pic(PausePic);
+ LoadPictureTGA(ExitPic, "HUNTDAT\\MENU\\exit.tga"); conv_pic(ExitPic);
+ LoadPictureTGA(TrophyExit, "HUNTDAT\\MENU\\trophy_e.tga"); conv_pic(TrophyExit);
+ LoadPictureTGA(MapPic, "HUNTDAT\\MENU\\mapframe.tga"); conv_pic(MapPic);
+
+ LoadPictureTGA(TFX_ENVMAP, "HUNTDAT\\FX\\envmap.tga"); ApplyAlphaFlags(TFX_ENVMAP.lpImage, TFX_ENVMAP.W*TFX_ENVMAP.W);
+ LoadPictureTGA(TFX_SPECULAR, "HUNTDAT\\FX\\specular.tga"); ApplyAlphaFlags(TFX_SPECULAR.lpImage, TFX_SPECULAR.W*TFX_SPECULAR.W);
+
+
+ PrintLog(" Done.\n");
+
+ PrintLoad("Loading area...");
+ LoadResources();
+
+ PrintLoad("Starting game...");
+ PrintLog("Loading area: Done.\n");
+
+ EndLoading();
+
+ ProcessSyncro();
+ blActive = TRUE;
+
+ PrintLog("Entering messages loop.\n");
+ for( ; ; )
+ if( PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ) ) {
+ if (msg.message == WM_QUIT) break;
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ } else {
+ if (QUITMODE==1) {
+ ShutDown3DHardware();
+ Audio_Shutdown();
+ DestroyWindow(hwndMain);
+ QUITMODE=2;
+ }
+ if (!QUITMODE)
+ if (blActive) ProcessGame();
+ else Sleep(100);
+ }
+
+
+
+ ShutDownEngine();
+ ShowCursor(TRUE);
+ PrintLog("Game normal shutdown.\n");
+
+ CloseLog();
+ return msg.wParam;
+}
diff --git a/IceAge.eal b/IceAge.eal
new file mode 100644
index 0000000..cedd04d
--- /dev/null
+++ b/IceAge.eal
Binary files differ
diff --git a/Interface.cpp b/Interface.cpp
new file mode 100644
index 0000000..ec1fe54
--- /dev/null
+++ b/Interface.cpp
@@ -0,0 +1,193 @@
+#define INITGUID
+#include "Hunt.h"
+#include "stdio.h"
+
+typedef struct _TMenuSet {
+ int x0, y0;
+ int Count;
+ char Item[32][32];
+} TMenuSet;
+
+
+TMenuSet Options[3];
+char HMLtxt[3][12];
+char CKtxt[2][16];
+char Restxt[8][24];
+char Textxt[3][12];
+char Ontxt[2][12];
+char Systxt[2][12];
+int CurPlayer = -1;
+int MaxDino, AreaMax, LoadCount;
+
+#define REGLISTX 320
+#define REGLISTY 370
+
+BOOL NEWPLAYER = FALSE;
+
+int MapVKKey(int k)
+{
+ if (k==VK_LBUTTON) return 124;
+ if (k==VK_RBUTTON) return 125;
+ return MapVirtualKey(k , 0);
+}
+
+
+
+
+POINT p;
+int OptMode = 0;
+int OptLine = 0;
+
+
+void wait_mouse_release()
+{
+ while (GetAsyncKeyState(VK_RBUTTON) & 0x80000000);
+ while (GetAsyncKeyState(VK_LBUTTON) & 0x80000000);
+
+}
+
+
+int GetTextW(HDC hdc, LPSTR s)
+{
+ SIZE sz;
+ GetTextExtentPoint(hdc, s, strlen(s), &sz);
+ return sz.cx;
+}
+
+void PrintText(LPSTR s, int x, int y, int rgb)
+{
+ HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcCMain,hbmpVideoBuf);
+ SetBkMode(hdcCMain, TRANSPARENT);
+
+ SetTextColor(hdcCMain, 0x00000000);
+ TextOut(hdcCMain, x+1, y+1, s, strlen(s));
+ SetTextColor(hdcCMain, rgb);
+ TextOut(hdcCMain, x, y, s, strlen(s));
+
+ SelectObject(hdcCMain,hbmpOld);
+}
+
+
+void DoHalt(LPSTR Mess)
+{
+ AudioStop();
+
+ if (strlen(Mess)) {
+ PrintLog("ABNORMAL_HALT: ");
+ PrintLog(Mess);
+ PrintLog("\n");
+ ShutDown3DHardware();
+ Audio_Shutdown();
+ EnableWindow(hwndMain, FALSE);
+ MessageBox(NULL, Mess, "Carnivores Termination", IDOK | MB_SYSTEMMODAL | MB_ICONEXCLAMATION);
+ CloseLog();
+ TerminateProcess(GetCurrentProcess(), 0);
+ } else QUITMODE=1;
+
+}
+
+
+void WaitRetrace()
+{
+ BOOL bv = FALSE;
+ if (DirectActive)
+ while (!bv) lpDD->GetVerticalBlankStatus(&bv);
+}
+
+
+
+void Wait(int time)
+{
+ unsigned int t = timeGetTime() + time;
+ while (t>timeGetTime()) ;
+}
+
+
+//#define loadww 210
+//#define loadwh 106
+char loadtxt[128];
+TPicture LoadWall;
+
+void UpdateLoadingWindow()
+{
+
+ HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcCMain, hbmpVideoBuf);
+ HFONT hfntOld = (HFONT)SelectObject(hdcCMain, fnt_Small);
+
+
+ for (int y=0; y<LoadWall.H/2; y++)
+ memcpy( (WORD*)lpVideoBuf + y*1024,
+ LoadWall.lpImage + y*LoadWall.W,
+ LoadWall.W*2);
+
+ if (LoadCount)
+ for (int y=0; y<LoadWall.H/2; y++)
+ memcpy( (WORD*)lpVideoBuf + y*1024,
+ LoadWall.lpImage + (y+LoadWall.H/2)*LoadWall.W,
+ (LoadWall.W*LoadCount/8)*2);
+
+ //FillMemory(lpVideoBuf, 1024*loadwh*2, 1);
+/*
+ SetBkMode(hdcCMain, TRANSPARENT);
+ SetTextColor(hdcCMain, 0x000000);
+ TextOut(hdcCMain, 19, LoadWall.H/2-22, loadtxt, strlen(loadtxt) );
+ SetTextColor(hdcCMain, 0xB0B070);
+ TextOut(hdcCMain, 18, LoadWall.H/2-23, loadtxt, strlen(loadtxt) );
+*/
+ BitBlt(hdcMain,0,0,LoadWall.W,LoadWall.H/2, hdcCMain,0,0, SRCCOPY);
+
+ SelectObject(hdcCMain,hfntOld);
+ SelectObject(hdcCMain,hbmpOld);
+}
+
+
+
+
+
+void StartLoading()
+{
+ LoadPictureTGA(LoadWall, "HUNTDAT\\MENU\\loading.tga");
+ SetWindowPos(hwndMain, HWND_TOP, (GetSystemMetrics(SM_CXSCREEN) - LoadWall.W)/2,
+ (GetSystemMetrics(SM_CYSCREEN) - LoadWall.H/2)/2, LoadWall.W, LoadWall.H/2,
+ SWP_SHOWWINDOW);
+}
+
+void EndLoading()
+{
+ FillMemory(lpVideoBuf, 1024*768*2, 0);
+ _HeapFree(Heap, 0, (void*)LoadWall.lpImage);
+}
+
+
+void PrintLoad(char *t)
+{
+ strcpy(loadtxt, t);
+ LoadCount++;
+ UpdateLoadingWindow();
+
+}
+
+
+void SetVideoMode(int W, int H)
+{
+ WinW = W;
+ WinH = H;
+
+ WinEX = WinW - 1;
+ WinEY = WinH - 1;
+ VideoCX = WinW / 2;
+ VideoCY = WinH / 2;
+
+ CameraW = (float)VideoCX*1.25f;
+ CameraH = CameraW * (WinH * 1.3333f / WinW);
+
+ SetWindowPos(hwndMain, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_SHOWWINDOW);
+ SetCursorPos(VideoCX, VideoCY);
+
+ LoDetailSky =(W>400);
+ SetCursor(hcArrow);
+ while (ShowCursor(FALSE)>=0) ;
+}
+
+
+
diff --git a/Loading.cpp b/Loading.cpp
new file mode 100644
index 0000000..815215f
--- /dev/null
+++ b/Loading.cpp
@@ -0,0 +1,159 @@
+//#ifdef _load
+
+#include "Hunt.h"
+
+#define winw 240
+#define winh 120
+
+HWND hwndLoad;
+bool _EndLoading;
+HANDLE hLoadThread;
+DWORD hLOADID;
+HDC hdcLoad, hdcCLoad;
+HBITMAP hbmpLoad;
+void *lpLoadVideoBuf;
+char txt[128];
+bool lock;
+
+void CreateLoadDIB()
+{
+ hdcLoad=GetDC(hwndLoad);
+ hdcCLoad = CreateCompatibleDC(hdcLoad);
+
+ SetBkMode(hdcCLoad, TRANSPARENT);
+ SetTextColor(hdcCLoad, 0x909090);
+
+ BITMAPINFOHEADER bmih;
+ bmih.biSize = sizeof( BITMAPINFOHEADER );
+ bmih.biWidth = winw;
+ bmih.biHeight = -winh;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 16;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = 0;
+ bmih.biXPelsPerMeter = 400;
+ bmih.biYPelsPerMeter = 400;
+ bmih.biClrUsed = 0;
+ bmih.biClrImportant = 0;
+
+ BITMAPINFO binfo;
+ binfo.bmiHeader = bmih;
+ hbmpLoad =
+ CreateDIBSection(hdcLoad, &binfo, DIB_RGB_COLORS, &lpLoadVideoBuf, NULL, 0);
+ DeleteDC(hdcLoad);
+
+}
+
+
+void UpdateLWindow()
+{
+ lock = TRUE;
+ HBITMAP hbmpOld = SelectObject(hdcCLoad, hbmpLoad);
+ HFONT hfntOld = SelectObject(hdcCLoad, fnt_Small);
+
+ FillMemory(lpLoadVideoBuf, winw*winh*2, 1);
+
+ TextOut(hdcCLoad, 10, winh-16, txt, strlen(txt) );
+
+ BitBlt(hdcLoad,0,0,winw,winh, hdcCLoad,0,0, SRCCOPY);
+ MessageBeep(0xFFFFFFFF);
+
+ SelectObject(hdcCLoad,hfntOld);
+ SelectObject(hdcCLoad,hbmpOld);
+ lock = FALSE;
+}
+
+
+
+LONG APIENTRY LoadWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam)
+{
+
+
+ switch (message) {
+ case WM_CREATE: return 0;
+ //case WM_ERASEBKGND:
+ //case WM_NCPAINT : break;
+ case WM_PAINT: {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hWnd, &ps );
+ EndPaint(hWnd, &ps);
+ UpdateLWindow();
+ break;
+ }
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+
+ return 0;
+}
+
+
+
+DWORD WINAPI ProcessLoading (LPVOID ptr)
+{
+ WNDCLASS wc;
+ wc.style = CS_OWNDC;
+ wc.lpfnWndProc = (WNDPROC)LoadWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInst;
+ wc.hIcon = wc.hIcon = LoadIcon(hInst,"ACTION");
+ wc.hCursor = NULL;
+ wc.hbrBackground = GetStockObject( BLACK_BRUSH );
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "HuntLoadingWindow";
+ if (!RegisterClass(&wc)) return FALSE;
+
+ hwndLoad = CreateWindow(
+ "HuntLoadingWindow","Loading...",
+ WS_VISIBLE | WS_POPUP,
+ 400-winw/2, 300-winh/2, winw, winh, NULL, NULL, hInst, NULL );
+
+ CreateLoadDIB();
+
+ ShowWindow(hwndLoad, SW_SHOW);
+
+ MSG msg;
+ while (!_EndLoading) {
+ if( PeekMessage( &msg, hwndLoad, NULL, NULL, PM_REMOVE ) ) {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ } else {
+ Sleep(100);
+ UpdateLWindow();
+ }
+ }
+
+ DestroyWindow(hwndLoad);
+
+ ExitThread(0);
+ return 0;
+}
+
+
+void PrintLoad(char *t)
+{
+ if (t) {
+ strcpy(txt, t);
+ }
+}
+
+void StartLoading()
+{
+ hLoadThread = CreateThread(NULL, 0, ProcessLoading, NULL, 0, &hLOADID);
+ SetThreadPriority(hLoadThread, THREAD_PRIORITY_HIGHEST);
+}
+
+
+void EndLoading()
+{
+ _EndLoading = TRUE;
+
+ //SetFocus(hwndMain);
+ //SetActiveWindow(hwndMain);
+ //ShowWindow(hwndMain, SW_SHOW);
+ //BringWindowToTop(hwndMain);
+
+}
+
+//#endif \ No newline at end of file
diff --git a/Render3DFX.cpp b/Render3DFX.cpp
new file mode 100644
index 0000000..f47f612
--- /dev/null
+++ b/Render3DFX.cpp
@@ -0,0 +1,4051 @@
+#ifdef _3dfx
+#include "Hunt.h"
+
+#include <glide.h>
+#include <sst1vid.h>
+#include <stdio.h>
+
+#undef TCMAX
+#undef TCMIN
+#define TCMAX 255.5f
+#define TCMIN 0.5f
+
+#define _ZSCALE (16.f*65534.f)
+
+Vector2di ORList[2048];
+int ORLCount = 0;
+
+void RenderShadowClip (TModel*, float, float, float, float, float, float, int, float, float);
+
+GrVertex gvtx[16];
+int zs;
+float SunLight;
+float TraceK,SkyTraceK,FogYGrad,FogYBase;
+int SunScrX, SunScrY;
+int SkySumR, SkySumG, SkySumB;
+int LowHardMemory;
+float vFogT[1024];
+float vLight[1024];
+GrLfbInfo_t linfo;
+int lsw;
+BOOL SmallFont;
+BOOL WaterMode;
+
+//float mdlScale = 1.0f;
+
+
+FxU32 FXConstTstartAddress, FXConstTendAddress;
+
+int FxMemUsageCount;
+int FxMemLoaded;
+int FxLastTexture;
+int FxTMUNumber;
+
+typedef struct _fxmemmap {
+ int cpuaddr, size, lastused;
+ FxU32 FXTbaseaddr;
+ GrTexInfo FXtexinfo;
+} Tfxmemmap;
+
+#define fxmemmapsize 128
+Tfxmemmap FxMemMap[fxmemmapsize+2];
+
+void CalcFogLevel_Gradient(Vector3d v)
+{
+ FogYBase = CalcFogLevel(v);
+ if (FogYBase>0) {
+ v.y+=800;
+ FogYGrad = (CalcFogLevel(v) - FogYBase) / 800.f;
+ } else FogYGrad=0;
+}
+
+
+void Hardware_ZBuffer(BOOL bl)
+{
+ if (bl) {
+ grDepthBiasLevel(0);
+ } else {
+ grDepthBiasLevel(8000);
+ }
+}
+
+void Init3DHardware()
+{
+ PrintLog("Checking 3dfx:\n");
+ GrHwConfiguration hwconfig;
+ FxTMUNumber = 1;
+ grGlideInit();
+ grSstQueryHardware(&hwconfig);
+ if (hwconfig.SSTs[0].type == GR_SSTTYPE_VOODOO) {
+ FxTMUNumber = hwconfig.SSTs[0].sstBoard.VoodooConfig.nTexelfx;
+ PrintLog("Voodoo card.\n");
+ }
+
+ if (hwconfig.SSTs[0].type == GR_SSTTYPE_Voodoo2) {
+ FxTMUNumber = hwconfig.SSTs[0].sstBoard.Voodoo2Config.nTexelfx;
+ PrintLog("Voodoo2 card.\n");
+ }
+
+ if (hwconfig.SSTs[0].type == GR_SSTTYPE_SST96) {
+ FxTMUNumber = hwconfig.SSTs[0].sstBoard.VoodooConfig.nTexelfx;
+ PrintLog("Voodoo Rush card.\n");
+ }
+
+ grSstSelect( 0 );
+ HARD3D = TRUE;
+
+ FXConstTstartAddress = grTexMinAddress(GR_TMU0);
+ FXConstTendAddress = grTexMaxAddress(GR_TMU0);
+ //wsprintf(logt, "Start Address: %d\n", FXConstTstartAddress); PrintLog(logt);
+ //wsprintf(logt, "End Address: %d\n", FXConstTendAddress); PrintLog(logt);
+ //if (FXConstTendAddress > 2097144) FXConstTendAddress = 2097144;
+
+}
+
+
+void Activate3DHardware()
+{
+
+ if (WinW<512)
+ SetVideoMode(512,384);
+
+ SetVideoMode(WinW,WinH);
+
+ int fxmode = GR_RESOLUTION_640x480;
+ switch (WinW) {
+ case 320: fxmode = GR_RESOLUTION_320x240; break;
+ case 400: fxmode = GR_RESOLUTION_400x300; break;
+ case 512: fxmode = GR_RESOLUTION_512x384; break;
+ case 640: fxmode = GR_RESOLUTION_640x480; break;
+ case 800: fxmode = GR_RESOLUTION_800x600; break;
+ case 1024: fxmode = GR_RESOLUTION_1024x768; break;
+ case 1280: fxmode = GR_RESOLUTION_1280x1024; break;
+ case 1600: fxmode = GR_RESOLUTION_1600x1200; break;
+ }
+
+
+
+RESET:
+ if (!grSstWinOpen( (unsigned int) hwndMain, fxmode, GR_REFRESH_NONE, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ) )
+ if (!grSstWinOpen( (unsigned int) hwndMain, fxmode, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ) ) {
+ if (fxmode!=GR_RESOLUTION_640x480) {
+ PrintLog("Voodoo: Can't set selected video mode\n");
+ fxmode = GR_RESOLUTION_640x480;
+ OptRes = 3;
+ SetVideoMode(640,480);
+ goto RESET;
+ } else
+ DoHalt("Voodoo: Can't set video mode");
+ }
+
+
+ grHints(GR_HINT_STWHINT, 0);
+ grHints(GR_HINT_FPUPRECISION, 0);
+ grHints(GR_HINT_ALLOW_MIPMAP_DITHER, 0);
+
+
+ FXConstTstartAddress = grTexMinAddress(GR_TMU0);
+ FXConstTendAddress = grTexMaxAddress(GR_TMU0);
+ wsprintf(logt, "Start Address: %d\n", FXConstTstartAddress); PrintLog(logt);
+ wsprintf(logt, "End Address: %d\n", FXConstTendAddress); PrintLog(logt);
+ //if (FXConstTendAddress > 2097144) FXConstTendAddress = 2097144;
+
+
+ grColorMask(FXTRUE, FXFALSE);
+
+ grDepthBufferMode( GR_DEPTHBUFFER_ZBUFFER );
+ grDepthBufferFunction( GR_CMP_GEQUAL );
+ grDepthMask( FXTRUE );
+
+ //grCullMode(GR_CULL_NEGATIVE);
+
+
+ //======= setup gouraud ===========//
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+
+ grTexCombineFunction(GR_TMU0, GR_TEXTURECOMBINE_DECAL);
+ grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP);
+
+ //====== setup alpha ==========//
+ //guAlphaSource(GR_ALPHASOURCE_CC_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
+ grConstantColorValue(0xFF000000);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA,
+ GR_BLEND_ONE_MINUS_SRC_ALPHA,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE);
+ grAlphaTestFunction(GR_CMP_GREATER);
+ grAlphaTestReferenceValue(1);
+
+ grDitherMode(GR_DITHER_4x4);
+ grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
+
+
+ grFogColorValue( (SkyB<<16) + (SkyG<<8) + SkyR);
+
+ grFogMode(GR_FOG_DISABLE);
+
+ grChromakeyValue(0x00);
+ grChromakeyMode(GR_CHROMAKEY_ENABLE);
+ grChromakeyMode(GR_CHROMAKEY_DISABLE);
+
+ grBufferClear( 0xFF000000, 0, 0);
+
+ grGammaCorrectionValue(1.2f);
+ FxLastTexture = fxmemmapsize+1;
+}
+
+
+void ResetTextureMap()
+{
+ FxMemUsageCount = 0;
+ FxLastTexture = fxmemmapsize+1;
+ for (int m=0; m<fxmemmapsize+2; m++) {
+ FxMemMap[m].lastused = 0;
+ FxMemMap[m].cpuaddr = 0;
+ FxMemMap[m].FXTbaseaddr = 0;
+ FxMemMap[m].size = 0;
+ }
+ while (grBufferNumPending() > 0);
+
+}
+
+
+void ShutDown3DHardware()
+{
+ grSstWinClose();
+ grGlideShutdown();
+ ResetTextureMap();
+}
+
+
+int Get_GR_LOD(int TW)
+{
+ if (TW==128) return GR_LOD_128;
+ if (TW==256) return GR_LOD_256;
+ if (TW==64) return GR_LOD_64;
+ if (TW==32) return GR_LOD_32;
+ return 0;
+}
+
+
+void guDownLoad(int fxm, int FXTstartAddress, LPVOID tptr, int w, int h)
+{
+ int textureSize = w*w*2;
+ /*
+ if (FXTstartAddress<=2097152 && FXTstartAddress+textureSize>=2097152) {
+ FxMemMap[fxm-1].size = 2097152 - FxMemMap[fxm-1].FXTbaseaddr;
+ FXTstartAddress=2097152;
+ }
+ */
+/*
+ if (FXTstartAddress + textureSize >= FXConstTendAddress)
+ DoHalt("3DFX memory overflow.");
+ */
+ FxMemMap[fxm].FXtexinfo.smallLod = Get_GR_LOD(w);
+ FxMemMap[fxm].FXtexinfo.largeLod = FxMemMap[fxm].FXtexinfo.smallLod;
+ FxMemMap[fxm].FXtexinfo.aspectRatio = GR_ASPECT_1x1;
+ FxMemMap[fxm].FXtexinfo.format = GR_TEXFMT_ARGB_1555;
+ FxMemMap[fxm].FXtexinfo.data = tptr;
+
+ FxMemMap[fxm].FXTbaseaddr = FXTstartAddress;
+ FxMemMap[fxm].size = textureSize;
+ FxMemMap[fxm].cpuaddr = (int)tptr;
+
+ FxMemLoaded+=textureSize;
+
+ grTexDownloadMipMap(GR_TMU0,
+ FXTstartAddress + FXConstTstartAddress,
+ GR_MIPMAPLEVELMASK_BOTH,
+ &FxMemMap[fxm].FXtexinfo);
+}
+
+
+void InsertFxMM(int m)
+{
+/* memcpy(&FxMemMap[m+1],
+ &FxMemMap[m],
+ (fxmemmapsize-m) * sizeof(Tfxmemmap) ); */
+ for (int mm=fxmemmapsize-1; mm>m; mm--)
+ FxMemMap[m] = FxMemMap[m-1];
+}
+
+
+
+
+
+int FXDownLoadTexture(LPVOID tptr, int w, int h)
+{
+ FxU32 FXTstartAddress = 0;
+ FxU32 FXTendAddress = FXConstTendAddress;
+ int textureSize = w*w*2;
+ int fxm = 0;
+ int m;
+
+
+//========== if no memory used ==========//
+ if (!FxMemMap[0].cpuaddr) {
+ guDownLoad(0, 0, tptr, w, h);
+ return 0;
+ }
+
+
+
+//======= search for hole in the memory usage ==========//
+
+ for (m=0; m<fxmemmapsize; m++) {
+ int nextbegin;
+ int curend = FxMemMap[m].FXTbaseaddr + FxMemMap[m].size;
+
+ if (!FxMemMap[m].cpuaddr) break;
+
+ if (FxMemMap[m+1].cpuaddr) nextbegin = FxMemMap[m+1].FXTbaseaddr;
+ else nextbegin = FXTendAddress;
+
+ if (curend<=2097152 && curend+textureSize>=2097152)
+ curend = 2097152;
+
+ if (nextbegin - curend >= textureSize) {
+ InsertFxMM(m+1);
+ guDownLoad(m+1, curend, tptr, w, h);
+
+ return m+1;
+ }
+ }
+
+
+
+//====== search for most older acceptable block =====================//
+ fxm = -1;
+ int unusedtime = 1;
+ for (m=0; m<fxmemmapsize; m++) {
+ if (!FxMemMap[m].cpuaddr) break;
+
+ int ut = FxMemUsageCount - FxMemMap[m].lastused;
+
+ if (FxMemMap[m].size==textureSize)
+ if (ut >= unusedtime) {
+ unusedtime = ut;
+ fxm = m; }
+
+ if (FxMemMap[m].size>textureSize)
+ if (ut > unusedtime) {
+ unusedtime = ut;
+ fxm = m; }
+ }
+
+ if (fxm!=-1) {
+ guDownLoad(fxm, FxMemMap[fxm].FXTbaseaddr, tptr, w, h);
+ return fxm;
+ }
+
+
+
+//=== not free or unused memory found => perfoming half-memory reset ======//
+ ResetTextureMap();
+ guDownLoad(0, 0, tptr, w, h);
+ return 0;
+}
+
+
+
+void SetFXTexture(LPVOID tptr, int w, int h)
+{
+ if (FxMemMap[FxLastTexture].cpuaddr == (int)tptr) return;
+
+ int fxm = -1;
+ for (int m=0; m<fxmemmapsize; m++) {
+ if (FxMemMap[m].cpuaddr == (int)tptr) { fxm = m; break; }
+ if (!FxMemMap[m].cpuaddr) break;
+ }
+
+ if (fxm==-1) fxm = FXDownLoadTexture(tptr, w, h);
+
+ FxMemMap[fxm].lastused = FxMemUsageCount;
+ grTexSource(GR_TMU0,
+ FxMemMap[fxm].FXTbaseaddr + FXConstTstartAddress,
+ GR_MIPMAPLEVELMASK_BOTH,
+ &FxMemMap[fxm].FXtexinfo);
+ FxLastTexture = fxm;
+}
+
+
+
+
+float GetTraceK(int x, int y)
+{
+ if (x<8 || y<8 || x>WinW-8 || y>WinH-8) return 0.f;
+
+ float k = 0;
+
+ linfo.size = sizeof(GrLfbInfo_t);
+ if (!grLfbLock(
+ GR_LFB_READ_ONLY,
+ GR_BUFFER_AUXBUFFER,
+ GR_LFBWRITEMODE_ANY,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &linfo)) return 0.f;
+
+ WORD CC = 0;
+ int bw = (linfo.strideInBytes>>1);
+ if ( *((WORD*)linfo.lfbPtr + (y+0)*bw + x+0) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y+10)*bw + x+0) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y-10)*bw + x+0) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y+0)*bw + x+10) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y+0)*bw + x-10) == CC ) k+=1.f;
+
+ if ( *((WORD*)linfo.lfbPtr + (y+8)*bw + x+8) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y+8)*bw + x-8) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y-8)*bw + x+8) == CC ) k+=1.f;
+ if ( *((WORD*)linfo.lfbPtr + (y-8)*bw + x-8) == CC ) k+=1.f;
+
+ grLfbUnlock(GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER);
+ k/=9;
+
+ DeltaFunc(TraceK, k, TimeDt / 1024.f);
+ return TraceK;
+}
+
+
+void AddSkySum(WORD C)
+{
+ int R = C>>11;
+ int G = (C>>5) & 63;
+ int B = C & 31;
+ SkySumR += R*8;
+ SkySumG += G*4;
+ SkySumB += B*8;
+}
+
+float GetSkyK(int x, int y)
+{
+ if (x<10 || y<10 || x>WinW-10 || y>WinH-10) return 0.5;
+ SkySumR = 0;
+ SkySumG = 0;
+ SkySumB = 0;
+ float k = 0;
+
+ linfo.size = sizeof(GrLfbInfo_t);
+ if (!grLfbLock(
+ GR_LFB_READ_ONLY,
+ GR_BUFFER_BACKBUFFER,
+ GR_LFBWRITEMODE_ANY,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &linfo)) return 0.f;
+
+ int bw = (linfo.strideInBytes>>1);
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y+0)*bw + x+0));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y+6)*bw + x+0));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y-6)*bw + x+0));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y+0)*bw + x+6));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y+0)*bw + x-6));
+
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y+4)*bw + x+4));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y+4)*bw + x-4));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y-4)*bw + x+4));
+ AddSkySum(*((WORD*)linfo.lfbPtr + (y-4)*bw + x-4));
+
+ grLfbUnlock(GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER);
+
+
+
+ SkySumR-=SkyTR*9;
+ SkySumG-=SkyTG*9;
+ SkySumB-=SkyTB*9;
+/*
+ SkySumR-=55*9;
+ SkySumG-=88*9;
+ SkySumB-=122*9;
+ */
+
+ k = (float)sqrt(SkySumR*SkySumR + SkySumG*SkySumG + SkySumB*SkySumB) / 9;
+
+
+ if (k>80) k = 80;
+ if (k< 0) k = 0;
+ k = 1.0f - k/80.f;
+ if (k<0.2) k=0.2f;
+ if (OptDayNight==2) k=0.3 + k/2.75;
+ DeltaFunc(SkyTraceK, k, (0.07f + (float)fabs(k-SkyTraceK)) * (TimeDt / 512.f) );
+ return SkyTraceK;
+}
+
+
+
+void TryHiResTx()
+{
+ int UsedMem = 0;
+ for (int m=0; m<fxmemmapsize; m++) {
+ if (!FxMemMap[m].cpuaddr) break;
+ if (FxMemMap[m].lastused+2>=FxMemUsageCount)
+ UsedMem+= FxMemMap[m].size;
+ }
+
+ if (UsedMem*3 < (int)FXConstTendAddress)
+ LOWRESTX = FALSE;
+}
+
+
+void RenderFSRect(DWORD color)
+{
+
+ guColorCombineFunction( GR_COLORCOMBINE_CCRGB );
+ grConstantColorValue(color);
+
+ gvtx[0].x = 0;
+ gvtx[0].y = 0;
+ gvtx[0].tmuvtx[0].sow = 0.0;
+ gvtx[0].tmuvtx[0].tow = 0.0;
+ gvtx[0].z = (float)1.f;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+
+ gvtx[1].x = WinW;
+ gvtx[1].y = 0;
+ gvtx[1].tmuvtx[0].sow = 0.0;
+ gvtx[1].tmuvtx[0].tow = 0.0;
+ gvtx[1].z = (float)1.f;
+ gvtx[1].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[1].oow = 1.0f/gvtx[0].z;
+
+ gvtx[2].x = WinW;
+ gvtx[2].y = WinH;
+ gvtx[2].tmuvtx[0].sow = 0.0;
+ gvtx[2].tmuvtx[0].tow = 0.0;
+ gvtx[2].z = (float)1.f;
+ gvtx[2].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[2].oow = 1.0f/gvtx[0].z;
+
+ gvtx[3].x = 0;
+ gvtx[3].y = WinH;
+ gvtx[3].tmuvtx[0].sow = 0.0;
+ gvtx[3].tmuvtx[0].tow = 0.0;
+ gvtx[3].z = (float)1.f;
+ gvtx[3].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[3].oow = 1.0f/gvtx[0].z;
+
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+ grDrawTriangle(&gvtx[0], &gvtx[2], &gvtx[3]);
+ dFacesCount++;
+
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+ grConstantColorValue(0xFF000000);
+
+}
+
+
+
+
+void RenderCircle(float cx, float cy, float z, float _R, DWORD RGBA, DWORD RGBA2)
+{
+
+ float R = (float)((int)( _R*16.f)) / 16.f;
+ float R2 = (float)((int)(0.65f*_R*16.f)) / 16.f;
+
+ int r = (RGBA ) & 0xFF;
+ int g = (RGBA>>8 ) & 0xFF;
+ int b = (RGBA>>16) & 0xFF;
+ int a = (RGBA>>24) & 0xFF;
+
+ gvtx[0].r = r; gvtx[0].g = g; gvtx[0].b = b; gvtx[0].a = a;
+ gvtx[0].z = -z;
+ gvtx[0].ooz = (_ZSCALE/-z);
+ gvtx[0].oow = 1.0f;
+
+ //if (RunMode)
+ if (R<1.2f) {
+ gvtx[0].a = ((RGBA>>25) + (RGBA2>>25)) * R;
+ gvtx[0].x = cx;
+ gvtx[0].y = cy;
+ grDrawPoint(&gvtx[0]);
+ dFacesCount++;
+ return;
+ }
+
+
+
+ r = (RGBA2 ) & 0xFF;
+ g = (RGBA2>>8 ) & 0xFF;
+ b = (RGBA2>>16) & 0xFF;
+ a = (RGBA2>>24) & 0xFF;
+
+ gvtx[1].r = r; gvtx[1].g = g; gvtx[1].b = b; gvtx[1].a = a;
+ gvtx[1].z = -z;
+ gvtx[1].ooz = (_ZSCALE/-z);
+ gvtx[1].oow = 1.0f;
+
+ gvtx[2].r = r; gvtx[2].g = g; gvtx[2].b = b; gvtx[2].a = a;
+ gvtx[2].z = z;
+ gvtx[2].ooz = (_ZSCALE/-z);
+ gvtx[2].oow = 1.0f;
+
+
+
+ gvtx[0].x = cx;
+ gvtx[0].y = cy;
+ gvtx[1].x = cx;
+ gvtx[1].y = cy-R;
+ gvtx[2].x = cx+R2;
+ gvtx[2].y = cy-R2;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+
+ gvtx[2].x = cx-R2;
+ gvtx[2].y = cy-R2;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+ gvtx[1].x = cx-R;
+ gvtx[1].y = cy;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+
+ gvtx[2].x = cx+R2;
+ gvtx[2].y = cy-R2;
+ gvtx[1].x = cx+R;
+ gvtx[1].y = cy;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+
+
+
+ gvtx[1].x = cx;
+ gvtx[1].y = cy+R;
+ gvtx[2].x = cx+R2;
+ gvtx[2].y = cy+R2;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+
+ gvtx[2].x = cx-R2;
+ gvtx[2].y = cy+R2;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+ gvtx[1].x = cx-R;
+ gvtx[1].y = cy;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+
+ gvtx[2].x = cx+R2;
+ gvtx[2].y = cy+R2;
+ gvtx[1].x = cx+R;
+ gvtx[1].y = cy;
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+ dFacesCount+=6;
+
+}
+
+void ShowVideo()
+{
+ if (FxMemLoaded > 1024*1024) LowHardMemory++;
+ else LowHardMemory=0;
+ if (LowHardMemory>2) {
+ LOWRESTX = TRUE;
+ LowHardMemory = 0;
+ }
+
+ if (OptText==0) LOWRESTX = TRUE;
+ if (OptText==1) LOWRESTX = FALSE;
+ if (OptText==2)
+ if (LOWRESTX && (Takt & 63)==0) TryHiResTx();
+/*
+ char t[128];
+ wsprintf(t, "FX mem loaded: %dK", FxMemLoaded >> 10);
+ if (FxMemLoaded) AddMessage(t); */
+ FxMemLoaded = 0;
+
+
+ gvtx[0].a = 0;
+ gvtx[1].a = 0;
+
+
+ if (UNDERWATER) RenderFSRect(0x80000000 + CurFogColor);
+
+
+
+ if (OptDayNight!=2)
+ if (!UNDERWATER && (SunLight>1.0f) ) {
+ SunLight *= GetTraceK(SunScrX, SunScrY);
+ RenderFSRect(0xC0FFFF + ((int)SunLight<<24));
+ }
+
+
+ RenderHealthBar();
+
+
+ while (grBufferNumPending() > 2);
+ grBufferSwap(0);
+ grBufferClear( 0xFF000000+ (SkyB<<16) + (SkyG<<8) + SkyR,0,0);
+ FxMemUsageCount++;
+}
+
+
+void CopyHARDToDIB()
+{
+ grLfbReadRegion(
+ GR_BUFFER_FRONTBUFFER,
+ 0,0,WinW,WinH, 2048, lpVideoBuf);
+
+}
+
+
+
+
+void FXPutBitMapWithKey(int x0, int y0, int w, int h, int smw, LPVOID lpData)
+{
+
+ //grLfbConstantDepth(65000);
+ //grConstantColorValue(0xD0000000);
+
+ linfo.size = sizeof(GrLfbInfo_t);
+ if (!grLfbLock(
+ GR_LFB_WRITE_ONLY,
+ GR_BUFFER_BACKBUFFER,
+ GR_LFBWRITEMODE_565,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &linfo)) return;
+
+ for (int y=0; y<h; y++)
+ for (int x=0; x<w; x++) {
+ WORD c = *((WORD*)lpData + y*smw + x);
+ if (c!=0xFFFF)
+ *((WORD*)linfo.lfbPtr + (y+y0)*(linfo.strideInBytes>>1) + x+x0) = conv_565(c);
+ }
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
+}
+
+
+
+
+void FXPutBitMap(int x0, int y0, int w, int h, int smw, LPVOID lpData)
+{
+
+ //grLfbConstantDepth(65000);
+ //grConstantColorValue(0xD0000000);
+
+ linfo.size = sizeof(GrLfbInfo_t);
+ if (!grLfbLock(
+ GR_LFB_WRITE_ONLY,
+ GR_BUFFER_BACKBUFFER,
+ GR_LFBWRITEMODE_565,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &linfo)) return;
+
+ smw*=2; w*=2;
+ linfo.lfbPtr = (void*) ( (WORD*)linfo.lfbPtr + x0);
+ for (int y=0; y<h; y++)
+ memcpy((BYTE*)linfo.lfbPtr + (y+y0)*(linfo.strideInBytes),
+ (BYTE*)lpData + y*smw,
+ w);
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
+}
+
+
+
+void DrawPicture(int x, int y, TPicture &pic)
+{
+ FXPutBitMap(x, y, pic.W, pic.H, pic.W, pic.lpImage);
+}
+
+
+
+void FXTextOut(int x, int y, LPSTR t, int color)
+{
+
+ HDC _hdc = hdcCMain;
+ HBITMAP hbmpOld = SelectObject(_hdc,hbmpVideoBuf);
+ SetBkMode(_hdc, TRANSPARENT);
+
+ HFONT oldfont;
+ if (SmallFont) oldfont = SelectObject(_hdc, fnt_Small);
+
+ int w = GetTextW(_hdc, t)+4;
+ for (int h=0; h<18; h++)
+ FillMemory((BYTE*)lpVideoBuf + h*2048, w*2, 0xFF);
+
+
+ SetTextColor(_hdc, 0x00101010);
+ TextOut(_hdc, 2, 1, t, strlen(t));
+
+ SetTextColor(_hdc, color);
+ TextOut(_hdc, 1, 0, t, strlen(t));
+
+ if (SmallFont) SelectObject(_hdc, oldfont);
+ SelectObject(_hdc,hbmpOld);
+
+
+ FXPutBitMapWithKey(x, y, w, 18, 1024, lpVideoBuf);
+
+}
+
+
+void DrawTrophyText(int x0, int y0)
+{
+ int x;
+ SmallFont = TRUE;
+ HFONT oldfont = SelectObject(hdcMain, fnt_Small);
+ int tc = TrophyBody;
+
+ int dtype = TrophyRoom.Body[tc].ctype;
+ int time = TrophyRoom.Body[tc].time;
+ int date = TrophyRoom.Body[tc].date;
+ int wep = TrophyRoom.Body[tc].weapon;
+ int score = TrophyRoom.Body[tc].score;
+ float scale = TrophyRoom.Body[tc].scale;
+ float range = TrophyRoom.Body[tc].range;
+ char t[32];
+
+ x0+=14; y0+=18;
+ x = x0;
+ FXTextOut(x, y0 , "Name: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Name: ");
+ FXTextOut(x, y0 , DinoInfo[dtype].Name, 0x0000BFBF);
+
+ x = x0;
+ FXTextOut(x, y0+16, "Weight: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Weight: ");
+ if (OptSys)
+ sprintf(t,"%3.2ft ", DinoInfo[dtype].Mass * scale * scale / 0.907);
+ else
+ sprintf(t,"%3.2fT ", DinoInfo[dtype].Mass * scale * scale);
+
+
+ FXTextOut(x, y0+16, t, 0x0000BFBF); x+=GetTextW(hdcMain,t);
+ FXTextOut(x, y0+16, "Length: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Length: ");
+
+ if (OptSys)
+ sprintf(t,"%3.2fft", DinoInfo[dtype].Length * scale / 0.3);
+ else
+ sprintf(t,"%3.2fm", DinoInfo[dtype].Length * scale);
+
+ FXTextOut(x, y0+16, t, 0x0000BFBF);
+
+ x = x0;
+ FXTextOut(x, y0+32, "Weapon: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Weapon: ");
+ wsprintf(t,"%s ", WeapInfo[wep].Name);
+ FXTextOut(x, y0+32, t, 0x0000BFBF); x+=GetTextW(hdcMain,t);
+ FXTextOut(x, y0+32, "Score: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Score: ");
+ wsprintf(t,"%d", score);
+ FXTextOut(x, y0+32, t, 0x0000BFBF);
+
+
+ x = x0;
+ FXTextOut(x, y0+48, "Range of kill: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Range of kill: ");
+ if (OptSys) sprintf(t,"%3.1fft", range / 0.3);
+ else sprintf(t,"%3.1fm", range);
+ FXTextOut(x, y0+48, t, 0x0000BFBF);
+
+
+ x = x0;
+ FXTextOut(x, y0+64, "Date: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Date: ");
+ if (OptSys)
+ wsprintf(t,"%d.%d.%d ", ((date>>10) & 255), (date & 255), date>>20);
+ else
+ wsprintf(t,"%d.%d.%d ", (date & 255), ((date>>10) & 255), date>>20);
+
+ FXTextOut(x, y0+64, t, 0x0000BFBF); x+=GetTextW(hdcMain,t);
+ FXTextOut(x, y0+64, "Time: ", 0x00BFBFBF); x+=GetTextW(hdcMain,"Time: ");
+ wsprintf(t,"%d:%02d", ((time>>10) & 255), (time & 255));
+ FXTextOut(x, y0+64, t, 0x0000BFBF);
+
+ SmallFont = FALSE;
+
+ SelectObject(hdcMain, oldfont);
+}
+
+
+
+
+void Render_LifeInfo(int li)
+{
+ int x,y;
+ SmallFont = TRUE;
+ HFONT oldfont = SelectObject(hdcMain, fnt_Small);
+
+ int ctype = Characters[li].CType;
+ float scale = Characters[li].scale;
+ char t[32];
+
+ x = VideoCX + WinW / 64;
+ y = VideoCY + (int)(WinH / 6.8);
+
+ FXTextOut(x, y, DinoInfo[ctype].Name, 0x0000b000);
+
+ if (OptSys) sprintf(t,"Weight: %3.2ft ", DinoInfo[ctype].Mass * scale * scale / 0.907);
+ else sprintf(t,"Weight: %3.2fT ", DinoInfo[ctype].Mass * scale * scale);
+
+ FXTextOut(x, y+16, t, 0x0000b000);
+
+ int R = (int)(VectorLength( SubVectors(Characters[li].pos, PlayerPos) )*3 / 64.f);
+ if (OptSys) sprintf(t,"Distance: %dft ", R);
+ else sprintf(t,"Distance: %dm ", R/3);
+
+ FXTextOut(x, y+32, t, 0x0000b000);
+
+
+
+
+
+ SmallFont = FALSE;
+ SelectObject(hdcMain, oldfont);
+}
+
+
+void RenderFXMMap()
+{
+ WORD fxmm[32][256];
+ byte mused[1024];
+
+ FillMemory(fxmm, sizeof(fxmm), 0);
+ FillMemory(mused, sizeof(mused), 4);
+ FillMemory(mused, (FXConstTendAddress+8)>>13, 0);
+
+ for (int m=0; m<fxmemmapsize; m++) {
+ if (!FxMemMap[m].cpuaddr) break;
+ int b0 = FxMemMap[m].FXTbaseaddr >> 13;
+ int bc = FxMemMap[m].size >> 13;
+ bc+=b0;
+
+ for (int mm=b0; mm<=bc; mm++)
+ if (FxMemMap[m].lastused+2<FxMemUsageCount) mused[mm] = 1; else mused[mm] = 2;
+ }
+
+ WORD c;
+ for (int y=0; y<8; y++)
+ for (int x=0; x<64; x++) {
+ if (mused[y*64+x]==0) c=16<<5; else
+ if (mused[y*64+x]==4) c=8*0x421; else
+ if (mused[y*64+x]==1) c=10<<10;
+ else c=18<<10;
+
+ for (int yy=y*4; yy<y*4+3; yy++)
+ for (int xx=x*4; xx<x*4+3; xx++)
+ fxmm[yy][xx] = c;
+ }
+
+ FXPutBitMap(16, WinH-46, 256, 32, 256, fxmm);
+}
+
+
+void ShowControlElements()
+{
+
+ //if (DEBUG) RenderFXMMap();
+
+ char buf[128];
+
+ if (TIMER) {
+ wsprintf(buf,"msc: %d", TimeDt);
+ FXTextOut(WinEX-81, 11, buf, 0x0020A0A0);
+
+ wsprintf(buf,"polys: %d", dFacesCount);
+ FXTextOut(WinEX-90, 24, buf, 0x0020A0A0);
+ }
+
+ if (MessageList.timeleft) {
+ if (RealTime>MessageList.timeleft) MessageList.timeleft = 0;
+ FXTextOut(10, 10, MessageList.mtext, 0x0020A0A0);
+ }
+
+ if (ExitTime) {
+ int y = WinH / 3;
+ wsprintf(buf,"Preparing for evacuation...");
+ FXTextOut(VideoCX - GetTextW(hdcCMain, buf)/2, y, buf, 0x0060C0D0);
+ wsprintf(buf,"%d seconds left.", 1 + ExitTime / 1000);
+ FXTextOut(VideoCX - GetTextW(hdcCMain, buf)/2, y + 18, buf, 0x0060C0D0);
+ }
+
+}
+
+
+
+
+
+
+
+
+
+void ClipVector(CLIPPLANE& C, int vn)
+{
+ int ClipRes = 0;
+ float s,s1,s2;
+ int vleft = (vn-1); if (vleft <0) vleft=vused-1;
+ int vright = (vn+1); if (vright>=vused) vright=0;
+
+ MulVectorsScal(cp[vn].ev.v, C.nv, s); /*s=SGN(s-0.01f);*/
+ if (s>=0) return;
+
+ MulVectorsScal(cp[vleft ].ev.v, C.nv, s1); /* s1=SGN(s1+0.01f); */ //s1+=0.0001f;
+ MulVectorsScal(cp[vright].ev.v, C.nv, s2); /* s2=SGN(s2+0.01f); */ //s2+=0.0001f;
+
+ if (s1>0) {
+ ClipRes+=1;
+ /*
+ CalcHitPoint(C,cp[vn].ev.v,
+ cp[vleft].ev.v, hleft.ev.v);
+
+ float ll = VectorLength(SubVectors(cp[vleft].ev.v, cp[vn].ev.v));
+ float lc = VectorLength(SubVectors(hleft.ev.v, cp[vn].ev.v));
+ lc = lc / ll;
+ */
+
+ float lc = -s / (s1-s);
+ hleft.ev.v.x = cp[vn].ev.v.x + ((cp[vleft].ev.v.x - cp[vn].ev.v.x) * lc);
+ hleft.ev.v.y = cp[vn].ev.v.y + ((cp[vleft].ev.v.y - cp[vn].ev.v.y) * lc);
+ hleft.ev.v.z = cp[vn].ev.v.z + ((cp[vleft].ev.v.z - cp[vn].ev.v.z) * lc);
+
+ hleft.tx = cp[vn].tx + ((cp[vleft].tx - cp[vn].tx) * lc);
+ hleft.ty = cp[vn].ty + ((cp[vleft].ty - cp[vn].ty) * lc);
+ hleft.ev.Light = cp[vn].ev.Light + (int)((cp[vleft].ev.Light - cp[vn].ev.Light) * lc);
+ hleft.ev.ALPHA = cp[vn].ev.ALPHA + (int)((cp[vleft].ev.ALPHA - cp[vn].ev.ALPHA) * lc);
+ hleft.ev.Fog = cp[vn].ev.Fog + (int)((cp[vleft].ev.Fog - cp[vn].ev.Fog) * lc);
+ }
+
+ if (s2>0) {
+ ClipRes+=2;
+ /*
+ CalcHitPoint(C,cp[vn].ev.v,
+ cp[vright].ev.v, hright.ev.v);
+
+ float ll = VectorLength(SubVectors(cp[vright].ev.v, cp[vn].ev.v));
+ float lc = VectorLength(SubVectors(hright.ev.v, cp[vn].ev.v));
+ lc = lc / ll;
+ */
+ float lc = -s / (s2-s);
+ hright.ev.v.x = cp[vn].ev.v.x + ((cp[vright].ev.v.x - cp[vn].ev.v.x) * lc);
+ hright.ev.v.y = cp[vn].ev.v.y + ((cp[vright].ev.v.y - cp[vn].ev.v.y) * lc);
+ hright.ev.v.z = cp[vn].ev.v.z + ((cp[vright].ev.v.z - cp[vn].ev.v.z) * lc);
+
+ hright.tx = cp[vn].tx + ((cp[vright].tx - cp[vn].tx) * lc);
+ hright.ty = cp[vn].ty + ((cp[vright].ty - cp[vn].ty) * lc);
+ hright.ev.Light = cp[vn].ev.Light + (int)((cp[vright].ev.Light - cp[vn].ev.Light) * lc);
+ hright.ev.ALPHA = cp[vn].ev.ALPHA + (int)((cp[vright].ev.ALPHA - cp[vn].ev.ALPHA) * lc);
+ hright.ev.Fog = cp[vn].ev.Fog + (int)((cp[vright].ev.Fog - cp[vn].ev.Fog) * lc);
+ }
+
+ if (ClipRes == 0) {
+ u--; vused--;
+ cp[vn] = cp[vn+1];
+ cp[vn+1] = cp[vn+2];
+ cp[vn+2] = cp[vn+3];
+ cp[vn+3] = cp[vn+4];
+ cp[vn+4] = cp[vn+5];
+ cp[vn+5] = cp[vn+6];
+ //memcpy(&cp[vn], &cp[vn+1], (15-vn)*sizeof(ClipPoint));
+ }
+ if (ClipRes == 1) {cp[vn] = hleft; }
+ if (ClipRes == 2) {cp[vn] = hright;}
+ if (ClipRes == 3) {
+ u++; vused++;
+ //memcpy(&cp[vn+1], &cp[vn], (15-vn)*sizeof(ClipPoint));
+ cp[vn+6] = cp[vn+5];
+ cp[vn+5] = cp[vn+4];
+ cp[vn+4] = cp[vn+3];
+ cp[vn+3] = cp[vn+2];
+ cp[vn+2] = cp[vn+1];
+ cp[vn+1] = cp[vn];
+
+ cp[vn] = hleft;
+ cp[vn+1] = hright;
+ }
+}
+
+
+
+void _fillmapping(BOOL SECOND)
+{
+ if (ReverseOn)
+ if (SECOND) {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ }
+ }
+ else
+ if (SECOND) {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ }
+ }
+}
+
+
+
+void _fillmappingclip(BOOL SECOND)
+{
+ if (ReverseOn)
+ if (SECOND) {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ }
+ }
+ else
+ if (SECOND) {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ }
+ }
+}
+
+
+
+
+
+void DrawTPlaneClip(BOOL SECOND)
+{
+
+ MulVectorsVect(SubVectors(ev[1].v, ev[0].v), SubVectors(ev[2].v, ev[0].v), nv);
+ if (nv.x*ev[0].v.x + nv.y*ev[0].v.y + nv.z*ev[0].v.z<0) return;
+
+ cp[0].ev = ev[0]; cp[1].ev = ev[1]; cp[2].ev = ev[2];
+
+ _fillmappingclip(SECOND);
+
+ vused = 3;
+
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) return;
+
+ for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) return;
+
+ for (u=0; u<vused; u++) {
+ cp[u].ev.scrx = (VideoCX)*16 - (int)(cp[u].ev.v.x*16 / cp[u].ev.v.z * CameraW);
+ cp[u].ev.scry = (VideoCY)*16 + (int)(cp[u].ev.v.y*16 / cp[u].ev.v.z * CameraH);
+ }
+
+
+ gvtx[0].a = (float)cp[0].ev.Fog;
+
+ gvtx[0].x = (float)cp[0].ev.scrx/16.f;
+ gvtx[0].y = (float)cp[0].ev.scry/16.f;
+ gvtx[0].z = (float)-cp[0].ev.v.z;
+ gvtx[0].r = (float)(cp[0].ev.Light); gvtx[0].g = gvtx[0].r; gvtx[0].b = gvtx[0].r;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+ gvtx[0].tmuvtx[0].sow = (float)cp[0].tx * gvtx[0].oow;
+ gvtx[0].tmuvtx[0].tow = (float)cp[0].ty * gvtx[0].oow;
+
+ for (u=0; u<vused-2; u++) {
+
+ gvtx[1].a = (float)cp[1+u].ev.Fog;
+ gvtx[1].x = (float)cp[1+u].ev.scrx/16.f;
+ gvtx[1].y = (float)cp[1+u].ev.scry/16.f;
+ gvtx[1].z = -cp[1+u].ev.v.z;
+ gvtx[1].r = (float)(cp[1+u].ev.Light); gvtx[1].g = gvtx[1].r; gvtx[1].b = gvtx[1].r;
+ gvtx[1].ooz = (_ZSCALE/gvtx[1].z);
+ gvtx[1].oow = 1.0f/gvtx[1].z;
+ gvtx[1].tmuvtx[0].sow = (float)cp[1+u].tx * gvtx[1].oow;
+ gvtx[1].tmuvtx[0].tow = (float)cp[1+u].ty * gvtx[1].oow;
+
+ gvtx[2].a = (float)cp[2+u].ev.Fog;
+ gvtx[2].x = (float)cp[2+u].ev.scrx/16.f;
+ gvtx[2].y = (float)cp[2+u].ev.scry/16.f;
+ gvtx[2].z = -cp[2+u].ev.v.z;
+ gvtx[2].r = (float)(cp[2+u].ev.Light); gvtx[2].g = gvtx[2].r; gvtx[2].b = gvtx[2].r;
+ gvtx[2].ooz = (_ZSCALE/gvtx[2].z);
+ gvtx[2].oow = 1.0f/gvtx[2].z;
+ gvtx[2].tmuvtx[0].sow = (float)cp[2+u].tx * gvtx[2].oow;
+ gvtx[2].tmuvtx[0].tow = (float)cp[2+u].ty * gvtx[2].oow;
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+ }
+}
+
+
+
+
+void DrawTPlaneClipW(BOOL SECOND)
+{
+ cp[0].ev = ev[0]; cp[1].ev = ev[1]; cp[2].ev = ev[2];
+
+ _fillmappingclip(SECOND);
+
+ vused = 3;
+
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) return;
+
+ for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) return;
+
+ for (u=0; u<vused; u++) {
+ cp[u].ev.scrx = (VideoCX)*16 - (int)(cp[u].ev.v.x*16 / cp[u].ev.v.z * CameraW);
+ cp[u].ev.scry = (VideoCY)*16 + (int)(cp[u].ev.v.y*16 / cp[u].ev.v.z * CameraH);
+ }
+
+
+ gvtx[0].a = (float)cp[0].ev.ALPHA;
+
+ gvtx[0].x = (float)cp[0].ev.scrx/16.f;
+ gvtx[0].y = (float)cp[0].ev.scry/16.f;
+ gvtx[0].z = (float)-cp[0].ev.v.z;
+ gvtx[0].r = (float)(cp[0].ev.Light); gvtx[0].g = gvtx[0].r; gvtx[0].b = gvtx[0].r;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+ gvtx[0].tmuvtx[0].sow = (float)cp[0].tx * gvtx[0].oow;
+ gvtx[0].tmuvtx[0].tow = (float)cp[0].ty * gvtx[0].oow;
+
+ for (u=0; u<vused-2; u++) {
+
+ gvtx[1].a = (float)cp[1+u].ev.ALPHA;
+ gvtx[1].x = (float)cp[1+u].ev.scrx/16.f;
+ gvtx[1].y = (float)cp[1+u].ev.scry/16.f;
+ gvtx[1].z = -cp[1+u].ev.v.z;
+ gvtx[1].r = (float)(cp[1+u].ev.Light); gvtx[1].g = gvtx[1].r; gvtx[1].b = gvtx[1].r;
+ gvtx[1].ooz = (_ZSCALE/gvtx[1].z);
+ gvtx[1].oow = 1.0f/gvtx[1].z;
+ gvtx[1].tmuvtx[0].sow = (float)cp[1+u].tx * gvtx[1].oow;
+ gvtx[1].tmuvtx[0].tow = (float)cp[1+u].ty * gvtx[1].oow;
+
+ gvtx[2].a = (float)cp[2+u].ev.ALPHA;
+ gvtx[2].x = (float)cp[2+u].ev.scrx/16.f;
+ gvtx[2].y = (float)cp[2+u].ev.scry/16.f;
+ gvtx[2].z = -cp[2+u].ev.v.z;
+ gvtx[2].r = (float)(cp[2+u].ev.Light); gvtx[2].g = gvtx[2].r; gvtx[2].b = gvtx[2].r;
+ gvtx[2].ooz = (_ZSCALE/gvtx[2].z);
+ gvtx[2].oow = 1.0f/gvtx[2].z;
+ gvtx[2].tmuvtx[0].sow = (float)cp[2+u].tx * gvtx[2].oow;
+ gvtx[2].tmuvtx[0].tow = (float)cp[2+u].ty * gvtx[2].oow;
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+ }
+}
+
+
+
+
+
+
+
+
+
+void DrawTPlane(BOOL SECOND)
+{
+ int n;
+ BOOL SecondPass = FALSE;
+
+
+ MulVectorsVect(SubVectors(ev[1].v, ev[0].v), SubVectors(ev[2].v, ev[0].v), nv);
+ if (nv.x*ev[0].v.x + nv.y*ev[0].v.y + nv.z*ev[0].v.z<0) return;
+
+ Mask1=0x007F;
+ for (n=0; n<3; n++) {
+ if (ev[n].DFlags & 128) return;
+ Mask1=Mask1 & ev[n].DFlags; }
+ if (Mask1>0) return;
+
+ _fillmapping(SECOND);
+
+ gvtx[0].a = (float)ev[0].Fog;
+ gvtx[1].a = (float)ev[1].Fog;
+ gvtx[2].a = (float)ev[2].Fog;
+
+
+ if (zs > (ctViewR-8)<<8) {
+ //guAlphaSource(GR_ALPHASOURCE_ITERATED_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED, FXFALSE);
+ grFogMode(GR_FOG_DISABLE);
+ SecondPass = TRUE;
+
+ float zz;
+ zz = VectorLength(ev[0].v) - 256 * (ctViewR-4);
+ if (zz > 0) gvtx[0].a = max(0.f,255.f - zz / 3.f); else gvtx[0].a = 255.f;
+
+ zz = VectorLength(ev[1].v) - 256 * (ctViewR-4);
+ if (zz > 0) gvtx[1].a = max(0.f, 255.f - zz / 3.f); else gvtx[1].a = 255.f;
+
+ zz = VectorLength(ev[2].v) - 256 * (ctViewR-4);
+ if (zz > 0) gvtx[2].a = max(0,255.f - zz / 3.f); else gvtx[2].a = 255.f;
+ }
+
+
+
+
+ gvtx[0].x = (float)ev[0].scrx/16.f;
+ gvtx[0].y = (float)ev[0].scry/16.f;
+ gvtx[0].z = -ev[0].v.z;
+ gvtx[0].r = (float)(ev[0].Light); gvtx[0].g = gvtx[0].r; gvtx[0].b = gvtx[0].r;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+ gvtx[0].tmuvtx[0].sow = (float)scrp[0].tx * gvtx[0].oow;
+ gvtx[0].tmuvtx[0].tow = (float)scrp[0].ty * gvtx[0].oow;
+
+
+
+ gvtx[1].x = (float)ev[1].scrx/16.f;
+ gvtx[1].y = (float)ev[1].scry/16.f;
+ gvtx[1].z = -ev[1].v.z;
+ gvtx[1].r = (float)(ev[1].Light); gvtx[1].g = gvtx[1].r; gvtx[1].b = gvtx[1].r;
+ gvtx[1].ooz = (_ZSCALE/gvtx[1].z);
+ gvtx[1].oow = 1.0f/gvtx[1].z;
+ gvtx[1].tmuvtx[0].sow = (float)scrp[1].tx * gvtx[1].oow;
+ gvtx[1].tmuvtx[0].tow = (float)scrp[1].ty * gvtx[1].oow;
+
+
+
+ gvtx[2].x = (float)ev[2].scrx/16.f;
+ gvtx[2].y = (float)ev[2].scry/16.f;
+ gvtx[2].z = -ev[2].v.z;
+ gvtx[2].r = (float)(ev[2].Light); gvtx[2].g = gvtx[2].r; gvtx[2].b = gvtx[2].r;
+ gvtx[2].ooz = (_ZSCALE/gvtx[2].z);
+ gvtx[2].oow = 1.0f/gvtx[2].z;
+ gvtx[2].tmuvtx[0].sow = (float)scrp[2].tx * gvtx[2].oow;
+ gvtx[2].tmuvtx[0].tow = (float)scrp[2].ty * gvtx[2].oow;
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+
+
+
+ if (SecondPass) {
+ if (FOGON) {
+ gvtx[0].a*= min(1.f, ev[0].Fog / 255.f);
+ gvtx[1].a*= min(1.f, ev[1].Fog / 255.f);
+ gvtx[2].a*= min(1.f, ev[2].Fog / 255.f);
+ guColorCombineFunction(GR_COLORCOMBINE_CCRGB);
+
+ grConstantColorValue(CurFogColor);
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+
+ grFogMode(GR_FOG_WITH_ITERATED_ALPHA);
+ }
+
+
+ //guAlphaSource(GR_ALPHASOURCE_CC_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
+ grConstantColorValue(0xFF000000);
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+ }
+}
+
+
+
+void DrawTPlaneW(BOOL SECOND)
+{
+ int n;
+ BOOL SecondPass = FALSE;
+
+ Mask1=0x007F;
+ for (n=0; n<3; n++) {
+ if (ev[n].DFlags & 128) return;
+ Mask1=Mask1 & ev[n].DFlags; }
+ if (Mask1>0) return;
+
+
+ _fillmapping(SECOND);
+
+ if (!UNDERWATER)
+ if (zs > (ctViewR-8)<<8) {
+ float zz;
+ zz = VectorLength(ev[0].v) - 256 * (ctViewR-4);
+ if (zz > 0) ev[0].ALPHA = max(0.f,255.f - zz / 3.f);
+
+ zz = VectorLength(ev[1].v) - 256 * (ctViewR-4);
+ if (zz > 0) ev[1].ALPHA = max(0.f, 255.f - zz / 3.f);
+
+ zz = VectorLength(ev[2].v) - 256 * (ctViewR-4);
+ if (zz > 0) ev[2].ALPHA = max(0,255.f - zz / 3.f);
+ }
+
+ gvtx[0].x = (float)ev[0].scrx/16.f;
+ gvtx[0].y = (float)ev[0].scry/16.f;
+ gvtx[0].z = -ev[0].v.z;
+ gvtx[0].r = (float)(ev[0].Light); gvtx[0].g = gvtx[0].r; gvtx[0].b = gvtx[0].r;
+ gvtx[0].a = (float)ev[0].ALPHA;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+ gvtx[0].tmuvtx[0].sow = (float)scrp[0].tx * gvtx[0].oow;
+ gvtx[0].tmuvtx[0].tow = (float)scrp[0].ty * gvtx[0].oow;
+
+
+
+ gvtx[1].x = (float)ev[1].scrx/16.f;
+ gvtx[1].y = (float)ev[1].scry/16.f;
+ gvtx[1].z = -ev[1].v.z;
+ gvtx[1].r = (float)(ev[1].Light); gvtx[1].g = gvtx[1].r; gvtx[1].b = gvtx[1].r;
+ gvtx[1].a = (float)ev[1].ALPHA;
+ gvtx[1].ooz = (_ZSCALE/gvtx[1].z);
+ gvtx[1].oow = 1.0f/gvtx[1].z;
+ gvtx[1].tmuvtx[0].sow = (float)scrp[1].tx * gvtx[1].oow;
+ gvtx[1].tmuvtx[0].tow = (float)scrp[1].ty * gvtx[1].oow;
+
+
+ gvtx[2].x = (float)ev[2].scrx/16.f;
+ gvtx[2].y = (float)ev[2].scry/16.f;
+ gvtx[2].z = -ev[2].v.z;
+ gvtx[2].r = (float)(ev[2].Light); gvtx[2].g = gvtx[2].r; gvtx[2].b = gvtx[2].r;
+ gvtx[2].a = (float)ev[2].ALPHA;
+ gvtx[2].ooz = (_ZSCALE/gvtx[2].z);
+ gvtx[2].oow = 1.0f/gvtx[2].z;
+ gvtx[2].tmuvtx[0].sow = (float)scrp[2].tx * gvtx[2].oow;
+ gvtx[2].tmuvtx[0].tow = (float)scrp[2].ty * gvtx[2].oow;
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+}
+
+
+
+
+
+
+
+void RenderObject(int x, int y)
+{
+ if (OMap[y][x]==255) return;
+ if (!MODELS) return;
+ if (ORLCount>2000) return;
+ ORList[ORLCount].x = x;
+ ORList[ORLCount].y = y;
+ ORLCount++;
+}
+
+
+void _RenderObject(int x, int y)
+{
+ int ob = OMap[y][x];
+
+ if (!MObjects[ob].model) {
+ //return;
+ wsprintf(logt,"Incorrect model at [%d][%d]!", x, y);
+ DoHalt(logt);
+ }
+
+ int FI = (FMap[y][x] >> 2) & 3;
+ float fi = CameraAlpha + (float)(FI * 2.f*pi / 4.f);
+
+
+ int mlight;
+ if (MObjects[ob].info.flags & ofDEFLIGHT)
+ mlight = MObjects[ob].info.DefLight; else
+ if (MObjects[ob].info.flags & ofGRNDLIGHT)
+ {
+ mlight = 128;
+ CalcModelGroundLight(MObjects[ob].model, x*256+128, y*256+128, FI);
+ FI = 0;
+ }
+ else
+ mlight = -(RandomMap[y & 31][x & 31] >> 5) + (LMap[y][x]>>1) + 96;
+
+ if (mlight >192) mlight =192;
+ if (mlight < 64) mlight = 64;
+
+ v[0].x = x*256+128 - CameraX;
+ v[0].z = y*256+128 - CameraZ;
+ v[0].y = (float)(HMapO[y][x]) * ctHScale - CameraY;
+
+ float zs = VectorLength(v[0]);
+
+ //if (v[0].y + MObjects[ob].info.YHi < (int)(HMap[y][x]+HMap[y+1][x+1]) / 2 * ctHScale - CameraY) return;
+
+ CalcFogLevel_Gradient(v[0]);
+
+ gvtx[0].a = FogYBase;
+ gvtx[1].a = gvtx[0].a;
+ gvtx[2].a = gvtx[0].a;
+
+ v[0] = RotateVector(v[0]);
+ GlassL = 0;
+
+ if (zs > 256 * (ctViewR-8)) {
+ GlassL=min(255,(zs - 256 * (ctViewR-8)) / 4);
+ grAlphaTestReferenceValue(1);
+ } else grAlphaTestReferenceValue(128);
+
+ if (GlassL==255) return;
+ grConstantColorValue( (255-GlassL) << 24);
+
+ if (MObjects[ob].info.flags & ofANIMATED)
+ if (MObjects[ob].info.LastAniTime!=RealTime) {
+ MObjects[ob].info.LastAniTime=RealTime;
+ CreateMorphedObject(MObjects[ob].model,
+ MObjects[ob].vtl,
+ RealTime % MObjects[ob].vtl.AniTime);
+ }
+
+
+ if (MObjects[ob].info.flags & ofNOBMP) zs = 0;
+/*
+ if (!NeedWater && zs>ctViewRM*256 && zs<(ctViewRM+1)*256) {
+ GlassL = zs - ctViewRM*256;
+ grConstantColorValue(GlassL << 24);
+ RenderBMPModel(&MObjects[ob].bmpmodel, v[0].x, v[0].y, v[0].z, mlight-32);
+ grConstantColorValue( (255-GlassL) << 24);
+ RenderModel(MObjects[ob].model, v[0].x, v[0].y, v[0].z, mlight, FI, fi, CameraBeta);
+ } else */
+ if (zs>ctViewRM*256)
+ RenderBMPModel(&MObjects[ob].bmpmodel, v[0].x, v[0].y, v[0].z, mlight-16);
+ else
+ if (v[0].z<-256*12)
+ RenderModel(MObjects[ob].model, v[0].x, v[0].y, v[0].z, mlight, FI, fi, CameraBeta);
+ else
+ RenderModelClip(MObjects[ob].model, v[0].x, v[0].y, v[0].z, mlight, FI, fi, CameraBeta);
+
+}
+
+
+
+
+
+void ProcessMapW(int x, int y, int r)
+{
+
+ if (!( (FMap[y ][x ] & fmWaterA) &&
+ (FMap[y ][x+1] & fmWaterA) &&
+ (FMap[y+1][x ] & fmWaterA) &&
+ (FMap[y+1][x+1] & fmWaterA) )) return;
+
+ int t1 = WaterList[ WMap[y][x] ].tindex;
+
+ ev[0] = VMap2[y-CCY+128][x-CCX+128];
+ if (ev[0].v.z>BackViewR) return;
+
+ ReverseOn = FALSE;
+ TDirection = 0;
+
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap2[y][x+1];
+ ev[2] = VMap2[y+1][x+1];
+
+ float xx = (ev[0].v.x + VMap2[y+1][x+1].v.x) / 2;
+ float yy = (ev[0].v.y + VMap2[y+1][x+1].v.y) / 2;
+ float zz = (ev[0].v.z + VMap2[y+1][x+1].v.z) / 2;
+
+
+ if ( fabs(xx*FOVK) > -zz + BackViewR) return;
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+/*
+ if (MIPMAP && (zs > 256 * 10 && t1 || LOWRESTX)) SetFXTexture(Textures[t1]->DataB, 64, 64);
+ else SetFXTexture(Textures[t1]->DataA, 128, 128);
+*/
+ if (!LOWRESTX) {
+ if (zs > 256 * 20) SetFXTexture(Textures[t1]->DataC, 32, 32); else
+ if (zs > 256 * 10) SetFXTexture(Textures[t1]->DataB, 64, 64);
+ else SetFXTexture(Textures[t1]->DataA, 128, 128);
+ } else {
+ if (zs > 256 * 10) SetFXTexture(Textures[t1]->DataC, 32, 32);
+ else SetFXTexture(Textures[t1]->DataB, 64, 64);
+ }
+
+ if (r>8) DrawTPlaneW(FALSE);
+ else DrawTPlaneClipW(FALSE);
+
+ ev[1] = ev[2]; ev[2] = VMap2[y+1][x];
+
+ if (r>8) DrawTPlaneW(TRUE);
+ else DrawTPlaneClipW(TRUE);
+
+}
+
+
+
+
+void ProcessMapW2(int x, int y, int r)
+{
+ if (!( (FMap[y ][x ] & fmWaterA) &&
+ (FMap[y ][x+2] & fmWaterA) &&
+ (FMap[y+2][x ] & fmWaterA) &&
+ (FMap[y+2][x+2] & fmWaterA) )) return;
+
+ int t1 = WaterList[ WMap[y][x] ].tindex;
+
+ ev[0] = VMap2[y-CCY+128][x-CCX+128];
+ if (ev[0].v.z>BackViewR) return;
+
+
+ ReverseOn = FALSE;
+ TDirection = 0;
+
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap2[y][x+2];
+ ev[2] = VMap2[y+2][x+2];
+
+ float xx = (ev[0].v.x + VMap2[y+2][x+2].v.x) / 2;
+ float yy = (ev[0].v.y + VMap2[y+2][x+2].v.y) / 2;
+ float zz = (ev[0].v.z + VMap2[y+2][x+2].v.z) / 2;
+
+ if ( fabs(xx*FOVK) > -zz + BackViewR) return;
+
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+
+
+ SetFXTexture(Textures[t1]->DataB, 64, 64);
+
+ DrawTPlaneW(FALSE);
+
+ ev[1] = ev[2]; ev[2] = VMap2[y+2][x];
+
+ DrawTPlaneW(TRUE);
+}
+
+
+
+void RenderGround()
+{
+ for (r=ctViewR; r>=ctViewR1; r-=2) {
+
+ for (int x=r; x>0; x-=2) {
+ ProcessMap2(CCX-x, CCY+r, r);
+ ProcessMap2(CCX+x, CCY+r, r);
+ ProcessMap2(CCX-x, CCY-r, r);
+ ProcessMap2(CCX+x, CCY-r, r);
+ }
+
+ ProcessMap2(CCX, CCY-r, r);
+ ProcessMap2(CCX, CCY+r, r);
+
+ for (int y=r-2; y>0; y-=2) {
+ ProcessMap2(CCX+r, CCY-y, r);
+ ProcessMap2(CCX+r, CCY+y, r);
+ ProcessMap2(CCX-r, CCY+y, r);
+ ProcessMap2(CCX-r, CCY-y, r);
+ }
+ ProcessMap2(CCX-r, CCY, r);
+ ProcessMap2(CCX+r, CCY, r);
+
+ }
+
+
+ r = ctViewR1-1;
+ for (int x=r; x>-r; x--) {
+ ProcessMap(CCX+r, CCY+x, r);
+ ProcessMap(CCX+x, CCY+r, r);
+ }
+
+ for (r=ctViewR1-2; r>0; r--) {
+
+ for (int x=r; x>0; x--) {
+ ProcessMap(CCX-x, CCY+r, r);
+ ProcessMap(CCX+x, CCY+r, r);
+ ProcessMap(CCX-x, CCY-r, r);
+ ProcessMap(CCX+x, CCY-r, r);
+ }
+
+ ProcessMap(CCX, CCY-r, r);
+ ProcessMap(CCX, CCY+r, r);
+
+ for (int y=r-1; y>0; y--) {
+ ProcessMap(CCX+r, CCY-y, r);
+ ProcessMap(CCX+r, CCY+y, r);
+ ProcessMap(CCX-r, CCY+y, r);
+ ProcessMap(CCX-r, CCY-y, r);
+ }
+ ProcessMap(CCX-r, CCY, r);
+ ProcessMap(CCX+r, CCY, r);
+
+ }
+
+ ProcessMap(CCX, CCY, 0);
+}
+
+
+
+void RenderWCircles()
+{
+
+ //guAlphaSource(GR_ALPHASOURCE_CC_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
+ grFogMode(GR_FOG_WITH_ITERATED_ALPHA);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE);
+
+ TWCircle *wptr;
+ Vector3d rpos;
+ for (int c=0; c<WCCount; c++) {
+
+ wptr = &WCircles[c];
+ rpos.x = wptr->pos.x - CameraX;
+ rpos.y = wptr->pos.y - CameraY;
+ rpos.z = wptr->pos.z - CameraZ;
+
+ float r = (float)max( fabs(rpos.x), fabs(rpos.z) );
+ int ri = -1 + (int)(r / 256.f + 0.4f);
+ if (ri < 0) ri = 0;
+ if (ri > ctViewR) continue;
+
+ rpos = RotateVector(rpos);
+
+ if ( rpos.z > BackViewR) continue;
+ if ( fabs(rpos.x) > -rpos.z + BackViewR ) continue;
+ if ( fabs(rpos.y) > -rpos.z + BackViewR ) continue;
+
+
+ grConstantColorValue( ((2000-wptr->FTime) / 38) << 24 );
+
+ CreateMorphedModel(WCircleModel.mptr, &WCircleModel.Animation[0], (int)(wptr->FTime), wptr->scale);
+
+ if ( fabs(rpos.z) + fabs(rpos.x) < 1000)
+ RenderModelClip(WCircleModel.mptr,
+ rpos.x, rpos.y, rpos.z, 250, 0, 0, CameraBeta);
+ else
+ RenderModel(WCircleModel.mptr,
+ rpos.x, rpos.y, rpos.z, 250, 0, 0, CameraBeta);
+
+ }
+}
+
+
+void RenderWater()
+{
+ grDepthMask( FXFALSE );
+ grConstantColorValue(0xFF000000);
+ //guAlphaSource(GR_ALPHASOURCE_ITERATED_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED, FXFALSE);
+ grFogMode(GR_FOG_DISABLE);
+
+ for (int r=ctViewR; r>=ctViewR1; r-=2) {
+
+ for (int x=r; x>0; x-=2) {
+ ProcessMapW2(CCX-x, CCY+r, r);
+ ProcessMapW2(CCX+x, CCY+r, r);
+ ProcessMapW2(CCX-x, CCY-r, r);
+ ProcessMapW2(CCX+x, CCY-r, r);
+ }
+
+ ProcessMapW2(CCX, CCY-r, r);
+ ProcessMapW2(CCX, CCY+r, r);
+
+ for (int y=r-2; y>0; y-=2) {
+ ProcessMapW2(CCX+r, CCY-y, r);
+ ProcessMapW2(CCX+r, CCY+y, r);
+ ProcessMapW2(CCX-r, CCY+y, r);
+ ProcessMapW2(CCX-r, CCY-y, r);
+ }
+ ProcessMapW2(CCX-r, CCY, r);
+ ProcessMapW2(CCX+r, CCY, r);
+ }
+
+ for (int y=-ctViewR1+2; y<ctViewR1; y++)
+ for (int x=-ctViewR1+2; x<ctViewR1; x++)
+ ProcessMapW(CCX+x, CCY+y, max(abs(x), abs(y)));
+
+ RenderWCircles();
+
+ grConstantColorValue(0xFF000000);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA,
+ GR_BLEND_ONE_MINUS_SRC_ALPHA,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE);
+ grDepthMask( FXTRUE );
+
+}
+
+
+void RenderModelsList()
+{
+ for (int o=0; o<ORLCount; o++)
+ _RenderObject(ORList[o].x, ORList[o].y);
+ ORLCount=0;
+ grAlphaTestReferenceValue(1);
+}
+
+
+void ProcessMap(int x, int y, int r)
+{
+
+ if (x>=ctMapSize-1 || y>=ctMapSize-1 ||
+ x<0 || y<0) return;
+
+ float BackR = BackViewR;
+
+ if (OMap[y][x]!=255) BackR+=MObjects[OMap[y][x]].info.BoundR;
+
+ ev[0] = VMap[y-CCY+128][x-CCX+128];
+
+
+ if (ev[0].v.z>BackR) return;
+
+ if (FOGON) {
+ int cf = FogsMap[y>>1][x>>1];
+ if (UNDERWATER) cf=127;
+ if (cf) {
+ CurFogColor = FogsList[ cf ].fogRGB;
+ grFogColorValue( CurFogColor );
+ } else if (CAMERAINFOG) {
+ cf = CameraFogI;
+ CurFogColor = FogsList[ cf ].fogRGB;
+ grFogColorValue( CurFogColor );
+ }
+ }
+
+ int t1 = TMap1[y][x];
+ ReverseOn = (FMap[y][x] & fmReverse);
+ TDirection = (FMap[y][x] & 3);
+
+
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap[y][x+1];
+
+ if (ReverseOn) ev[2] = VMap[y+1][x];
+ else ev[2] = VMap[y+1][x+1];
+
+
+ float xx = (ev[0].v.x + VMap[y+1][x+1].v.x) / 2;
+ float yy = (ev[0].v.y + VMap[y+1][x+1].v.y) / 2;
+ float zz = (ev[0].v.z + VMap[y+1][x+1].v.z) / 2;
+
+ //wsprintf(logt, "%d", (int) (FOVK*100));
+ //AddMessage(logt);
+
+ if ( fabs(xx*FOVK) > -zz + BackR) return;
+
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+
+ grConstantColorValue( 0xFF000000);
+ /*
+ if (MIPMAP && (zs > 256 * 10 || LOWRESTX)) SetFXTexture(Textures[t1]->DataB, 64, 64);
+ else SetFXTexture(Textures[t1]->DataA, 128, 128);
+ */
+
+ if (!LOWRESTX) {
+ if (zs > 256 * 20) SetFXTexture(Textures[t1]->DataC, 32, 32); else
+ if (zs > 256 * 10) SetFXTexture(Textures[t1]->DataB, 64, 64);
+ else SetFXTexture(Textures[t1]->DataA, 128, 128);
+ } else {
+ if (zs > 256 * 10) SetFXTexture(Textures[t1]->DataC, 32, 32);
+ else SetFXTexture(Textures[t1]->DataB, 64, 64);
+ }
+
+ if (r>8) DrawTPlane(FALSE);
+ else DrawTPlaneClip(FALSE);
+
+ if (ReverseOn) { ev[0] = ev[2]; ev[2] = VMap[y+1][x+1]; }
+ else { ev[1] = ev[2]; ev[2] = VMap[y+1][x]; }
+
+
+ if (r>8) DrawTPlane(TRUE);
+ else DrawTPlaneClip(TRUE);
+
+ x = x + CCX - 128;
+ y = y + CCY - 128;
+
+ RenderObject(x, y);
+
+}
+
+
+
+
+
+void ProcessMap2(int x, int y, int r)
+{
+
+
+
+ if (x>=ctMapSize-1 || y>=ctMapSize-1 ||
+ x<0 || y<0) return;
+
+ ev[0] = VMap[y-CCY+128][x-CCX+128];
+ if (ev[0].v.z>BackViewR) return;
+
+ if (FOGON) {
+ int cf = FogsMap[y>>1][x>>1];
+ if (UNDERWATER) cf=127;
+ if (cf) {
+ CurFogColor = FogsList[ cf ].fogRGB;
+ grFogColorValue( CurFogColor );
+ } else if (CAMERAINFOG) {
+ cf = CameraFogI;
+ CurFogColor = FogsList[ cf ].fogRGB;
+ grFogColorValue( CurFogColor );
+ }
+ }
+
+ int t1 = TMap2[y][x];
+ TDirection = ((FMap[y][x]>>8) & 3);
+
+ ReverseOn = FALSE;
+
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap[y][x+2];
+
+ if (ReverseOn) ev[2] = VMap[y+2][x];
+ else ev[2] = VMap[y+2][x+2];
+
+ float xx = (ev[0].v.x + VMap[y+2][x+2].v.x) / 2;
+ float yy = (ev[0].v.y + VMap[y+2][x+2].v.y) / 2;
+ float zz = (ev[0].v.z + VMap[y+2][x+2].v.z) / 2;
+
+ if ( fabs(xx*FOVK) > -zz + BackViewR) return;
+
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+
+ grConstantColorValue( 0xFF000000);
+ SetFXTexture(Textures[t1]->DataB, 64, 64);
+
+ DrawTPlane(FALSE);
+
+ if (ReverseOn) { ev[0] = ev[2]; ev[2] = VMap[y+2][x+2]; }
+ else { ev[1] = ev[2]; ev[2] = VMap[y+2][x]; }
+
+
+ DrawTPlane(TRUE);
+
+ x = x + CCX - 128;
+ y = y + CCY - 128;
+
+ RenderObject(x , y);
+ RenderObject(x+1, y);
+ RenderObject(x , y+1);
+ RenderObject(x+1, y+1);
+}
+
+
+
+
+
+void BuildTreeClip()
+{
+ Current = -1;
+ TFace* fptr;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+
+ if (fptr->Flags & (sfDarkBack + sfNeedVC) ) {
+ MulVectorsVect(SubVectors(rVertex[fptr->v2], rVertex[fptr->v1]), SubVectors(rVertex[fptr->v3], rVertex[fptr->v1]), nv);
+ if (nv.x*rVertex[fptr->v1].x + nv.y*rVertex[fptr->v1].y + nv.z*rVertex[fptr->v1].z<0) continue;
+ }
+
+ fptr->Distant = (int)(-(rVertex[fptr->v1].z + rVertex[fptr->v2].z + rVertex[fptr->v3].z));
+ fptr->Next=-1;
+ if (Current==-1) Current=f; else
+ if (mptr->gFace[Current].Distant < fptr->Distant)
+ { fptr->Next=Current; Current=f; } else {
+ int n=Current;
+ while (mptr->gFace[n].Next!=-1 && mptr->gFace[mptr->gFace[n].Next].Distant > fptr->Distant)
+ n=mptr->gFace[n].Next;
+ fptr->Next = mptr->gFace[n].Next;
+ mptr->gFace[n].Next = f; }
+ }
+}
+
+
+void BuildTreeNoSort()
+{
+ Vector2di v[3];
+ Current = -1;
+ int LastFace = -1;
+ TFace* fptr;
+ int sg;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+ v[0] = gScrp[fptr->v1];
+ v[1] = gScrp[fptr->v2];
+ v[2] = gScrp[fptr->v3];
+
+ if (v[0].x == 0xFFFFFF) continue;
+ if (v[1].x == 0xFFFFFF) continue;
+ if (v[2].x == 0xFFFFFF) continue;
+
+ if (fptr->Flags & (sfDarkBack+sfNeedVC)) {
+ sg = (v[1].x-v[0].x)*(v[2].y-v[1].y) - (v[1].y-v[0].y)*(v[2].x-v[1].x);
+ if (sg<0) continue;
+ }
+
+ fptr->Next=-1;
+ if (Current==-1) { Current=f; LastFace = f; } else
+ { mptr->gFace[LastFace].Next=f; LastFace=f; }
+
+ }
+}
+
+
+
+int BuildTreeClipNoSort()
+{
+ Current = -1;
+ int fc = 0;
+ int LastFace = -1;
+ TFace* fptr;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+
+ if (fptr->Flags & (sfDarkBack + sfNeedVC) ) {
+ MulVectorsVect(SubVectors(rVertex[fptr->v2], rVertex[fptr->v1]), SubVectors(rVertex[fptr->v3], rVertex[fptr->v1]), nv);
+ if (nv.x*rVertex[fptr->v1].x + nv.y*rVertex[fptr->v1].y + nv.z*rVertex[fptr->v1].z<0) continue;
+ }
+
+ fc++;
+ fptr->Next=-1;
+ if (Current==-1) { Current=f; LastFace = f; } else
+ { mptr->gFace[LastFace].Next=f; LastFace=f; }
+
+ }
+ return fc;
+}
+
+
+
+
+
+
+void RenderModel(TModel* _mptr, float x0, float y0, float z0, int light, int VT, float al, float bt)
+{
+ int f;
+
+ if (fabs(y0) > -(z0-256*6)) return;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+ int minx = 10241024;
+ int maxx =-10241024;
+ int miny = 10241024;
+ int maxy =-10241024;
+
+ float ml = (float)(light);
+ /*
+ gvtx[0].r = ml; gvtx[0].g = ml; gvtx[0].b = ml;
+ gvtx[1].r = ml; gvtx[1].g = ml; gvtx[1].b = ml;
+ gvtx[2].r = ml; gvtx[2].g = ml; gvtx[2].b = ml;
+
+ gvtx[0].z = 1.0f;
+ gvtx[1].z = 1.0f;
+ gvtx[2].z = 1.0f;
+*/
+
+ gvtx[0].oow = 1.0f;
+ gvtx[1].oow = 1.0f;
+ gvtx[2].oow = 1.0f;
+
+ BOOL FOGACTIVE = (FOGON && (FogYBase>0));
+
+ if (!FOGACTIVE) {
+ gvtx[0].a = 0;
+ gvtx[1].a = 0;
+ gvtx[2].a = 0;
+ }
+
+ TPoint3d p;
+ for (int s=0; s<mptr->VCount; s++) {
+ p = mptr->gVertex[s];
+
+ if (FOGACTIVE) {
+ vFogT[s] = FogYBase + p.y * FogYGrad;
+ if (vFogT[s]<0.f ) vFogT[s] = 0.f;
+ if (vFogT[s]>250.f) vFogT[s]=250.f;
+ }
+
+ vLight[s] = ml + mptr->VLight[VT][s];
+
+ rVertex[s].x = (p.x * ca + p.z * sa) + x0;
+ float vz = p.z * ca - p.x * sa;
+ rVertex[s].y = (p.y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + p.y * sb) + z0;
+
+ if (rVertex[s].z>-64) rVertex[s].z=-64;
+
+ gScrp[s].x = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ gScrp[s].y = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+
+ if (gScrp[s].x > maxx) maxx = gScrp[s].x;
+ if (gScrp[s].x < minx) minx = gScrp[s].x;
+ if (gScrp[s].y > maxy) maxy = gScrp[s].y;
+ if (gScrp[s].y < miny) miny = gScrp[s].y;
+
+ }
+
+ if (minx == 10241024) return;
+ if (minx>WinW || maxx<0 || miny>WinH || maxy<0) return;
+
+
+ BuildTreeNoSort();
+
+
+ float d = (float) sqrt(x0*x0 + y0*y0 + z0*z0);
+ if (LOWRESTX) d = 14*256;
+ if (MIPMAP && (d > 12*256)) SetFXTexture(mptr->lpTexture2, 128, 128);
+ else SetFXTexture(mptr->lpTexture, 256, 256);
+
+ int PrevOpacity = 0;
+ int NewOpacity = 0;
+ int PrevTransparent = 0;
+ int NewTransparent = 0;
+
+
+ f = Current;
+ while( f!=-1 ) {
+ TFace *fptr = & mptr->gFace[f];
+
+ f = mptr->gFace[f].Next;
+
+
+ if (minx<0)
+ if (gScrp[fptr->v1].x<0 && gScrp[fptr->v2].x<0 && gScrp[fptr->v3].x<0) continue;
+ if (maxx>WinW)
+ if (gScrp[fptr->v1].x>WinW && gScrp[fptr->v2].x>WinW && gScrp[fptr->v3].x>WinW) continue;
+
+ if (miny<0)
+ if (gScrp[fptr->v1].y<0 && gScrp[fptr->v2].y<0 && gScrp[fptr->v3].y<0) continue;
+ if (maxy>WinH)
+ if (gScrp[fptr->v1].y>WinH && gScrp[fptr->v2].y>WinH && gScrp[fptr->v3].y>WinH) continue;
+
+ NewTransparent = (fptr->Flags & sfTransparent);
+
+
+ if (NewTransparent != PrevTransparent)
+ if (NewTransparent)
+ {
+ grConstantColorValue(0x80000000);
+ PrevTransparent = NewTransparent;
+ } else {
+ grConstantColorValue(0xFF000000);
+ PrevTransparent = NewTransparent;
+ }
+
+
+
+ if (FOGACTIVE) {
+ gvtx[0].a = vFogT[fptr->v1];
+ gvtx[1].a = vFogT[fptr->v2];
+ gvtx[2].a = vFogT[fptr->v3];
+ }
+
+ gvtx[0].x = (float)gScrp[fptr->v1].x;
+ gvtx[0].y = (float)gScrp[fptr->v1].y;
+ gvtx[0].ooz = _ZSCALE / -rVertex[fptr->v1].z;
+ gvtx[0].tmuvtx[0].sow = fptr->tax;
+ gvtx[0].tmuvtx[0].tow = fptr->tay;
+ gvtx[0].b = gvtx[0].g = gvtx[0].r = vLight[fptr->v1];
+
+ gvtx[1].x = (float)gScrp[fptr->v2].x;
+ gvtx[1].y = (float)gScrp[fptr->v2].y;
+ gvtx[1].ooz = _ZSCALE / -rVertex[fptr->v2].z;
+ gvtx[1].tmuvtx[0].sow = fptr->tbx;
+ gvtx[1].tmuvtx[0].tow = fptr->tby;
+ gvtx[1].b = gvtx[1].g = gvtx[1].r = vLight[fptr->v2];
+
+ gvtx[2].x = (float)gScrp[fptr->v3].x;
+ gvtx[2].y = (float)gScrp[fptr->v3].y;
+ gvtx[2].ooz = _ZSCALE / -rVertex[fptr->v3].z;
+ gvtx[2].tmuvtx[0].sow = fptr->tcx;
+ gvtx[2].tmuvtx[0].tow = fptr->tcy;
+ gvtx[2].b = gvtx[2].g = gvtx[2].r = vLight[fptr->v3];
+
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+ }
+
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ grConstantColorValue(0xFF000000);
+/* if (NewTransparent)
+ grDepthMask( FXTRUE ); */
+
+}
+
+
+
+
+void RenderBMPModel(TBMPModel* mptr, float x0, float y0, float z0, int light)
+{
+ int f;
+
+ if (fabs(y0) > -(z0-256*6)) return;
+
+ int minx = 10241024;
+ int maxx =-10241024;
+ int miny = 10241024;
+ int maxy =-10241024;
+
+
+ float ml = (float)(light);
+
+ BOOL FOGACTIVE = (FOGON && (FogYBase>0));
+
+ TPoint3d p;
+ for (int s=0; s<4; s++) {
+
+ if (FOGACTIVE) {
+ vFogT[s] = FogYBase + mptr->gVertex[s].y * FogYGrad;
+ if (vFogT[s]<0.f ) vFogT[s] = 0.f;
+ if (vFogT[s]>250.f) vFogT[s]=250.f;
+ }
+
+ rVertex[s].x = mptr->gVertex[s].x + x0;
+ rVertex[s].y = mptr->gVertex[s].y * cb + y0;
+ rVertex[s].z = mptr->gVertex[s].y * sb + z0;
+
+ if (rVertex[s].z<-256) {
+ gScrp[s].x = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ gScrp[s].y = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+ } else return;
+
+ if (gScrp[s].x > maxx) maxx = gScrp[s].x;
+ if (gScrp[s].x < minx) minx = gScrp[s].x;
+ if (gScrp[s].y > maxy) maxy = gScrp[s].y;
+ if (gScrp[s].y < miny) miny = gScrp[s].y;
+ }
+
+ if (minx == 10241024) return;
+ if (minx>WinW || maxx<0 || miny>WinH || maxy<0) return;
+
+ float d = (float) sqrt(x0*x0 + y0*y0 + z0*z0);
+ SetFXTexture(mptr->lpTexture, 128, 128);
+
+
+// grChromakeyMode(GR_CHROMAKEY_ENABLE);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
+
+
+ if (FOGACTIVE) {
+ gvtx[0].a = vFogT[0];
+ gvtx[1].a = vFogT[1];
+ gvtx[2].a = vFogT[2];
+ gvtx[3].a = vFogT[3];
+ } else {
+ gvtx[0].a = 0;
+ gvtx[1].a = 0;
+ gvtx[2].a = 0;
+ gvtx[3].a = 0;
+ }
+
+ gvtx[0].x = (float)gScrp[0].x;
+ gvtx[0].y = (float)gScrp[0].y;
+ gvtx[0].ooz = _ZSCALE / -rVertex[0].z;
+ gvtx[0].oow = -1.0f/ rVertex[0].z;
+ gvtx[0].tmuvtx[0].sow = 0.5f * gvtx[0].oow;
+ gvtx[0].tmuvtx[0].tow = 0.5f * gvtx[0].oow;
+ gvtx[0].r = ml; gvtx[0].g = ml; gvtx[0].b = ml;
+
+ gvtx[1].x = (float)gScrp[1].x;
+ gvtx[1].y = (float)gScrp[1].y;
+ gvtx[1].ooz = _ZSCALE / -rVertex[1].z;
+ gvtx[1].oow = -1.0f/ rVertex[1].z;
+ gvtx[1].tmuvtx[0].sow = 254.5f * gvtx[1].oow;
+ gvtx[1].tmuvtx[0].tow = 0.5f * gvtx[1].oow;
+ gvtx[1].r = ml; gvtx[1].g = ml; gvtx[1].b = ml;
+
+ gvtx[2].x = (float)gScrp[2].x;
+ gvtx[2].y = (float)gScrp[2].y;
+ gvtx[2].ooz = _ZSCALE / -rVertex[2].z;
+ gvtx[2].oow = -1.0f/ rVertex[2].z;
+ gvtx[2].tmuvtx[0].sow = 254.5f * gvtx[2].oow;
+ gvtx[2].tmuvtx[0].tow = 254.5f * gvtx[2].oow;
+ gvtx[2].r = ml; gvtx[2].g = ml; gvtx[2].b = ml;
+
+ gvtx[3].x = (float)gScrp[3].x;
+ gvtx[3].y = (float)gScrp[3].y;
+ gvtx[3].ooz = _ZSCALE / -rVertex[3].z;
+ gvtx[3].oow = -1.0f/ rVertex[3].z;
+ gvtx[3].tmuvtx[0].sow = 0.5f * gvtx[3].oow;
+ gvtx[3].tmuvtx[0].tow = 254.5f * gvtx[3].oow;
+ gvtx[3].r = ml; gvtx[3].g = ml; gvtx[3].b = ml;
+
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+ grDrawTriangle(&gvtx[0], &gvtx[2], &gvtx[3]);
+ dFacesCount++;
+
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ grConstantColorValue(0xFF000000);
+}
+
+
+void RenderShadowClip(TModel* _mptr,
+ float xm0, float ym0, float zm0,
+ float x0, float y0, float z0, float cal, float al, float bt)
+{
+ int f,CMASK;
+
+ mptr = _mptr;
+
+
+ float cla = (float)cos(cal);
+ float sla = (float)sin(cal);
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+ float flight = 0;
+
+
+ BOOL BL = FALSE;
+ for (int s=0; s<mptr->VCount; s++) {
+ float mrx = mptr->gVertex[s].x * cla + mptr->gVertex[s].z * sla;
+ float mrz = mptr->gVertex[s].z * cla - mptr->gVertex[s].x * sla;
+
+ float shx = mrx + mptr->gVertex[s].y * SunShadowK;
+ float shz = mrz + mptr->gVertex[s].y * SunShadowK;
+ float shy = GetLandH(shx + xm0, shz + zm0) - ym0;
+
+ rVertex[s].x = (shx * ca + shz * sa) + x0;
+ float vz = shz * ca - shx * sa;
+ rVertex[s].y = (shy * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + shy * sb) + z0;
+ if (rVertex[s].z<0) BL=TRUE;
+
+ if (rVertex[s].z>-256) { gScrp[s].x = 0xFFFFFF; gScrp[s].y = 0xFF; }
+ else {
+ int f = 0;
+ int sx = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ int sy = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+
+ if (sx>=WinEX) f+=1;
+ if (sx<=0 ) f+=2;
+
+ if (sy>=WinEY) f+=4;
+ if (sy<=0 ) f+=8;
+
+ gScrp[s].y = f;
+ }
+
+ }
+
+ if (!BL) return;
+
+
+ float d = (float) sqrt(x0*x0 + y0*y0 + z0*z0);
+ if (LOWRESTX) d = 14*256;
+ if (MIPMAP && (d > 12*256)) SetFXTexture(mptr->lpTexture2, 128, 128);
+ else SetFXTexture(mptr->lpTexture, 256, 256);
+
+ int BiasValue = BuildTreeClipNoSort();
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+ CMASK = 0;
+ CMASK|=gScrp[fptr->v1].y;
+ CMASK|=gScrp[fptr->v2].y;
+ CMASK|=gScrp[fptr->v3].y;
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].tx = fptr->tax; cp[0].ty = fptr->tay;
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].tx = fptr->tbx; cp[1].ty = fptr->tby;
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].tx = fptr->tcx; cp[2].ty = fptr->tcy;
+
+ if (CMASK == 0xFF) {
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) goto LNEXT;
+ }
+
+ if (CMASK & 1) for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) goto LNEXT;
+ if (CMASK & 2) for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) goto LNEXT;
+ if (CMASK & 4) for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) goto LNEXT;
+ if (CMASK & 8) for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) {
+ gvtx[u].x = (float)(VideoCX - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW));
+ gvtx[u].y = (float)(VideoCY + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH));
+ gvtx[u].z = -cp[u].ev.v.z - 16.f;
+ gvtx[u].ooz = (_ZSCALE/gvtx[u].z);
+ gvtx[u].oow = 1.0f/gvtx[u].z;
+ gvtx[u].tmuvtx[0].sow = (float)cp[u].tx/65534.f * gvtx[u].oow;
+ gvtx[u].tmuvtx[0].tow = (float)cp[u].ty/65534.f * gvtx[u].oow;
+ gvtx[u].r = flight; gvtx[u].g = gvtx[u].r; gvtx[u].b = gvtx[u].r;
+ }
+
+
+ if (fptr->Flags & sfOpacity) {
+ //grChromakeyMode(GR_CHROMAKEY_ENABLE);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
+ } else {
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ }
+
+ //grDepthBiasLevel( (BiasValue--)>>5);
+ for (u=0; u<vused-2; u++) {
+ grDrawTriangle(&gvtx[0], &gvtx[u+1], &gvtx[u+2]);
+ dFacesCount++;
+ }
+LNEXT:
+ f = mptr->gFace[f].Next;
+
+ }
+
+ grConstantColorValue(0xFF000000);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ //grDepthBiasLevel(0);
+
+ //grDepthMask( FXTRUE );
+
+}
+
+
+
+
+
+void RenderModelClip(TModel* _mptr, float x0, float y0, float z0, int light, int VT, float al, float bt)
+{
+ int f,CMASK;
+
+ //if (fabs(y0) > -(z0-256*6)) return;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+
+ float flight = (float)(light);
+
+
+
+ BOOL BL = FALSE;
+ BOOL FOGACTIVE = (FOGON && (FogYBase>0));
+
+ for (int s=0; s<mptr->VCount; s++) {
+
+ if (FOGACTIVE) {
+ vFogT[s] = FogYBase + mptr->gVertex[s].y * FogYGrad;
+ if (vFogT[s]<0.f) vFogT[s] = 0.f;
+ if (vFogT[s]>250.f) vFogT[s]=250.f;
+ } else vFogT[s]=0;
+
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) /* * mdlScale */ + x0;
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) /* * mdlScale */ + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) /* * mdlScale */ + z0;
+ if (rVertex[s].z<0) BL=TRUE;
+
+ if (rVertex[s].z>-256) { gScrp[s].x = 0xFFFFFF; gScrp[s].y = 0xFF; }
+ else {
+ int f = 0;
+ int sx = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ int sy = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+
+ if (sx>=WinEX) f+=1;
+ if (sx<=0 ) f+=2;
+
+ if (sy>=WinEY) f+=4;
+ if (sy<=0 ) f+=8;
+
+ gScrp[s].y = f;
+ }
+
+ }
+
+ if (!BL) return;
+
+ if (!FOGACTIVE) {
+ gvtx[0].a = 0;
+ gvtx[1].a = 0;
+ gvtx[2].a = 0;
+ }
+
+ gvtx[3].a = FogYBase;
+ gvtx[4].a = FogYBase;
+ gvtx[5].a = FogYBase;
+ gvtx[6].a = FogYBase;
+ gvtx[7].a = FogYBase;
+
+
+ if (LOWRESTX) SetFXTexture(mptr->lpTexture2, 128, 128);
+ else SetFXTexture(mptr->lpTexture, 256, 256);
+
+ BuildTreeClip();
+ int NewOpacity = 0;
+ int PrevOpacity = 0;
+ int NewTransparent = 0;
+ int PrevTransparent = 0;
+
+ ca = (float)cos(CameraAlpha);
+ sa = (float)sin(CameraAlpha);
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+ CMASK = 0;
+
+ CMASK|=gScrp[fptr->v1].y;
+ CMASK|=gScrp[fptr->v2].y;
+ CMASK|=gScrp[fptr->v3].y;
+
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].ev.Fog = vFogT[fptr->v1]; cp[0].tx = fptr->tax; cp[0].ty = fptr->tay; cp[0].ev.Light = (int)mptr->VLight[VT][fptr->v1];
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].ev.Fog = vFogT[fptr->v2]; cp[1].tx = fptr->tbx; cp[1].ty = fptr->tby; cp[1].ev.Light = (int)mptr->VLight[VT][fptr->v2];
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].ev.Fog = vFogT[fptr->v3]; cp[2].tx = fptr->tcx; cp[2].ty = fptr->tcy; cp[2].ev.Light = (int)mptr->VLight[VT][fptr->v3];
+
+ //if (CMASK == 0xFF)
+ {
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) goto LNEXT;
+ }
+
+ if (CMASK & 1) for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) goto LNEXT;
+ if (CMASK & 2) for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) goto LNEXT;
+ if (CMASK & 4) for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) goto LNEXT;
+ if (CMASK & 8) for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) {
+ gvtx[u].a = cp[u].ev.Fog;
+ gvtx[u].x = (float)(VideoCX16 - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW16))/16.f;
+ gvtx[u].y = (float)(VideoCY16 + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH16))/16.f;
+ gvtx[u].z = -cp[u].ev.v.z;
+ gvtx[u].ooz = (_ZSCALE/gvtx[u].z);
+ gvtx[u].oow = 1.0f / gvtx[u].z;
+ gvtx[u].tmuvtx[0].sow = (float)cp[u].tx * gvtx[u].oow;
+ gvtx[u].tmuvtx[0].tow = (float)cp[u].ty * gvtx[u].oow;
+ float _flight = flight + cp[u].ev.Light;
+ gvtx[u].r = _flight; gvtx[u].g = gvtx[u].r; gvtx[u].b = gvtx[u].r;
+ }
+
+
+ NewTransparent = (fptr->Flags & sfTransparent);
+
+ if (NewTransparent != PrevTransparent)
+ if (NewTransparent)
+ {
+ grConstantColorValue(0x80000000);
+ PrevTransparent = NewTransparent;
+ } else {
+ grConstantColorValue(0xFF000000);
+ PrevTransparent = NewTransparent;
+ }
+
+
+
+
+ for (u=0; u<vused-2; u++) {
+ grDrawTriangle(&gvtx[0], &gvtx[u+1], &gvtx[u+2]);
+ dFacesCount++;
+ }
+
+LNEXT:
+ f = mptr->gFace[f].Next;
+ }
+
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ grConstantColorValue(0xFF000000);
+ /*if (NewTransparent)
+ grDepthMask( FXTRUE );*/
+}
+
+
+
+
+
+
+void RenderModelClipEnvMap(TModel* _mptr, float x0, float y0, float z0, float al, float bt)
+{
+ int f,CMASK;
+ BOOL BL = FALSE;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+
+ for (int s=0; s<mptr->VCount; s++) {
+
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) + x0;
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) + z0;
+ if (rVertex[s].z<0) BL=TRUE;
+
+ if (rVertex[s].z>-256) { gScrp[s].x = 0xFFFFFF; gScrp[s].y = 0xFF; }
+ else {
+ int f = 0;
+ int sx = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ int sy = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+
+ if (sx>=WinEX) f+=1;
+ if (sx<=0 ) f+=2;
+
+ if (sy>=WinEY) f+=4;
+ if (sy<=0 ) f+=8;
+
+ gScrp[s].y = f;
+ }
+
+ }
+
+ if (!BL) return;
+
+ gvtx[0].a = 0; gvtx[1].a = 0; gvtx[2].a = 0; gvtx[4].a = 0; gvtx[5].a = 0;
+
+
+ SetFXTexture(TFX_ENVMAP.lpImage, TFX_ENVMAP.W, TFX_ENVMAP.W);
+ grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP);
+
+ grConstantColorValue(0xFF000000);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ONE, GR_BLEND_ONE);
+
+ BuildTreeClipNoSort();
+
+ ca = (float)cos(CameraAlpha);
+ sa = (float)sin(CameraAlpha);
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+ if (!(fptr->Flags & sfEnvMap)) goto LNEXT;
+
+ CMASK = 0;
+
+ CMASK|=gScrp[fptr->v1].y;
+ CMASK|=gScrp[fptr->v2].y;
+ CMASK|=gScrp[fptr->v3].y;
+
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].tx = PhongMapping[fptr->v1].x; cp[0].ty = PhongMapping[fptr->v1].y;
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].tx = PhongMapping[fptr->v2].x; cp[1].ty = PhongMapping[fptr->v2].y;
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].tx = PhongMapping[fptr->v3].x; cp[2].ty = PhongMapping[fptr->v3].y;
+
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) goto LNEXT;
+
+ if (CMASK & 1) for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) goto LNEXT;
+ if (CMASK & 2) for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) goto LNEXT;
+ if (CMASK & 4) for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) goto LNEXT;
+ if (CMASK & 8) for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) {
+ gvtx[u].a = 0x00;
+ gvtx[u].x = (float)(VideoCX16 - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW16))/16.f;
+ gvtx[u].y = (float)(VideoCY16 + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH16))/16.f;
+ gvtx[u].z = -cp[u].ev.v.z;
+ gvtx[u].ooz = (_ZSCALE/gvtx[u].z);
+ gvtx[u].oow = 1.0f / gvtx[u].z;
+
+ gvtx[u].tmuvtx[0].sow = (float)cp[u].tx * gvtx[u].oow;
+ gvtx[u].tmuvtx[0].tow = (float)cp[u].ty * gvtx[u].oow;
+
+ gvtx[u].r = 255; gvtx[u].g = gvtx[u].r; gvtx[u].b = gvtx[u].r;
+ }
+
+
+
+ for (u=0; u<vused-2; u++) {
+ grDrawTriangle(&gvtx[0], &gvtx[u+1], &gvtx[u+2]);
+ dFacesCount++; }
+
+
+LNEXT:
+ f = mptr->gFace[f].Next;
+ }
+
+ grDepthBiasLevel(8000);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ONE);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ grConstantColorValue(0xFF000000);
+}
+
+
+
+
+
+
+
+void RenderModelClipPhongMap(TModel* _mptr, float x0, float y0, float z0, float al, float bt)
+{
+ int f,CMASK;
+ BOOL BL = FALSE;
+
+ mptr = _mptr;
+
+ float rv = SkyR +64; if (rv>255) rv = 255;
+ float gv = SkyG +64; if (gv>255) gv = 255;
+ float bv = SkyB +64; if (bv>255) bv = 255;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+
+ for (int s=0; s<mptr->VCount; s++) {
+
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) + x0;
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) + z0;
+ if (rVertex[s].z<0) BL=TRUE;
+
+ if (rVertex[s].z>-256) { gScrp[s].x = 0xFFFFFF; gScrp[s].y = 0xFF; }
+ else {
+ int f = 0;
+ int sx = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ int sy = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+
+ if (sx>=WinEX) f+=1;
+ if (sx<=0 ) f+=2;
+
+ if (sy>=WinEY) f+=4;
+ if (sy<=0 ) f+=8;
+
+ gScrp[s].y = f;
+ }
+
+ }
+
+ if (!BL) return;
+ for (s=0; s<6; s++) { gvtx[s].r = rv; gvtx[s].g = gv; gvtx[s].b = bv; gvtx[s].a = 0; }
+
+
+ SetFXTexture(TFX_SPECULAR.lpImage, TFX_SPECULAR.W, TFX_SPECULAR.W);
+ grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP);
+ //grDepthBiasLevel(8002);
+ grConstantColorValue(0xFF000000);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ONE, GR_BLEND_ONE);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+
+ BuildTreeClipNoSort();
+
+ ca = (float)cos(CameraAlpha);
+ sa = (float)sin(CameraAlpha);
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+ if (!(fptr->Flags & sfPhong)) goto LNEXT;
+
+ CMASK = 0;
+
+ CMASK|=gScrp[fptr->v1].y;
+ CMASK|=gScrp[fptr->v2].y;
+ CMASK|=gScrp[fptr->v3].y;
+
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].tx = PhongMapping[fptr->v1].x; cp[0].ty = PhongMapping[fptr->v1].y;
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].tx = PhongMapping[fptr->v2].x; cp[1].ty = PhongMapping[fptr->v2].y;
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].tx = PhongMapping[fptr->v3].x; cp[2].ty = PhongMapping[fptr->v3].y;
+
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) goto LNEXT;
+
+ if (CMASK & 1) for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) goto LNEXT;
+ if (CMASK & 2) for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) goto LNEXT;
+ if (CMASK & 4) for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) goto LNEXT;
+ if (CMASK & 8) for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) {
+ gvtx[u].a = 0x00;
+ gvtx[u].x = (float)(VideoCX16 - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW16))/16.f;
+ gvtx[u].y = (float)(VideoCY16 + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH16))/16.f;
+ gvtx[u].z = -cp[u].ev.v.z;
+ gvtx[u].ooz = (_ZSCALE/gvtx[u].z);
+ gvtx[u].oow = 1.0f / gvtx[u].z;
+ gvtx[u].tmuvtx[0].sow = (float)cp[u].tx * gvtx[u].oow;
+ gvtx[u].tmuvtx[0].tow = (float)cp[u].ty * gvtx[u].oow;
+ }
+
+
+
+ for (u=0; u<vused-2; u++) {
+ grDrawTriangle(&gvtx[0], &gvtx[u+1], &gvtx[u+2]);
+ dFacesCount++; }
+
+
+LNEXT:
+ f = mptr->gFace[f].Next;
+ }
+
+ grDepthBiasLevel(8000);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ONE, GR_BLEND_ONE);
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ grConstantColorValue(0xFF000000);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void RenderModelSun(TModel* _mptr, float x0, float y0, float z0, int Alpha)
+{
+ int f;
+
+ mptr = _mptr;
+
+ int minx = 10241024;
+ int maxx =-10241024;
+ int miny = 10241024;
+ int maxy =-10241024;
+
+ gvtx[0].r = 255.f; gvtx[0].g = gvtx[0].r; gvtx[0].b = gvtx[0].r;
+ gvtx[1].r = gvtx[0].r; gvtx[1].g = gvtx[0].g; gvtx[1].b = gvtx[0].b;
+ gvtx[2].r = gvtx[0].r; gvtx[2].g = gvtx[0].g; gvtx[2].b = gvtx[0].b;
+
+ gvtx[0].z = 1.0f;
+ gvtx[1].z = 1.0f;
+ gvtx[2].z = 1.0f;
+
+ gvtx[0].oow = 1.0f;
+ gvtx[1].oow = 1.0f;
+ gvtx[2].oow = 1.0f;
+
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+
+ for (int s=0; s<mptr->VCount; s++) {
+ rVertex[s].x = mptr->gVertex[s].x + x0;
+ rVertex[s].y = mptr->gVertex[s].y + y0;
+ rVertex[s].z = mptr->gVertex[s].z + z0;
+
+ if (rVertex[s].z>-64) gScrp[s].x = 0xFFFFFF; else {
+ gScrp[s].x = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ gScrp[s].y = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH); }
+
+ if (gScrp[s].x > maxx) maxx = gScrp[s].x;
+ if (gScrp[s].x < minx) minx = gScrp[s].x;
+ if (gScrp[s].y > maxy) maxy = gScrp[s].y;
+ if (gScrp[s].y < miny) miny = gScrp[s].y;
+ }
+
+ if (minx == 10241024) return;
+ if (minx>WinW || maxx<0 || miny>WinH || maxy<0) return;
+
+ BuildTreeNoSort();
+
+ /*if (LOWRESTX) SetFXTexture(mptr->lpTexture2, 128, 128);
+ else SetFXTexture(mptr->lpTexture, 256, 256);*/
+ SetFXTexture(mptr->lpTexture2, 128, 128);
+
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
+ grConstantColorValue(Alpha<<24);
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE);
+
+ f = Current;
+ while( f!=-1 ) {
+ TFace *fptr = & mptr->gFace[f];
+
+ gvtx[0].x = (float)gScrp[fptr->v1].x;
+ gvtx[0].y = (float)gScrp[fptr->v1].y;
+ gvtx[0].ooz = _ZSCALE/-rVertex[fptr->v1].z;
+ gvtx[0].tmuvtx[0].sow = fptr->tax;
+ gvtx[0].tmuvtx[0].tow = fptr->tay;
+
+ gvtx[1].x = (float)gScrp[fptr->v2].x;
+ gvtx[1].y = (float)gScrp[fptr->v2].y;
+ gvtx[1].ooz = _ZSCALE / -rVertex[fptr->v2].z;
+ gvtx[1].tmuvtx[0].sow = fptr->tbx;
+ gvtx[1].tmuvtx[0].tow = fptr->tby;
+
+ gvtx[2].x = (float)gScrp[fptr->v3].x;
+ gvtx[2].y = (float)gScrp[fptr->v3].y;
+ gvtx[2].ooz = _ZSCALE/-rVertex[fptr->v3].z;
+ gvtx[2].tmuvtx[0].sow = fptr->tcx;
+ gvtx[2].tmuvtx[0].tow = fptr->tcy;
+
+ grDrawTriangle(&gvtx[0], &gvtx[1], &gvtx[2]);
+ dFacesCount++;
+
+ f = mptr->gFace[f].Next;
+ }
+
+ //grTexFilterMode(GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR);
+ //grChromakeyMode(GR_CHROMAKEY_DISABLE);
+ grConstantColorValue(0xFF000000);
+
+ grAlphaBlendFunction(GR_BLEND_SRC_ALPHA,
+ GR_BLEND_ONE_MINUS_SRC_ALPHA,
+ GR_BLEND_ONE,
+ GR_BLEND_ONE);
+}
+
+
+
+
+
+
+void RenderNearModel(TModel* _mptr, float x0, float y0, float z0, int light, float al, float bt)
+{
+ BOOL bl = LOWRESTX;
+ Vector3d v;
+
+ v.x = 0; v.y =-128; v.z = 0;
+ CalcFogLevel_Gradient(v);
+ grFogColorValue(CurFogColor);
+ FogYGrad = 0;
+
+
+ LOWRESTX = FALSE;
+ RenderModelClip(_mptr, x0, y0, z0, light, 0, al, bt);
+
+ LOWRESTX = bl;
+}
+
+
+
+void RenderModelClipWater(TModel* _mptr, float x0, float y0, float z0, int light, int VT, float al, float bt)
+{
+}
+
+
+
+void RenderCharacter(int index)
+{
+}
+
+void RenderExplosion(int index)
+{
+}
+
+void RenderShip()
+{
+}
+
+void RenderCharacterPost(TCharacter *cptr)
+{
+ //mdlScale = 1.0f;
+ CreateChMorphedModel(cptr);
+
+ float zs = (float)sqrt( cptr->rpos.x*cptr->rpos.x + cptr->rpos.y*cptr->rpos.y + cptr->rpos.z*cptr->rpos.z);
+ if (zs > ctViewR*256) return;
+
+ GlassL = 0;
+ if (zs > 256 * (ctViewR-8)) {
+ GlassL = (int)(zs - 256 * (ctViewR-8)) / 8;
+ if (GlassL>255) GlassL=255;
+ }
+
+ waterclip = FALSE;
+
+ grConstantColorValue( (255-GlassL) << 24);
+ if ( cptr->rpos.z >-256*10)
+ RenderModelClip(cptr->pinfo->mptr,
+ cptr->rpos.x, cptr->rpos.y, cptr->rpos.z, 210, 0,
+ -cptr->alpha + pi / 2 + CameraAlpha,
+ CameraBeta );
+ else
+ RenderModel(cptr->pinfo->mptr,
+ cptr->rpos.x, cptr->rpos.y, cptr->rpos.z, 210, 0,
+ -cptr->alpha + pi / 2 + CameraAlpha,
+ CameraBeta );
+
+
+ grConstantColorValue(0xFF000000);
+ if (!SHADOWS3D) return;
+ if (zs > 256 * (ctViewR-8)) return;
+
+ int Al = 0x50;
+ if (cptr->Health==0) {
+ int at = cptr->pinfo->Animation[cptr->Phase].AniTime;
+ if (Tranq) return;
+ if (cptr->FTime==at-1) return;
+ Al = Al * (at-cptr->FTime) / at; }
+ if (cptr->AI==0) Al = 0x50;
+
+ grConstantColorValue(Al<<24);
+
+ RenderShadowClip(cptr->pinfo->mptr,
+ cptr->pos.x, cptr->pos.y, cptr->pos.z,
+ cptr->rpos.x, cptr->rpos.y, cptr->rpos.z,
+ pi/2-cptr->alpha,
+ CameraAlpha,
+ CameraBeta );
+
+ grConstantColorValue(0xFF000000);
+}
+
+
+
+
+
+void RenderShipPost()
+{
+ if (Ship.State==-1) return;
+ GlassL = 0;
+ zs = (int)VectorLength(Ship.rpos);
+ if (zs > 256 * (ctViewR)) return;
+
+ if (zs > 256 * (ctViewR-4))
+ GlassL = min(255,(int)(zs - 256 * (ctViewR-4)) / 4);
+
+
+ grConstantColorValue( (255-GlassL) << 24);
+
+ CreateMorphedModel(ShipModel.mptr, &ShipModel.Animation[0], Ship.FTime, 1.0);
+
+ if ( fabs(Ship.rpos.z) < 4000)
+ RenderModelClip(ShipModel.mptr,
+ Ship.rpos.x, Ship.rpos.y, Ship.rpos.z, 210, 0, -Ship.alpha -pi/2 + CameraAlpha, CameraBeta);
+ else
+ RenderModel(ShipModel.mptr,
+ Ship.rpos.x, Ship.rpos.y, Ship.rpos.z, 210, 0, -Ship.alpha -pi/2+ CameraAlpha, CameraBeta);
+ grConstantColorValue( 0xFF000000);
+}
+
+
+
+
+
+
+
+float GetLandUH(float x, float y, int s)
+{
+
+ int CX = (int)x / 256;
+ int CY = (int)y / 256;
+
+ int dx = (int)x % 256;
+ int dy = (int)y % 256;
+/*
+ int h1 = HMap[CY][CX];
+ int h2 = HMap[CY][CX+1];
+ int h3 = HMap[CY+1][CX+1];
+ int h4 = HMap[CY+1][CX];
+ */
+
+ float h = (float)
+ (HMap[CY][CX] * (256-dx) + HMap[CY][CX+1] * dx) * (256-dy) +
+ (HMap[CY+1][CX] * (256-dx) + HMap[CY+1][CX+1] * dx) * dy;
+
+ return h / 256.f / 256.f * ctHScale;
+}
+
+/*
+void RenderVoxelEnd()
+{
+ Vector3d lv, gv, cp, p;
+ int sy, _sy, t, l;
+ DWORD alpha;
+
+ //if (!RunMode) return;
+
+ guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
+
+ for (int x=0; x<=WinW; x+=2) {
+
+ lv.y = 0;
+ lv.z = -1;
+ lv.x = (x-VideoCX)/CameraW *(1+cb)/2;
+ NormVector(lv, 256.0f);
+
+ gv.z = lv.z * ca + lv.x * sa;
+ gv.x = lv.x * ca - lv.z * sa;
+ gv.y = 0;
+
+ lv = gv;
+ NormVector(lv, (ctViewR-10)*256.0f);
+ cp = AddVectors(CameraPos, lv);
+
+ p = cp; p.y = GetLandUpH(p.x, p.z);
+ t = TMap1[(int)(p.z)>>8][(int)(p.x)>>8];
+ l = 256-GetLandLt(p.x, p.z)*4;
+ p.x -= CameraX;
+ p.y -= CameraY;
+ p.z -= CameraZ;
+
+
+ p = RotateVector(p);
+ _sy = VideoCY + CameraH * p.y / p.z;
+ gvtx[0].x=x;
+ gvtx[1].x=x;
+ gvtx[0].a=16;
+ gvtx[1].a=16;
+
+ gvtx[0].r = Textures[t]->mR*l/256;
+ gvtx[0].g = Textures[t]->mG*l/256;
+ gvtx[0].b = Textures[t]->mB*l/256;
+
+ gvtx[0].ooz = (-1.0f/p.z)*4.f*65534.f;
+ gvtx[0].oow = 1.0f;
+ gvtx[0].y = _sy;
+
+ gvtx[1] = gvtx[0];
+
+ gv.y = 0;
+ for (int s=0; s<30; s++) {
+ //if (s==15) NormVector(gv, 512.0f);
+
+ cp.y = GetLandUH(p.x, p.z, s);
+ if (s>4) {
+ cp = AddVectors(cp, gv);
+ cp.y = max(cp.y,GetLandUH(cp.x, cp.z, s));
+ }
+
+ if (s>15) {
+ cp = AddVectors(cp, gv);
+ cp.y = max(cp.y,GetLandUH(cp.x, cp.z, s));
+ cp = AddVectors(cp, gv);
+ cp.y = max(cp.y,GetLandUH(cp.x, cp.z, s));
+ }
+
+ p = cp;
+ t = TMap1[(int)(cp.z)>>8][(int)(cp.x)>>8];
+
+ p.x -= CameraX;
+ p.y -= CameraY;
+ p.z -= CameraZ;
+ p = RotateVector(p);
+ sy = VideoCY + CameraH * p.y / p.z;
+
+
+ if (sy < _sy-1)
+ {
+ //l = 256-LMap[(int)cp.z/256][(int)cp.x/256]*4;
+ l = 256-GetLandLt(cp.x, cp.z)*4;
+
+ gvtx[1].a=s*4+16;
+
+ gvtx[1].ooz = (-1.0f/p.z)*4.f*65534.f;
+ gvtx[1].oow = 1.0f;
+ gvtx[1].y = sy;
+ gvtx[1].r = Textures[t]->mR*l/256;
+ gvtx[1].g = Textures[t]->mG*l/256;
+ gvtx[1].b = Textures[t]->mB*l/256;
+
+ grConstantColorValue(alpha +
+ (Textures[t]->mR*l/256) +
+ ((Textures[t]->mG*l/256)<<8) +
+ ((Textures[t]->mB*l/256)<<16) );
+
+
+ gvtx[0].x = x; gvtx[1].x = x;
+ grDrawLine(&gvtx[0], &gvtx[1]);
+ gvtx[0].x = x+1; gvtx[1].x = x+1;
+ grDrawLine(&gvtx[0], &gvtx[1]);
+
+ dFacesCount++;
+ gvtx[0] = gvtx[1];
+ _sy = sy;
+ } else gvtx[0].a=s*4+16;
+
+
+ cp = AddVectors(cp, gv);
+ }
+ }
+
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+ grConstantColorValue(0xFF000000);
+}
+
+*/
+
+
+
+void RenderElements()
+{
+ guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
+ //guAlphaSource(GR_ALPHASOURCE_ITERATED_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED, FXFALSE);
+ grFogMode(GR_FOG_DISABLE);
+ grDepthMask( FXFALSE );
+
+ for (int eg = 0; eg<ElCount; eg++) {
+ for (int e = 0; e<Elements[eg].ECount; e++) {
+ Vector3d rpos;
+ TElement *el = &Elements[eg].EList[e];
+ rpos.x = el->pos.x - CameraX;
+ rpos.y = el->pos.y - CameraY;
+ rpos.z = el->pos.z - CameraZ;
+ float r = el->R;
+
+ rpos = RotateVector(rpos);
+ if (rpos.z > -64) continue;
+ if ( fabs(rpos.x) > -rpos.z) continue;
+ if ( fabs(rpos.y) > -rpos.z) continue;
+
+ float sx = VideoCX - (int)(CameraW * rpos.x / rpos.z * 16) / 16.f;
+ float sy = VideoCY + (int)(CameraH * rpos.y / rpos.z * 16) / 16.f;
+ RenderCircle(sx, sy, rpos.z, -r*CameraW*0.64 / rpos.z, Elements[eg].RGBA, Elements[eg].RGBA2);
+ }
+ }
+
+ for (int b=0; b<BloodTrail.Count; b++) {
+ Vector3d rpos = BloodTrail.Trail[b].pos;
+ DWORD A1 = (0xE0 * BloodTrail.Trail[b].LTime / 20000); if (A1>0xE0) A1=0xE0;
+ DWORD A2 = (0x20 * BloodTrail.Trail[b].LTime / 20000); if (A2>0x20) A2=0x20;
+ rpos.x = rpos.x - CameraX;
+ rpos.y = rpos.y - CameraY;
+ rpos.z = rpos.z - CameraZ;
+
+ rpos = RotateVector(rpos);
+ if (rpos.z > -64) continue;
+ if ( fabs(rpos.x) > -rpos.z) continue;
+ if ( fabs(rpos.y) > -rpos.z) continue;
+
+ float sx = VideoCX - (int)(CameraW * rpos.x / rpos.z * 16) / 16.f;
+ float sy = VideoCY + (int)(CameraH * rpos.y / rpos.z * 16) / 16.f;
+ RenderCircle(sx, sy, rpos.z, -12*CameraW*0.64 / rpos.z, (A1<<24)+conv_xGx(0x000070), (A2<<24)+conv_xGx(0x000030));
+ }
+
+
+
+ if (SNOW)
+ for (int s=0; s<SnCount; s++) {
+ Vector3d rpos = Snow[s].pos;
+
+
+ rpos.x = rpos.x - CameraX;
+ rpos.y = rpos.y - CameraY;
+ rpos.z = rpos.z - CameraZ;
+
+
+ rpos = RotateVector(rpos);
+ if (rpos.z > -64) continue;
+ if ( fabs(rpos.x) > -rpos.z) continue;
+ if ( fabs(rpos.y) > -rpos.z) continue;
+
+ float sx = VideoCX - (int)(CameraW * rpos.x / rpos.z * 16) / 16.f;
+ float sy = VideoCY + (int)(CameraH * rpos.y / rpos.z * 16) / 16.f;
+
+ DWORD A1 = 0xFF;
+ DWORD A2 = 0x30;
+ if (Snow[s].ftime) {
+ A1 = A1 * (2000-Snow[s].ftime) / 2000;
+ A2 = A2 * (2000-Snow[s].ftime) / 2000;
+ }
+
+ RenderCircle(sx, sy, rpos.z, -8*CameraW*0.64 / rpos.z, (A1<<24)+conv_xGx(0xF0F0F0), (A2<<24)+conv_xGx(0xB0B0B0));
+ }
+
+ //guAlphaSource(GR_ALPHASOURCE_CC_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+ if (FOGON) grFogMode(GR_FOG_WITH_ITERATED_ALPHA);
+ grDepthMask( FXTRUE );
+}
+
+
+
+void Render3DHardwarePosts()
+{
+ TCharacter *cptr;
+
+ for (int c=0; c<ChCount; c++) {
+ //if (!RunMode) continue;
+ cptr = &Characters[c];
+ cptr->rpos.x = cptr->pos.x - CameraX;
+ cptr->rpos.y = cptr->pos.y - CameraY;
+ cptr->rpos.z = cptr->pos.z - CameraZ;
+
+
+ float r = (float)max( fabs(cptr->rpos.x), fabs(cptr->rpos.z) );
+ int ri = -1 + (int)(r / 256.f + 0.5f);
+ if (ri < 0) ri = 0;
+ if (ri > ctViewR) continue;
+
+ if (FOGON) {
+ CalcFogLevel_Gradient(cptr->rpos);
+ grFogColorValue(CurFogColor);
+ }
+
+ cptr->rpos = RotateVector(cptr->rpos);
+
+ float br = BackViewR + DinoInfo[cptr->CType].Radius;
+ if (cptr->rpos.z > br) continue;
+ if ( fabs(cptr->rpos.x) > -cptr->rpos.z + br ) continue;
+ if ( fabs(cptr->rpos.y) > -cptr->rpos.z + br ) continue;
+
+ RenderCharacterPost(cptr);
+ }
+
+
+
+
+ Ship.rpos.x = Ship.pos.x - CameraX;
+ Ship.rpos.y = Ship.pos.y - CameraY;
+ Ship.rpos.z = Ship.pos.z - CameraZ;
+ float r = (float)max( fabs(Ship.rpos.x), fabs(Ship.rpos.z) );
+
+ int ri = -1 + (int)(r / 256.f + 0.2f);
+ if (ri < 0) ri = 0;
+ if (ri < ctViewR) {
+
+ if (FOGON) {
+ CalcFogLevel_Gradient(Ship.rpos);
+ grFogColorValue(CurFogColor);
+ }
+
+ Ship.rpos = RotateVector(Ship.rpos);
+ if (Ship.rpos.z > BackViewR) goto NOSHIP;
+ if ( fabs(Ship.rpos.x) > -Ship.rpos.z + BackViewR ) goto NOSHIP;
+
+ RenderShipPost();
+ }
+NOSHIP: ;
+}
+
+
+
+
+
+void ClearVideoBuf()
+{
+ //grBufferClear( 0xFF000000, 0, 0);
+}
+
+
+
+int CircleCX, CircleCY;
+
+
+
+WORD _CRCOLOR;
+void PutPixel(int x, int y)
+{ *((WORD*)linfo.lfbPtr + y*lsw + x) = _CRCOLOR; }
+
+void Put8pix(int X,int Y)
+{
+ PutPixel(CircleCX + X, CircleCY + Y);
+ PutPixel(CircleCX + X, CircleCY - Y);
+ PutPixel(CircleCX - X, CircleCY + Y);
+ PutPixel(CircleCX - X, CircleCY - Y);
+ PutPixel(CircleCX + Y, CircleCY + X);
+ PutPixel(CircleCX + Y, CircleCY - X);
+ PutPixel(CircleCX - Y, CircleCY + X);
+ PutPixel(CircleCX - Y, CircleCY - X);
+}
+
+void DrawCircle(int cx, int cy, int R)
+{
+ int d = 3 - (2 * R);
+ int x = 0;
+ int y = R;
+ CircleCX=cx;
+ CircleCY=cy;
+ do {
+ Put8pix(x,y); x++;
+ if (d < 0) d = d + (x<<2) + 6; else
+ { d = d + (x - y) * 4 + 10; y--; }
+ } while (x<y);
+ Put8pix(x,y);
+}
+
+
+
+
+
+
+
+void DrawBox( WORD *lfbPtr, int lsw, int xx, int yy, WORD c)
+{
+ yy = yy * lsw + xx;
+ *(lfbPtr + yy) = c;
+ *(lfbPtr + yy + 1) = c;
+ yy+=lsw;
+ *(lfbPtr + yy) = c;
+ *(lfbPtr + yy + 1) = c;
+}
+
+void DrawHMap()
+{
+ int c;
+
+ DrawPicture(VideoCX-MapPic.W/2, VideoCY - MapPic.H/2-6, MapPic);
+
+ linfo.size = sizeof(GrLfbInfo_t);
+ if (!grLfbLock(
+ GR_LFB_WRITE_ONLY,
+ GR_BUFFER_BACKBUFFER,
+ GR_LFBWRITEMODE_565,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &linfo)) return;
+
+ lsw = linfo.strideInBytes / 2;
+
+
+
+ int xx = VideoCX - 128 + (CCX>>2);
+ int yy = VideoCY - 128 + (CCY>>2);
+
+
+ if (yy<0 || yy>=WinH) goto endmap;
+ if (xx<0 || xx>=WinW) goto endmap;
+
+ DrawBox( (WORD*)linfo.lfbPtr, lsw, xx+1, yy+1, 8<<11);
+ DrawBox( (WORD*)linfo.lfbPtr, lsw, xx, yy, 30<<11);
+
+ _CRCOLOR = 4<<6; DrawCircle(xx+1, yy+1, (ctViewR/4));
+ _CRCOLOR = 18<<6; DrawCircle(xx, yy, (ctViewR/4));
+
+ if (RadarMode)
+ for (c=0; c<ChCount; c++) {
+ if (Characters[c].AI<10) continue;
+ if (! (TargetDino & (1<<Characters[c].AI)) ) continue;
+
+ if (!Characters[c].Health) continue;
+ xx = VideoCX - 128 + (int)Characters[c].pos.x / 1024;
+ yy = VideoCY - 128 + (int)Characters[c].pos.z / 1024;
+ if (yy<=0 || yy>=WinH) goto endmap;
+ if (xx<=0 || xx>=WinW) goto endmap;
+
+ DrawBox( (WORD*)linfo.lfbPtr, lsw, xx, yy, 31);
+ }
+
+endmap:
+ grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
+}
+
+
+
+
+void RenderSun(float x, float y, float z)
+{
+ SunScrX = VideoCX + (int)(x / (-z) * CameraW);
+ SunScrY = VideoCY - (int)(y / (-z) * CameraH);
+ GetSkyK(SunScrX, SunScrY);
+ float d = (float)sqrt(x*x + y*y);
+ if (d<2048) {
+ SunLight = (220.f- d*220.f/2048.f);
+ if (SunLight>140) SunLight = 140;
+ SunLight*=SkyTraceK;
+ }
+
+ if (d>812.f) d = 812.f;
+ d = (2048.f + d) / 3048.f;
+ d+=(1.f-SkyTraceK)/2.f;
+ if (OptDayNight==2) d=1.5;
+ RenderModelSun(SunModel, x*d, y*d, z*d, (int)(200.f*SkyTraceK));
+}
+
+
+
+void RotateVVector(Vector3d& v)
+{
+ float x = v.x * ca - v.z * sa;
+ float y = v.y;
+ float z = v.z * ca + v.x * sa;
+
+ float xx = x;
+ float xy = y * cb + z * sb;
+ float xz = z * cb - y * sb;
+
+ v.x = xx; v.y = xy; v.z = xz;
+}
+
+
+void RenderSkyPlane2()
+{
+ Vector3d v,vbase;
+ Vector3d tx,ty,nv;
+ float p,q, qx, qy, qz, px, py, pz, rx, ry, rz, ddx, ddy;
+ float lastdt = 0.f;
+
+
+ nv.x = 512; nv.y = 4024; nv.z=0;
+ int FogBase = (int)CalcFogLevel(nv);
+
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+ //SKYDTime = RealTime & ((1<<16) - 1);
+
+ float sh = - CameraY;
+ if (MapMinY==10241024) MapMinY=0;
+ sh = (float)((int)MapMinY)*ctHScale - CameraY;
+
+ v.x = 0;
+ v.z = (ctViewR*4.f)/5.f*256.f;
+ v.y = sh;
+
+ vbase.x = v.x;
+ vbase.y = v.y * cb + v.z * sb;
+ vbase.z = v.z * cb - v.y * sb;
+
+ if (vbase.z < 128) vbase.z = 128;
+
+ int scry = VideoCY - (int)(vbase.y / vbase.z * CameraH);
+
+ if (scry<0) return;
+ if (scry>WinEY+1) scry = WinEY+1;
+
+ cb = (float)cos(CameraBeta-0.15);
+ sb = (float)sin(CameraBeta-0.15);
+
+ tx.x=0.0025f; tx.y=0; tx.z=0;
+ ty.x=0.0f; ty.y=0; ty.z=0.0025f;
+ nv.x=0; nv.y=-1.f; nv.z=0;
+
+ RotateVVector(tx);
+ RotateVVector(ty);
+ RotateVVector(nv);
+
+ sh = 4*512*16;
+ vbase.x = -CameraX;
+ vbase.y = sh;
+ vbase.z = +CameraZ;
+ RotateVVector(vbase);
+
+//============= calc render params =================//
+ p = nv.x * vbase.x + nv.y * vbase.y + nv.z * vbase.z;
+ ddx = vbase.x * tx.x + vbase.y * tx.y + vbase.z * tx.z;
+ ddy = vbase.x * ty.x + vbase.y * ty.y + vbase.z * ty.z;
+
+ qx = CameraH * nv.x; qy = CameraW * nv.y; qz = CameraW*CameraH * nv.z;
+ px = p*CameraH*tx.x; py = p*CameraW*tx.y; pz = p*CameraW*CameraH* tx.z;
+ rx = p*CameraH*ty.x; ry = p*CameraW*ty.y; rz = p*CameraW*CameraH* ty.z;
+
+ px=px - ddx*qx; py=py - ddx*qy; pz=pz - ddx*qz;
+ rx=rx - ddy*qx; ry=ry - ddy*qy; rz=rz - ddy*qz;
+
+ int sx1 = - VideoCX;
+ int sx2 = + VideoCX;
+
+ float qx1 = qx * sx1 + qz;
+ float qx2 = qx * sx2 + qz;
+ float qyy;
+
+ grConstantColorValue(0xFF000000);
+ grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP);
+ //guAlphaSource(GR_ALPHASOURCE_ITERATED_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_ITERATED, FXFALSE);
+ grFogMode(GR_FOG_DISABLE);
+
+ float l = 255.f;
+ gvtx[0].r = l; gvtx[0].g = l; gvtx[0].b = l;
+ gvtx[1].r = l; gvtx[1].g = l; gvtx[1].b = l;
+
+ gvtx[0].a = 0.5f;
+ gvtx[1].a = 0.5f;
+
+ gvtx[0].x = 0;
+ gvtx[1].x = (float)WinEX+1;
+
+ gvtx[0].z = (float)1.f;
+ gvtx[1].z = (float)1.f;
+
+ gvtx[0].oow = 1.0f;
+ gvtx[1].oow = 1.0f;
+
+ for (int sky=0; sky<=scry; sky++) {
+ int sy = VideoCY - sky;
+ qyy = qy * sy;
+
+ q = qx1 + qyy;
+ float fxa = (px * sx1 + py * sy + pz) / q;
+ float fya = (rx * sx1 + ry * sy + rz) / q;
+
+ q = qx2 + qyy;
+ float fxb = (px * sx2 + py * sy + pz) / q;
+ float fyb = (rx * sx2 + ry * sy + rz) / q;
+
+ float dtt = (float)(SKYDTime) / 256.f;
+
+ float dt = ((float)sqrt( (fxb-fxa)*(fxb-fxa) + (fyb-fya)*(fyb-fya) ) / 0x40 ) - 4.f;
+ if (UNDERWATER) dt=6 + dt*3;
+ if (dt>10.f) dt = 10.f;
+ if (dt<lastdt) dt = lastdt;
+ lastdt = dt;
+ gvtx[0].a = max(164-dt*245.f/10.f, 0);
+ gvtx[1].a = gvtx[0].a;
+
+ gvtx[0].y = (float)sky;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].tmuvtx[0].sow = fxa + dtt;
+ gvtx[0].tmuvtx[0].tow = fya - dtt;
+
+ gvtx[1].y = (float)sky;
+ gvtx[1].ooz = (_ZSCALE/gvtx[1].z);
+ gvtx[1].tmuvtx[0].sow = fxb + dtt;
+ gvtx[1].tmuvtx[0].tow = fyb - dtt;
+
+ grDrawLine(&gvtx[0], &gvtx[1]);
+ dFacesCount++;
+ }
+
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+
+ //guAlphaSource(GR_ALPHASOURCE_CC_ALPHA);
+ grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_TEXTURE_ALPHA, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_CONSTANT, FXFALSE);
+}
+
+
+void RenderSkyPlane()
+{
+ Vector3d v,vbase;
+ Vector3d tx,ty,nv;
+ float p,q, qx, qy, qz, px, py, pz, rx, ry, rz, ddx, ddy;
+ float lastdt = 0.f;
+
+ SetFXTexture(SkyPic, 256, 256);
+
+ nv.x = 512; nv.y = 4024; nv.z=0;
+ int FogBase = (int)CalcFogLevel(nv);
+
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+ SKYDTime = RealTime & ((1<<18) - 1);
+
+ float sh = - CameraY;
+ if (MapMinY==10241024) MapMinY=0;
+ sh = (float)((int)MapMinY)*ctHScale - CameraY;
+
+ v.x = 0;
+ v.z = (ctViewR*4.f)/5.f*256.f;
+ v.y = sh;
+
+ vbase.x = v.x;
+ vbase.y = v.y * cb + v.z * sb;
+ vbase.z = v.z * cb - v.y * sb;
+
+ if (vbase.z < 128) vbase.z = 128;
+
+ int scry = VideoCY - (int)(vbase.y / vbase.z * CameraH);
+
+ if (scry<0) return;
+ if (scry>WinEY+1) scry = WinEY+1;
+
+ cb = (float)cos(CameraBeta-0.15);
+ sb = (float)sin(CameraBeta-0.15);
+
+ tx.x=0.002f; tx.y=0; tx.z=0;
+ ty.x=0.0f; ty.y=0; ty.z=0.002f;
+ nv.x=0; nv.y=-1.f; nv.z=0;
+
+ RotateVVector(tx);
+ RotateVVector(ty);
+ RotateVVector(nv);
+
+ sh = 4*512*16;
+ vbase.x = -CameraX;
+ vbase.y = sh;
+ vbase.z = +CameraZ;
+ RotateVVector(vbase);
+
+//============= calc render params =================//
+ p = nv.x * vbase.x + nv.y * vbase.y + nv.z * vbase.z;
+ ddx = vbase.x * tx.x + vbase.y * tx.y + vbase.z * tx.z;
+ ddy = vbase.x * ty.x + vbase.y * ty.y + vbase.z * ty.z;
+
+ qx = CameraH * nv.x; qy = CameraW * nv.y; qz = CameraW*CameraH * nv.z;
+ px = p*CameraH*tx.x; py = p*CameraW*tx.y; pz = p*CameraW*CameraH* tx.z;
+ rx = p*CameraH*ty.x; ry = p*CameraW*ty.y; rz = p*CameraW*CameraH* ty.z;
+
+ px=px - ddx*qx; py=py - ddx*qy; pz=pz - ddx*qz;
+ rx=rx - ddy*qx; ry=ry - ddy*qy; rz=rz - ddy*qz;
+
+ int sx1 = - VideoCX;
+ int sx2 = + VideoCX;
+
+ float qx1 = qx * sx1 + qz;
+ float qx2 = qx * sx2 + qz;
+ float qyy;
+
+ grDepthMask( FXFALSE );
+ grFogMode(GR_FOG_WITH_ITERATED_ALPHA);
+ grConstantColorValue(0xFF000000);
+ grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP);
+ if (UNDERWATER) grFogColorValue( CurFogColor );
+ else grFogColorValue( (SkyB<<16) + (SkyG<<8) + SkyR);
+
+ float l = 255.f;
+ gvtx[0].r = l; gvtx[0].g = l; gvtx[0].b = l;
+ gvtx[1].r = l; gvtx[1].g = l; gvtx[1].b = l;
+
+ gvtx[0].a = 0.f;
+ gvtx[1].a = 0.f;
+
+ gvtx[0].x = 0;
+ gvtx[1].x = (float)WinEX+1;
+
+ gvtx[0].z = (float)1.f;
+ gvtx[1].z = (float)1.f;
+
+ gvtx[0].oow = 1.0f;
+ gvtx[1].oow = 1.0f;
+
+ for (int sky=0; sky<=scry; sky++) {
+ int sy = VideoCY - sky;
+ qyy = qy * sy;
+
+ q = qx1 + qyy;
+ float fxa = (px * sx1 + py * sy + pz) / q;
+ float fya = (rx * sx1 + ry * sy + rz) / q;
+
+ q = qx2 + qyy;
+ float fxb = (px * sx2 + py * sy + pz) / q;
+ float fyb = (rx * sx2 + ry * sy + rz) / q;
+
+ float dtt = (float)(SKYDTime) / 512.f;
+
+ float dt = ((float)sqrt( (fxb-fxa)*(fxb-fxa) + (fyb-fya)*(fyb-fya) ) / 0x40 ) - 5.f;
+ if (UNDERWATER) dt=6 + dt*3;
+ if (dt>10.f) dt = 10.f;
+ if (dt<lastdt) dt = lastdt;
+ lastdt = dt;
+ gvtx[0].a = max(dt*245.f/10.f, FogBase);
+ gvtx[1].a = gvtx[0].a;
+
+ gvtx[0].y = (float)sky;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].tmuvtx[0].sow = fxa + dtt;
+ gvtx[0].tmuvtx[0].tow = fya - dtt;
+
+ gvtx[1].y = (float)sky;
+ gvtx[1].ooz = (_ZSCALE/gvtx[1].z);
+ gvtx[1].tmuvtx[0].sow = fxb + dtt;
+ gvtx[1].tmuvtx[0].tow = fyb - dtt;
+
+ grDrawLine(&gvtx[0], &gvtx[1]);
+ dFacesCount++;
+ }
+
+ //if (RunMode)
+ // RenderSkyPlane2();
+
+ if (!FOGON) grFogMode(GR_FOG_DISABLE);
+ else grFogMode(GR_FOG_WITH_ITERATED_ALPHA);
+ grTexClampMode(GR_TMU0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP);
+
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+
+
+ gvtx[0].a = 0;
+ gvtx[1].a = 0;
+ gvtx[2].a = 0;
+
+ nv = RotateVector(Sun3dPos);
+ SunLight = 0;
+ if (nv.z < -2024) RenderSun(nv.x, nv.y, nv.z);
+
+ grDepthMask( FXTRUE );
+ grFogColorValue(CurFogColor);
+
+}
+
+
+void RenderHealthBar()
+{
+ if (MyHealth >= 100000) return;
+ if (MyHealth == 000000) return;
+
+ int L = WinW / 4;
+ int x0 = WinW - (WinW / 20) - L;
+ int y0 = WinH / 40;
+ int G = min( (MyHealth * 240 / 100000), 160);
+ int R = min( ( (100000 - MyHealth) * 240 / 100000), 160);
+
+
+ int L0 = (L * MyHealth) / 100000;
+ int H = WinH / 200;
+
+ gvtx[0].tmuvtx[0].sow = 0.0;
+ gvtx[0].tmuvtx[0].tow = 0.0;
+ gvtx[0].z = (float)1.f;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+
+ gvtx[1].tmuvtx[0].sow = 0.0;
+ gvtx[1].tmuvtx[0].tow = 0.0;
+ gvtx[1].z = (float)1.f;
+ gvtx[1].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[1].oow = 1.0f/gvtx[0].z;
+
+ guColorCombineFunction( GR_COLORCOMBINE_CCRGB );
+
+ grConstantColorValue(0xD0000000);
+
+ for (int y=-1; y<3; y++) {
+ gvtx[0].x = (float)x0-1; gvtx[0].y = (float)y0+y;
+ gvtx[1].x = (float)x0+L0+1; gvtx[1].y = (float)y0+y;
+ grDrawLine(&gvtx[0], &gvtx[1]);
+ }
+
+
+ grConstantColorValue(0xFF000000 + (G<<8) + R);
+
+ gvtx[0].x = (float)x0; gvtx[0].y = (float)y0;
+ gvtx[1].x = (float)x0+L0; gvtx[1].y = (float)y0;
+ grDrawLine(&gvtx[0], &gvtx[1]);
+
+ gvtx[0].x = (float)x0; gvtx[0].y = (float)y0+1.f;
+ gvtx[1].x = (float)x0+L0; gvtx[1].y = (float)y0+1.f;
+ grDrawLine(&gvtx[0], &gvtx[1]);
+
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+ grConstantColorValue(0xFF000000);
+}
+
+void Render_Cross(int sx, int sy)
+{
+
+ guColorCombineFunction( GR_COLORCOMBINE_CCRGB );
+ grConstantColorValue(0x60000000);
+
+ gvtx[0].tmuvtx[0].sow = 0.0;
+ gvtx[0].tmuvtx[0].tow = 0.0;
+ gvtx[0].z = (float)1.f;
+ gvtx[0].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[0].oow = 1.0f/gvtx[0].z;
+
+ gvtx[1].tmuvtx[0].sow = 0.0;
+ gvtx[1].tmuvtx[0].tow = 0.0;
+ gvtx[1].z = (float)1.f;
+ gvtx[1].ooz = (_ZSCALE/gvtx[0].z);
+ gvtx[1].oow = 1.0f/gvtx[0].z;
+
+
+ float w = (float) WinW / 12.f;
+
+ gvtx[0].x = (float)(sx - w);
+ gvtx[0].y = (float)sy;
+ gvtx[1].x = (float)(sx + w);
+ gvtx[1].y = (float)sy;
+
+ grDrawLine(&gvtx[0], &gvtx[1]);
+
+ gvtx[0].x = (float)(sx );
+ gvtx[0].y = (float)(sy - w);
+ gvtx[1].x = (float)(sx );
+ gvtx[1].y = (float)(sy + w);
+
+ grDrawLine(&gvtx[0], &gvtx[1]);
+
+ guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
+ grConstantColorValue(0xFF000000);
+}
+
+#endif \ No newline at end of file
diff --git a/RenderSoft.cpp b/RenderSoft.cpp
new file mode 100644
index 0000000..1bf4500
--- /dev/null
+++ b/RenderSoft.cpp
@@ -0,0 +1,2537 @@
+#ifdef _soft
+
+#include "Hunt.h"
+#include "stdio.h"
+/*
+typedef struct _tmpoint {
+ int x, y, tx, ty;
+} tmpoint;
+*/
+
+
+typedef struct _CharListItem {
+ int CType, Index;
+} TCharListItem;
+
+typedef struct _CharListLine {
+ int ICount;
+ TCharListItem Items[256];
+} TCharListLine;
+
+TCharListLine ChRenderList[128];
+
+
+Vector2di ORList[2][2048];
+int ORLCount[2];
+
+int rmlistselector;
+
+
+void RenderBMPModel2 (TBMPModel*, float, float, float, int);
+
+//================================================================//
+int xa; int xb; int xa16; int xb16;
+int v1, v2, v3,
+ l1, l2, l3,
+ x1, Y1, tx1, ty1, lt1, zdepth1,
+ x2, y2, tx2, ty2, lt2, zdepth2,
+ x3, y3, tx3, ty3, lt3, zdepth3;
+
+
+
+int dx1, dx2, dx3,
+ dtx1, dty1, dlt1,
+ dtx2, dty2, dlt2,
+ dtx3, dty3, dlt3,
+ tyb, tya, txa, txb, lta, ltb,
+ ddtx1, ddty1, ddtx2, ddty2, ddtx3, ddty3;
+
+int ctdy, ctdx, cdlt;
+int _sp;
+float k;
+BOOL LockWater;
+int OpacityMode;
+
+
+void STTextOut(int x, int y, LPSTR t, int color)
+{
+ SetTextColor(hdcCMain, 0x00000000);
+ TextOut(hdcCMain, x+1, y+1, t, strlen(t));
+ SetTextColor(hdcCMain, color);
+ TextOut(hdcCMain, x, y, t, strlen(t));
+}
+
+void ShowControlElements()
+{
+
+ HBITMAP hbmpOld = SelectObject(hdcCMain, hbmpVideoBuf);
+
+ char buf[128];
+
+ SetBkMode(hdcCMain, TRANSPARENT);
+
+ if (TIMER) {
+ wsprintf(buf,"msc: %d", TimeDt);
+ STTextOut(WinEX-70, 10, buf, 0x0020A0A0);
+ wsprintf(buf,"polys: %d", dFacesCount);
+ STTextOut(WinEX-90, 24, buf, 0x0020A0A0);
+ }
+
+ if (MessageList.timeleft) {
+ if (RealTime>MessageList.timeleft) MessageList.timeleft = 0;
+ STTextOut(10, 10, MessageList.mtext, 0x0020A0A0);
+ }
+
+
+ if (ExitTime) {
+ int y = WinH / 3;
+ wsprintf(buf,"Preparing for evacuation...");
+ STTextOut(VideoCX - GetTextW(hdcMain, buf)/2, y, buf, 0x0060C0D0);
+ wsprintf(buf,"%d seconds left.", 1 + ExitTime / 1000);
+ STTextOut(VideoCX - GetTextW(hdcMain, buf)/2, y + 18, buf, 0x0060C0D0);
+ }
+
+ SelectObject(hdcCMain, hbmpOld);
+
+}
+
+
+
+
+void _RenderObject(int x, int y)
+{
+ int ob = OMap[y][x];
+
+ if (!MObjects[ob].model) {
+ //return;
+ wsprintf(logt,"Incorrect model at [%d][%d]!", x, y);
+ DoHalt(logt);
+ }
+
+ int FI = (FMap[y][x] >> 2) & 3;
+ float fi = CameraAlpha + (float)(FI * 2.f*pi / 4.f);
+
+ int mlight;
+ if (MObjects[ob].info.flags & (ofDEFLIGHT+ofGRNDLIGHT) )
+ mlight = MObjects[ob].info.DefLight; else /*
+ if (MObjects[ob].info.flags & ofGRNDLIGHT)
+ {
+ mlight = 128;
+ CalcModelGroundLight(MObjects[ob].model, x*256+128, y*256+128, FI);
+ FI = 0;
+ }
+ else */
+ mlight = -(RandomMap[y & 31][x & 31] >> 5) + (LMap[y][x]>>1) + 96;
+
+ if (mlight >192) mlight =192;
+ if (mlight < 64) mlight = 64;
+
+ v[0].x = x*256+128 - CameraX;
+ v[0].z = y*256+128 - CameraZ;
+ v[0].y = (float)(HMapO[y][x]) * ctHScale - CameraY;
+
+ waterclip = FALSE;
+
+ if (!UNDERWATER)
+ if (FMap[y][x] & fmWaterA)
+ if (HMapO[y][x] < WaterList[ WMap[y][x] ].wlevel) {
+
+ if (WaterList[ WMap[y][x] ].wlevel * ctHScale >
+ HMapO[y][x] * ctHScale + MObjects[ob].info.YHi) return;
+
+ waterclipbase = v[0];
+ waterclipbase.y = WaterList[ WMap[y][x] ].wlevel * ctHScale - CameraY;
+ waterclipbase = RotateVector(waterclipbase);
+ waterclip = TRUE;
+ }
+
+
+ float zs = VectorLength(v[0]);
+
+ if (v[0].y + MObjects[ob].info.YHi < (int)(HMap[y][x]+HMap[y+1][x+1]) / 2 * ctHScale - CameraY) return;
+
+ v[0] = RotateVector(v[0]);
+ GlassL = 0;
+
+ if (zs > 256 * (ctViewR-4))
+ GlassL = min(255, (zs/4 - 64*(ctViewR-4)));
+
+ if (GlassL==255) return;
+
+
+ if (MObjects[ob].info.flags & ofANIMATED)
+ if (MObjects[ob].info.LastAniTime!=RealTime) {
+ MObjects[ob].info.LastAniTime=RealTime;
+ CreateMorphedObject(MObjects[ob].model,
+ MObjects[ob].vtl,
+ RealTime % MObjects[ob].vtl.AniTime);
+ }
+
+
+
+ if (MObjects[ob].info.flags & ofNOBMP) zs = 0;
+ if (zs>ctViewRM*256)
+ RenderBMPModel(&MObjects[ob].bmpmodel, v[0].x, v[0].y, v[0].z, mlight-16);
+ else
+ if (v[0].z<-256*12 && !waterclip)
+ RenderModel(MObjects[ob].model, v[0].x, v[0].y, v[0].z, mlight, FI, fi, CameraBeta);
+ else
+ RenderModelClip(MObjects[ob].model, v[0].x, v[0].y, v[0].z, mlight, FI, fi, CameraBeta);
+
+
+}
+
+
+
+
+void RenderMList()
+{
+ rmlistselector=1-rmlistselector;
+
+ for (int o=0; o<ORLCount[rmlistselector]; o++)
+ _RenderObject(ORList[rmlistselector][o].x,
+ ORList[rmlistselector][o].y);
+ ORLCount[rmlistselector] = 0;
+}
+
+
+
+
+void CreateChRenderList()
+{
+//=========== ship ================//
+ Ship.rpos.x = Ship.pos.x - CameraX;
+ Ship.rpos.y = Ship.pos.y - CameraY;
+ Ship.rpos.z = Ship.pos.z - CameraZ;
+ float r = (float)max( fabs(Ship.rpos.x), fabs(Ship.rpos.z) );
+ int ri = -1 + (int)(r / 256.f + 1.6f);
+
+ if (Ship.State!=-1)
+ if (ri < ctViewR-6) {
+ int h = (int)((Ship.pos.y - GetLandUpH(Ship.pos.x, Ship.pos.z)) / 1.8);
+// AddShadowCircle((int)Ship.pos.x+h, (int)Ship.pos.z+h, 1200, 24);
+ }
+
+
+ if (HARD3D) return;
+ for (int c=0; c<=ctViewR; c++)
+ ChRenderList[c].ICount = 0;
+
+
+//=========== ship ================//
+
+ if (Ship.State==-1) goto NOSHIP;
+ if (ri < 0) ri = 0;
+ if (ri < ctViewR) {
+ Ship.rpos = RotateVector(Ship.rpos);
+ if (Ship.rpos.z > BackViewR) goto NOSHIP;
+ if ( fabs(Ship.rpos.x) > -Ship.rpos.z + BackViewR ) goto NOSHIP;
+
+ int i = ChRenderList[ri].ICount++;
+ ChRenderList[ri].Items[i].CType = 3;
+ }
+NOSHIP: ;
+
+
+//============= Dinosaurs ====================//
+ TCharacter *cptr;
+ for (c=0; c<ChCount; c++) {
+ cptr = &Characters[c];
+ cptr->rpos.x = cptr->pos.x - CameraX;
+ cptr->rpos.y = cptr->pos.y - CameraY;
+ cptr->rpos.z = cptr->pos.z - CameraZ;
+
+ float r = (float)max( fabs(cptr->rpos.x), fabs(cptr->rpos.z) );
+ int ri = -1 + (int)(r / 256.f + 0.5f);
+ if (ri < 0) ri = 0;
+ if (ri > ctViewR) continue;
+
+ cptr->rpos = RotateVector(cptr->rpos);
+
+ float br = BackViewR + DinoInfo[cptr->CType].Radius;
+ if (cptr->rpos.z > br) continue;
+ if ( fabs(cptr->rpos.x) > -cptr->rpos.z + br ) continue;
+ if ( fabs(cptr->rpos.y) > -cptr->rpos.z + br ) continue;
+
+/*
+ if (cptr->rpos.z > BackViewR + ) continue;
+ if ( fabs(cptr->rpos.x) > -cptr->rpos.z + BackViewR ) continue;
+*/
+// AddShadowCircle((int)cptr->pos.x+100, (int)cptr->pos.z+100, 360, 16);
+
+ int i = ChRenderList[ri].ICount++;
+ ChRenderList[ri].Items[i].CType = 0;
+ ChRenderList[ri].Items[i].Index = c;
+ }
+
+
+
+
+}
+
+
+void RenderChList(int r)
+{
+ if (HARD3D) return;
+ for (int c=0; c<ChRenderList[r].ICount; c++) {
+ if (ChRenderList[r].Items[c].CType ==0) RenderCharacter(ChRenderList[r].Items[c].Index); else
+ if (ChRenderList[r].Items[c].CType ==3) RenderShip();
+ }
+}
+
+
+
+
+
+void ProcessWaterMap(int x, int y, int r)
+{
+ //WATERREVERSE = TRUE;
+ ReverseOn = (FMap[y][x] & fmReverse);
+ TDirection = (FMap[y][x] & 3);
+
+ int t1 = TMap1[y][x];
+ int t2 = TMap2[y][x];
+
+ x = x - CCX + 64;
+ y = y - CCY + 64;
+
+ if ((VMap2[y][x].DFlags & VMap2[y][x+1].DFlags & VMap2[y+1][x+1].DFlags & VMap2[y+1][x].DFlags) == 0xFFFF) return;
+
+ if (VMap2[y][x].DFlags!=0xFFFF) ev[0] = VMap2[y][x]; else ev[0] = VMap[y][x];
+ if (VMap2[y][x+1].DFlags!=0xFFFF) ev[1] = VMap2[y][x+1]; else ev[1] = VMap[y][x+1];
+
+ if (ReverseOn)
+ if (VMap2[y+1][x].DFlags!=0xFFFF) ev[2] = VMap2[y+1][x]; else ev[2] = VMap[y+1][x];
+ else
+ if (VMap2[y+1][x+1].DFlags!=0xFFFF) ev[2] = VMap2[y+1][x+1]; else ev[2] = VMap[y+1][x+1];
+
+ lpTextureAddr = &(Textures[0]->DataB[0]);
+ HLineT = (void*) HLineTBGlass25;
+
+ if (!t1)
+ if (r>4) DrawTPlane(FALSE);
+ else DrawTPlaneClip(FALSE);
+
+ if (ReverseOn) {
+ ev[0] = ev[2];
+ if (VMap2[y+1][x+1].DFlags!=0xFFFF) ev[2] = VMap2[y+1][x+1]; else ev[2] = VMap[y+1][x+1];
+ } else {
+ ev[1] = ev[2];
+ if (VMap2[y+1][x].DFlags!=0xFFFF) ev[2] = VMap2[y+1][x]; else ev[2] = VMap[y+1][x];
+ }
+
+
+ if (!t2)
+ if (r>4) DrawTPlane(TRUE);
+ else DrawTPlaneClip(TRUE);
+}
+
+
+
+void RenderElements()
+{
+}
+
+void RenderModelsList()
+{
+}
+
+void RenderWater()
+{
+}
+
+void RenderGround()
+{
+
+ rmlistselector = 0;
+ ORLCount[0] = 0;
+ ORLCount[1] = 0;
+
+
+ for (r=ctViewR; r>=ctViewR1-2; r-=2) {
+ if (r<ctViewR1) LockWater = TRUE;
+ for (int x=r; x>0; x-=2) {
+ ProcessMap2(CCX-x, CCY+r, r);
+ ProcessMap2(CCX+x, CCY+r, r);
+ ProcessMap2(CCX-x, CCY-r, r);
+ ProcessMap2(CCX+x, CCY-r, r);
+ }
+
+ ProcessMap2(CCX, CCY-r, r);
+ ProcessMap2(CCX, CCY+r, r);
+
+ for (int y=r-2; y>0; y-=2) {
+ ProcessMap2(CCX+r, CCY-y, r);
+ ProcessMap2(CCX+r, CCY+y, r);
+ ProcessMap2(CCX-r, CCY+y, r);
+ ProcessMap2(CCX-r, CCY-y, r);
+ }
+ ProcessMap2(CCX-r, CCY, r);
+ ProcessMap2(CCX+r, CCY, r);
+ RenderMList();
+ RenderMList();
+ RenderChList(r);
+ RenderChList(r-1);
+ }
+
+ LockWater = FALSE;
+
+ r = ctViewR1-1;
+ for (int x=r; x>-r; x--) {
+ ProcessMap(CCX+r, CCY+x, r);
+ ProcessMap(CCX+x, CCY+r, r);
+ }
+
+
+ for (r=ctViewR1-2; r>0; r--) {
+
+ for (int x=r; x>0; x--) {
+ ProcessMap(CCX-x, CCY+r, r);
+ ProcessMap(CCX+x, CCY+r, r);
+ ProcessMap(CCX-x, CCY-r, r);
+ ProcessMap(CCX+x, CCY-r, r);
+ }
+
+ ProcessMap(CCX, CCY-r, r);
+ ProcessMap(CCX, CCY+r, r);
+
+ for (int y=r-1; y>0; y--) {
+ ProcessMap(CCX+r, CCY-y, r);
+ ProcessMap(CCX+r, CCY+y, r);
+ ProcessMap(CCX-r, CCY+y, r);
+ ProcessMap(CCX-r, CCY-y, r);
+ }
+ ProcessMap(CCX-r, CCY, r);
+ ProcessMap(CCX+r, CCY, r);
+ RenderMList();
+ RenderChList(r);
+
+ }
+
+ ProcessMap(CCX, CCY, 0);
+ RenderMList();
+ RenderMList();
+ RenderChList(0);
+}
+
+
+
+void RenderObject(int x, int y)
+{
+ if (OMap[y][x]==255) return;
+ if (!MODELS) return;
+ int o = ORLCount[rmlistselector];
+ if (o>2000) return;
+ ORList[rmlistselector][o].x = x;
+ ORList[rmlistselector][o].y = y;
+ ORLCount[rmlistselector]++;
+}
+
+
+
+
+
+
+
+void ProcessMap2(int x, int y, int r)
+{
+ //WATERREVERSE = FALSE;
+ if (x>=ctMapSize-1 || y>=ctMapSize-1 ||
+ x<0 || y<0) return;
+
+ float BackR = BackViewR;
+ if (OMap[y][x]!=255) BackR+=MObjects[OMap[y][x]].info.BoundR;
+
+ ev[0] = VMap[y-CCY+128][x-CCX+128]; if (ev[0].v.z>BackR) return;
+
+
+ int t1 = TMap2[y][x];
+ int hw = WaterList[ WMap[y][x] ].wlevel-1;
+
+ ReverseOn = FALSE;
+ TDirection = ((FMap[y][x]>>8) & 3);
+
+
+ int _x = x;
+ int _y = y;
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap[y][x+2];
+ if (ReverseOn) ev[2] = VMap[y+2][x];
+ else ev[2] = VMap[y+2][x+2];
+
+ float xx = (ev[0].v.x + VMap[y+2][x+2].v.x) / 2;
+ float yy = (ev[0].v.y + VMap[y+2][x+2].v.y) / 2;
+ float zz = (ev[0].v.z + VMap[y+2][x+2].v.z) / 2;
+ int zs;
+
+ if ( fabs(xx) > -zz + BackR) return;
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+ GlassL = 0;
+
+ if (MIPMAP) ts = (int)CameraW * 4 * 128 / zs;
+ else ts = 128;
+
+ if (ts>=128) {
+ lpTextureAddr = &(Textures[t1]->DataA[0]);
+ HLineT = (void*) HLineTxGOURAUD; } else
+ if (ts>=64) {
+ lpTextureAddr = &(Textures[t1]->DataB[0]);
+ HLineT = (void*) HLineTxB; }
+ else {
+ lpTextureAddr = &(Textures[t1]->DataC[0]);
+ HLineT = (void*) HLineTxC;
+ }
+
+ if (zs > 256 * (ctViewR-4)) {
+ GlassL = min(255, (zs/4 - 64*(ctViewR-4)));
+
+ if (GlassL) lpTextureAddr = &(Textures[t1]->SDataC[1]);
+ if (GlassL)
+ if (GlassL>160) HLineT = (void*) HLineTDGlass25; else
+ if (GlassL>80 ) HLineT = (void*) HLineTDGlass50; else
+ HLineT = (void*) HLineTDGlass75;
+ }
+
+
+
+
+ if (!UNDERWATER)
+ if (ReverseOn) {
+ if ( (HMap[_y][_x]<hw) && (HMap[_y][_x+2]<hw) && (HMap[_y+2][_x]<hw) ) goto S1;
+ } else {
+ if ( (HMap[_y][_x]<hw) && (HMap[_y][_x+2]<hw) && (HMap[_y+2][_x+1]<hw) ) goto S1;
+ }
+
+ DrawTPlane(FALSE);
+
+S1:
+
+ if (!UNDERWATER)
+ if (ReverseOn) {
+ if ( (HMap[_y][_x+2]<hw) && (HMap[_y+2][_x+2]<hw) && (HMap[_y+2][_x]<hw) ) goto S2;
+ } else {
+ if ( (HMap[_y][_x]<hw) && (HMap[_y+2][_x+2]<hw) && (HMap[_y+2][_x]<hw) ) goto S2;
+ }
+
+ if (ReverseOn) { ev[0] = ev[2]; ev[2] = VMap[y+2][x+2]; }
+ else { ev[1] = ev[2]; ev[2] = VMap[y+2][x]; }
+
+ DrawTPlane(TRUE);
+S2:
+
+ x = x + CCX - 128;
+ y = y + CCY - 128;
+
+ if (!LockWater) {
+ RenderObject(x , y);
+ RenderObject(x+1, y);
+ RenderObject(x , y+1);
+ RenderObject(x+1, y+1);
+ if (FMap[y][x] & fmWaterA) ProcessMapW2(x,y,r);
+ }
+}
+
+
+
+void ProcessMap(int x, int y, int r)
+{
+ if (x>=ctMapSize-1 || y>=ctMapSize-1 ||
+ x<0 || y<0) return;
+
+ float BackR = BackViewR;
+ if (OMap[y][x]!=255) BackR+=MObjects[OMap[y][x]].info.BoundR;
+ int zs;
+ float xx,yy,zz;
+ int hw = WaterList[ WMap[y][x] ].wlevel;
+
+
+ ev[0] = VMap[y-CCY+128][x-CCX+128]; if (ev[0].v.z>BackR) return;
+
+ BOOL
+ wpr = ((FMap[y ][x ] & fmWaterA) &&
+ (FMap[y ][x+1] & fmWaterA) &&
+ (FMap[y+1][x ] & fmWaterA) &&
+ (FMap[y+1][x+1] & fmWaterA) );
+
+
+
+ int ob = OMap[y][x];
+ if (!MODELS) ob=255;
+
+ int t1 = TMap1[y][x];
+ ReverseOn = (FMap[y][x] & fmReverse);
+ TDirection = (FMap[y][x] & 3);
+
+ int _x = x;
+ int _y = y;
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+
+
+ ev[1] = VMap[y][x+1];
+ if (ReverseOn) ev[2] = VMap[y+1][x];
+ else ev[2] = VMap[y+1][x+1];
+
+ xx = (ev[0].v.x + VMap[y+1][x+1].v.x) / 2;
+ yy = (ev[0].v.y + VMap[y+1][x+1].v.y) / 2;
+ zz = (ev[0].v.z + VMap[y+1][x+1].v.z) / 2;
+
+
+ if ( fabs(xx) > -zz + BackR) return;
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+
+ GlassL = 0;
+
+
+ if (MIPMAP) ts = (int)CameraW * 4 * 128 / zs;
+ else ts = 128;
+
+ if (ts>=128) {
+ lpTextureAddr = &(Textures[t1]->DataA[0]);
+ HLineT = (void*) HLineTxGOURAUD; } else
+ if (ts>=64) {
+ lpTextureAddr = &(Textures[t1]->DataB[0]);
+ HLineT = (void*) HLineTxB; }
+ else {
+ lpTextureAddr = &(Textures[t1]->DataC[0]);
+ HLineT = (void*) HLineTxC;
+ }
+
+ if (!UNDERWATER)
+ if (wpr)
+ if (ReverseOn) {
+ if ( (HMap[_y][_x]<hw) || (HMap[_y][_x+1]<hw) || (HMap[_y+1][_x]<hw) ) goto S1;
+ } else {
+ if ( (HMap[_y][_x]<hw) || (HMap[_y][_x+1]<hw) || (HMap[_y+1][_x+1]<hw) ) goto S1;
+ }
+
+
+ if (r>6) DrawTPlane(FALSE);
+ else DrawTPlaneClip(FALSE);
+S1:
+ if (ReverseOn) { ev[0] = ev[2]; ev[2] = VMap[y+1][x+1]; }
+ else { ev[1] = ev[2]; ev[2] = VMap[y+1][x]; }
+
+ if (!UNDERWATER)
+ if (wpr)
+ if (ReverseOn) {
+ if ( (HMap[_y][_x+1]<hw) || (HMap[_y+1][_x+1]<hw) || (HMap[_y+1][_x]<hw) ) goto S2;
+ } else {
+ if ( (HMap[_y][_x]<hw) || (HMap[_y+1][_x+1]<hw) || (HMap[_y+1][_x]<hw) ) goto S2;
+ }
+
+ if (r>6) DrawTPlane(TRUE);
+ else DrawTPlaneClip(TRUE);
+S2:
+ x = x + CCX - 128;
+ y = y + CCY - 128;
+
+SKIP:
+
+ RenderObject(x, y);
+
+ if (wpr) ProcessMapW(x,y,r);
+
+}
+
+
+
+
+
+
+void ProcessMapW(int x, int y, int r)
+{
+ if (RunMode) return;
+
+
+ if (x>=ctMapSize-1 || y>=ctMapSize-1 || x<0 || y<0) return;
+
+ int t1 = WaterList[ WMap[y][x] ].tindex;
+ int hw = WaterList[ WMap[y][x] ].wlevel;
+
+ ev[0] = VMap2[y-CCY+128][x-CCX+128];
+ if (ev[0].v.z>BackViewR) return;
+
+
+ ReverseOn = (FMap[y][x] & fmReverse);
+ TDirection = 0;
+// if ( (HMap[y][x]>hw) || (HMap[y+1][x+1]>hw) ) ReverseOn = TRUE;
+
+
+
+ int _x = x;
+ int _y = y;
+
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap2[y][x+1];
+ if (ReverseOn) ev[2] = VMap2[y+1][x];
+ else ev[2] = VMap2[y+1][x+1];
+
+ float xx = (ev[0].v.x + VMap2[y+1][x+1].v.x) / 2;
+ float yy = (ev[0].v.y + VMap2[y+1][x+1].v.y) / 2;
+ float zz = (ev[0].v.z + VMap2[y+1][x+1].v.z) / 2;
+
+ int zs;
+
+ if ( fabs(xx*FOVK) > -zz + BackViewR) return;
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+
+ GlassL = 0;
+
+ if (MIPMAP) ts = (int)CameraW * 4 * 128 / zs;
+ else ts = 128;
+
+ ts = 128;
+
+ if (ts>=128) {
+ lpTextureAddr = &(Textures[t1]->DataA[0]);
+ HLineT = (void*) HLineTxGOURAUD; } else
+ if (ts>=64) {
+ lpTextureAddr = &(Textures[t1]->DataB[0]);
+ HLineT = (void*) HLineTxB;
+ }
+ else {
+ lpTextureAddr = &(Textures[t1]->DataC[0]);
+ HLineT = (void*) HLineTxC;
+ }
+
+ if (UNDERWATER) {
+ lpTextureAddr = &(Textures[t1]->DataB[0]);
+ HLineT = (void*) HLineTBGlass25;
+ }
+
+ WATERREVERSE = UNDERWATER;
+
+ if (ReverseOn) {
+ if ( (HMap[_y][_x]>hw) || (HMap[_y][_x+1]>hw) || (HMap[_y+1][_x]>hw) ) goto S1;
+ } else {
+ if ( (HMap[_y][_x]>hw) || (HMap[_y][_x+1]>hw) || (HMap[_y+1][_x+1]>hw) ) goto S1;
+ }
+
+ if (r>6) DrawTPlane(FALSE);
+ else DrawTPlaneClip(FALSE);
+S1:
+ if (ReverseOn) { ev[0] = ev[2]; ev[2] = VMap2[y+1][x+1]; }
+ else { ev[1] = ev[2]; ev[2] = VMap2[y+1][x]; }
+
+ if (ReverseOn) {
+ if ( (HMap[_y][_x+1]>hw) || (HMap[_y+1][_x+1]>hw) || (HMap[_y+1][_x]>hw) ) goto S2;
+ } else {
+ if ( (HMap[_y][_x]>hw) || (HMap[_y+1][_x+1]>hw) || (HMap[_y+1][_x]>hw) ) goto S2;
+ }
+
+ if (r>6) DrawTPlane(TRUE);
+ else DrawTPlaneClip(TRUE);
+S2:
+ WATERREVERSE = FALSE;
+}
+
+
+
+void ProcessMapW2(int x, int y, int r)
+{
+ if (RunMode) return;
+ if (!( (FMap[y ][x ] & fmWaterA) &&
+ (FMap[y ][x+2] & fmWaterA) &&
+ (FMap[y+2][x ] & fmWaterA) &&
+ (FMap[y+2][x+2] & fmWaterA) )) return;
+
+ if (x>=ctMapSize-1 || y>=ctMapSize-1 || x<0 || y<0) return;
+
+ int t1 = WaterList[ WMap[y][x] ].tindex;
+ int hw = WaterList[ WMap[y][x] ].wlevel;
+
+ ev[0] = VMap2[y-CCY+128][x-CCX+128];
+ if (ev[0].v.z>BackViewR) return;
+
+
+// ReverseOn = (FMap[y][x] & fmReverse);
+ TDirection = 0;
+ if ( (HMap[y][x]>hw) || (HMap[y+2][x+2]>hw) ) ReverseOn = TRUE;
+
+
+ int _x = x;
+ int _y = y;
+
+ x = x - CCX + 128;
+ y = y - CCY + 128;
+ ev[1] = VMap2[y][x+2];
+ if (ReverseOn) ev[2] = VMap2[y+2][x];
+ else ev[2] = VMap2[y+2][x+2];
+
+ float xx = (ev[0].v.x + VMap2[y+1][x+2].v.x) / 2;
+ float yy = (ev[0].v.y + VMap2[y+1][x+2].v.y) / 2;
+ float zz = (ev[0].v.z + VMap2[y+1][x+2].v.z) / 2;
+
+ int zs;
+
+ if ( fabs(xx*FOVK) > -zz + BackViewR) return;
+
+ zs = (int)sqrt( xx*xx + zz*zz + yy*yy);
+ if (zs > ctViewR*256) return;
+
+
+ GlassL = 0;
+
+ if (MIPMAP) ts = (int)CameraW * 4 * 128 / zs;
+ else ts = 128;
+
+
+ if (UNDERWATER) {
+ lpTextureAddr = &(Textures[t1]->DataB[0]);
+ HLineT = (void*) HLineTBGlass25;
+ } else {
+ lpTextureAddr = &(Textures[t1]->DataC[0]);
+ HLineT = (void*) HLineTxC;
+ }
+
+
+ WATERREVERSE = UNDERWATER;
+
+ if (ReverseOn) {
+ if ( (HMap[_y][_x]>hw) && (HMap[_y][_x+2]>hw) && (HMap[_y+2][_x]>hw) ) goto S1;
+ } else {
+ if ( (HMap[_y][_x]>hw) && (HMap[_y][_x+2]>hw) && (HMap[_y+2][_x+2]>hw) ) goto S1;
+ }
+
+ if (r>6) DrawTPlane(FALSE);
+ else DrawTPlaneClip(FALSE);
+S1:
+ if (ReverseOn) { ev[0] = ev[2]; ev[2] = VMap2[y+2][x+2]; }
+ else { ev[1] = ev[2]; ev[2] = VMap2[y+2][x]; }
+
+ if (ReverseOn) {
+ if ( (HMap[_y][_x+2]>hw) && (HMap[_y+2][_x+2]>hw) && (HMap[_y+2][_x]>hw) ) goto S2;
+ } else {
+ if ( (HMap[_y][_x]>hw) && (HMap[_y+2][_x+2]>hw) && (HMap[_y+2][_x]>hw) ) goto S2;
+ }
+
+ if (r>6) DrawTPlane(TRUE);
+ else DrawTPlaneClip(TRUE);
+S2:
+ WATERREVERSE = FALSE;
+}
+
+
+
+
+
+
+
+#include "RenderASM.cpp"
+
+
+
+void ClipVector(CLIPPLANE& C, int vn)
+{
+ int ClipRes = 0;
+ float s,s1,s2;
+ int vleft = (vn-1); if (vleft <0) vleft=vused-1;
+ int vright = (vn+1); if (vright>=vused) vright=0;
+
+ MulVectorsScal(cp[vn].ev.v, C.nv, s); /*s=SGN(s-0.01f);*/
+ if (s>=0) return;
+
+ MulVectorsScal(cp[vleft ].ev.v, C.nv, s1); /* s1=SGN(s1+0.01f); */ //s1+=0.001f;
+ MulVectorsScal(cp[vright].ev.v, C.nv, s2); /* s2=SGN(s2+0.01f); */ //s2+=0.001f;
+
+ if (s1>0) {
+ ClipRes+=1;
+
+ /*
+ CalcHitPoint(C,cp[vn].ev.v,
+ cp[vleft].ev.v, hleft.ev.v);
+
+ float ll = VectorLength(SubVectors(cp[vleft].ev.v, cp[vn].ev.v));
+ float lc = VectorLength(SubVectors(hleft.ev.v, cp[vn].ev.v));
+ lc = lc / ll;
+ */
+
+
+ float lc = -s / (s1-s);
+ hleft.ev.v.x = cp[vn].ev.v.x + ((cp[vleft].ev.v.x - cp[vn].ev.v.x) * lc);
+ hleft.ev.v.y = cp[vn].ev.v.y + ((cp[vleft].ev.v.y - cp[vn].ev.v.y) * lc);
+ hleft.ev.v.z = cp[vn].ev.v.z + ((cp[vleft].ev.v.z - cp[vn].ev.v.z) * lc);
+
+ hleft.tx = cp[vn].tx + (int)((cp[vleft].tx - cp[vn].tx) * lc);
+ hleft.ty = cp[vn].ty + (int)((cp[vleft].ty - cp[vn].ty) * lc);
+ hleft.ev.Light = cp[vn].ev.Light + (int)((cp[vleft].ev.Light - cp[vn].ev.Light) * lc);
+ }
+
+ if (s2>0) {
+ ClipRes+=2;
+ /*
+ CalcHitPoint(C,cp[vn].ev.v,
+ cp[vright].ev.v, hright.ev.v);
+
+ float ll = VectorLength(SubVectors(cp[vright].ev.v, cp[vn].ev.v));
+ float lc = VectorLength(SubVectors(hright.ev.v, cp[vn].ev.v));
+ lc = lc / ll;
+ */
+
+ float lc = -s / (s2-s);
+ hright.ev.v.x = cp[vn].ev.v.x + ((cp[vright].ev.v.x - cp[vn].ev.v.x) * lc);
+ hright.ev.v.y = cp[vn].ev.v.y + ((cp[vright].ev.v.y - cp[vn].ev.v.y) * lc);
+ hright.ev.v.z = cp[vn].ev.v.z + ((cp[vright].ev.v.z - cp[vn].ev.v.z) * lc);
+
+ hright.tx = cp[vn].tx + (int)((cp[vright].tx - cp[vn].tx) * lc);
+ hright.ty = cp[vn].ty + (int)((cp[vright].ty - cp[vn].ty) * lc);
+ hright.ev.Light = cp[vn].ev.Light + (int)((cp[vright].ev.Light - cp[vn].ev.Light) * lc);
+ }
+
+ if (ClipRes == 0) {
+ u--; vused--;
+ cp[vn] = cp[vn+1];
+ cp[vn+1] = cp[vn+2];
+ cp[vn+2] = cp[vn+3];
+ cp[vn+3] = cp[vn+4];
+ cp[vn+4] = cp[vn+5];
+ cp[vn+5] = cp[vn+6];
+ //memcpy(&cp[vn], &cp[vn+1], (15-vn)*sizeof(ClipPoint));
+ }
+ if (ClipRes == 1) {cp[vn] = hleft; }
+ if (ClipRes == 2) {cp[vn] = hright;}
+ if (ClipRes == 3) {
+ u++; vused++;
+ //memcpy(&cp[vn+1], &cp[vn], (15-vn)*sizeof(ClipPoint));
+ cp[vn+6] = cp[vn+5];
+ cp[vn+5] = cp[vn+4];
+ cp[vn+4] = cp[vn+3];
+ cp[vn+3] = cp[vn+2];
+ cp[vn+2] = cp[vn+1];
+ cp[vn+1] = cp[vn];
+
+ cp[vn] = hleft;
+ cp[vn+1] = hright;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+int SGNi(int f)
+{
+ if (f<0) return -1;
+ else return 1;
+}
+
+
+void DrawTPlaneClip(BOOL SECONT)
+{
+ int n;
+
+ if (!WATERREVERSE) {
+ MulVectorsVect(SubVectors(ev[1].v, ev[0].v), SubVectors(ev[2].v, ev[0].v), nv);
+ if (nv.x*ev[0].v.x + nv.y*ev[0].v.y + nv.z*ev[0].v.z<0) return;
+ }
+
+ cp[0].ev = ev[0]; cp[1].ev = ev[1]; cp[2].ev = ev[2];
+
+ if (ReverseOn)
+ if (SECONT) {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ }
+ }
+ else
+ if (SECONT) {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ break;
+ case 1:
+ cp[0].tx = TCMIN; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMIN;
+ break;
+ case 2:
+ cp[0].tx = TCMAX; cp[0].ty = TCMAX;
+ cp[1].tx = TCMIN; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMIN;
+ break;
+ case 3:
+ cp[0].tx = TCMAX; cp[0].ty = TCMIN;
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ break;
+ }
+ }
+
+/*
+ cp[0].tx = TCMIN; cp[0].ty = TCMIN;
+
+ if (SECONT) {
+ cp[1].tx = TCMAX; cp[1].ty = TCMAX;
+ cp[2].tx = TCMIN; cp[2].ty = TCMAX;
+ } else {
+ cp[1].tx = TCMAX; cp[1].ty = TCMIN;
+ cp[2].tx = TCMAX; cp[2].ty = TCMAX;
+ }*/
+
+ vused = 3;
+
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) return;
+
+ for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) return;
+ for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) return;
+
+ //float dy = -1.1f;
+
+ //if (WATERREVERSE) dy = 0;
+ for (u=0; u<vused; u++) {
+ cp[u].ev.scrx = VideoCX - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW);
+ cp[u].ev.scry = VideoCY + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH);
+ }
+
+
+
+ scrp[0].x = cp[0].ev.scrx;
+ scrp[0].y = cp[0].ev.scry;
+ scrp[0].Light = cp[0].ev.Light/4;
+ scrp[0].tx = cp[0].tx;
+ scrp[0].ty = cp[0].ty;
+ scrp[0].z = (int)cp[0].ev.v.z;
+
+ for (u=0; u<vused-2; u++) {
+ for (n=1; n<3; n++) {
+ scrp[n].x = cp[n+u].ev.scrx;
+ scrp[n].y = cp[n+u].ev.scry;
+ scrp[n].Light = cp[n+u].ev.Light/4;
+ scrp[n].tx = cp[n+u].tx;
+ scrp[n].ty = cp[n+u].ty;
+ scrp[n].z = (int)cp[n+u].ev.v.z;
+ }
+ if (CORRECTION) DrawCorrectedTexturedFace();
+ else DrawTexturedFace();
+ }
+}
+
+
+
+void DrawTPlane(BOOL SECONT)
+{
+ int n;
+
+ if (!WATERREVERSE)
+ if ((ev[1].scrx-ev[0].scrx)*(ev[2].scry-ev[0].scry) -
+ (ev[1].scry-ev[0].scry)*(ev[2].scrx-ev[0].scrx) < 0) return;
+
+ Mask1=0x007F;
+ for (n=0; n<3; n++) {
+ if (ev[n].DFlags & 128) return;
+ Mask1=Mask1 & ev[n].DFlags; }
+ if (Mask1>0) return;
+
+ for (n=0; n<3; n++) {
+ scrp[n].x = ev[n].scrx;
+ scrp[n].y = ev[n].scry;
+ scrp[n].Light = ev[n].Light / 4;
+ }
+
+ if (ReverseOn)
+ if (SECONT) {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ }
+ }
+ else
+ if (SECONT) {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ }
+ } else {
+ switch (TDirection) {
+ case 0:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMAX;
+ break;
+ case 1:
+ scrp[0].tx = TCMIN; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMIN;
+ scrp[2].tx = TCMAX; scrp[2].ty = TCMIN;
+ break;
+ case 2:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMAX;
+ scrp[1].tx = TCMIN; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMIN;
+ break;
+ case 3:
+ scrp[0].tx = TCMAX; scrp[0].ty = TCMIN;
+ scrp[1].tx = TCMAX; scrp[1].ty = TCMAX;
+ scrp[2].tx = TCMIN; scrp[2].ty = TCMAX;
+ break;
+ }
+ }
+
+ DrawTexturedFace();
+}
+
+
+
+
+
+
+
+
+void BuildTree()
+{
+ Vector2di v[3];
+ Current = -1;
+ TFace* fptr;
+ int sg;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+ v[0] = gScrp[fptr->v1];
+ v[1] = gScrp[fptr->v2];
+ v[2] = gScrp[fptr->v3];
+
+ if (v[0].x == 0xFFFFFF) continue;
+ if (v[1].x == 0xFFFFFF) continue;
+ if (v[2].x == 0xFFFFFF) continue;
+
+ //fptr->Flags &= 0x00FF;
+
+ if (fptr->Flags & (sfDarkBack + sfNeedVC) ) {
+ sg = (v[1].x-v[0].x)*(v[2].y-v[1].y) - (v[1].y-v[0].y)*(v[2].x-v[1].x);
+ if (sg<0) continue;
+/*
+ if (fptr->Flags & sfNeedVC) { if (sg<0) continue; }
+ else if (sg<0) fptr->Flags |= sfDark; */
+ }
+
+ //if (NODARKBACK) fptr->Flags &= 0x00FF;
+
+ fptr->Distant = (int)(-(rVertex[fptr->v1].z + rVertex[fptr->v2].z + rVertex[fptr->v3].z));
+ fptr->Next=-1;
+ if (Current==-1) Current=f; else
+ if (mptr->gFace[Current].Distant < fptr->Distant)
+ { fptr->Next=Current; Current=f; } else {
+ int n=Current;
+ while (mptr->gFace[n].Next!=-1 && mptr->gFace[mptr->gFace[n].Next].Distant > fptr->Distant)
+ n=mptr->gFace[n].Next;
+ fptr->Next = mptr->gFace[n].Next;
+ mptr->gFace[n].Next = f; }
+ }
+}
+
+void BuildTreeNoSort()
+{
+ Vector2di v[3];
+ Current = -1;
+ int LastFace = -1;
+ TFace* fptr;
+ int sg;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+ v[0] = gScrp[fptr->v1];
+ v[1] = gScrp[fptr->v2];
+ v[2] = gScrp[fptr->v3];
+
+ if (v[0].x == 0xFFFFFF) continue;
+ if (v[1].x == 0xFFFFFF) continue;
+ if (v[2].x == 0xFFFFFF) continue;
+
+ if (fptr->Flags & (sfDarkBack+sfNeedVC)) {
+ sg = (v[1].x-v[0].x)*(v[2].y-v[1].y) - (v[1].y-v[0].y)*(v[2].x-v[1].x);
+ if (sg<0) continue;
+ }
+
+ fptr->Next=-1;
+ if (Current==-1) { Current=f; LastFace = f; } else
+ { mptr->gFace[LastFace].Next=f; LastFace=f; }
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void BuildTreeClip()
+{
+ Current = -1;
+ TFace* fptr;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+
+ if (fptr->Flags & (sfDarkBack + sfNeedVC) ) {
+ MulVectorsVect(SubVectors(rVertex[fptr->v2], rVertex[fptr->v1]), SubVectors(rVertex[fptr->v3], rVertex[fptr->v1]), nv);
+ if (nv.x*rVertex[fptr->v1].x + nv.y*rVertex[fptr->v1].y + nv.z*rVertex[fptr->v1].z<0) continue;
+ }
+
+ fptr->Distant = (int)(-(rVertex[fptr->v1].z + rVertex[fptr->v2].z + rVertex[fptr->v3].z));
+ fptr->Next=-1;
+ if (Current==-1) Current=f; else
+ if (mptr->gFace[Current].Distant < fptr->Distant)
+ { fptr->Next=Current; Current=f; } else {
+ int n=Current;
+ while (mptr->gFace[n].Next!=-1 && mptr->gFace[mptr->gFace[n].Next].Distant > fptr->Distant)
+ n=mptr->gFace[n].Next;
+ fptr->Next = mptr->gFace[n].Next;
+ mptr->gFace[n].Next = f; }
+ }
+}
+
+
+
+void BuildTreeClipNoSort()
+{
+ Current = -1;
+ int LastFace = -1;
+ TFace* fptr;
+
+ for (int f=0; f<mptr->FCount; f++)
+ {
+ fptr = &mptr->gFace[f];
+
+ if (fptr->Flags & (sfDarkBack + sfNeedVC) ) {
+ MulVectorsVect(SubVectors(rVertex[fptr->v2], rVertex[fptr->v1]), SubVectors(rVertex[fptr->v3], rVertex[fptr->v1]), nv);
+ if (nv.x*rVertex[fptr->v1].x + nv.y*rVertex[fptr->v1].y + nv.z*rVertex[fptr->v1].z<0) continue;
+ }
+
+ fptr->Next=-1;
+ if (Current==-1) { Current=f; LastFace = f; } else
+ { mptr->gFace[LastFace].Next=f; LastFace=f; }
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void RenderModelClip(TModel* _mptr, float x0, float y0, float z0, int light, int VT, float al, float bt)
+{
+ int f,CMASK;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+
+
+ __asm {
+ mov eax,light
+ shr eax,2
+ shl eax,16
+ add eax, offset FadeTab
+ mov iModelFade,eax
+ mov iModelBaseFade,eax
+ }
+
+
+ HLineT = (void*) HLineTxModel;
+ lpTextureAddr = (void*) mptr->lpTexture;
+
+ BOOL BL = FALSE;
+ for (int s=0; s<mptr->VCount; s++) {
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) + x0;
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) + z0;
+ if (rVertex[s].z<0) BL=TRUE;
+
+ if (rVertex[s].z>-64) { gScrp[s].x = 0xFFFFFF; gScrp[s].y = 0xFF; }
+ else {
+ int f = 0;
+ int sx = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ int sy = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+
+ if (sx<=0 ) f+=2;
+ if (sx>=WinEX) f+=1;
+ if (sy>=WinEY) f+=4;
+ if (sy<=0 ) f+=8;
+
+
+ if (f) { gScrp[s].x = 0xFFFFFF; gScrp[s].y = f; }
+ else { gScrp[s].x = sx; gScrp[s].y = sy; }
+ }
+
+ }
+
+ if (!BL) return;
+
+ BuildTreeClip();
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+
+//======== if face fully on screen NO 3D CLIPPING ====================/
+ if (!waterclip)
+ if (gScrp[fptr->v1].x != 0xFFFFFF && gScrp[fptr->v2].x != 0xFFFFFF && gScrp[fptr->v3].x != 0xFFFFFF )
+ {
+ mscrp[0].x = gScrp[fptr->v1].x; mscrp[0].y = gScrp[fptr->v1].y;
+ mscrp[0].tx = fptr->tax; mscrp[0].ty = fptr->tay;
+
+ mscrp[1].x = gScrp[fptr->v2].x; mscrp[1].y = gScrp[fptr->v2].y;
+ mscrp[1].tx = fptr->tbx; mscrp[1].ty = fptr->tby;
+
+ mscrp[2].x = gScrp[fptr->v3].x; mscrp[2].y = gScrp[fptr->v3].y;
+ mscrp[2].tx = fptr->tcx; mscrp[2].ty = fptr->tcy;
+
+ OpacityMode = (fptr->Flags & (sfOpacity + sfTransparent));
+ if (fptr->Flags & sfDark)
+ iModelFade = iModelBaseFade + 12*256*256;
+ else iModelFade = iModelBaseFade;
+
+ DrawModelFace();
+ goto LNEXT;
+ }
+
+
+ CMASK = 0;
+ if (gScrp[fptr->v1].x == 0xFFFFFF) CMASK|=gScrp[fptr->v1].y;
+ if (gScrp[fptr->v2].x == 0xFFFFFF) CMASK|=gScrp[fptr->v2].y;
+ if (gScrp[fptr->v3].x == 0xFFFFFF) CMASK|=gScrp[fptr->v3].y;
+// CMASK = 0xFF;
+
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].tx = fptr->tax; cp[0].ty = fptr->tay;
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].tx = fptr->tbx; cp[1].ty = fptr->tby;
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].tx = fptr->tcx; cp[2].ty = fptr->tcy;
+
+ if (CMASK == 0xFF) {
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) goto LNEXT;
+ }
+
+ if (waterclip) {
+ for (u=0; u<vused; u++) { cp[u].ev.v.x-=waterclipbase.x; cp[u].ev.v.y-=waterclipbase.y; cp[u].ev.v.z-=waterclipbase.z; }
+ for (u=0; u<vused; u++) ClipVector(ClipW,u);
+ for (u=0; u<vused; u++) { cp[u].ev.v.x+=waterclipbase.x; cp[u].ev.v.y+=waterclipbase.y; cp[u].ev.v.z+=waterclipbase.z; }
+ if (vused<3) goto LNEXT;
+ }
+
+ if (CMASK & 1) for (u=0; u<vused; u++) ClipVector(ClipA,u); if (vused<3) goto LNEXT;
+ if (CMASK & 2) for (u=0; u<vused; u++) ClipVector(ClipC,u); if (vused<3) goto LNEXT;
+
+ if (CMASK & 4) for (u=0; u<vused; u++) ClipVector(ClipB,u); if (vused<3) goto LNEXT;
+ if (CMASK & 8) for (u=0; u<vused; u++) ClipVector(ClipD,u); if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) {
+ cp[u].ev.scrx = VideoCX - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW);
+ cp[u].ev.scry = VideoCY + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH);
+ }
+
+ mscrp[0].x = cp[0].ev.scrx;
+ mscrp[0].y = cp[0].ev.scry;
+ mscrp[0].tx = cp[0].tx;
+ mscrp[0].ty = cp[0].ty;
+
+ OpacityMode = (fptr->Flags & (sfOpacity + sfTransparent));
+
+ for (u=0; u<vused-2; u++) {
+ for (int n=1; n<3; n++) {
+ mscrp[n].x = cp[n+u].ev.scrx;
+ mscrp[n].y = cp[n+u].ev.scry;
+ mscrp[n].tx = cp[n+u].tx;
+ mscrp[n].ty = cp[n+u].ty; }
+
+ DrawModelFace();
+ }
+LNEXT:
+ f = mptr->gFace[f].Next;
+ }
+}
+
+
+
+
+
+void RenderModelClipWater(TModel* _mptr, float x0, float y0, float z0, int light, int VT, float al, float bt)
+{
+ int f;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+
+
+ __asm {
+ mov eax,light
+ shr eax,2
+ shl eax,16
+ add eax, offset FadeTab
+ mov iModelFade,eax
+ mov iModelBaseFade,eax
+ }
+
+
+//=================== select mipmap & glass =============================//
+
+ if (!GlassL) HLineT = (void*) HLineTxModel; else
+ if (GlassL>160) HLineT = (void*) HLineTxModel25; else
+ if (GlassL>80 ) HLineT = (void*) HLineTxModel50; else
+ HLineT = (void*) HLineTxModel75;
+
+ lpTextureAddr = (void*) mptr->lpTexture;
+
+ if (GlassL) lpTextureAddr = (void*) mptr->lpTexture3;
+ else
+ if (ts <=64)
+ if (ts > 32) {
+ lpTextureAddr = (void*) mptr->lpTexture2;
+ HLineT = (void*) HLineTxModel2;
+ } else {
+ lpTextureAddr = (void*) mptr->lpTexture3;
+ HLineT = (void*) HLineTxModel3;
+ }
+
+
+
+ BOOL BL = FALSE;
+ float sg;
+ for (int s=0; s<mptr->VCount; s++) {
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) + x0;
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) + z0;
+
+ v[0] = SubVectors(rVertex[s], waterclipbase);
+ MulVectorsScal(v[0], ClipW.nv, sg);
+ if (sg>=0) gScrp[s].x = 0; else gScrp[s].x=1;
+
+ if (rVertex[s].z<0) BL=TRUE;
+ }
+
+ if (!BL) return;
+
+ if (fabs(z0) + fabs(x0)>256*10)
+ BuildTreeClipNoSort(); else BuildTreeClip();
+
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+ if (rVertex[fptr->v1].z > -128) goto LNEXT;
+ if (rVertex[fptr->v2].z > -128) goto LNEXT;
+ if (rVertex[fptr->v3].z > -128) goto LNEXT;
+
+ if (gScrp[fptr->v1].x & gScrp[fptr->v2].x & gScrp[fptr->v3].x) goto LNEXT;
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].tx = fptr->tax; cp[0].ty = fptr->tay;
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].tx = fptr->tbx; cp[1].ty = fptr->tby;
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].tx = fptr->tcx; cp[2].ty = fptr->tcy;
+
+ if (!(gScrp[fptr->v1].x | gScrp[fptr->v2].x | gScrp[fptr->v3].x)) goto LNOCLIP;
+
+ for (u=0; u<vused; u++) { cp[u].ev.v.x-=waterclipbase.x; cp[u].ev.v.y-=waterclipbase.y; cp[u].ev.v.z-=waterclipbase.z; }
+ for (u=0; u<vused; u++) ClipVector(ClipW,u);
+ for (u=0; u<vused; u++) { cp[u].ev.v.x+=waterclipbase.x; cp[u].ev.v.y+=waterclipbase.y; cp[u].ev.v.z+=waterclipbase.z; }
+ if (vused<3) goto LNEXT;
+
+LNOCLIP:
+ for (u=0; u<vused; u++) {
+ cp[u].ev.scrx = VideoCX - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW);
+ cp[u].ev.scry = VideoCY + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH);
+ }
+
+ mscrp[0].x = cp[0].ev.scrx;
+ mscrp[0].y = cp[0].ev.scry;
+ mscrp[0].tx = cp[0].tx;
+ mscrp[0].ty = cp[0].ty;
+
+ OpacityMode = (fptr->Flags & (sfOpacity + sfTransparent));
+
+ for (u=0; u<vused-2; u++) {
+ for (int n=1; n<3; n++) {
+ mscrp[n].x = cp[n+u].ev.scrx;
+ mscrp[n].y = cp[n+u].ev.scry;
+ mscrp[n].tx = cp[n+u].tx;
+ mscrp[n].ty = cp[n+u].ty; }
+
+ DrawModelFace();
+ }
+LNEXT:
+ f = mptr->gFace[f].Next;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+void RenderModel(TModel* _mptr, float x0, float y0, float z0, int light, int VT, float al, float bt)
+{
+ int f;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+ int minx = 10241024;
+ int maxx =-10241024;
+ int miny = 10241024;
+ int maxy =-10241024;
+
+
+
+ __asm {
+ mov eax,light
+ shr eax,2
+ shl eax,16
+ add eax, offset FadeTab
+ mov iModelFade,eax
+ mov iModelBaseFade,eax
+ }
+
+ if (!GlassL) HLineT = (void*) HLineTxModel; else
+ if (GlassL>160) HLineT = (void*) HLineTxModel25; else
+ if (GlassL>80 ) HLineT = (void*) HLineTxModel50; else
+ HLineT = (void*) HLineTxModel75;
+
+ lpTextureAddr = (void*) mptr->lpTexture;
+
+ if (GlassL) lpTextureAddr = (void*) mptr->lpTexture3;
+ else
+ if (ts <=64)
+ if (ts > 32) {
+ lpTextureAddr = (void*) mptr->lpTexture2;
+ HLineT = (void*) HLineTxModel2;
+ } else {
+ lpTextureAddr = (void*) mptr->lpTexture3;
+ HLineT = (void*) HLineTxModel3;
+ }
+
+
+
+
+ for (int s=0; s<mptr->VCount; s++) {
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) + x0;
+
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) + z0;
+
+ if (rVertex[s].z>-64) gScrp[s].x = 0xFFFFFF; else {
+ gScrp[s].x = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ gScrp[s].y = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH); }
+
+ if (gScrp[s].x > maxx) maxx = gScrp[s].x;
+ if (gScrp[s].x < minx) minx = gScrp[s].x;
+ if (gScrp[s].y > maxy) maxy = gScrp[s].y;
+ if (gScrp[s].y < miny) miny = gScrp[s].y;
+ }
+
+ if (minx == 10241024) return;
+ if (minx>WinW || maxx<0 || miny>WinH || maxy<0) return;
+
+ if (fabs(z0) + fabs(x0)>256*10)
+ BuildTreeNoSort(); else BuildTree();
+
+
+ if (Current != -1) DrawModelFaces();
+ return;
+
+ f = Current;
+ while( f!=-1 ) {
+ mscrp[0].x = gScrp[mptr->gFace[f].v1].x;
+ mscrp[0].y = gScrp[mptr->gFace[f].v1].y;
+ mscrp[0].tx = mptr->gFace[f].tax;
+ mscrp[0].ty = mptr->gFace[f].tay;
+
+ mscrp[1].x = gScrp[mptr->gFace[f].v2].x;
+ mscrp[1].y = gScrp[mptr->gFace[f].v2].y;
+ mscrp[1].tx = mptr->gFace[f].tbx;
+ mscrp[1].ty = mptr->gFace[f].tby;
+
+ mscrp[2].x = gScrp[mptr->gFace[f].v3].x;
+ mscrp[2].y = gScrp[mptr->gFace[f].v3].y;
+ mscrp[2].tx = mptr->gFace[f].tcx;
+ mscrp[2].ty = mptr->gFace[f].tcy;
+
+ OpacityMode = (mptr->gFace[f].Flags & (sfOpacity + sfTransparent));
+ if (mptr->gFace[f].Flags & sfDark)
+ iModelFade = iModelBaseFade + 12*256*256;
+ else iModelFade = iModelBaseFade;
+
+ DrawModelFace();
+ f = mptr->gFace[f].Next;
+ }
+}
+
+
+
+
+void RenderBMPModel(TBMPModel* _mptr, float x0, float y0, float z0, int light)
+{
+ int f;
+
+ TBMPModel *mptr = _mptr;
+
+
+ int minx = 10241024;
+ int maxx =-10241024;
+ int miny = 10241024;
+ int maxy =-10241024;
+
+ __asm {
+ mov eax,light
+ shr eax,2
+ shl eax,16
+ add eax, offset FadeTab
+ mov iModelFade,eax
+ mov iModelBaseFade,eax
+ }
+
+
+ lpTextureAddr = (void*) mptr->lpTexture;
+ HLineT = (void*) HLineTxModel2;
+
+
+ for (int s=0; s<4; s++) {
+
+ rVertex[s].x = mptr->gVertex[s].x + x0;
+ rVertex[s].y = mptr->gVertex[s].y + y0;
+ rVertex[s].z = z0;
+
+ if (rVertex[s].z<-256) {
+ gScrp[s].x = VideoCX + (int)(rVertex[s].x / (-rVertex[s].z) * CameraW);
+ gScrp[s].y = VideoCY - (int)(rVertex[s].y / (-rVertex[s].z) * CameraH);
+ } else return;
+
+ if (gScrp[s].x > maxx) maxx = gScrp[s].x;
+ if (gScrp[s].x < minx) minx = gScrp[s].x;
+ if (gScrp[s].y > maxy) maxy = gScrp[s].y;
+ if (gScrp[s].y < miny) miny = gScrp[s].y;
+ }
+
+ if (minx == 10241024) return;
+ if (minx>WinW || maxx<0 || miny>WinH || maxy<0) return;
+
+ //int w = gScrp[1].x - gScrp[0].x;
+ int h = gScrp[2].y - gScrp[1].y;
+ //int xo = (gScrp[1].x + gScrp[0].x) / 2;
+ int yo = gScrp[0].y;
+
+ if (!h) return;
+
+ xa = gScrp[0].x<<16;
+ xb = gScrp[1].x<<16;
+
+ Y1 = yo;
+ int DTY = 128*256*256 / h;
+ int TY = -DTY;
+ for (int y=0; y<h; y++) {
+ Y1++;
+ TY+=DTY;
+ if (Y1< 0 ) continue;
+ if (Y1>=WinH) continue;
+ lpTextureAddr = (void*) (mptr->lpTexture + (TY>>16)*128);
+ HLineTxModelBMP();
+ }
+}
+
+
+
+
+
+
+
+void RenderNearModel(TModel* _mptr, float x0, float y0, float z0, int light, float al, float bt)
+{
+ int f;
+
+ mptr = _mptr;
+
+ float ca = (float)cos(al);
+ float sa = (float)sin(al);
+
+ float cb = (float)cos(bt);
+ float sb = (float)sin(bt);
+
+
+ //light = 0;
+ __asm {
+ mov eax,light
+ shr eax,2
+ shl eax,16
+ add eax, offset FadeTab
+ mov iModelFade,eax
+ mov iModelBaseFade,eax
+ }
+
+
+ HLineT = (void*) HLineTxModel;
+ lpTextureAddr = (void*) mptr->lpTexture;
+
+ BOOL BL = FALSE;
+ for (int s=0; s<mptr->VCount; s++) {
+ rVertex[s].x = (mptr->gVertex[s].x * ca + mptr->gVertex[s].z * sa) + x0;
+ float vz = mptr->gVertex[s].z * ca - mptr->gVertex[s].x * sa;
+ rVertex[s].y = (mptr->gVertex[s].y * cb - vz * sb) + y0;
+ rVertex[s].z = (vz * cb + mptr->gVertex[s].y * sb) + z0;
+ if (rVertex[s].z<0) BL=TRUE;
+ }
+
+ if (!BL) return;
+
+ BuildTreeClip();
+
+ f = Current;
+ while( f!=-1 ) {
+
+ vused = 3;
+ TFace *fptr = &mptr->gFace[f];
+
+ cp[0].ev.v = rVertex[fptr->v1]; cp[0].tx = fptr->tax; cp[0].ty = fptr->tay;
+ cp[1].ev.v = rVertex[fptr->v2]; cp[1].tx = fptr->tbx; cp[1].ty = fptr->tby;
+ cp[2].ev.v = rVertex[fptr->v3]; cp[2].tx = fptr->tcx; cp[2].ty = fptr->tcy;
+
+ for (u=0; u<vused; u++) cp[u].ev.v.z+=12.0f;
+ for (u=0; u<vused; u++) ClipVector(ClipZ,u);
+ for (u=0; u<vused; u++) cp[u].ev.v.z-=12.0f;
+ if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) ClipVector(ClipA,u);
+ for (u=0; u<vused; u++) ClipVector(ClipC,u);
+
+ for (u=0; u<vused; u++) ClipVector(ClipB,u);
+ for (u=0; u<vused; u++) ClipVector(ClipD,u);
+ if (vused<3) goto LNEXT;
+
+ for (u=0; u<vused; u++) {
+ cp[u].ev.scrx = VideoCX - (int)(cp[u].ev.v.x / cp[u].ev.v.z * CameraW);
+ cp[u].ev.scry = VideoCY + (int)(cp[u].ev.v.y / cp[u].ev.v.z * CameraH);
+ }
+
+ scrp[0].x = cp[0].ev.scrx;
+ scrp[0].y = cp[0].ev.scry;
+ scrp[0].z = (int)cp[0].ev.v.z;
+ scrp[0].tx = cp[0].tx;
+ scrp[0].ty = cp[0].ty;
+
+
+ OpacityMode = (fptr->Flags & (sfOpacity + sfTransparent));
+ if (CORRECTION) Soft_Persp_K = 2.0f;
+ else Soft_Persp_K = 0.0f;
+ for (u=0; u<vused-2; u++) {
+ for (int n=1; n<3; n++) {
+ scrp[n].x = cp[n+u].ev.scrx;
+ scrp[n].y = cp[n+u].ev.scry;
+ scrp[n].z = (int)cp[n+u].ev.v.z;
+ scrp[n].tx = cp[n+u].tx;
+ scrp[n].ty = cp[n+u].ty; }
+
+ DrawCorrectedTexturedFace();
+ }
+ Soft_Persp_K = 1.5f;
+LNEXT:
+ f = mptr->gFace[f].Next;
+ }
+}
+
+
+
+
+
+
+
+void RenderCharacter(int index)
+{
+ TCharacter *cptr = &Characters[index];
+
+ float zs = (float)VectorLength( cptr->rpos );
+ if (zs > ctViewR*256) return;
+
+ GlassL = 0;
+ if (zs > 256 * (ctViewR-4))
+ GlassL = min(255, (zs/4 - 64*(ctViewR-4)));
+
+ CreateChMorphedModel(cptr);
+
+
+ float wh = GetLandUpH(cptr->pos.x, cptr->pos.z);
+ waterclip = FALSE;
+
+ if (!UNDERWATER)
+ if (wh > cptr->pos.y + 32*2) {
+ waterclipbase.x = cptr->pos.x - CameraX;
+ waterclipbase.y = wh - CameraY;
+ waterclipbase.z = cptr->pos.z - CameraZ;
+ waterclipbase = RotateVector(waterclipbase);
+ waterclip = TRUE;
+ }
+
+
+ if ( fabs(cptr->rpos.z) + fabs(cptr->rpos.x) <2560)
+ RenderModelClip(cptr->pinfo->mptr,
+ cptr->rpos.x, cptr->rpos.y, cptr->rpos.z, 240, 0,
+ -cptr->alpha + pi / 2 + CameraAlpha,
+ CameraBeta );
+ else
+ if (waterclip)
+ RenderModelClipWater(cptr->pinfo->mptr,
+ cptr->rpos.x, cptr->rpos.y, cptr->rpos.z, 240, 0,
+ -cptr->alpha + pi / 2 + CameraAlpha,
+ CameraBeta );
+ else
+ RenderModel(cptr->pinfo->mptr,
+ cptr->rpos.x, cptr->rpos.y, cptr->rpos.z, 240, 0,
+ -cptr->alpha + pi / 2 + CameraAlpha,
+ CameraBeta );
+}
+
+
+
+
+
+void RenderShip()
+{
+ float zs = (float)VectorLength( Ship.rpos );
+ if (zs > ctViewR*256) return;
+
+ GlassL = 0;
+ if (zs > 256 * (ctViewR-4))
+ GlassL = min(255, (zs/4 - 64*(ctViewR-4)));
+
+
+ CreateMorphedModel(ShipModel.mptr, &ShipModel.Animation[0], Ship.FTime, 1.0);
+
+ if ( fabs(Ship.rpos.z) < 4000)
+ RenderModelClip(ShipModel.mptr,
+ Ship.rpos.x, Ship.rpos.y, Ship.rpos.z, 240, 0, -Ship.alpha -pi/2 + CameraAlpha, CameraBeta);
+ else
+ RenderModel(ShipModel.mptr,
+ Ship.rpos.x, Ship.rpos.y, Ship.rpos.z, 240, 0, -Ship.alpha -pi/2 + CameraAlpha, CameraBeta);
+}
+
+
+
+
+
+
+
+
+void _FillMemoryWord(int maddr, int count, WORD w)
+{
+ __asm {
+ mov edi,maddr
+ mov ecx,count
+ shr ecx,2
+ mov ax,w
+ shl eax,16
+ mov ax,w
+ rep stosd
+ }
+}
+
+void FillMemoryWord(int maddr, int count, WORD w)
+{
+ WORD ww[4];
+ ww[0] = w; ww[1] = w; ww[2] = w; ww[3] = w;
+ __asm {
+ EMMS
+ mov edi,maddr
+ mov ecx,count
+ shr ecx,3
+ MOVQ MM0,ww
+ } L1: __asm {
+ MOVQ [edi],MM0
+ add edi,8
+ dec cx
+ jnz L1
+ EMMS
+ }
+}
+
+
+
+void _memcpy(void* daddr, void* saddr, int count)
+{
+ __asm {
+ EMMS
+ mov edi,daddr
+ mov esi,saddr
+ mov ecx,count
+ shr ecx,3
+ } L1: __asm {
+ MOVQ MM0,[esi]
+ MOVQ [edi],MM0
+ add edi,8
+ add esi,8
+ dec cx
+ jnz L1
+ EMMS
+ }
+}
+
+
+void DrawPicture(int x, int y, TPicture &pic)
+{
+ for (int yy=0; yy<pic.H; yy++)
+ if ( (yy+y>=0) && (yy+y < WinH) )
+ memcpy( (WORD*)lpVideoBuf + ((yy+y)<<10) + x,
+ pic.lpImage + yy*pic.W,
+ pic.W<<1);
+}
+
+
+void ClearVideoBuf()
+{
+ WORD w = HiColor(SkyR/8, SkyG/8, SkyB/8);
+
+ for(int y=0; y<WinH; y++) {
+ _FillMemoryWord( (int)lpVideoBuf + y*2048, WinW*2, w);
+ }
+}
+
+
+
+
+int CircleCX, CircleCY;
+
+void PutPixel(int x, int y)
+{
+ if (y<0 || y>=WinH) return;
+ *((WORD*)lpVideoBuf + (y<<10) + x) = 18<<5;
+}
+
+void Put8pix(int X,int Y)
+{
+ PutPixel(CircleCX + X, CircleCY + Y);
+ PutPixel(CircleCX + X, CircleCY - Y);
+ PutPixel(CircleCX - X, CircleCY + Y);
+ PutPixel(CircleCX - X, CircleCY - Y);
+ PutPixel(CircleCX + Y, CircleCY + X);
+ PutPixel(CircleCX + Y, CircleCY - X);
+ PutPixel(CircleCX - Y, CircleCY + X);
+ PutPixel(CircleCX - Y, CircleCY - X);
+}
+
+void DrawCircle(int cx, int cy, int R)
+{
+ int d = 3 - (2 * R);
+ int x = 0;
+ int y = R;
+ CircleCX=cx;
+ CircleCY=cy;
+ do {
+ Put8pix(x,y); x++;
+ if (d < 0) d = d + (x<<2) + 6; else
+ { d = d + (x - y) * 4 + 10; y--; }
+ } while (x<y);
+ Put8pix(x,y);
+}
+
+
+void DrawHMap()
+{
+ //if (WinH < 280) return;
+ DrawPicture(VideoCX-MapPic.W/2, VideoCY - MapPic.H/2, MapPic);
+ int xx = VideoCX - 128 + (CCX>>2);
+ int yy = VideoCY - 128 + (CCY>>2)+6;
+
+ if (yy>0 || yy<WinH) {
+ DrawCircle(xx, yy, 17);
+ *((WORD*)lpVideoBuf + yy*1024 + xx) = 31<<10;
+ *((WORD*)lpVideoBuf + yy*1024 + xx+1) = 31<<10;
+ yy++;
+ *((WORD*)lpVideoBuf + yy*1024 + xx) = 31<<10;
+ *((WORD*)lpVideoBuf + yy*1024 + xx+1) = 31<<10;
+ }
+
+ if (RadarMode)
+ for (int c=0; c<ChCount; c++) {
+
+ if (! (TargetDino & (1<<Characters[c].AI)) ) continue;
+ if (!Characters[c].Health) continue;
+ xx = VideoCX - 128 + (int)Characters[c].pos.x / 1024;
+ yy = VideoCY - 128 + (int)Characters[c].pos.z / 1024;
+ if (yy<=0 || yy>=WinH) continue;
+ if (xx<=0 || xx>=WinW) continue;
+ *((WORD*)lpVideoBuf + yy*1024 + xx) = 30<<5;
+ *((WORD*)lpVideoBuf + yy*1024 + xx+1) = 30<<5;
+ yy++;
+ *((WORD*)lpVideoBuf + yy*1024 + xx) = 30<<5;
+ *((WORD*)lpVideoBuf + yy*1024 + xx+1) = 30<<5;
+ }
+}
+
+
+
+void DrawTrophyText(int x0, int y0)
+{
+ int x;
+
+ HBITMAP hbmpOld = SelectObject(hdcCMain, hbmpVideoBuf);
+ HFONT oldfont = SelectObject(hdcCMain, fnt_Small);
+/*
+ int dtype = Characters[TrophyBody].CType;
+ int tc = Characters[TrophyBody].State;
+ int time = TrophyRoom.Body[tc].time;
+ int date = TrophyRoom.Body[tc].date;
+ int wep = TrophyRoom.Body[tc].weapon;
+ int score = TrophyRoom.Body[tc].score;
+ float scale = Characters[TrophyBody].scale;*/
+ int tc = TrophyBody;
+ int dtype = TrophyRoom.Body[tc].ctype;
+ int time = TrophyRoom.Body[tc].time;
+ int date = TrophyRoom.Body[tc].date;
+ int wep = TrophyRoom.Body[tc].weapon;
+ int score = TrophyRoom.Body[tc].score;
+ float scale = TrophyRoom.Body[tc].scale;
+ float range = TrophyRoom.Body[tc].range;
+
+ char t[32];
+
+ x0+=16; y0+=18;
+ x = x0;
+ STTextOut(x, y0 , "Name: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Name: ");
+ STTextOut(x, y0 , DinoInfo[dtype].Name, 0x0000BFBF);
+
+ x = x0;
+ STTextOut(x, y0+16, "Weight: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Weight: ");
+
+ if (OptSys)
+ sprintf(t,"%3.2ft ", DinoInfo[dtype].Mass * scale * scale / 0.907);
+ else
+ sprintf(t,"%3.2fT ", DinoInfo[dtype].Mass * scale * scale);
+
+ STTextOut(x, y0+16, t, 0x0000BFBF); x+=GetTextW(hdcCMain,t);
+ STTextOut(x, y0+16, "Length: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Length: ");
+
+ if (OptSys)
+ sprintf(t,"%3.2fft", DinoInfo[dtype].Length * scale / 0.3);
+ else
+ sprintf(t,"%3.2fm", DinoInfo[dtype].Length * scale);
+
+ STTextOut(x, y0+16, t, 0x0000BFBF);
+
+ x = x0;
+ STTextOut(x, y0+32, "Weapon: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Weapon: ");
+ wsprintf(t,"%s ", WeapInfo[wep].Name);
+ STTextOut(x, y0+32, t, 0x0000BFBF); x+=GetTextW(hdcCMain,t);
+ STTextOut(x, y0+32, "Score: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Score: ");
+ wsprintf(t,"%d", score);
+ STTextOut(x, y0+32, t, 0x0000BFBF);
+
+
+
+ x = x0;
+ STTextOut(x, y0+48, "Range of kill: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Range of kill: ");
+ if (OptSys) sprintf(t,"%3.1fft", range / 0.3);
+ else sprintf(t,"%3.1fm", range);
+ STTextOut(x, y0+48, t, 0x0000BFBF);
+
+
+ x = x0;
+ STTextOut(x, y0+64, "Date: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Date: ");
+ if (OptSys)
+ wsprintf(t,"%d.%d.%d ", ((date>>10) & 255), (date & 255), date>>20);
+ else
+ wsprintf(t,"%d.%d.%d ", (date & 255), ((date>>10) & 255), date>>20);
+
+ STTextOut(x, y0+64, t, 0x0000BFBF); x+=GetTextW(hdcCMain,t);
+ STTextOut(x, y0+64, "Time: ", 0x00BFBFBF); x+=GetTextW(hdcCMain,"Time: ");
+ wsprintf(t,"%d:%02d", ((time>>10) & 255), (time & 255));
+ STTextOut(x, y0+64, t, 0x0000BFBF);
+
+ SelectObject(hdcCMain, oldfont);
+ SelectObject(hdcCMain, hbmpOld);
+}
+
+
+
+
+void Render_LifeInfo(int li)
+{
+ int x,y;
+
+ HBITMAP hbmpOld = SelectObject(hdcCMain, hbmpVideoBuf);
+ HFONT oldfont = SelectObject(hdcCMain, fnt_Small);
+
+ int ctype = Characters[li].CType;
+ float scale = Characters[li].scale;
+ char t[32];
+
+ x = VideoCX + WinW / 64;
+ y = VideoCY + (int)(WinH / 6.8);
+
+ STTextOut(x, y, DinoInfo[ctype].Name, 0x0000b000);
+
+ if (OptSys) sprintf(t,"Weight: %3.2ft ", DinoInfo[ctype].Mass * scale * scale / 0.907);
+ else sprintf(t,"Weight: %3.2fT ", DinoInfo[ctype].Mass * scale * scale);
+ STTextOut(x, y+16, t, 0x0000b000);
+
+ int R = (int)(VectorLength( SubVectors(Characters[li].pos, PlayerPos) )*3 / 64.f);
+ if (OptSys) sprintf(t,"Distance: %dft ", R);
+ else sprintf(t,"Distance: %dm ", R/3);
+
+ STTextOut(x, y+32, t, 0x0000b000);
+
+ SelectObject(hdcMain, oldfont);
+
+ SelectObject(hdcCMain, oldfont);
+ SelectObject(hdcCMain, hbmpOld);
+}
+
+
+
+void RotateVVector(Vector3d& v)
+{
+ float x = v.x * ca - v.z * sa;
+ float y = v.y;
+ float z = v.z * ca + v.x * sa;
+
+ float xx = x;
+ float xy = y * cb + z * sb;
+ float xz = z * cb - y * sb;
+
+ v.x = xx; v.y = xy; v.z = xz;
+}
+
+
+
+void RenderSkyPlane()
+{
+ ClearVideoBuf();
+ Vector3d v,vbase;
+ Vector3d tx,ty,nv;
+ float p,q, qx, qy, qz, px, py, pz, rx, ry, rz, ddx, ddy;
+ int lastdt = 0;
+
+ cb = (float)cos(CameraBeta);
+ sb = (float)sin(CameraBeta);
+ SKYDTime = (RealTime*256) & ((256<<16) - 1);
+
+ float sh = - CameraY;
+ if (MapMinY==10241024) MapMinY=0;
+ sh = (float)((int)MapMinY)*ctHScale - CameraY;
+
+ v.x = 0;
+ v.z = (ctViewR*4.f)/5.f*256.f;
+ v.y = sh;
+
+ vbase.x = v.x;
+ vbase.y = v.y * cb + v.z * sb;
+ vbase.z = v.z * cb - v.y * sb;
+
+ if (vbase.z < 128) vbase.z = 128;
+
+ int scry = VideoCY - (int)(vbase.y / vbase.z * CameraH);
+
+ if (scry<0) return;
+ if (scry>WinEY) scry = WinEY;
+
+
+ cb = (float)cos(CameraBeta-0.15);
+ sb = (float)sin(CameraBeta-0.15);
+
+ tx.x=0.004f; tx.y=0; tx.z=0;
+ ty.x=0.0f; ty.y=0; ty.z=0.004f;
+ nv.x=0; nv.y=-1.f; nv.z=0;
+
+ tx.x*=0x10000;
+ ty.z*=0x10000;
+
+ RotateVVector(tx);
+ RotateVVector(ty);
+ RotateVVector(nv);
+
+ sh = 4*512*16;
+ vbase.x = -CameraX;
+ vbase.y = sh;
+ vbase.z = +CameraZ;
+ RotateVVector(vbase);
+
+//============= calc render params =================//
+ p = nv.x * vbase.x + nv.y * vbase.y + nv.z * vbase.z;
+ ddx = vbase.x * tx.x + vbase.y * tx.y + vbase.z * tx.z;
+ ddy = vbase.x * ty.x + vbase.y * ty.y + vbase.z * ty.z;
+
+ qx = CameraH * nv.x; qy = CameraW * nv.y; qz = CameraW*CameraH * nv.z;
+ px = p*CameraH*tx.x; py = p*CameraW*tx.y; pz = p*CameraW*CameraH* tx.z;
+ rx = p*CameraH*ty.x; ry = p*CameraW*ty.y; rz = p*CameraW*CameraH* ty.z;
+
+ px=px - ddx*qx; py=py - ddx*qy; pz=pz - ddx*qz;
+ rx=rx - ddy*qx; ry=ry - ddy*qy; rz=rz - ddy*qz;
+
+ int sx1 = - VideoCX;
+ int sx2 = + VideoCX;
+
+ float qx1 = qx * sx1 + qz;
+ float qx2 = qx * sx2 + qz;
+ float qyy;
+
+
+ for (int sky=0; sky<=scry; sky++) {
+ int sy = VideoCY - sky;
+ qyy = qy * sy;
+
+ q = qx1 + qyy;
+ float fxa = (px * sx1 + py * sy + pz) / q;
+ float fya = (rx * sx1 + ry * sy + rz) / q;
+
+ q = qx2 + qyy;
+ float fxb = (px * sx2 + py * sy + pz) / q;
+ float fyb = (rx * sx2 + ry * sy + rz) / q;
+
+ txa = ((int)fxa + SKYDTime) & ((256<<16) - 1);
+ tya = ((int)fya - SKYDTime) & ((256<<16) - 1);
+
+ ctdx = (int)(fxb-fxa);
+ ctdy = (int)(fyb-fya);
+
+ int dt = (int)(sqrt( (fxb-fxa)*(fxb-fxa) + (fyb-fya)*(fyb-fya) ) / 0x600000 ) - 7;
+ if (dt>8) dt = 8;
+ if (dt<lastdt) dt = lastdt;
+ lastdt = dt;
+
+ ctdx/=WinW; ctdy/=WinW;
+
+ if (LoDetailSky)
+ if (dt) RenderSkyLineFadeLo(sky, dt); else RenderSkyLineLo(sky); else
+ if (dt) RenderSkyLineFade(sky,dt); else RenderSkyLine(sky);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+void ShowVideo()
+{
+ HDC _hdc = hdcCMain;
+ HBITMAP hbmpOld = SelectObject(_hdc,hbmpVideoBuf);
+
+ if (UNDERWATER & CORRECTION)
+ for (int y=0; y<WinH; y++)
+ for (int x=0; x<WinW; x++)
+ *((WORD*)lpVideoBuf + y*1024 + x) = FadeTab[64][*((WORD*)lpVideoBuf + y*1024 + x) & 0x7FFF];
+
+
+ RenderHealthBar();
+
+ BitBlt(hdcMain,0,0,WinW,WinH, _hdc,0,0, SRCCOPY);
+
+ SelectObject(_hdc,hbmpOld);
+ //DeleteDC(_hdc);
+}
+
+
+
+
+void RenderHealthBar()
+{
+ if (MyHealth >= 100000) return;
+ if (MyHealth == 000000) return;
+
+ int L = WinW / 4;
+ int x0 = WinW - (WinW / 20) - L;
+ int y0 = WinH / 40;
+ int G = min( (MyHealth * 30 / 100000), 20);
+ int R = min( ( (100000 - MyHealth) * 30 / 100000), 20);
+ int HCOLOR = (G<<5) + (R<<10);
+
+ int L0 = (L * MyHealth) / 100000;
+ int H = WinH / 200;
+
+ FillMemory((WORD*)lpVideoBuf + ((y0-1)<<10) + x0-1, L*2+4, 0);
+ FillMemory((WORD*)lpVideoBuf + ((y0+H+1)<<10) + x0-1, L*2+4, 0);
+ for (int y=0; y<=H; y++) {
+ *((WORD*)lpVideoBuf + ((y0+y)<<10) + x0 - 1) = 0;
+ *((WORD*)lpVideoBuf + ((y0+y)<<10) + x0 + L) = 0;
+ for (int x=0; x<L0; x++)
+ *((WORD*)lpVideoBuf + ((y0+y)<<10) + x0 + x) = HCOLOR;
+ }
+}
+
+
+void Render_Cross(int sx, int sy)
+{
+ int w = WinW / 12;
+ for (int x=-w+1; x<w; x++) {
+ int offset = (sy<<10) + (sx+x);
+ WORD C = *((WORD*)lpVideoBuf + offset);
+ *((WORD*)lpVideoBuf + offset) = (C & 0x7BDE) >> 1;
+ }
+
+ for (int y=-w+1; y<w; y++) {
+ int offset = ((sy+y)<<10) + sx;
+ WORD C = *((WORD*)lpVideoBuf + offset);
+ *((WORD*)lpVideoBuf + offset) = (C & 0x7BDE) >> 1;
+ }
+}
+
+//======== software has no implementation for 3DHard ===========/
+void Init3DHardware()
+{
+ PrintLog("\n");
+ PrintLog("==Init Direct Draw==\n");
+ HRESULT hres;
+
+ hres = DirectDrawCreate( NULL, &lpDD, NULL );
+ if( hres != DD_OK ) {
+ wsprintf(logt, "DirectDrawCreate Error: %Xh\n", hres);
+ PrintLog(logt);
+ DoHalt("");
+ }
+ PrintLog("DirectDrawCreate: Ok\n");
+
+ PrintLog("Direct Draw activated.\n");
+ PrintLog("\n");
+ DirectActive = TRUE;
+}
+
+
+
+void Activate3DHardware()
+{
+ SetVideoMode(WinW, WinH);
+
+ DWORD cl = DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN;
+
+#ifdef _DEBUG
+ cl = DDSCL_NORMAL;
+#endif
+
+ HRESULT hres = lpDD->SetCooperativeLevel( hwndMain, cl);
+ if( hres != DD_OK ) {
+ wsprintf(logt, "SetCooperativeLevel Error: %Xh\n", hres);
+ PrintLog(logt);
+ DoHalt("");
+ }
+ PrintLog("SetCooperativeLevel: Ok\n");
+
+ hres = lpDD->SetDisplayMode( WinW, WinH, 16);
+
+ if (hres != DD_OK) {
+ wsprintf(logt, "DDRAW: Error set video mode %dx%d\n", WinW, WinH);
+ PrintLog(logt);
+ }
+}
+
+void ShutDown3DHardware()
+{
+ lpDD->RestoreDisplayMode();
+ lpDD->SetCooperativeLevel( hwndMain, DDSCL_NORMAL);
+}
+
+
+void Render3DHardwarePosts()
+{
+}
+
+
+void CopyHARDToDIB()
+{
+}
+
+
+void Hardware_ZBuffer(BOOL bl)
+{
+}
+
+#endif \ No newline at end of file
diff --git a/Resources.cpp b/Resources.cpp
new file mode 100644
index 0000000..172572e
--- /dev/null
+++ b/Resources.cpp
@@ -0,0 +1,1988 @@
+#include "Hunt.h"
+#include "stdio.h"
+HANDLE hfile;
+DWORD l;
+
+void GenerateModelMipMaps(TModel *mptr);
+void GenerateAlphaFlags(TModel *mptr);
+
+
+LPVOID _HeapAlloc(HANDLE hHeap,
+ DWORD dwFlags,
+ DWORD dwBytes)
+{
+ LPVOID res = HeapAlloc(hHeap,
+ dwFlags | HEAP_ZERO_MEMORY,
+ dwBytes);
+ if (!res)
+ DoHalt("Heap allocation error!");
+
+ HeapAllocated+=dwBytes;
+ return res;
+}
+
+
+BOOL _HeapFree(HANDLE hHeap,
+ DWORD dwFlags,
+ LPVOID lpMem)
+{
+ if (!lpMem) return FALSE;
+
+ HeapReleased+=
+ HeapSize(hHeap, HEAP_NO_SERIALIZE, lpMem);
+
+ BOOL res = HeapFree(hHeap,
+ dwFlags,
+ lpMem);
+ if (!res)
+ DoHalt("Heap free error!");
+
+ return res;
+}
+
+
+void AddMessage(LPSTR mt)
+{
+ MessageList.timeleft = timeGetTime() + 2 * 1000;
+ lstrcpy(MessageList.mtext, mt);
+}
+
+void PlaceHunter()
+{
+ if (LockLanding) return;
+
+ if (TrophyMode) {
+ PlayerX = 76*256+128;
+ PlayerZ = 70*256+128;
+ PlayerY = GetLandQH(PlayerX, PlayerZ);
+ return;
+ }
+
+ int p = (timeGetTime() % LandingList.PCount);
+ PlayerX = (float)LandingList.list[p].x * 256+128;
+ PlayerZ = (float)LandingList.list[p].y * 256+128;
+ PlayerY = GetLandQH(PlayerX, PlayerZ);
+}
+
+
+int DitherHi(int C)
+{
+ int d = C & 255;
+ C = C / 256;
+ if (rand() * 255 / RAND_MAX < d) C++;
+ if (C>31) C=31;
+ return C;
+}
+
+
+
+
+void CreateWaterTab()
+{
+ for (int c=0; c<0x8000; c++) {
+ int R = (c >> 10);
+ int G = (c >> 5) & 31;
+ int B = c & 31;
+ R = 1+(R * 8 ) / 28; if (R>31) R=31;
+ G = 2+(G * 18) / 28; if (G>31) G=31;
+ B = 3+(B * 22) / 28; if (B>31) B=31;
+ FadeTab[64][c] = HiColor(R, G, B);
+ }
+}
+
+void CreateFadeTab()
+{
+#ifdef _soft
+ for (int l=0; l<64; l++)
+ for (int c=0; c<0x8000; c++) {
+ int R = (c >> 10);
+ int G = (c >> 5) & 31;
+ int B = c & 31;
+
+ R = (int)((float)R * (l) / 60.f + (float)rand() *0.2f / RAND_MAX); if (R>31) R=31;
+ G = (int)((float)G * (l) / 60.f + (float)rand() *0.2f / RAND_MAX); if (G>31) G=31;
+ B = (int)((float)B * (l) / 60.f + (float)rand() *0.2f / RAND_MAX); if (B>31) B=31;
+ FadeTab[l][c] = HiColor(R, G, B);
+ }
+
+ CreateWaterTab();
+#endif
+}
+
+
+void CreateDivTable()
+{
+ DivTbl[0] = 0x7fffffff;
+ DivTbl[1] = 0x7fffffff;
+ DivTbl[2] = 0x7fffffff;
+ for( int i = 3; i < 10240; i++ )
+ DivTbl[i] = (int) ((float)0x100000000 / i);
+
+ for (int y=0; y<32; y++)
+ for (int x=0; x<32; x++)
+ RandomMap[y][x] = rand() * 1024 / RAND_MAX;
+}
+
+
+void CreateVideoDIB()
+{
+ hdcMain=GetDC(hwndMain);
+ hdcCMain = CreateCompatibleDC(hdcMain);
+
+ SelectObject(hdcMain, fnt_Midd);
+ SelectObject(hdcCMain, fnt_Midd);
+
+ BITMAPINFOHEADER bmih;
+ bmih.biSize = sizeof( BITMAPINFOHEADER );
+ bmih.biWidth =1024;
+ bmih.biHeight = -768;
+ bmih.biPlanes = 1;
+ bmih.biBitCount = 16;
+ bmih.biCompression = BI_RGB;
+ bmih.biSizeImage = 0;
+ bmih.biXPelsPerMeter = 400;
+ bmih.biYPelsPerMeter = 400;
+ bmih.biClrUsed = 0;
+ bmih.biClrImportant = 0;
+
+ BITMAPINFO binfo;
+ binfo.bmiHeader = bmih;
+ hbmpVideoBuf =
+ CreateDIBSection(hdcMain, &binfo, DIB_RGB_COLORS, &lpVideoBuf, NULL, 0);
+}
+
+
+
+
+
+
+int GetObjectH(int x, int y, int R)
+{
+ x = (x<<8) + 128;
+ y = (y<<8) + 128;
+ float hr,h;
+ hr =GetLandH((float)x, (float)y);
+ h = GetLandH( (float)x+R, (float)y); if (h < hr) hr = h;
+ h = GetLandH( (float)x-R, (float)y); if (h < hr) hr = h;
+ h = GetLandH( (float)x, (float)y+R); if (h < hr) hr = h;
+ h = GetLandH( (float)x, (float)y-R); if (h < hr) hr = h;
+ hr += 15;
+ return (int) (hr / ctHScale);
+}
+
+
+int GetObjectHWater(int x, int y)
+{
+ if (FMap[y][x] & fmReverse)
+ return (int)(HMap[y][x+1]+HMap[y+1][x]) / 2 + 48;
+ else
+ return (int)(HMap[y][x]+HMap[y+1][x+1]) / 2 + 48;
+}
+
+
+
+void CreateTMap()
+{
+ int x,y;
+ LandingList.PCount = 0;
+
+ int ScMaps = 0;
+ int SL = (100*(OptBrightness + 128))>>8;
+ for (y=0; y<ctMapSize; y++)
+ for (x=0; x<ctMapSize; x++) {
+ if (TMap1[y][x]==0xFFFF) TMap1[y][x] = 1;
+ if (TMap2[y][x]==0xFFFF) TMap2[y][x] = 1;
+
+ if (Textures[TMap1[y][x]]->mR > SL &&
+ Textures[TMap1[y][x]]->mG > SL &&
+ Textures[TMap1[y][x]]->mB > SL) ScMaps++;
+ }
+
+ SNOW = (ScMaps > 200000);
+
+
+/*
+ for (y=1; y<ctMapSize-1; y++)
+ for (x=1; x<ctMapSize-1; x++)
+ if (!(FMap[y][x] & fmWater) ) {
+
+ if (FMap[y ][x+1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y ][x+1];}
+ if (FMap[y+1][x ] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y+1][x ];}
+ if (FMap[y ][x-1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y ][x-1];}
+ if (FMap[y-1][x ] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y-1][x ];}
+
+ if (FMap[y][x] & fmWater2)
+ if (HMap[y][x] > WaterList[WMap[y][x]].wlevel) HMap[y][x]=WaterList[WMap[y][x]].wlevel;
+ }
+
+ for (y=1; y<ctMapSize-1; y++)
+ for (x=1; x<ctMapSize-1; x++)
+ if (FMap[y][x] & fmWater2) {
+ FMap[y][x]-=fmWater2;
+ FMap[y][x]+=fmWater;
+ }
+*/
+
+
+ for (y=1; y<ctMapSize-1; y++)
+ for (x=1; x<ctMapSize-1; x++)
+ if (!(FMap[y][x] & fmWater) ) {
+
+ if (FMap[y ][x+1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y ][x+1];}
+ if (FMap[y+1][x ] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y+1][x ];}
+ if (FMap[y ][x-1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y ][x-1];}
+ if (FMap[y-1][x ] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y-1][x ];}
+
+ BOOL l = TRUE;
+
+#ifdef _soft
+ if (FMap[y][x] & fmWater2) {
+ l = FALSE;
+ if (HMap[y][x] > WaterList[WMap[y][x]].wlevel) HMap[y][x]=WaterList[WMap[y][x]].wlevel;
+ HMap[y][x]=WaterList[WMap[y][x]].wlevel;
+ }
+#endif
+
+ if (FMap[y-1][x-1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y-1][x-1];}
+ if (FMap[y-1][x+1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y-1][x+1];}
+ if (FMap[y+1][x-1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y+1][x-1];}
+ if (FMap[y+1][x+1] & fmWater) { FMap[y][x]|= fmWater2; WMap[y][x] = WMap[y+1][x+1];}
+
+ if (l)
+ if (FMap[y][x] & fmWater2)
+ if (HMap[y][x] == WaterList[WMap[y][x]].wlevel) HMap[y][x]+=1;
+
+ //if (FMap[y][x] & fmWater2)
+
+ }
+
+#ifdef _soft
+ for (y=0; y<1024; y++)
+ for (x=0; x<1024; x++ ) {
+ if( abs( HMap[y][x]-HMap[y+1][x+1] ) > abs( HMap[y+1][x]-HMap[y][x+1] ) )
+ FMap[y][x] |= fmReverse;
+ else
+ FMap[y][x] &= ~fmReverse;
+ }
+#endif
+
+
+ for (y=0; y<ctMapSize; y++)
+ for (x=0; x<ctMapSize; x++) {
+
+ if (!(FMap[y][x] & fmWaterA))
+ WMap[y][x]=255;
+
+#ifdef _soft
+ if (MObjects[OMap[y][x]].info.flags & ofNOSOFT2)
+ if ( (x+y) & 1 )
+ OMap[y][x]=255;
+
+ if (MObjects[OMap[y][x]].info.flags & ofNOSOFT)
+ OMap[y][x]=255;
+#endif
+
+ if (OMap[y][x]==254) {
+ LandingList.list[LandingList.PCount].x = x;
+ LandingList.list[LandingList.PCount].y = y;
+ LandingList.PCount++;
+ OMap[y][x]=255;
+ }
+
+ int ob = OMap[y][x];
+ if (ob == 255) { HMapO[y][x] = 0; continue; }
+
+ //HMapO[y][x] = GetObjectH(x,y);
+ if (MObjects[ob].info.flags & ofPLACEGROUND) HMapO[y][x] = GetObjectH(x,y, MObjects[ob].info.GrRad);
+ //if (MObjects[ob].info.flags & ofPLACEWATER) HMapO[y][x] = GetObjectHWater(x,y);
+
+ }
+
+ if (!LandingList.PCount) {
+ LandingList.list[LandingList.PCount].x = 256;
+ LandingList.list[LandingList.PCount].y = 256;
+ LandingList.PCount=1;
+ }
+
+ if (TrophyMode) {
+ LandingList.PCount = 0;
+ for (x=0; x<6; x++) {
+ LandingList.list[LandingList.PCount].x = 69 + x*3;
+ LandingList.list[LandingList.PCount].y = 66;
+ LandingList.PCount++;
+ }
+
+ for (y=0; y<6; y++) {
+ LandingList.list[LandingList.PCount].x = 87;
+ LandingList.list[LandingList.PCount].y = 69 + y*3;
+ LandingList.PCount++;
+ }
+
+ for (x=0; x<6; x++) {
+ LandingList.list[LandingList.PCount].x = 84 - x*3;
+ LandingList.list[LandingList.PCount].y = 87;
+ LandingList.PCount++;
+ }
+
+ for (y=0; y<6; y++) {
+ LandingList.list[LandingList.PCount].x = 66;
+ LandingList.list[LandingList.PCount].y = 84 - y*3;
+ LandingList.PCount++;
+ }
+ }
+
+
+}
+
+
+
+void CreateMipMap(WORD* src, WORD* dst, int Ls, int Ld)
+{
+ int scale = Ls / Ld;
+
+ int R[64][64], G[64][64], B[64][64];
+
+ FillMemory(R, sizeof(R), 0);
+ FillMemory(G, sizeof(R), 0);
+ FillMemory(B, sizeof(R), 0);
+
+ for (int y=0; y<Ls; y++)
+ for (int x=0; x<Ls; x++) {
+ WORD C = *(src + x + y*Ls);
+ B[ y/scale ][ x/scale ]+= (C>> 0) & 31;
+ G[ y/scale ][ x/scale ]+= (C>> 5) & 31;
+ R[ y/scale ][ x/scale ]+= (C>>10) & 31;
+ }
+
+ scale*=scale;
+
+ for (y=0; y<Ld; y++)
+ for (int x=0; x<Ld; x++) {
+ R[y][x]/=scale;
+ G[y][x]/=scale;
+ B[y][x]/=scale;
+ *(dst + x + y*Ld) = (R[y][x]<<10) + (G[y][x]<<5) + B[y][x];
+ }
+}
+
+
+
+int CalcImageDifference(WORD* A, WORD* B, int L)
+{
+ int r = 0; L*=L;
+ for (int l=0; l<L; l++) {
+ WORD C1 = *(A + l);
+ WORD C2 = *(B + l);
+ int R1 = (C1>>10) & 31;
+ int G1 = (C1>> 5) & 31;
+ int B1 = (C1>> 0) & 31;
+ int R2 = (C2>>10) & 31;
+ int G2 = (C2>> 5) & 31;
+ int B2 = (C2>> 0) & 31;
+
+ r+=(R1-R2)*(R1-R2) +
+ (G1-G2)*(G1-G2) +
+ (B1-B2)*(B1-B2);
+ }
+
+ return r;
+}
+
+
+void RotateImage(WORD* src, WORD* dst, int L)
+{
+ for (int y=0; y<L; y++)
+ for (int x=0; x<L; x++)
+ *(dst + x*L + (L-1-y) ) = *(src + x + y*L);
+}
+
+
+void BrightenTexture(WORD* A, int L)
+{
+ int factor=OptBrightness + 128;
+ //if (factor > 256) factor = (factor-256)*3/2 + 256;
+ for (int c=0; c<L; c++) {
+ WORD w = *(A + c);
+ int B = (w>> 0) & 31;
+ int G = (w>> 5) & 31;
+ int R = (w>>10) & 31;
+ B = (B * factor) >> 8; if (B > 31) B = 31;
+ G = (G * factor) >> 8; if (G > 31) G = 31;
+ R = (R * factor) >> 8; if (R > 31) R = 31;
+
+ if (OptDayNight==2) { B=G>>3; R=G>>3; }
+
+ *(A + c) = (B) + (G<<5) + (R<<10);
+ }
+}
+
+void GenerateMipMap(WORD* A, WORD* D, int L)
+{
+ for (int y=0; y<L; y++)
+ for (int x=0; x<L; x++) {
+ int C1 = *(A + x*2 + (y*2+0)*2*L);
+ int C2 = *(A + x*2+1 + (y*2+0)*2*L);
+ int C3 = *(A + x*2 + (y*2+1)*2*L);
+ int C4 = *(A + x*2+1 + (y*2+1)*2*L);
+ //C4 = C1;
+ /*
+ if (L==64)
+ C3=((C3 & 0x7bde) + (C1 & 0x7bde))>>1;
+ */
+ int B = ( ((C1>>0) & 31) + ((C2>>0) & 31) + ((C3>>0) & 31) + ((C4>>0) & 31) +2 ) >> 2;
+ int G = ( ((C1>>5) & 31) + ((C2>>5) & 31) + ((C3>>5) & 31) + ((C4>>5) & 31) +2 ) >> 2;
+ int R = ( ((C1>>10) & 31) + ((C2>>10) & 31) + ((C3>>10) & 31) + ((C4>>10) & 31) +2 ) >> 2;
+ *(D + x + y * L) = HiColor(R,G,B);
+ }
+}
+
+
+int CalcColorSum(WORD* A, int L)
+{
+ int R = 0, G = 0, B = 0;
+ for (int x=0; x<L; x++) {
+ B+= (*(A+x) >> 0) & 31;
+ G+= (*(A+x) >> 5) & 31;
+ R+= (*(A+x) >>10) & 31;
+ }
+ return HiColor(R/L, G/L, B/L);
+}
+
+
+void GenerateShadedMipMap(WORD* src, WORD* dst, int L)
+{
+ for (int x=0; x<16*16; x++) {
+ int B = (*(src+x) >> 0) & 31;
+ int G = (*(src+x) >> 5) & 31;
+ int R = (*(src+x) >>10) & 31;
+ R=DitherHi(SkyR*L/8 + R*(256-L)+6);
+ G=DitherHi(SkyG*L/8 + G*(256-L)+6);
+ B=DitherHi(SkyB*L/8 + B*(256-L)+6);
+ *(dst + x) = HiColor(R,G,B);
+ }
+}
+
+
+void GenerateShadedSkyMipMap(WORD* src, WORD* dst, int L)
+{
+ for (int x=0; x<128*128; x++) {
+ int B = (*(src+x) >> 0) & 31;
+ int G = (*(src+x) >> 5) & 31;
+ int R = (*(src+x) >>10) & 31;
+ R=DitherHi(SkyR*L/8 + R*(256-L)+6);
+ G=DitherHi(SkyG*L/8 + G*(256-L)+6);
+ B=DitherHi(SkyB*L/8 + B*(256-L)+6);
+ *(dst + x) = HiColor(R,G,B);
+ }
+}
+
+
+void DATASHIFT(WORD* d, int cnt)
+{
+ cnt>>=1;
+ /*
+ for (int l=0; l<cnt; l++)
+ *(d+l)=(*(d+l)) & 0x3e0;
+*/
+ if (HARD3D) return;
+
+ for (l=0; l<cnt; l++)
+ *(d+l)*=2;
+
+}
+
+
+
+void ApplyAlphaFlags(WORD* tptr, int cnt)
+{
+#ifdef _soft
+#else
+ for (int w=0; w<cnt; w++)
+ *(tptr+w)|=0x8000;
+#endif
+}
+
+
+void CalcMidColor(WORD* tptr, int l, int &mr, int &mg, int &mb)
+{
+ for (int w=0; w<l; w++) {
+ WORD c = *(tptr + w);
+ mb+=((c>> 0) & 31)*8;
+ mg+=((c>> 5) & 31)*8;
+ mr+=((c>>10) & 31)*8;
+ }
+
+ mr/=l; mg/=l; mb/=l;
+}
+
+void LoadTexture(TEXTURE* &T)
+{
+ T = (TEXTURE*) _HeapAlloc(Heap, 0, sizeof(TEXTURE));
+ DWORD L;
+ ReadFile(hfile, T->DataA, 128*128*2, &L, NULL);
+ for (int y=0; y<128; y++)
+ for (int x=0; x<128; x++)
+ if (!T->DataA[y*128+x]) T->DataA[y*128+x]=1;
+
+ BrightenTexture(T->DataA, 128*128);
+
+ CalcMidColor(T->DataA, 128*128, T->mR, T->mG, T->mB);
+
+ GenerateMipMap(T->DataA, T->DataB, 64);
+ GenerateMipMap(T->DataB, T->DataC, 32);
+ GenerateMipMap(T->DataC, T->DataD, 16);
+ memcpy(T->SDataC[0], T->DataC, 32*32*2);
+ memcpy(T->SDataC[1], T->DataC, 32*32*2);
+
+ DATASHIFT((unsigned short *)T, sizeof(TEXTURE));
+ for (int w=0; w<32*32; w++)
+ T->SDataC[1][w] = FadeTab[48][T->SDataC[1][w]>>1];
+
+ ApplyAlphaFlags(T->DataA, 128*128);
+ ApplyAlphaFlags(T->DataB, 64*64);
+ ApplyAlphaFlags(T->DataC, 32*32);
+}
+
+
+
+
+void LoadSky()
+{
+ SetFilePointer(hfile, 256*512*OptDayNight, NULL, FILE_CURRENT);
+ ReadFile(hfile, SkyPic, 256*256*2, &l, NULL);
+ SetFilePointer(hfile, 256*512*(2-OptDayNight), NULL, FILE_CURRENT);
+
+ BrightenTexture(SkyPic, 256*256);
+
+ for (int y=0; y<128; y++)
+ for (int x=0; x<128; x++)
+ SkyFade[0][y*128+x] = SkyPic[y*2*256 + x*2];
+
+ for (int l=1; l<8; l++)
+ GenerateShadedSkyMipMap(SkyFade[0], SkyFade[l], l*32-16);
+ GenerateShadedSkyMipMap(SkyFade[0], SkyFade[8], 250);
+ ApplyAlphaFlags(SkyPic, 256*256);
+ //DATASHIFT(SkyPic, 256*256*2);
+}
+
+
+void LoadSkyMap()
+{
+ ReadFile(hfile, SkyMap, 128*128, &l, NULL);
+}
+
+
+
+
+
+void fp_conv(LPVOID d)
+{
+ int i;
+ float f;
+ memcpy(&i, d, 4);
+#ifdef _d3d
+ f = ((float)i) / 256.f;
+#else
+ f = ((float)i);
+#endif
+ memcpy(d, &f, 4);
+}
+
+
+
+void CorrectModel(TModel *mptr)
+{
+ TFace tface[1024];
+
+ for (int f=0; f<mptr->FCount; f++) {
+ if (!(mptr->gFace[f].Flags & sfDoubleSide))
+ mptr->gFace[f].Flags |= sfNeedVC;
+#ifdef _soft
+ mptr->gFace[f].tax = (mptr->gFace[f].tax<<16) + 0x8000;
+ mptr->gFace[f].tay = (mptr->gFace[f].tay<<16) + 0x8000;
+ mptr->gFace[f].tbx = (mptr->gFace[f].tbx<<16) + 0x8000;
+ mptr->gFace[f].tby = (mptr->gFace[f].tby<<16) + 0x8000;
+ mptr->gFace[f].tcx = (mptr->gFace[f].tcx<<16) + 0x8000;
+ mptr->gFace[f].tcy = (mptr->gFace[f].tcy<<16) + 0x8000;
+#else
+ fp_conv(&mptr->gFace[f].tax);
+ fp_conv(&mptr->gFace[f].tay);
+ fp_conv(&mptr->gFace[f].tbx);
+ fp_conv(&mptr->gFace[f].tby);
+ fp_conv(&mptr->gFace[f].tcx);
+ fp_conv(&mptr->gFace[f].tcy);
+#endif
+ }
+
+
+ int fp = 0;
+ for (f=0; f<mptr->FCount; f++)
+ if ( (mptr->gFace[f].Flags & (sfOpacity | sfTransparent))==0)
+ {
+ tface[fp] = mptr->gFace[f];
+ fp++;
+ }
+
+ for (f=0; f<mptr->FCount; f++)
+ if ( (mptr->gFace[f].Flags & sfOpacity)!=0)
+ {
+ tface[fp] = mptr->gFace[f];
+ fp++;
+ }
+
+ for (f=0; f<mptr->FCount; f++)
+ if ( (mptr->gFace[f].Flags & sfTransparent)!=0)
+ {
+ tface[fp] = mptr->gFace[f];
+ fp++;
+ }
+
+
+
+ memcpy( mptr->gFace, tface, sizeof(tface) );
+}
+
+void LoadModel(TModel* &mptr)
+{
+ mptr = (TModel*) _HeapAlloc(Heap, 0, sizeof(TModel));
+
+ ReadFile( hfile, &mptr->VCount, 4, &l, NULL );
+ ReadFile( hfile, &mptr->FCount, 4, &l, NULL );
+ ReadFile( hfile, &OCount, 4, &l, NULL );
+ ReadFile( hfile, &mptr->TextureSize, 4, &l, NULL );
+ ReadFile( hfile, mptr->gFace, mptr->FCount<<6, &l, NULL );
+ ReadFile( hfile, mptr->gVertex, mptr->VCount<<4, &l, NULL );
+ ReadFile( hfile, gObj, OCount*48, &l, NULL );
+
+ if (HARD3D) CalcLights(mptr);
+
+ int ts = mptr->TextureSize;
+
+ if (HARD3D) mptr->TextureHeight = 256;
+ else mptr->TextureHeight = mptr->TextureSize>>9;
+
+ mptr->TextureSize = mptr->TextureHeight*512;
+
+ mptr->lpTexture = (WORD*) _HeapAlloc(Heap, 0, mptr->TextureSize);
+
+ ReadFile(hfile, mptr->lpTexture, ts, &l, NULL);
+ BrightenTexture(mptr->lpTexture, ts/2);
+
+ for (int v=0; v<mptr->VCount; v++) {
+ mptr->gVertex[v].x*=2.f;
+ mptr->gVertex[v].y*=2.f;
+ mptr->gVertex[v].z*=-2.f;
+ }
+
+ CorrectModel(mptr);
+
+ DATASHIFT(mptr->lpTexture, mptr->TextureSize);
+}
+
+
+
+void LoadAnimation(TVTL &vtl)
+{
+ int vc;
+ DWORD l;
+
+ ReadFile( hfile, &vc, 4, &l, NULL );
+ ReadFile( hfile, &vc, 4, &l, NULL );
+ ReadFile( hfile, &vtl.aniKPS, 4, &l, NULL );
+ ReadFile( hfile, &vtl.FramesCount, 4, &l, NULL );
+ vtl.FramesCount++;
+
+ vtl.AniTime = (vtl.FramesCount * 1000) / vtl.aniKPS;
+ vtl.aniData = (short int*)
+ _HeapAlloc(Heap, 0, (vc*vtl.FramesCount*6) );
+ ReadFile( hfile, vtl.aniData, (vc*vtl.FramesCount*6), &l, NULL);
+
+}
+
+
+
+void LoadModelEx(TModel* &mptr, char* FName)
+{
+
+ hfile = CreateFile(FName,
+ GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hfile==INVALID_HANDLE_VALUE) {
+ char sz[512];
+ wsprintf( sz, "Error opening file\n%s.", FName );
+ DoHalt(sz);
+ }
+
+ mptr = (TModel*) _HeapAlloc(Heap, 0, sizeof(TModel));
+
+ ReadFile( hfile, &mptr->VCount, 4, &l, NULL );
+ ReadFile( hfile, &mptr->FCount, 4, &l, NULL );
+ ReadFile( hfile, &OCount, 4, &l, NULL );
+ ReadFile( hfile, &mptr->TextureSize, 4, &l, NULL );
+ ReadFile( hfile, mptr->gFace, mptr->FCount<<6, &l, NULL );
+ ReadFile( hfile, mptr->gVertex, mptr->VCount<<4, &l, NULL );
+ ReadFile( hfile, gObj, OCount*48, &l, NULL );
+
+ int ts = mptr->TextureSize;
+ if (HARD3D) mptr->TextureHeight = 256;
+ else mptr->TextureHeight = mptr->TextureSize>>9;
+ mptr->TextureSize = mptr->TextureHeight*512;
+
+ mptr->lpTexture = (WORD*) _HeapAlloc(Heap, 0, mptr->TextureSize);
+
+ ReadFile(hfile, mptr->lpTexture, ts, &l, NULL);
+ BrightenTexture(mptr->lpTexture, ts/2);
+
+ for (int v=0; v<mptr->VCount; v++) {
+ mptr->gVertex[v].x*=2.f;
+ mptr->gVertex[v].y*=2.f;
+ mptr->gVertex[v].z*=-2.f;
+ }
+
+ CorrectModel(mptr);
+
+ DATASHIFT(mptr->lpTexture, mptr->TextureSize);
+ GenerateModelMipMaps(mptr);
+ GenerateAlphaFlags(mptr);
+}
+
+
+
+
+void LoadWav(char* FName, TSFX &sfx)
+{
+ DWORD l;
+
+ HANDLE hfile = CreateFile(FName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if( hfile==INVALID_HANDLE_VALUE ) {
+ char sz[512];
+ wsprintf( sz, "Error opening file\n%s.", FName );
+ DoHalt(sz);
+ }
+
+ _HeapFree(Heap, 0, (void*)sfx.lpData);
+ sfx.lpData = NULL;
+
+ SetFilePointer( hfile, 36, NULL, FILE_BEGIN );
+
+ char c[5]; c[4] = 0;
+
+ for ( ; ; ) {
+ ReadFile( hfile, c, 1, &l, NULL );
+ if( c[0] == 'd' ) {
+ ReadFile( hfile, &c[1], 3, &l, NULL );
+ if( !lstrcmp( c, "data" ) ) break;
+ else SetFilePointer( hfile, -3, NULL, FILE_CURRENT );
+ }
+ }
+
+ ReadFile( hfile, &sfx.length, 4, &l, NULL );
+
+ sfx.lpData = (short int*)
+ _HeapAlloc( Heap, 0, sfx.length );
+
+ ReadFile( hfile, sfx.lpData, sfx.length, &l, NULL );
+ CloseHandle(hfile);
+}
+
+
+WORD conv_565(WORD c)
+{
+ return (c & 31) + ( (c & 0xFFE0) << 1 );
+}
+
+
+int conv_xGx(int c) {
+ if (OptDayNight!=2) return c;
+ DWORD a = c;
+ int r = ((c>> 0) & 0xFF);
+ int g = ((c>> 8) & 0xFF);
+ int b = ((c>>16) & 0xFF);
+ c = max(r,g);
+ c = max(c,b);
+ return (c<<8) + (a & 0xFF000000);
+}
+
+void conv_pic(TPicture &pic)
+{
+ if (!HARD3D) return;
+ for (int y=0; y<pic.H; y++)
+ for (int x=0; x<pic.W; x++)
+ *(pic.lpImage + x + y*pic.W) = conv_565(*(pic.lpImage + x + y*pic.W));
+}
+
+
+
+
+void LoadPicture(TPicture &pic, LPSTR pname)
+{
+ int C;
+ byte fRGB[800][3];
+ BITMAPFILEHEADER bmpFH;
+ BITMAPINFOHEADER bmpIH;
+ DWORD l;
+ HANDLE hfile;
+
+ hfile = CreateFile(pname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if( hfile==INVALID_HANDLE_VALUE ) {
+ char sz[512];
+ wsprintf( sz, "Error opening file\n%s.", pname );
+ DoHalt(sz);
+ }
+
+ ReadFile( hfile, &bmpFH, sizeof( BITMAPFILEHEADER ), &l, NULL );
+ ReadFile( hfile, &bmpIH, sizeof( BITMAPINFOHEADER ), &l, NULL );
+
+
+ _HeapFree(Heap, 0, (void*)pic.lpImage);
+ pic.lpImage = NULL;
+
+ pic.W = bmpIH.biWidth;
+ pic.H = bmpIH.biHeight;
+ pic.lpImage = (WORD*) _HeapAlloc(Heap, 0, pic.W * pic.H * 2);
+
+
+
+ for (int y=0; y<pic.H; y++) {
+ ReadFile( hfile, fRGB, 3*pic.W, &l, NULL );
+ for (int x=0; x<pic.W; x++) {
+ C = ((int)fRGB[x][2]/8<<10) + ((int)fRGB[x][1]/8<< 5) + ((int)fRGB[x][0]/8) ;
+ *(pic.lpImage + (pic.H-y-1)*pic.W+x) = C;
+ }
+ }
+
+ CloseHandle( hfile );
+}
+
+
+
+void LoadPictureTGA(TPicture &pic, LPSTR pname)
+{
+ DWORD l;
+ WORD w,h;
+ HANDLE hfile;
+
+
+ hfile = CreateFile(pname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if( hfile==INVALID_HANDLE_VALUE ) {
+ char sz[512];
+ wsprintf( sz, "Error opening file\n%s.", pname );
+ DoHalt(sz);
+ }
+
+ SetFilePointer(hfile, 12, 0, FILE_BEGIN);
+
+ ReadFile( hfile, &w, 2, &l, NULL );
+ ReadFile( hfile, &h, 2, &l, NULL );
+
+ SetFilePointer(hfile, 18, 0, FILE_BEGIN);
+
+ _HeapFree(Heap, 0, (void*)pic.lpImage);
+ pic.lpImage = NULL;
+
+ pic.W = w;
+ pic.H = h;
+ pic.lpImage = (WORD*) _HeapAlloc(Heap, 0, pic.W * pic.H * 2);
+
+ for (int y=0; y<pic.H; y++)
+ ReadFile( hfile, (void*)(pic.lpImage + (pic.H-y-1)*pic.W), 2*pic.W, &l, NULL );
+
+ CloseHandle( hfile );
+}
+
+
+
+
+void CreateMipMapMT(WORD* dst, WORD* src, int H)
+{
+ for (int y=0; y<H; y++)
+ for (int x=0; x<127; x++) {
+ int C1 = *(src + (x*2+0) + (y*2+0)*256);
+ int C2 = *(src + (x*2+1) + (y*2+0)*256);
+ int C3 = *(src + (x*2+0) + (y*2+1)*256);
+ int C4 = *(src + (x*2+1) + (y*2+1)*256);
+
+ if (!HARD3D) { C1>>=1; C2>>=1; C3>>=1; C4>>=1; }
+
+ /*if (C1 == 0 && C2!=0) C1 = C2;
+ if (C1 == 0 && C3!=0) C1 = C3;
+ if (C1 == 0 && C4!=0) C1 = C4;*/
+
+ if (C1 == 0) { *(dst + x + y*128) = 0; continue; }
+
+ //C4 = C1;
+
+ if (!C2) C2=C1;
+ if (!C3) C3=C1;
+ if (!C4) C4=C1;
+
+ int B = ( ((C1>> 0) & 31) + ((C2 >>0) & 31) + ((C3 >>0) & 31) + ((C4 >>0) & 31) +2 ) >> 2;
+ int G = ( ((C1>> 5) & 31) + ((C2 >>5) & 31) + ((C3 >>5) & 31) + ((C4 >>5) & 31) +2 ) >> 2;
+ int R = ( ((C1>>10) & 31) + ((C2>>10) & 31) + ((C3>>10) & 31) + ((C4>>10) & 31) +2 ) >> 2;
+ if (!HARD3D) *(dst + x + y * 128) = HiColor(R,G,B)*2;
+ else *(dst + x + y * 128) = HiColor(R,G,B);
+ }
+}
+
+
+
+void CreateMipMapMT2(WORD* dst, WORD* src, int H)
+{
+ for (int y=0; y<H; y++)
+ for (int x=0; x<63; x++) {
+ int C1 = *(src + (x*2+0) + (y*2+0)*128);
+ int C2 = *(src + (x*2+1) + (y*2+0)*128);
+ int C3 = *(src + (x*2+0) + (y*2+1)*128);
+ int C4 = *(src + (x*2+1) + (y*2+1)*128);
+
+ if (!HARD3D) { C1>>=1; C2>>=1; C3>>=1; C4>>=1; }
+
+ if (C1 == 0) { *(dst + x + y*64) = 0; continue; }
+
+ //C2 = C1;
+
+ if (!C2) C2=C1;
+ if (!C3) C3=C1;
+ if (!C4) C4=C1;
+
+ int B = ( ((C1>> 0) & 31) + ((C2 >>0) & 31) + ((C3 >>0) & 31) + ((C4 >>0) & 31) +2 ) >> 2;
+ int G = ( ((C1>> 5) & 31) + ((C2 >>5) & 31) + ((C3 >>5) & 31) + ((C4 >>5) & 31) +2 ) >> 2;
+ int R = ( ((C1>>10) & 31) + ((C2>>10) & 31) + ((C3>>10) & 31) + ((C4>>10) & 31) +2 ) >> 2;
+ if (!HARD3D) *(dst + x + y * 64) = HiColor(R,G,B)*2;
+ else *(dst + x + y * 64) = HiColor(R,G,B);
+ }
+}
+
+
+
+void GetObjectCaracteristics(TModel* mptr, int& ylo, int& yhi)
+{
+ ylo = 10241024;
+ yhi =-10241024;
+ for (int v=0; v<mptr->VCount; v++) {
+ if (mptr->gVertex[v].y < ylo) ylo = (int)mptr->gVertex[v].y;
+ if (mptr->gVertex[v].y > yhi) yhi = (int)mptr->gVertex[v].y;
+ }
+ if (yhi<ylo) yhi=ylo+1;
+}
+
+
+
+void GenerateAlphaFlags(TModel *mptr)
+{
+#ifdef _soft
+#else
+
+ int w;
+ BOOL Opacity = FALSE;
+ WORD* tptr = mptr->lpTexture;
+
+ for (w=0; w<mptr->FCount; w++)
+ if ((mptr->gFace[w].Flags & sfOpacity)>0) Opacity = TRUE;
+
+ if (Opacity) {
+ for (w=0; w<256*256; w++)
+ if ( *(tptr+w)>0 ) *(tptr+w)=(*(tptr+w)) + 0x8000; }
+ else
+ for (w=0; w<256*256; w++)
+ *(tptr+w)=(*(tptr+w)) + 0x8000;
+
+ tptr = mptr->lpTexture2;
+ if (tptr==NULL) return;
+
+ if (Opacity) {
+ for (w=0; w<128*128; w++)
+ if ( (*(tptr+w))>0 ) *(tptr+w)=(*(tptr+w)) + 0x8000; }
+ else
+ for (w=0; w<128*128; w++)
+ *(tptr+w)=(*(tptr+w)) + 0x8000;
+
+ tptr = mptr->lpTexture3;
+ if (tptr==NULL) return;
+
+ if (Opacity) {
+ for (w=0; w<64*64; w++)
+ if ( (*(tptr+w))>0 ) *(tptr+w)=(*(tptr+w)) + 0x8000; }
+ else
+ for (w=0; w<64*64; w++)
+ *(tptr+w)=(*(tptr+w)) + 0x8000;
+
+#endif
+}
+
+
+
+
+void GenerateModelMipMaps(TModel *mptr)
+{
+ int th = (mptr->TextureHeight) / 2;
+ mptr->lpTexture2 =
+ (WORD*) _HeapAlloc(Heap, HEAP_ZERO_MEMORY , (1+th)*128*2);
+ CreateMipMapMT(mptr->lpTexture2, mptr->lpTexture, th);
+
+ th = (mptr->TextureHeight) / 4;
+ mptr->lpTexture3 =
+ (WORD*) _HeapAlloc(Heap, HEAP_ZERO_MEMORY , (1+th)*64*2);
+ CreateMipMapMT2(mptr->lpTexture3, mptr->lpTexture2, th);
+}
+
+
+void GenerateMapImage()
+{
+ int YShift = 23;
+ int XShift = 11;
+ int lsw = MapPic.W;
+ for (int y=0; y<256; y++)
+ for (int x=0; x<256; x++) {
+ int t;
+ WORD c;
+
+ if (FMap[y<<2][x<<2] & fmWater) {
+ t = WaterList[WMap[y<<2][x<<2]].tindex;
+ c= Textures[t]->DataD[(y & 15)*16+(x&15)];
+ } else {
+ t = TMap1[y<<2][x<<2];
+ c= Textures[t]->DataC[(y & 31)*32+(x&31)];
+ }
+
+ if (!HARD3D) c=c>>1; else c=conv_565(c);
+ *((WORD*)MapPic.lpImage + (y+YShift)*lsw + x + XShift) = c;
+ }
+}
+
+
+
+void ReleaseResources()
+{
+ HeapReleased=0;
+ for (int t=0; t<1024; t++)
+ if (Textures[t]) {
+ _HeapFree(Heap, 0, (void*)Textures[t]);
+ Textures[t] = NULL;
+ } else break;
+
+
+ for (int m=0; m<255; m++) {
+ TModel *mptr = MObjects[m].model;
+ if (mptr) {
+ _HeapFree(Heap,0,MObjects[m].bmpmodel.lpTexture);
+ MObjects[m].bmpmodel.lpTexture = NULL;
+
+ if (MObjects[m].vtl.FramesCount>0) {
+ _HeapFree(Heap, 0, MObjects[m].vtl.aniData);
+ MObjects[m].vtl.aniData = NULL;
+ }
+
+ _HeapFree(Heap,0,mptr->lpTexture); mptr->lpTexture = NULL;
+ _HeapFree(Heap,0,mptr->lpTexture2); mptr->lpTexture2 = NULL;
+ _HeapFree(Heap,0,mptr->lpTexture3); mptr->lpTexture3 = NULL;
+ _HeapFree(Heap,0,MObjects[m].model);
+ MObjects[m].model = NULL;
+ MObjects[m].vtl.FramesCount = 0;
+ } else break;
+ }
+
+ for (int a=0; a<255; a++) {
+ if (!Ambient[a].sfx.lpData) break;
+ _HeapFree(Heap, 0, Ambient[a].sfx.lpData);
+ Ambient[a].sfx.lpData = NULL;
+ }
+
+ for (int r=0; r<255; r++) {
+ if (!RandSound[r].lpData) break;
+ _HeapFree(Heap, 0, RandSound[r].lpData);
+ RandSound[r].lpData = NULL;
+ RandSound[r].length = 0;
+ }
+}
+
+
+void LoadBMPModel(TObject &obj)
+{
+ obj.bmpmodel.lpTexture = (WORD*) _HeapAlloc(Heap, 0, 128 * 128 * 2);
+ //WORD * lpT = (WORD*) _HeapAlloc(Heap, 0, 256 * 256 * 2);
+ //ReadFile(hfile, lpT, 256*256*2, &l, NULL);
+ //DATASHIFT(obj.bmpmodel.lpTexture, 128*128*2);
+ //BrightenTexture(lpT, 256*256);
+ ReadFile(hfile, obj.bmpmodel.lpTexture, 128*128*2, &l, NULL);
+ BrightenTexture(obj.bmpmodel.lpTexture, 128*128);
+ DATASHIFT(obj.bmpmodel.lpTexture, 128*128*2);
+ //CreateMipMapMT(obj.bmpmodel.lpTexture, lpT, 128);
+
+ //_HeapFree(Heap, 0, lpT);
+
+ if (HARD3D)
+ for (int x=0; x<128; x++)
+ for (int y=0; y<128; y++)
+ if ( *(obj.bmpmodel.lpTexture + x + y*128) )
+ *(obj.bmpmodel.lpTexture + x + y*128) |= 0x8000;
+
+ float mxx = obj.model->gVertex[0].x+0.5f;
+ float mnx = obj.model->gVertex[0].x-0.5f;
+
+ float mxy = obj.model->gVertex[0].x+0.5f;
+ float mny = obj.model->gVertex[0].y-0.5f;
+
+ for (int v=0; v<obj.model->VCount; v++) {
+ float x = obj.model->gVertex[v].x;
+ float y = obj.model->gVertex[v].y;
+ if (x > mxx) mxx=x;
+ if (x < mnx) mnx=x;
+ if (y > mxy) mxy=y;
+ if (y < mny) mny=y;
+ }
+
+ obj.bmpmodel.gVertex[0].x = mnx;
+ obj.bmpmodel.gVertex[0].y = mxy;
+ obj.bmpmodel.gVertex[0].z = 0;
+
+ obj.bmpmodel.gVertex[1].x = mxx;
+ obj.bmpmodel.gVertex[1].y = mxy;
+ obj.bmpmodel.gVertex[1].z = 0;
+
+ obj.bmpmodel.gVertex[2].x = mxx;
+ obj.bmpmodel.gVertex[2].y = mny;
+ obj.bmpmodel.gVertex[2].z = 0;
+
+ obj.bmpmodel.gVertex[3].x = mnx;
+ obj.bmpmodel.gVertex[3].y = mny;
+ obj.bmpmodel.gVertex[3].z = 0;
+}
+
+
+void LoadResources()
+{
+
+ int FadeRGB[3][3];
+ int TransRGB[3][3];
+
+ int tc,mc;
+ char MapName[128],RscName[128];
+ HeapAllocated=0;
+ if (strstr(ProjectName, "trophy")) {
+ TrophyMode = TRUE;
+ ctViewR = 60;
+ ctViewR1 = 48;
+ }
+ wsprintf(MapName,"%s%s", ProjectName, ".map");
+ wsprintf(RscName,"%s%s", ProjectName, ".rsc");
+
+ ReleaseResources();
+
+
+
+
+
+
+
+
+
+ hfile = CreateFile(RscName,
+ GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hfile==INVALID_HANDLE_VALUE) {
+ char sz[512];
+ wsprintf( sz, "Error opening resource file\n%s.", RscName );
+ DoHalt(sz);
+ return; }
+
+ ReadFile(hfile, &tc, 4, &l, NULL);
+ ReadFile(hfile, &mc, 4, &l, NULL);
+
+
+ ReadFile(hfile, FadeRGB, 4*3*3, &l, NULL);
+ ReadFile(hfile, TransRGB, 4*3*3, &l, NULL);
+
+ SkyR = FadeRGB[OptDayNight][0];
+ SkyG = FadeRGB[OptDayNight][1];
+ SkyB = FadeRGB[OptDayNight][2];
+
+ SkyTR = TransRGB[OptDayNight][0];
+ SkyTG = TransRGB[OptDayNight][1];
+ SkyTB = TransRGB[OptDayNight][2];
+
+ if (OptDayNight==2) {
+ SkyR = 0; SkyB = 0; SkyTR = 0; SkyTB = 0;
+ }
+
+ SkyTR = min(255,SkyTR * (OptBrightness + 128) / 256);
+ SkyTG = min(255,SkyTG * (OptBrightness + 128) / 256);
+ SkyTB = min(255,SkyTB * (OptBrightness + 128) / 256);
+
+ SkyR = min(255,SkyR * (OptBrightness + 128) / 256);
+ SkyG = min(255,SkyG * (OptBrightness + 128) / 256);
+ SkyB = min(255,SkyB * (OptBrightness + 128) / 256);
+
+
+ PrintLog("Loading textures:");
+ for (int tt=0; tt<tc; tt++)
+ LoadTexture(Textures[tt]);
+ PrintLog(" Done.\n");
+
+
+
+ PrintLog("Loading models:");
+ PrintLoad("Loading models...");
+ for (int mm=0; mm<mc; mm++) {
+ ReadFile(hfile, &MObjects[mm].info, 64, &l, NULL);
+ MObjects[mm].info.Radius*=2;
+ MObjects[mm].info.YLo*=2;
+ MObjects[mm].info.YHi*=2;
+ MObjects[mm].info.linelenght = (MObjects[mm].info.linelenght / 128) * 128;
+ LoadModel(MObjects[mm].model);
+ LoadBMPModel(MObjects[mm]);
+
+ if (MObjects[mm].info.flags & ofNOLIGHT)
+ FillMemory(MObjects[mm].model->VLight, 4*1024*4, 0);
+
+ if (MObjects[mm].info.flags & ofANIMATED)
+ LoadAnimation(MObjects[mm].vtl);
+
+
+ MObjects[mm].info.BoundR = 0;
+ for (int v=0; v<MObjects[mm].model->VCount; v++) {
+ float r = (float)sqrt(MObjects[mm].model->gVertex[v].x * MObjects[mm].model->gVertex[v].x +
+ MObjects[mm].model->gVertex[v].z * MObjects[mm].model->gVertex[v].z );
+ if (r>MObjects[mm].info.BoundR) MObjects[mm].info.BoundR=r;
+ }
+
+ if (MObjects[mm].info.flags & ofBOUND)
+ CalcBoundBox(MObjects[mm].model, MObjects[mm].bound);
+
+ GenerateModelMipMaps(MObjects[mm].model);
+ GenerateAlphaFlags(MObjects[mm].model);
+ }
+ PrintLog(" Done.\n");
+
+
+
+
+ PrintLoad("Finishing with .res...");
+ PrintLog("Finishing with .res:");
+ LoadSky();
+ LoadSkyMap();
+
+ int FgCount;
+ ReadFile(hfile, &FgCount, 4, &l, NULL);
+ ReadFile(hfile, &FogsList[1], FgCount * sizeof(TFogEntity), &l, NULL);
+
+
+ for (int f=0; f<=FgCount; f++) {
+ int fb = (FogsList[f].fogRGB >> 00) & 0xFF;
+ int fg = (FogsList[f].fogRGB >> 8) & 0xFF;
+ int fr = (FogsList[f].fogRGB >> 16) & 0xFF;
+ #ifdef _d3d
+ FogsList[f].fogRGB = (fr) + (fg<<8) + (fb<<16);
+ #endif
+ if (OptDayNight==2) FogsList[f].fogRGB&=0x00FF00;
+ }
+
+
+ int RdCount, AmbCount, WtrCount;
+
+ ReadFile(hfile, &RdCount, 4, &l, NULL);
+ for (int r=0; r<RdCount; r++) {
+ ReadFile(hfile, &RandSound[r].length, 4, &l, NULL);
+ RandSound[r].lpData = (short int*) _HeapAlloc(Heap,0,RandSound[r].length);
+ ReadFile(hfile, RandSound[r].lpData, RandSound[r].length, &l, NULL);
+ }
+
+ ReadFile(hfile, &AmbCount, 4, &l, NULL);
+ for (int a=0; a<AmbCount; a++) {
+ ReadFile(hfile, &Ambient[a].sfx.length, 4, &l, NULL);
+ Ambient[a].sfx.lpData = (short int*) _HeapAlloc(Heap,0,Ambient[a].sfx.length);
+ ReadFile(hfile, Ambient[a].sfx.lpData, Ambient[a].sfx.length, &l, NULL);
+
+ ReadFile(hfile, Ambient[a].rdata, sizeof(Ambient[a].rdata), &l, NULL);
+ ReadFile(hfile, &Ambient[a].RSFXCount, 4, &l, NULL);
+ ReadFile(hfile, &Ambient[a].AVolume, 4, &l, NULL);
+
+ if (Ambient[a].RSFXCount)
+ Ambient[a].RndTime = (Ambient[a].rdata[0].RFreq / 2 + rRand(Ambient[a].rdata[0].RFreq)) * 1000;
+
+ int F = Ambient[a].rdata[0].RFreq;
+ int E = Ambient[a].rdata[0].REnvir;
+/////////////////
+
+ //wsprintf(logt,"Env=%d Flag=%d Freq=%d\n", E, Ambient[a].rdata[0].Flags, F);
+ //PrintLog(logt);
+
+ if (OptDayNight==2)
+ for (int r=0; r<Ambient[a].RSFXCount; r++)
+ if (Ambient[a].rdata[r].Flags)
+ {
+ if (r!=15) memcpy(&Ambient[a].rdata[r], &Ambient[a].rdata[r+1], (15-r)*sizeof(TRD));
+ Ambient[a].RSFXCount--;
+ r--;
+ }
+
+ Ambient[a].rdata[0].RFreq = F;
+ Ambient[a].rdata[0].REnvir = E;
+
+
+ }
+
+ ReadFile(hfile, &WtrCount, 4, &l, NULL);
+ ReadFile(hfile, WaterList, 16*WtrCount, &l, NULL);
+
+ WaterList[255].wlevel = 0;
+ for (int w=0; w<WtrCount; w++) {
+#ifdef _3dfx
+ WaterList[w].fogRGB = (Textures[WaterList[w].tindex]->mR) +
+ (Textures[WaterList[w].tindex]->mG<<8) +
+ (Textures[WaterList[w].tindex]->mB<<16);
+#else
+ WaterList[w].fogRGB = (Textures[WaterList[w].tindex]->mB) +
+ (Textures[WaterList[w].tindex]->mG<<8) +
+ (Textures[WaterList[w].tindex]->mR<<16);
+#endif
+ }
+ CloseHandle(hfile);
+ PrintLog(" Done.\n");
+
+
+
+
+//================ Load MAPs file ==================//
+ PrintLoad("Loading .map...");
+ PrintLog("Loading .map:");
+ hfile = CreateFile(MapName,
+ GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hfile==INVALID_HANDLE_VALUE)
+ DoHalt("Error opening map file.");
+
+ ReadFile(hfile, HMap, 1024*1024, &l, NULL);
+ ReadFile(hfile, TMap1, 1024*1024*2, &l, NULL);
+ ReadFile(hfile, TMap2, 1024*1024*2, &l, NULL);
+ ReadFile(hfile, OMap, 1024*1024, &l, NULL);
+ ReadFile(hfile, FMap, 1024*1024*2, &l, NULL);
+ SetFilePointer(hfile, 1024*1024*OptDayNight, NULL, FILE_CURRENT);
+ ReadFile(hfile, LMap, 1024*1024, &l, NULL);
+ SetFilePointer(hfile, 1024*1024*(2-OptDayNight), NULL, FILE_CURRENT);
+ ReadFile(hfile, WMap , 1024*1024, &l, NULL);
+ ReadFile(hfile, HMapO, 1024*1024, &l, NULL);
+ ReadFile(hfile, FogsMap, 512*512, &l, NULL);
+ ReadFile(hfile, AmbMap, 512*512, &l, NULL);
+
+ if (FogsList[1].YBegin>1.f)
+ for (int x=0; x<510; x++)
+ for (int y=0; y<510; y++)
+ if (!FogsMap[y][x])
+ if (HMap[y*2+0][x*2+0]<FogsList[1].YBegin || HMap[y*2+0][x*2+1]<FogsList[1].YBegin || HMap[y*2+0][x*2+2] < FogsList[1].YBegin ||
+ HMap[y*2+1][x*2+0]<FogsList[1].YBegin || HMap[y*2+1][x*2+1]<FogsList[1].YBegin || HMap[y*2+1][x*2+2] < FogsList[1].YBegin ||
+ HMap[y*2+2][x*2+0]<FogsList[1].YBegin || HMap[y*2+2][x*2+1]<FogsList[1].YBegin || HMap[y*2+2][x*2+2] < FogsList[1].YBegin)
+ FogsMap[y][x] = 1;
+
+ CloseHandle(hfile);
+ PrintLog(" Done.\n");
+
+
+
+
+//======= Post load rendering ==============//
+ PrintLoad("Prepearing maps...");
+ CreateTMap();
+ RenderLightMap();
+
+ LoadPictureTGA(MapPic, "HUNTDAT\\MENU\\mapframe.tga");
+ conv_pic(MapPic);
+
+ GenerateMapImage();
+
+ if (TrophyMode) LoadPictureTGA(TrophyPic, "HUNTDAT\\MENU\\trophy.tga");
+ else LoadPictureTGA(TrophyPic, "HUNTDAT\\MENU\\trophy_g.tga");
+ conv_pic(TrophyPic);
+
+// ReInitGame();
+}
+
+
+
+void LoadCharacters()
+{
+ BOOL pres[64];
+ FillMemory(pres, sizeof(pres), 0);
+ pres[0]=TRUE;
+ for (int c=0; c<ChCount; c++) {
+ pres[Characters[c].CType] = TRUE;
+ }
+
+ for (c=0; c<TotalC; c++) if (pres[c]) {
+ if (!ChInfo[c].mptr) {
+ wsprintf(logt, "HUNTDAT\\%s", DinoInfo[c].FName);
+ LoadCharacterInfo(ChInfo[c], logt);
+ PrintLog("Loading: "); PrintLog(logt); PrintLog("\n");
+ }
+ }
+
+ for (c=10; c<20; c++)
+ if (TargetDino & (1<<c))
+ if (!DinoInfo[AI_to_CIndex[c]].CallIcon.lpImage) {
+ wsprintf(logt, "HUNTDAT\\MENU\\PICS\\call%d.tga", c-9);
+ LoadPictureTGA(DinoInfo[AI_to_CIndex[c]].CallIcon, logt);
+ conv_pic(DinoInfo[AI_to_CIndex[c]].CallIcon);
+ }
+
+
+ for (c=0; c<TotalW; c++)
+ if (WeaponPres & (1<<c)) {
+ if (!Weapon.chinfo[c].mptr) {
+ wsprintf(logt, "HUNTDAT\\WEAPONS\\%s", WeapInfo[c].FName);
+ LoadCharacterInfo(Weapon.chinfo[c], logt);
+ PrintLog("Loading: "); PrintLog(logt); PrintLog("\n");
+ }
+
+
+ if (!Weapon.BulletPic[c].lpImage) {
+ wsprintf(logt, "HUNTDAT\\WEAPONS\\%s", WeapInfo[c].BFName);
+ LoadPictureTGA(Weapon.BulletPic[c], logt);
+ conv_pic(Weapon.BulletPic[c]);
+ PrintLog("Loading: "); PrintLog(logt); PrintLog("\n");
+ }
+
+ }
+
+ for (c=10; c<20; c++)
+ if (TargetDino & (1<<c))
+ if (!fxCall[c-10][0].lpData) {
+ wsprintf(logt,"HUNTDAT\\SOUNDFX\\CALLS\\call%d_a.wav", (c-9));
+ LoadWav(logt, fxCall[c-10][0]);
+ wsprintf(logt,"HUNTDAT\\SOUNDFX\\CALLS\\call%d_b.wav", (c-9));
+ LoadWav(logt, fxCall[c-10][1]);
+ wsprintf(logt,"HUNTDAT\\SOUNDFX\\CALLS\\call%d_c.wav", (c-9));
+ LoadWav(logt, fxCall[c-10][2]);
+ }
+}
+
+void ReInitGame()
+{
+ PrintLog("ReInitGame();\n");
+ PlaceHunter();
+ if (TrophyMode) PlaceTrophy();
+ else PlaceCharacters();
+
+ LoadCharacters();
+
+ LockLanding = FALSE;
+ Wind.alpha = rRand(1024) * 2.f * pi / 1024.f;
+ Wind.speed = 10;
+ MyHealth = MAX_HEALTH;
+ TargetWeapon = -1;
+
+ for (int w=0; w<TotalW; w++)
+ if ( WeaponPres & (1<<w) ) {
+ ShotsLeft[w] = WeapInfo[w].Shots;
+ if (DoubleAmmo) AmmoMag[w] = 1;
+ if (TargetWeapon==-1) TargetWeapon=w;
+ }
+
+ CurrentWeapon = TargetWeapon;
+
+ Weapon.state = 0;
+ Weapon.FTime = 0;
+ PlayerAlpha = 0;
+ PlayerBeta = 0;
+
+ WCCount = 0;
+ SnCount = 0;
+ ElCount = 0;
+ BloodTrail.Count = 0;
+ BINMODE = FALSE;
+ OPTICMODE = FALSE;
+ EXITMODE = FALSE;
+ PAUSE = FALSE;
+
+ Ship.pos.x = PlayerX;
+ Ship.pos.z = PlayerZ;
+ Ship.pos.y = GetLandUpH(Ship.pos.x, Ship.pos.z) + 2048;
+ Ship.State = -1;
+ Ship.tgpos.x = Ship.pos.x;
+ Ship.tgpos.z = Ship.pos.z + 60*256;
+ Ship.cindex = -1;
+ Ship.tgpos.y = GetLandUpH(Ship.tgpos.x, Ship.tgpos.z) + 2048;
+ ShipTask.tcount = 0;
+
+ if (!TrophyMode) {
+ TrophyRoom.Last.smade = 0;
+ TrophyRoom.Last.success = 0;
+ TrophyRoom.Last.path = 0;
+ TrophyRoom.Last.time = 0;
+ }
+
+ DemoPoint.DemoTime = 0;
+ RestartMode = FALSE;
+ TrophyTime=0;
+ answtime = 0;
+ ExitTime = 0;
+}
+
+
+
+void ReleaseCharacterInfo(TCharacterInfo &chinfo)
+{
+ if (!chinfo.mptr) return;
+
+ _HeapFree(Heap, 0, chinfo.mptr);
+ chinfo.mptr = NULL;
+
+ for (int c = 0; c<64; c++) {
+ if (!chinfo.Animation[c].aniData) break;
+ _HeapFree(Heap, 0, chinfo.Animation[c].aniData);
+ chinfo.Animation[c].aniData = NULL;
+ }
+
+ for (c = 0; c<64; c++) {
+ if (!chinfo.SoundFX[c].lpData) break;
+ _HeapFree(Heap, 0, chinfo.SoundFX[c].lpData);
+ chinfo.SoundFX[c].lpData = NULL;
+ }
+
+ chinfo.AniCount = 0;
+ chinfo.SfxCount = 0;
+}
+
+
+
+
+void LoadCharacterInfo(TCharacterInfo &chinfo, char* FName)
+{
+ ReleaseCharacterInfo(chinfo);
+
+ HANDLE hfile = CreateFile(FName,
+ GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hfile==INVALID_HANDLE_VALUE) {
+ char sz[512];
+ wsprintf( sz, "Error opening character file:\n%s.", FName );
+ DoHalt(sz);
+ }
+
+ ReadFile(hfile, chinfo.ModelName, 32, &l, NULL);
+ ReadFile(hfile, &chinfo.AniCount, 4, &l, NULL);
+ ReadFile(hfile, &chinfo.SfxCount, 4, &l, NULL);
+
+//============= read model =================//
+
+ chinfo.mptr = (TModel*) _HeapAlloc(Heap, 0, sizeof(TModel));
+
+ ReadFile( hfile, &chinfo.mptr->VCount, 4, &l, NULL );
+ ReadFile( hfile, &chinfo.mptr->FCount, 4, &l, NULL );
+ ReadFile( hfile, &chinfo.mptr->TextureSize, 4, &l, NULL );
+ ReadFile( hfile, chinfo.mptr->gFace, chinfo.mptr->FCount<<6, &l, NULL );
+ ReadFile( hfile, chinfo.mptr->gVertex, chinfo.mptr->VCount<<4, &l, NULL );
+
+ int ts = chinfo.mptr->TextureSize;
+ if (HARD3D) chinfo.mptr->TextureHeight = 256;
+ else chinfo.mptr->TextureHeight = chinfo.mptr->TextureSize>>9;
+ chinfo.mptr->TextureSize = chinfo.mptr->TextureHeight*512;
+
+ chinfo.mptr->lpTexture = (WORD*) _HeapAlloc(Heap, 0, chinfo.mptr->TextureSize);
+
+ ReadFile(hfile, chinfo.mptr->lpTexture, ts, &l, NULL);
+ BrightenTexture(chinfo.mptr->lpTexture, ts/2);
+
+ DATASHIFT(chinfo.mptr->lpTexture, chinfo.mptr->TextureSize);
+ GenerateModelMipMaps(chinfo.mptr);
+ GenerateAlphaFlags(chinfo.mptr);
+ //CalcLights(chinfo.mptr);
+
+ //ApplyAlphaFlags(chinfo.mptr->lpTexture, 256*256);
+ //ApplyAlphaFlags(chinfo.mptr->lpTexture2, 128*128);
+//============= read animations =============//
+ for (int a=0; a<chinfo.AniCount; a++) {
+ ReadFile(hfile, chinfo.Animation[a].aniName, 32, &l, NULL);
+ ReadFile(hfile, &chinfo.Animation[a].aniKPS, 4, &l, NULL);
+ ReadFile(hfile, &chinfo.Animation[a].FramesCount, 4, &l, NULL);
+ chinfo.Animation[a].AniTime = (chinfo.Animation[a].FramesCount * 1000) / chinfo.Animation[a].aniKPS;
+ chinfo.Animation[a].aniData = (short int*)
+ _HeapAlloc(Heap, 0, (chinfo.mptr->VCount*chinfo.Animation[a].FramesCount*6) );
+
+ ReadFile(hfile, chinfo.Animation[a].aniData, (chinfo.mptr->VCount*chinfo.Animation[a].FramesCount*6), &l, NULL);
+ }
+
+//============= read sound fx ==============//
+ BYTE tmp[32];
+ for (int s=0; s<chinfo.SfxCount; s++) {
+ ReadFile(hfile, tmp, 32, &l, NULL);
+ ReadFile(hfile, &chinfo.SoundFX[s].length, 4, &l, NULL);
+ chinfo.SoundFX[s].lpData = (short int*) _HeapAlloc(Heap, 0, chinfo.SoundFX[s].length);
+ ReadFile(hfile, chinfo.SoundFX[s].lpData, chinfo.SoundFX[s].length, &l, NULL);
+ }
+
+ for (int v=0; v<chinfo.mptr->VCount; v++) {
+ chinfo.mptr->gVertex[v].x*=2.f;
+ chinfo.mptr->gVertex[v].y*=2.f;
+ chinfo.mptr->gVertex[v].z*=-2.f;
+ }
+
+ CorrectModel(chinfo.mptr);
+
+
+ ReadFile(hfile, chinfo.Anifx, 64*4, &l, NULL);
+ if (l!=256)
+ for (l=0; l<64; l++) chinfo.Anifx[l] = -1;
+ CloseHandle(hfile);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//================ light map ========================//
+
+
+
+void FillVector(int x, int y, Vector3d& v)
+{
+ v.x = (float)x*256;
+ v.z = (float)y*256;
+ v.y = (float)((int)HMap[y][x])*ctHScale;
+}
+
+BOOL TraceVector(Vector3d v, Vector3d lv)
+{
+ v.y+=4;
+ NormVector(lv,64);
+ for (int l=0; l<32; l++) {
+ v.x-=lv.x; v.y-=lv.y/6; v.z-=lv.z;
+ if (v.y>255 * ctHScale) return TRUE;
+ if (GetLandH(v.x, v.z) > v.y) return FALSE;
+ }
+ return TRUE;
+}
+
+
+void AddShadow(int x, int y, int d)
+{
+ if (x<0 || y<0 || x>1023 || y>1023) return;
+ int l = LMap[y][x];
+ l-=d;
+ if (l<32) l=32;
+ LMap[y][x]=l;
+}
+
+void RenderShadowCircle(int x, int y, int R, int D)
+{
+ int cx = x / 256;
+ int cy = y / 256;
+ int cr = 1 + R / 256;
+ for (int yy=-cr; yy<=cr; yy++)
+ for (int xx=-cr; xx<=cr; xx++) {
+ int tx = (cx+xx)*256;
+ int ty = (cy+yy)*256;
+ int r = (int)sqrt( (tx-x)*(tx-x) + (ty-y)*(ty-y) );
+ if (r>R) continue;
+ AddShadow(cx+xx, cy+yy, D * (R-r) / R);
+ }
+}
+
+void RenderLightMap()
+{
+
+
+ Vector3d lv;
+ int x,y;
+
+ lv.x = - 412;
+ lv.z = - 412;
+ lv.y = - 1024;
+ NormVector(lv, 1.0f);
+
+ for (y=1; y<ctMapSize-1; y++)
+ for (x=1; x<ctMapSize-1; x++) {
+ int ob = OMap[y][x];
+ if (ob == 255) continue;
+
+ int l = MObjects[ob].info.linelenght / 128;
+ int s = 1;
+ if (OptDayNight==2) s=-1;
+ if (OptDayNight!=1) l = MObjects[ob].info.linelenght / 70;
+ if (l>0) RenderShadowCircle(x*256+128,y*256+128, 256, MObjects[ob].info.lintensity * 2);
+ for (int i=1; i<l; i++)
+ AddShadow(x+i*s, y+i*s, MObjects[ob].info.lintensity);
+
+ l = MObjects[ob].info.linelenght * 2;
+ RenderShadowCircle(x*256+128+l*s,y*256+128+l*s,
+ MObjects[ob].info.circlerad*2,
+ MObjects[ob].info.cintensity*4);
+ }
+
+}
+
+
+
+
+
+void SaveScreenShot()
+ {
+
+ HANDLE hf; /* file handle */
+ BITMAPFILEHEADER hdr; /* bitmap file-header */
+ BITMAPINFOHEADER bmi; /* bitmap info-header */
+ DWORD dwTmp;
+
+ if (WinW>1024) return;
+
+
+ //MessageBeep(0xFFFFFFFF);
+ CopyHARDToDIB();
+
+ bmi.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.biWidth = WinW;
+ bmi.biHeight = WinH;
+ bmi.biPlanes = 1;
+ bmi.biBitCount = 24;
+ bmi.biCompression = BI_RGB;
+
+ bmi.biSizeImage = WinW*WinH*3;
+ bmi.biClrImportant = 0;
+ bmi.biClrUsed = 0;
+
+
+
+ hdr.bfType = 0x4d42;
+ hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
+ bmi.biSize + bmi.biSizeImage);
+ hdr.bfReserved1 = 0;
+ hdr.bfReserved2 = 0;
+ hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
+ bmi.biSize;
+
+
+ char t[12];
+ wsprintf(t,"HUNT%004d.BMP",++_shotcounter);
+ hf = CreateFile(t,
+ GENERIC_READ | GENERIC_WRITE,
+ (DWORD) 0,
+ (LPSECURITY_ATTRIBUTES) NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ (HANDLE) NULL);
+
+
+
+ WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL);
+
+ WriteFile(hf, &bmi, sizeof(BITMAPINFOHEADER), (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL);
+
+ byte fRGB[1024][3];
+
+ for (int y=0; y<WinH; y++) {
+ for (int x=0; x<WinW; x++) {
+ WORD C = *((WORD*)lpVideoBuf + (WinEY-y)*1024+x);
+ fRGB[x][0] = (C & 31)<<3;
+ if (HARD3D) {
+ fRGB[x][1] = ((C>> 5) & 63)<<2;
+ fRGB[x][2] = ((C>>11) & 31)<<3;
+ } else {
+ fRGB[x][1] = ((C>> 5) & 31)<<3;
+ fRGB[x][2] = ((C>>10) & 31)<<3;
+ }
+ }
+ WriteFile( hf, fRGB, 3*WinW, &dwTmp, NULL );
+ }
+
+ CloseHandle(hf);
+ //MessageBeep(0xFFFFFFFF);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+//===============================================================================================
+void ReadWeapons(FILE *stream)
+{
+ TotalW = 0;
+ char line[256], *value;
+ while (fgets( line, 255, stream))
+ {
+ if (strstr(line, "}")) break;
+ if (strstr(line, "{"))
+ while (fgets( line, 255, stream)) {
+ if (strstr(line, "}")) { TotalW++; break; }
+ value = strstr(line, "=");
+ if (!value) DoHalt("Script loading error");
+ value++;
+
+ if (strstr(line, "power")) WeapInfo[TotalW].Power = (float)atof(value);
+ if (strstr(line, "prec")) WeapInfo[TotalW].Prec = (float)atof(value);
+ if (strstr(line, "loud")) WeapInfo[TotalW].Loud = (float)atof(value);
+ if (strstr(line, "rate")) WeapInfo[TotalW].Rate = (float)atof(value);
+ if (strstr(line, "shots")) WeapInfo[TotalW].Shots = atoi(value);
+ if (strstr(line, "reload")) WeapInfo[TotalW].Reload= atoi(value);
+ if (strstr(line, "trace")) WeapInfo[TotalW].TraceC= atoi(value)-1;
+ if (strstr(line, "optic")) WeapInfo[TotalW].Optic = atoi(value);
+ if (strstr(line, "fall")) WeapInfo[TotalW].Fall = atoi(value);
+ //if (strstr(line, "price")) WeapInfo[TotalW].Price = atoi(value);
+
+ if (strstr(line, "name")) {
+ value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
+ value[strlen(value)-2] = 0;
+ strcpy(WeapInfo[TotalW].Name, &value[1]); }
+
+ if (strstr(line, "file")) {
+ value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
+ value[strlen(value)-2] = 0;
+ strcpy(WeapInfo[TotalW].FName, &value[1]);}
+
+ if (strstr(line, "pic")) {
+ value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
+ value[strlen(value)-2] = 0;
+ strcpy(WeapInfo[TotalW].BFName, &value[1]);}
+ }
+
+ }
+
+}
+
+
+void ReadCharacters(FILE *stream)
+{
+ TotalC = 0;
+ char line[256], *value;
+ while (fgets( line, 255, stream))
+ {
+ if (strstr(line, "}")) break;
+ if (strstr(line, "{"))
+ while (fgets( line, 255, stream)) {
+
+ if (strstr(line, "}")) {
+ AI_to_CIndex[DinoInfo[TotalC].AI] = TotalC;
+ TotalC++;
+ break;
+ }
+
+ value = strstr(line, "=");
+ if (!value)
+ DoHalt("Script loading error");
+ value++;
+
+ if (strstr(line, "mass" )) DinoInfo[TotalC].Mass = (float)atof(value);
+ if (strstr(line, "length" )) DinoInfo[TotalC].Length = (float)atof(value);
+ if (strstr(line, "radius" )) DinoInfo[TotalC].Radius = (float)atof(value);
+ if (strstr(line, "health" )) DinoInfo[TotalC].Health0 = atoi(value);
+ if (strstr(line, "basescore")) DinoInfo[TotalC].BaseScore = atoi(value);
+ if (strstr(line, "ai" )) DinoInfo[TotalC].AI = atoi(value);
+ if (strstr(line, "smell" )) DinoInfo[TotalC].SmellK = (float)atof(value);
+ if (strstr(line, "hear" )) DinoInfo[TotalC].HearK = (float)atof(value);
+ if (strstr(line, "look" )) DinoInfo[TotalC].LookK = (float)atof(value);
+ if (strstr(line, "shipdelta")) DinoInfo[TotalC].ShDelta = (float)atof(value);
+ if (strstr(line, "scale0" )) DinoInfo[TotalC].Scale0 = atoi(value);
+ if (strstr(line, "scaleA" )) DinoInfo[TotalC].ScaleA = atoi(value);
+ if (strstr(line, "danger" )) DinoInfo[TotalC].DangerCall= TRUE;
+
+ if (strstr(line, "name")) {
+ value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
+ value[strlen(value)-2] = 0;
+ strcpy(DinoInfo[TotalC].Name, &value[1]); }
+
+ if (strstr(line, "file")) {
+ value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
+ value[strlen(value)-2] = 0;
+ strcpy(DinoInfo[TotalC].FName, &value[1]);}
+
+ if (strstr(line, "pic")) {
+ value = strstr(line, "'"); if (!value) DoHalt("Script loading error");
+ value[strlen(value)-2] = 0;
+ strcpy(DinoInfo[TotalC].PName, &value[1]);}
+ }
+
+ }
+}
+
+
+
+void LoadResourcesScript()
+{
+ FILE *stream;
+ char line[256];
+
+ stream = fopen("HUNTDAT\\_res.txt", "r");
+ if (!stream) DoHalt("Can't open resources file _res.txt");
+
+ while (fgets( line, 255, stream)) {
+ if (line[0] == '.') break;
+ if (strstr(line, "weapons") ) ReadWeapons(stream);
+ if (strstr(line, "characters") ) ReadCharacters(stream);
+ }
+
+ fclose (stream);
+}
+//===============================================================================================
+
+
+
+
+
+void CreateLog()
+{
+
+ hlog = CreateFile("render.log",
+ GENERIC_WRITE,
+ FILE_SHARE_READ, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+#ifdef _d3d
+ PrintLog("Carnivores Ice Age D3D video driver.");
+#endif
+
+#ifdef _3dfx
+ PrintLog("Carnivores Ice Age 3DFX video driver.");
+#endif
+
+#ifdef _soft
+ PrintLog("Carnivores Ice Age Soft video driver.");
+#endif
+ PrintLog(" Build v2.04. Sep.24 1999.\n");
+}
+
+
+void PrintLog(LPSTR l)
+{
+ DWORD w;
+
+ if (l[strlen(l)-1]==0x0A) {
+ BYTE b = 0x0D;
+ WriteFile(hlog, l, strlen(l)-1, &w, NULL);
+ WriteFile(hlog, &b, 1, &w, NULL);
+ b = 0x0A;
+ WriteFile(hlog, &b, 1, &w, NULL);
+ } else
+ WriteFile(hlog, l, strlen(l), &w, NULL);
+
+}
+
+void CloseLog()
+{
+ CloseHandle(hlog);
+} \ No newline at end of file
diff --git a/a.bat b/a.bat
new file mode 100644
index 0000000..5fd6dac
--- /dev/null
+++ b/a.bat
@@ -0,0 +1 @@
+v_d3d.exe prj=HUNTDAT\AREAS\area1 x=600 y=800 dtm=1 wep=31 -radar \ No newline at end of file
diff --git a/action.ico b/action.ico
new file mode 100644
index 0000000..a71305d
--- /dev/null
+++ b/action.ico
Binary files differ
diff --git a/mathematics.cpp b/mathematics.cpp
new file mode 100644
index 0000000..d29d76e
--- /dev/null
+++ b/mathematics.cpp
@@ -0,0 +1,956 @@
+#include "Hunt.h"
+
+Vector3d TraceA, TraceB, TraceNv;
+int TraceRes;
+
+
+
+
+//====================================================
+void NormVector(Vector3d& v, float Scale)
+{
+ double n;
+ n=v.x*v.x + v.y*v.y + v.z*v.z;
+ if (n<0.000000001) n=0.000000001;
+ n=(double)Scale / sqrt(n);
+ v.x=v.x*n;
+ v.y=v.y*n;
+ v.z=v.z*n;
+}
+
+float SGN(float f)
+{
+ if (f<0) return -1.f;
+ else return 1.f;
+}
+
+void DeltaFunc(float &a, float b, float d)
+{
+ if (b > a) {
+ a+=d; if (a > b) a = b;
+ } else {
+ a-=d; if (a < b) a = b;
+ }
+}
+
+
+void MulVectorsScal(Vector3d& v1,Vector3d& v2, float& r)
+{
+ r = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
+}
+
+
+void MulVectorsVect(Vector3d& v1, Vector3d& v2, Vector3d& r )
+{
+ r.x= v1.y*v2.z - v2.y*v1.z;
+ r.y=-v1.x*v2.z + v2.x*v1.z;
+ r.z= v1.x*v2.y - v2.x*v1.y;
+}
+
+Vector3d RotateVector(Vector3d& v)
+{
+ Vector3d vv;
+ float vx = v.x * ca + v.z * sa;
+ float vz = v.z * ca - v.x * sa;
+ float vy = v.y;
+ vv.x = vx;
+ vv.y = vy * cb - vz * sb;
+ vv.z = vz * cb + vy * sb;
+ return vv;
+}
+
+
+
+Vector3d SubVectors( Vector3d& v1, Vector3d& v2 )
+{
+ Vector3d res;
+ res.x = v1.x-v2.x;
+ res.y = v1.y-v2.y;
+ res.z = v1.z-v2.z;
+ return res;
+}
+
+Vector3d AddVectors( Vector3d& v1, Vector3d& v2 )
+{
+ Vector3d res;
+ res.x = v1.x+v2.x;
+ res.y = v1.y+v2.y;
+ res.z = v1.z+v2.z;
+ return res;
+}
+
+float VectorLength(Vector3d v)
+{
+ return (float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
+}
+
+
+int siRand(int R)
+{
+ return (rand() * (R * 2 +1)) / RAND_MAX - R;
+}
+
+
+int rRand(int r)
+{
+ if (!r) return 0;
+ int res = rand() % (r+1);// / (RAND_MAX);
+ //if (res > r) res = r;
+ return res;
+}
+
+
+
+void CalcHitPoint(CLIPPLANE& C, Vector3d& a, Vector3d& b, Vector3d& hp)
+{
+ float SCLN,SCVN;
+ Vector3d lv = SubVectors(b,a);
+ NormVector(lv, 1.0);
+
+ MulVectorsScal(a, C.nv, SCLN);
+ MulVectorsScal(lv,C.nv, SCVN);
+
+ SCLN/=SCVN; SCLN=(float)fabs(SCLN);
+ hp.x = a.x + lv.x * SCLN;
+ hp.y = a.y + lv.y * SCLN;
+ hp.z = a.z + lv.z * SCLN;
+}
+
+
+float PointToVectorD(Vector3d A, Vector3d AB, Vector3d C)
+{
+ Vector3d AC = SubVectors(C,A);
+ Vector3d vm;
+ MulVectorsVect(AB, AC, vm);
+ return VectorLength(vm);
+}
+
+
+float Mul2dVectors(float vx, float vy, float ux, float uy)
+{
+ return vx*uy - ux*vy;
+}
+
+
+float _FindVectorAlpha(float vx, float vy)
+{
+ float adx, ady, alpha, dalpha;
+
+ adx=(float)fabs(vx);
+ ady=(float)fabs(vy);
+
+ alpha = pi / 4.f;
+ dalpha = pi / 8.f;
+
+ for (int i=1; i<=10; i++) {
+ alpha=alpha-dalpha*SGN(Mul2dVectors(adx,ady, (float)f_cos(alpha), (float)f_sin(alpha)));
+ dalpha/=2;
+ }
+
+ if (vx<0) if (vy<0) alpha+=pi; else alpha=pi-alpha;
+ else if (vy<0) alpha=2.f*pi-alpha;
+
+ return alpha;
+}
+
+float FindVectorAlpha(float vx, float vy)
+{
+ float al = atan2(-vy, -vx)+pi;
+ if (al<0) al = 2.f*pi-al;
+ if (al>2.f*pi) al = al-2.f*pi;
+ //wsprintf(logt, "%d %d", (int)(al*100), (int)(_FindVectorAlpha(vx, vy)*100));
+ //AddMessage(logt);
+ return al;
+}
+
+
+void CheckBoundCollision(float &px, float &py, float cx, float cy, float oy, TBound *bound, int angle)
+{
+ float ppx=px-cx;
+ float ppy=py-cy;
+
+ float ca = (float) f_cos(angle*pi / 2.f);
+ float sa = (float) f_sin(angle*pi / 2.f);
+ float w,h;
+
+ for (int o=0; o<8; o++) {
+
+ if (bound[o].a<0) continue;
+ if (bound[o].y2 + oy < PlayerY + 128) continue;
+ if (bound[o].y1 + oy > PlayerY + 256) continue;
+
+ float ccx = bound[o].cx*ca + bound[o].cy*sa;
+ float ccy = bound[o].cy*ca - bound[o].cx*sa;
+
+ if (angle & 1) {
+ w = bound[o].b+2.f;
+ h = bound[o].a+2.f;
+ } else {
+ w = bound[o].a+2.f;
+ h = bound[o].b+2.f;
+ }
+
+ float dw = fabs(ppx - ccx) - w;
+ float dh = fabs(ppy - ccy) - h;
+
+ if ( (dw > 0) || (dh > 0) ) continue;
+
+ if (dw > dh) {
+ px = cx+ccx + w * SGN(ppx-ccx);
+ } else {
+ py = cy+ccy + h * SGN(ppy-ccy);
+ }
+ }
+}
+
+
+
+void CheckCollision(float &cx, float &cz)
+{
+ if (cx < 36*256) cx = 36*256;
+ if (cz < 36*256) cz = 36*256;
+ if (cx >980*256) cx =980*256;
+ if (cz >980*256) cz =980*256;
+ int ccx = (int)cx / 256;
+ int ccz = (int)cz / 256;
+
+ for (int z=-4; z<=4; z++)
+ for (int x=-4; x<=4; x++)
+ if (OMap[ccz+z][ccx+x]!=255) {
+ int ob = OMap[ccz+z][ccx+x];
+ float CR = (float)MObjects[ob].info.Radius;
+
+ float oz = (ccz+z) * 256.f + 128.f;
+ float ox = (ccx+x) * 256.f + 128.f;
+
+ float LandY = GetLandOH(ccx+x, ccz+z);
+
+ if (!(MObjects[ob].info.flags & ofBOUND)) {
+ if (MObjects[ob].info.YHi + LandY < PlayerY + 128) continue;
+ if (MObjects[ob].info.YLo + LandY > PlayerY + 256) continue;
+ }
+
+ if (MObjects[ob].info.flags & ofBOUND) {
+ CheckBoundCollision(cx, cz, ox, oz, LandY, MObjects[ob].bound, ((FMap[ccz+z][ccx+x] >> 2) & 3) );
+ }
+ else
+ if (MObjects[ob].info.flags & ofCIRCLE) {
+ float r = (float) sqrt( (ox-cx)*(ox-cx) + (oz-cz)*(oz-cz) );
+ if (r<CR) {
+ cx = cx - (ox - cx) * (CR-r)/r;
+ cz = cz - (oz - cz) * (CR-r)/r; }
+ } else {
+ float r = (float) max( fabs(ox-cx) , fabs(oz-cz) );
+ if (r<CR) {
+ if (fabs(ox-cx) > fabs(oz-cz) )
+ cx = cx - (ox - cx) * (CR-r)/r;
+ else
+ cz = cz - (oz - cz) * (CR-r)/r;
+ }
+ }
+ }
+
+ if (!TrophyMode) return;
+ for (int c=0; c<ChCount; c++) {
+ float px = Characters[c].pos.x;
+ float pz = Characters[c].pos.z;
+ float CR = DinoInfo[ Characters[c].CType ].Radius;
+ float r = (float) sqrt( (px-cx)*(px-cx) + (pz-cz)*(pz-cz) );
+ if (r<CR) {
+ cx = cx - (px - cx) * (CR-r)/r;
+ cz = cz - (pz - cz) * (CR-r)/r;
+ }
+
+ }
+
+}
+
+
+
+int TraceCheckPlane(Vector3d a, Vector3d b, Vector3d c)
+{
+ Vector3d pnv,hp;
+ float sa, sb;
+ MulVectorsVect(SubVectors(b,a), SubVectors(c,a), pnv);
+ NormVector(pnv, 1.f);
+
+ MulVectorsScal(SubVectors(TraceA,a), pnv, sa);
+ MulVectorsScal(SubVectors(TraceB,a), pnv, sb);
+ if (sa*sb>-1.f) return 0;
+
+//========= calc hit point =======//
+ float SCLN,SCVN;
+
+ MulVectorsScal(SubVectors(TraceA,a), pnv, SCLN);
+ MulVectorsScal(TraceNv, pnv, SCVN);
+
+ SCLN/=SCVN; SCLN=(float)fabs(SCLN);
+ hp.x = TraceA.x + TraceNv.x * SCLN;
+ hp.y = TraceA.y + TraceNv.y * SCLN;
+ hp.z = TraceA.z + TraceNv.z * SCLN;
+
+ Vector3d vm;
+ MulVectorsVect( SubVectors(b,a), SubVectors(hp,a), vm);
+ MulVectorsScal( vm, pnv, sa); if (sa<0) return 0;
+
+ MulVectorsVect( SubVectors(c,b), SubVectors(hp,b), vm);
+ MulVectorsScal( vm, pnv, sa); if (sa<0) return 0;
+
+ MulVectorsVect( SubVectors(a,c), SubVectors(hp,c), vm);
+ MulVectorsScal( vm, pnv, sa); if (sa<0) return 0;
+
+
+ if (VectorLength(SubVectors(hp, TraceA)) <
+ VectorLength(SubVectors(TraceB, TraceA)) ) {
+ TraceB = hp;
+ return 1; }
+
+ return 0;
+}
+
+
+void TraceModel(int xx, int zz, int o)
+{
+ TModel *mptr = MObjects[o].model;
+ v[0].x = xx * 256.f + 128.f;
+ v[0].z = zz * 256.f + 128.f;
+ v[0].y = (float)(HMapO[zz][xx]) * ctHScale;
+
+ v[0].y+=700.f;
+ if (PointToVectorD(TraceA, TraceNv, v[0]) >1400.f) return;
+ v[0].y-=700.f;
+
+ float malp = (float)((FMap[zz][xx] >> 2) & 7) * 2.f*pi / 8.f;
+
+ float ca = (float)f_cos(malp);
+ float sa = (float)f_sin(malp);
+
+ for (int vv=0; vv<mptr->VCount; vv++) {
+ rVertex[vv].x = mptr->gVertex[vv].x * ca + mptr->gVertex[vv].z * sa + v[0].x;
+ rVertex[vv].y = mptr->gVertex[vv].y + v[0].y;
+ rVertex[vv].z = mptr->gVertex[vv].z * ca - mptr->gVertex[vv].x * sa + v[0].z;
+ }
+
+ for (int f=0; f<mptr->FCount; f++) {
+ TFace *fptr = &mptr->gFace[f];
+ if (fptr->Flags & (sfOpacity + sfTransparent) ) continue;
+ v[0] = rVertex[fptr->v1];
+ v[1] = rVertex[fptr->v2];
+ v[2] = rVertex[fptr->v3];
+ if (TraceCheckPlane(v[0], v[1], v[2]) )
+ TraceRes = tresModel;
+ }
+}
+
+
+
+
+void TraceCharacter(int c)
+{
+ TCharacter *cptr = &Characters[c];
+
+ if (PointToVectorD(TraceA, TraceNv, cptr->pos) > 1024.f) return;
+
+ TModel *mptr = cptr->pinfo->mptr;
+ CreateChMorphedModel(cptr);
+ float ca = (float)f_cos(-cptr->alpha + pi / 2.f);
+ float sa = (float)f_sin(-cptr->alpha + pi / 2.f);
+ for (int vv=0; vv<mptr->VCount; vv++) {
+ rVertex[vv].x = mptr->gVertex[vv].x * ca + mptr->gVertex[vv].z * sa + cptr->pos.x;
+ rVertex[vv].y = mptr->gVertex[vv].y + cptr->pos.y;
+ rVertex[vv].z = mptr->gVertex[vv].z * ca - mptr->gVertex[vv].x * sa + cptr->pos.z;
+ }
+
+ for (int f=0; f<mptr->FCount; f++) {
+ TFace *fptr = &mptr->gFace[f];
+ if (fptr->Flags & (sfOpacity + sfTransparent) ) continue;
+ v[0] = rVertex[fptr->v1];
+ v[1] = rVertex[fptr->v2];
+ v[2] = rVertex[fptr->v3];
+ if (TraceCheckPlane(v[0], v[1], v[2]) ) {
+ TraceRes = tresChar; ShotDino = c;
+ if (fptr->Flags & sfMortal) TraceRes |= 0x8000;
+ }
+
+ }
+}
+
+
+void FillVGround(Vector3d &v, int xx, int zz)
+{
+ v.x = xx*256.f;
+ v.z = zz*256.f;
+ v.y = (float)HMap[zz][xx]*ctHScale;
+}
+
+
+void FillWGround(Vector3d &v, int xx, int zz)
+{
+ v.x = xx*256.f;
+ v.z = zz*256.f;
+ v.y = (float)WaterList[ WMap[zz][xx] ].wlevel*ctHScale;
+}
+
+
+int TraceLook(float ax, float ay, float az,
+ float bx, float by, float bz)
+{
+ TraceA.x = ax; TraceA.y = ay; TraceA.z = az;
+ TraceB.x = bx; TraceB.y = by; TraceB.z = bz;
+
+ TraceNv = SubVectors(TraceB, TraceA);
+
+ Vector3d TraceNvP;
+
+ TraceNvP = TraceNv;
+ TraceNvP.y = 0;
+
+ NormVector(TraceNv, 1.0f);
+ NormVector(TraceNvP, 1.0f);
+ ObjectsOnLook=0;
+
+ int axi = (int)(ax/256.f);
+ int azi = (int)(az/256.f);
+
+ int bxi = (int)(bx/256.f);
+ int bzi = (int)(bz/256.f);
+
+ int xm1 = min(axi, bxi) - 2;
+ int xm2 = max(axi, bxi) + 2;
+ int zm1 = min(azi, bzi) - 2;
+ int zm2 = max(azi, bzi) + 2;
+
+//======== trace ground model and static objects ============//
+ for (int zz=zm1; zz<=zm2; zz++)
+ for (int xx=xm1; xx<=xm2; xx++) {
+ if (xx<2 || xx>1010) continue;
+ if (zz<2 || zz>1010) continue;
+
+ BOOL ReverseOn = (FMap[zz][xx] & fmReverse);
+
+ FillVGround(v[0], xx, zz);
+ FillVGround(v[1], xx+1, zz);
+ if (ReverseOn) FillVGround(v[2], xx, zz+1);
+ else FillVGround(v[2], xx+1, zz+1);
+ if (TraceCheckPlane(v[0], v[1], v[2])) return 1;
+
+ if (ReverseOn) { v[0] = v[2]; FillVGround(v[2], xx+1, zz+1); }
+ else { v[1] = v[2]; FillVGround(v[2], xx, zz+1); }
+ if (TraceCheckPlane(v[0], v[1], v[2])) return 1;
+
+ int o = OMap[zz][xx];
+ if ( o!=255) {
+ float s1,s2;
+ v[0].x = xx * 256.f + 128.f;
+ v[0].z = zz * 256.f + 128.f;
+ v[0].y = TraceB.y;
+ MulVectorsScal( SubVectors(v[0], TraceB), TraceNv, s1); s1*=-1;
+ v[0].y = TraceA.y;
+ MulVectorsScal( SubVectors(v[0], TraceA), TraceNv, s2);
+
+ if (s1>0 && s2>0)
+ if (PointToVectorD(TraceA, TraceNvP, v[0]) < 180.f) {
+ ObjectsOnLook++;
+ if (MObjects[o].info.Radius > 32) ObjectsOnLook++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+
+int TraceShot(float ax, float ay, float az,
+ float &bx, float &by, float &bz)
+{
+ TraceA.x = ax; TraceA.y = ay; TraceA.z = az;
+ TraceB.x = bx; TraceB.y = by; TraceB.z = bz;
+
+ TraceNv = SubVectors(TraceB, TraceA);
+ NormVector(TraceNv, 1.0f);
+ TraceRes = -1;
+
+ int axi = (int)(ax/256.f);
+ int azi = (int)(az/256.f);
+
+ int bxi = (int)(bx/256.f);
+ int bzi = (int)(bz/256.f);
+
+ int xm1 = min(axi, bxi) - 2;
+ int xm2 = max(axi, bxi) + 2;
+ int zm1 = min(azi, bzi) - 2;
+ int zm2 = max(azi, bzi) + 2;
+
+//======== trace ground model and static objects ============//
+ for (int zz=zm1; zz<=zm2; zz++)
+ for (int xx=xm1; xx<=xm2; xx++) {
+ if (xx<2 || xx>1010) continue;
+ if (zz<2 || zz>1010) continue;
+
+ BOOL ReverseOn = (FMap[zz][xx] & fmReverse);
+
+ FillVGround(v[0], xx, zz);
+ FillVGround(v[1], xx+1, zz);
+ if (ReverseOn) FillVGround(v[2], xx, zz+1);
+ else FillVGround(v[2], xx+1, zz+1);
+ if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresGround;
+
+ if (ReverseOn) { v[0] = v[2]; FillVGround(v[2], xx+1, zz+1); }
+ else { v[1] = v[2]; FillVGround(v[2], xx, zz+1); }
+ if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresGround;
+
+ if ( (FMap[zz][xx] & fmWaterA)>0) {
+ FillWGround(v[0], xx, zz);
+ FillWGround(v[1], xx+1, zz);
+ FillWGround(v[2], xx+1, zz+1);
+ if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresWater;
+ v[1] = v[2]; FillWGround(v[2], xx, zz+1);
+ if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresWater;
+ }
+
+ if (OMap[zz][xx] !=255)
+ TraceModel(xx, zz, OMap[zz][xx]);
+ }
+
+//======== trace characters ============//
+ for (int c=0; c<ChCount; c++)
+ TraceCharacter(c);
+
+ float l;
+ if ((TraceRes & 0xFF)==tresChar) l = 32.f; else l=16.f;
+ bx = TraceB.x - TraceNv.x * l;
+ by = TraceB.y - TraceNv.y * l;
+ bz = TraceB.z - TraceNv.z * l;
+
+ return TraceRes;
+}
+
+
+
+
+void InitClips2()
+{
+ ClipA.v1.x = - (float)f_sin(pi/4-0.11); // 0.741
+ ClipA.v1.y = 0;
+ ClipA.v1.z = (float)f_cos(pi/4-0.11); // 0.820
+ ClipA.v2.x = 0; ClipA.v2.y = 1; ClipA.v2.z = 0;
+ MulVectorsVect(ClipA.v1, ClipA.v2, ClipA.nv);
+
+ ClipC.v1.x = + (float)f_sin(pi/4-0.11);
+ ClipC.v1.y = 0;
+ ClipC.v1.z = (float)f_cos(pi/4-0.11);
+ ClipC.v2.x = 0; ClipC.v2.y =-1; ClipC.v2.z = 0;
+ MulVectorsVect(ClipC.v1, ClipC.v2, ClipC.nv);
+
+
+ ClipB.v1.x = 0;
+ ClipB.v1.y = (float)f_sin(pi/5-.02);
+ ClipB.v1.z = (float)f_cos(pi/5-.02);
+ ClipB.v2.x = 1; ClipB.v2.y = 0; ClipB.v2.z = 0;
+ MulVectorsVect(ClipB.v1, ClipB.v2, ClipB.nv);
+
+ ClipD.v1.x = 0;
+ ClipD.v1.y = - (float)f_sin(pi/5-.02);
+ ClipD.v1.z = (float)f_cos(pi/5-.02);
+ ClipD.v2.x =-1; ClipD.v2.y = 0; ClipD.v2.z = 0;
+ MulVectorsVect(ClipD.v1, ClipD.v2, ClipD.nv);
+
+ ClipZ.v1.x = 0; ClipZ.v1.y = 1; ClipZ.v1.z = 0;
+ ClipZ.v2.x = 1; ClipZ.v2.y = 0; ClipZ.v2.z = 0;
+ MulVectorsVect(ClipZ.v1, ClipZ.v2, ClipZ.nv);
+
+}
+
+
+
+void InitClips()
+{
+// float XFOV = atan(CameraW , VideoCX); //1.6
+// float YFOV = atan(CameraH , VideoCY);
+ float xx = (VideoCX+1) / (CameraW);
+ float yy = (VideoCY+2) / (CameraH);
+ float LX = sqrt(1.0 + xx * xx);
+ float LY = sqrt(1.0 + yy * yy);
+
+ ClipA.v1.x = - (float)xx / LX;
+ ClipA.v1.y = 0;
+ ClipA.v1.z = (float)1 / LX;
+ ClipA.v2.x = 0; ClipA.v2.y = 1; ClipA.v2.z = 0;
+ MulVectorsVect(ClipA.v1, ClipA.v2, ClipA.nv);
+
+ ClipC.v1.x = + (float)xx / LX;
+ ClipC.v1.y = 0;
+ ClipC.v1.z = (float)1 / LX;
+ ClipC.v2.x = 0; ClipC.v2.y =-1; ClipC.v2.z = 0;
+ MulVectorsVect(ClipC.v1, ClipC.v2, ClipC.nv);
+
+
+ ClipB.v1.x = 0;
+ ClipB.v1.y = (float)yy / LY;
+ ClipB.v1.z = (float)1 / LY;
+ ClipB.v2.x = 1; ClipB.v2.y = 0; ClipB.v2.z = 0;
+ MulVectorsVect(ClipB.v1, ClipB.v2, ClipB.nv);
+
+ ClipD.v1.x = 0;
+ ClipD.v1.y = - (float)yy / LY;
+ ClipD.v1.z = (float)1 / LY;
+ ClipD.v2.x =-1; ClipD.v2.y = 0; ClipD.v2.z = 0;
+ MulVectorsVect(ClipD.v1, ClipD.v2, ClipD.nv);
+
+ ClipZ.v1.x = 0; ClipZ.v1.y = 1; ClipZ.v1.z = 0;
+ ClipZ.v2.x = 1; ClipZ.v2.y = 0; ClipZ.v2.z = 0;
+ MulVectorsVect(ClipZ.v1, ClipZ.v2, ClipZ.nv);
+
+ ClipW.nv.x = 0;
+ ClipW.nv.y = cb;
+ ClipW.nv.z = sb;
+
+}
+
+
+
+
+
+void CalcLights(TModel* mptr)
+{
+ int VCount = mptr->VCount;
+ int FCount = mptr->FCount;
+ int FUsed;
+ float c;
+ Vector3d norms[1024];
+ Vector3d a, b, nv, rv;
+ Vector3d slight;
+ slight.x =-Sun3dPos.x;
+ slight.y =-Sun3dPos.y/2;
+ slight.z =-Sun3dPos.z;
+
+
+ NormVector(slight, 1.0f);
+
+ for (int f=0; f<FCount; f++) {
+ int v1 = mptr->gFace[f].v1;
+ int v2 = mptr->gFace[f].v2;
+ int v3 = mptr->gFace[f].v3;
+
+ a.x = mptr->gVertex[v2].x - mptr->gVertex[v1].x;
+ a.y = mptr->gVertex[v2].y - mptr->gVertex[v1].y;
+ a.z = mptr->gVertex[v2].z - mptr->gVertex[v1].z;
+
+ b.x = mptr->gVertex[v3].x - mptr->gVertex[v1].x;
+ b.y = mptr->gVertex[v3].y - mptr->gVertex[v1].y;
+ b.z = mptr->gVertex[v3].z - mptr->gVertex[v1].z;
+
+ MulVectorsVect(a, b, norms[f]);
+ NormVector(norms[f], 1.0f);
+ }
+
+ for (int VT=0; VT<4; VT++) {
+ float ca = (float)f_cos (VT * pi / 2);
+ float sa = (float)f_sin (VT * pi / 2);
+ for (int v=0; v<VCount; v++) {
+ FUsed = 0;
+ nv.x=0; nv.y=0; nv.z=0;
+ for (f=0; f<FCount; f++)
+ if (!(mptr->gFace[f].Flags & sfDoubleSide) )
+ if (mptr->gFace[f].v1 == v || mptr->gFace[f].v2 == v || mptr->gFace[f].v3 == v )
+ { FUsed++; nv = AddVectors(nv, norms[f]); }
+
+ if (!FUsed) mptr->VLight[VT][v] = 0;
+ else {
+ NormVector(nv, 1.0f);
+ rv.y = nv.y;
+ rv.x = nv.x * sa + nv.z * ca;
+ rv.z = nv.z * sa - nv.x * ca;
+ MulVectorsScal(rv, slight, c);
+ c = c * 64;
+ //if (c>64) c=64;
+ //if (c<-64) c=-64;
+ mptr->VLight[VT][v] = c;
+ }
+ }
+ }
+}
+
+
+/*
+void CalcGouraud(TModel* mptr, Vecto3d *nvs[])
+{
+ int VCount = mptr->VCount;
+ int FCount = mptr->FCount;
+ int FUsed;
+ float c;
+ Vector3d norms[1024];
+ Vector3d a, b, nv, rv;
+ Vector3d slight;
+ slight.x =-Sun3dPos.x;
+ slight.y =-Sun3dPos.y;
+ slight.z =-Sun3dPos.z;
+
+ NormVector(slight, 1.0f);
+
+ for (int f=0; f<FCount; f++) {
+ int v1 = mptr->gFace[f].v1;
+ int v2 = mptr->gFace[f].v2;
+ int v3 = mptr->gFace[f].v3;
+
+ a.x = mptr->gVertex[v2].x - mptr->gVertex[v1].x;
+ a.y = mptr->gVertex[v2].y - mptr->gVertex[v1].y;
+ a.z = mptr->gVertex[v2].z - mptr->gVertex[v1].z;
+
+ b.x = mptr->gVertex[v3].x - mptr->gVertex[v1].x;
+ b.y = mptr->gVertex[v3].y - mptr->gVertex[v1].y;
+ b.z = mptr->gVertex[v3].z - mptr->gVertex[v1].z;
+
+ MulVectorsVect(a, b, norms[f]);
+ NormVector(norms[f], 1.0f);
+ }
+
+ for (int v=0; v<VCount; v++) {
+ FUsed = 0;
+ nv.x=0; nv.y=0; nv.z=0;
+ for (f=0; f<FCount; f++)
+ if (!(mptr->gFace[f].Flags & sfDoubleSide) )
+ if (mptr->gFace[f].v1 == v || mptr->gFace[f].v2 == v || mptr->gFace[f].v3 == v )
+ { FUsed++; nv = AddVectors(nv, norms[f]); }
+
+ if (!FUsed) mptr->VLight[0][v] = 0;
+ else {
+ NormVector(nv, 1.0f);
+ MulVectorsScal(nv, slight, c);
+ if (c<0) c=0; c=(c-0.5)*2;
+ c=c*c*c;
+ c = c * 98;
+ if (c>96) c=96;
+ if (c<-96) c=-96;
+ mptr->VLight[0][v] = c;
+ }
+