for safekeeping
This commit is contained in:
RD42 2024-09-27 23:11:36 +08:00
parent 92cfcac5ac
commit 988a8d3686
189 changed files with 17191 additions and 1667 deletions

27
.gitattributes vendored
View File

@ -1,26 +1 @@
*.cpp text eol=crlf
*.c text eol=crlf
*.h text eol=crlf
*.inl text eol=crlf
*.rc text eol=crlf
*.rc2 text eol=crlf
*.dsp text eol=crlf
*.clw text eol=crlf
*.dsw text eol=crlf
*.sln text eol=crlf
*.vcproj text eol=crlf
*.txt text eol=crlf
*.pas text eol=crlf
*.dfm binary
Makefile text eol=crlf
Makefile.am text eol=crlf
archive/files/*.cfg text eol=crlf
archive/files/*.ini text eol=crlf
archive/files/*.dat text eol=crlf
archive/files/*.ide text eol=crlf
archive/files/*.bin binary
archive/files/*.txd binary
archive/files/*.png binary
archive/files/*.scm binary
* text=auto

34
README.md Normal file
View File

@ -0,0 +1,34 @@
# San Andreas Multiplayer
This is an ongoing matching decompilation of the 0.3.7 version of San Andreas Multiplayer.
## Status
- [ ] **samp.exe** - Mostly decompiled. Not matching due to issues with PACKAGEINFO.
- [ ] **samp.dll** - Incomplete.
- [x] **rcon.exe** - Fully decompiled.
- [x] **samp_debug.exe** - Fully decompiled.
- [ ] **samp-server.exe** - Incomplete.
- [ ] **samp03svr** - Incomplete.
- [x] **announce.exe** - Fully decompiled.
- [ ] **announce** - System and the GCC version not have been determined.
- [ ] **samp-npc.exe** - Incomplete.
- [ ] **samp-npc** - Incomplete.
## Building
### Requirements
- A clean virtual machine with Windows XP installed
- Microsoft Visual C++ 6.0
- Microsoft Visual C++ 6.0 (Service Pack 6)
- Microsoft Visual Studio .NET 2003
- Borland Delphi 7
- (Nullsoft Scriptable Install System (NSIS) v2.46)[https://sourceforge.net/projects/nsis/files/NSIS%202/2.46/]
Note(s):
- Make a backup of your Microsoft Visual C++ 6.0 installation before you install Service Pack 6 update. This update will overwrite your compiler binaries and alter your building results. You can find your Visual C++ 6.0 installation at `C:\Program Files\Microsoft Visual Studio`.
### Compiling
#### Windows
TODO
#### Linux
TODO
## Contributing
If you are interested in this decompilation project, feel free to create a pull request.

View File

@ -68,10 +68,15 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
MinimalRebuild="TRUE"
RuntimeLibrary="0"
StructMemberAlignment="1"
BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -750,6 +755,12 @@
<File
RelativePath="..\server\system.h">
</File>
<File
RelativePath=".\unnamed_1.cpp">
</File>
<File
RelativePath=".\unnamed_1.h">
</File>
</Files>
<Globals>
</Globals>

View File

@ -2,6 +2,7 @@
#include "../main.h"
#include "../../raknet/SocketDataEncryptor.h"
#include "../mathutils.h"
#include "../unnamed_1.h"
#define NETGAME_VERSION 4057
@ -27,7 +28,7 @@ typedef struct _TRAILER_SYNC_DATA // size: 54
char _gap0[54];
} TRAILER_SYNC_DATA;
char unnamed_2[63];
INCAR_SYNC_DATA icSync;
PASSENGER_SYNC_DATA unnamed_5[MAX_PLAYERS];
BOOL bPlayerSlotState[MAX_PLAYERS];
BYTE byteState;
@ -220,6 +221,47 @@ BOOL CNetGame::GetPlayerKeys(PLAYERID playerId, WORD *udAnalog, WORD *lrAnalog,
}
}
float CNetGame::GetPlayerFacingAngle(PLAYERID playerId)
{
if(playerId >= MAX_PLAYERS) return 0.0f;
if(bPlayerSlotState[playerId] == FALSE) return 0.0f;
MATRIX4X4 mat;
if(bytePlayerState[playerId] == PLAYER_STATE_ONFOOT)
{
QuaternionToMatrix(&unnamed_3[playerId].quatRotation, &mat);
float fZAngle = atan2(-mat.up.X, mat.up.Y) * 180.0f/PI;
// Bound it to [0, 360)
while(fZAngle < 0.0f)
fZAngle += 360.0f;
while(fZAngle >= 360.0f)
fZAngle -= 360.0f;
return fZAngle;
}
else if(bytePlayerState[playerId] == PLAYER_STATE_DRIVER)
{
QuaternionToMatrix(&unnamed_4[playerId].quatRotation, &mat);
float fZAngle = atan2(-mat.up.X, mat.up.Y) * 180.0f/PI;
// Bound it to [0, 360)
while(fZAngle < 0.0f)
fZAngle += 360.0f;
while(fZAngle >= 360.0f)
fZAngle -= 360.0f;
return fZAngle;
}
else
{
return 0.0f;
}
}
BYTE CNetGame::GetPlayerSpecialAction(PLAYERID playerId)
{
if(playerId >= MAX_PLAYERS) return SPECIAL_ACTION_NONE;
@ -233,7 +275,7 @@ BYTE CNetGame::GetPlayerSpecialAction(PLAYERID playerId)
}
//----------------------------------------------------
// MATCH
BOOL CNetGame::IsPlayerAdded(PLAYERID playerId)
{
if(playerId >= MAX_PLAYERS) return FALSE;
@ -242,6 +284,7 @@ BOOL CNetGame::IsPlayerAdded(PLAYERID playerId)
}
//----------------------------------------------------
BOOL CNetGame::IsVehicleAdded(VEHICLEID VehicleID)
{
if(VehicleID >= MAX_VEHICLES) return FALSE;
@ -250,6 +293,7 @@ BOOL CNetGame::IsVehicleAdded(VEHICLEID VehicleID)
}
//----------------------------------------------------
float CNetGame::GetDistanceFromMeToPoint(PVECTOR vecPos)
{
VECTOR vecMyPos;
@ -269,6 +313,7 @@ float CNetGame::GetDistanceFromMeToPoint(PVECTOR vecPos)
}
//----------------------------------------------------
PVECTOR CNetGame::GetMyPos(PVECTOR Vector)
{
if(byteState == PLAYER_STATE_ONFOOT)
@ -292,6 +337,7 @@ PVECTOR CNetGame::GetMyPos(PVECTOR Vector)
}
//----------------------------------------------------
void CNetGame::SetMyPos(PVECTOR Vector)
{
if(byteState == PLAYER_STATE_ONFOOT)
@ -309,6 +355,7 @@ void CNetGame::SetMyPos(PVECTOR Vector)
}
//----------------------------------------------------
float CNetGame::GetMyZAngle()
{
MATRIX4X4 mat;
@ -343,7 +390,7 @@ float CNetGame::GetMyZAngle()
}
//----------------------------------------------------
// MATCH
void CNetGame::SetMyZAngle(float fAngle)
{
//logprintf("CNetGame::SetMyZAngle(%f)", fAngle);
@ -428,13 +475,13 @@ void CNetGame::ShutdownForGameModeRestart()
StopRecordingPlayback();
memset(unnamed_2,0,sizeof(unnamed_2));
memset(unnamed_3,0,sizeof(unnamed_3));
memset(unnamed_4,0,sizeof(unnamed_4));
memset(unnamed_5,0,sizeof(unnamed_5));
memset(&bVehicleSlotState[0],0,sizeof(BOOL)*MAX_VEHICLES);
memset(&ofSync,0,sizeof(ONFOOT_SYNC_DATA));
memset(&icSync,0,sizeof(INCAR_SYNC_DATA));
memset(unnamed_3, 0, sizeof(unnamed_3));
memset(unnamed_4, 0, sizeof(unnamed_4));
memset(unnamed_5, 0, sizeof(unnamed_5));
memset(&bPlayerSlotState[0],0,sizeof(BOOL)*MAX_PLAYERS);
memset(&bVehicleSlotState[0],0,sizeof(BOOL)*MAX_VEHICLES);
memset(&bytePlayerState[0],0,sizeof(BYTE)*MAX_PLAYERS);
m_bZoneNames = FALSE;
@ -496,16 +543,16 @@ void CNetGame::Init(PCHAR szHostOrIp, int iPort,
m_bZoneNames = FALSE;
m_bInstagib = FALSE;
memset(unnamed_2,0,sizeof(unnamed_2));
memset(&ofSync,0,sizeof(ONFOOT_SYNC_DATA));
memset(&icSync,0,sizeof(INCAR_SYNC_DATA));
memset(unnamed_3,0,sizeof(unnamed_3));
memset(unnamed_4,0,sizeof(unnamed_4));
memset(unnamed_5,0,sizeof(unnamed_5));
memset(&bVehicleSlotState[0],0,sizeof(BOOL)*MAX_VEHICLES);
memset(&bPlayerSlotState[0],0,sizeof(BOOL)*MAX_PLAYERS);
memset(&bVehicleSlotState[0],0,sizeof(BOOL)*MAX_VEHICLES);
memset(&bytePlayerState[0],0,sizeof(BYTE)*MAX_PLAYERS);
field_1DE = 0;
field_1E2 = 0;
field_1E2 = NULL;
field_1F2 = GetTickCount();
byteState = PLAYER_STATE_NONE;
field_1FA = -1;
@ -579,6 +626,23 @@ void CNetGame::Process()
UpdateNetwork();
if(m_iGameState == GAMESTATE_CONNECTED)
{
if(m_pGameMode) m_pGameMode->Frame(fElapsedTime);
if(m_pScriptTimers) m_pScriptTimers->Process((DWORD)(fElapsedTime * 1000.0f));
if(bSpawned)
{
if(field_1DE)
{
}
else
{
byteState = 1;
}
}
}
// TODO: CNetGame::Process (W: 00418370 L: 080AD6A4)
@ -619,6 +683,9 @@ void CNetGame::UpdateNetwork()
switch(packetIdentifier)
{
case ID_UNK_12:
Packet_Unk12(pkt);
break;
case ID_RSA_PUBLIC_KEY_MISMATCH:
Packet_RSAPublicKeyMismatch(pkt);
break;
@ -646,6 +713,12 @@ void CNetGame::UpdateNetwork()
case ID_CONNECTION_REQUEST_ACCEPTED:
Packet_ConnectionSucceeded(pkt);
break;
case ID_PLAYER_SYNC:
Packet_PlayerSync(pkt);
break;
case ID_VEHICLE_SYNC:
Packet_VehicleSync(pkt);
break;
case ID_PASSENGER_SYNC:
Packet_PassengerSync(pkt);
break;
@ -665,6 +738,25 @@ void CNetGame::UpdateNetwork()
// PACKET HANDLERS INTERNAL
//----------------------------------------------------
void CNetGame::Packet_PlayerSync(Packet *p)
{
RakNet::BitStream bsPlayerSync((PCHAR)p->data, p->length, false);
ONFOOT_SYNC_DATA ofSync;
BYTE bytePacketID=0;
PLAYERID playerId=0;
if(GetGameState() != GAMESTATE_CONNECTED) return;
memset(&ofSync,0,sizeof(ONFOOT_SYNC_DATA));
bsPlayerSync.Read(bytePacketID);
bsPlayerSync.Read(playerId);
// TODO: CNetGame::Packet_PlayerSync
}
//----------------------------------------------------
void CNetGame::Packet_AimSync(Packet *p)
{
RakNet::BitStream bsAimSync((PCHAR)p->data, p->length, false);
@ -681,6 +773,13 @@ void CNetGame::Packet_AimSync(Packet *p)
//----------------------------------------------------
void CNetGame::Packet_VehicleSync(Packet *p)
{
// TODO: CNetGame::Packet_VehicleSync
}
//----------------------------------------------------
void CNetGame::Packet_PassengerSync(Packet *p)
{
RakNet::BitStream bsPassengerSync((PCHAR)p->data, p->length, false);
@ -831,6 +930,35 @@ void CNetGame::Packet_ConnectionSucceeded(Packet *p)
//----------------------------------------------------
void CNetGame::Packet_Unk12(Packet *p)
{
RakNet::BitStream bsRecv((PCHAR)p->data, p->length, false);
RakNet::BitStream bsSend;
//bsSend.Write((BYTE)ID_UNK_12);
// TODO: CNetGame::Packet_Unk12
}
//----------------------------------------------------
void CNetGame::UpdatePlayerScoresAndPings()
{
if(!m_pRakClient) return;
if(!m_pRakClient->IsConnected()) return;
static DWORD dwLastUpdateTick = 0;
if ((GetTickCount() - dwLastUpdateTick) > 3000) {
dwLastUpdateTick = GetTickCount();
RakNet::BitStream bsParams;
m_pRakClient->RPC(RPC_UpdateScoresPingsIPs, &bsParams, HIGH_PRIORITY, RELIABLE, 0, FALSE);
}
}
//----------------------------------------------------
void CNetGame::ResetVehiclePool()
{
if(m_pVehiclePool) {
@ -872,6 +1000,56 @@ void CNetGame::SendCommand(char *szCommand)
GetRakClient()->RPC(RPC_ServerCommand,&bsParams,HIGH_PRIORITY,RELIABLE,0,false);
}
void CNetGame::StartRecordingPlayback(int iPlaybackType, char *szRecordName)
{
int v5 = 0;
if(field_1E2)
{
fclose(field_1E2);
field_1E2 = NULL;
}
char s[MAX_PATH];
sprintf(s, "./npcmodes/recordings/%s.rec", szRecordName);
field_1E2 = fopen(s, "rb");
if(!field_1E2)
{
//logprintf("NPC: Total failure. Can't open recording playback file %s.", s);
exit(1);
}
fseek(field_1E2, 0, SEEK_END);
v5 = ftell(field_1E2);
rewind(field_1E2);
if(v5 == 0)
{
//logprintf("NPC: Total failure. %s is a 0 length file.", s);
exit(1);
}
int v4 = 0;
int v3 = 0;
fread(&v4, 1, sizeof(int), field_1E2);
fread(&v3, 1, sizeof(int), field_1E2);
if(v4 != 1000)
{
//logprintf("NPC: %s is not the correct recording version for this bot.", s);
//logprintf("NPC: Trying to upgrade %s...", s);
fclose(field_1E2);
if(!UpgradeRecordFile(s, v5, iPlaybackType) )
{
//logprintf("NPC: Fatal Error. Could not upgrade file. I'm out of options so I'm quiting.");
exit(1);
}
//logprintf("NPC: File %s was upgraded. Please restart the bot.", s);
exit(1);
}
}
void CNetGame::StopRecordingPlayback()
{
field_1DE = 0;

View File

@ -8,6 +8,10 @@
#define GAMESTATE_RESTARTING 5
#define PLAYER_RECORDING_TYPE_NONE 0
#define PLAYER_RECORDING_TYPE_DRIVER 1
#define PLAYER_RECORDING_TYPE_ONFOOT 2
//----------------------------------------------------
class CNetGame // size: 910 bytes
@ -23,6 +27,8 @@ private:
// Packet handlers
void Packet_AimSync(Packet *p);
void Packet_PlayerSync(Packet *p);
void Packet_VehicleSync(Packet *p);
void Packet_PassengerSync(Packet *p);
void Packet_ConnectionSucceeded(Packet *p);
void Packet_RSAPublicKeyMismatch(Packet* packet);
@ -35,6 +41,7 @@ private:
void Packet_ModifiedPacket(Packet* packet);
void Packet_ConnectAttemptFailed(Packet* packet);
void Packet_TrailerSync(Packet *p);
void Packet_Unk12(Packet *p);
public:
@ -95,6 +102,7 @@ public:
void Init(PCHAR szHostOrIp,int iPort,PCHAR szPlayerName,PCHAR szPass,PCHAR szNpcMode);
void Process();
void UpdatePlayerScoresAndPings();
void ResetVehiclePool();
void ResetPlayerPool();
void ShutdownForGameModeRestart();
@ -112,6 +120,7 @@ public:
BYTE GetPlayerHealth(PLAYERID playerId);
BYTE GetPlayerArmour(PLAYERID playerId);
BOOL GetPlayerKeys(PLAYERID playerId, WORD *udAnalog, WORD *lrAnalog, WORD *wKeys);
float GetPlayerFacingAngle(PLAYERID playerId);
BYTE GetPlayerSpecialAction(PLAYERID playerId);
BOOL IsPlayerAdded(PLAYERID playerId);
BOOL IsVehicleAdded(VEHICLEID VehicleID);
@ -121,6 +130,7 @@ public:
float GetMyZAngle();
void SetMyZAngle(float fAngle);
void StartRecordingPlayback(int iPlaybackType, char *szRecordName);
void StopRecordingPlayback();
void PauseRecordingPlayback();
void ResumeRecordingPlayback();

View File

@ -346,11 +346,18 @@ void RequestSpawn(RPCParameters *rpcParams)
}
}
//----------------------------------------------------
// Remote client is dead.
void Death(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
// Remote client is trying to enter vehicle gracefully.
void EnterVehicle(RPCParameters *rpcParams)
{
{
}
//----------------------------------------------------
@ -421,7 +428,7 @@ void ConnectionRejected(RPCParameters *rpcParams)
if(byteRejectReason==REJECT_REASON_BAD_VERSION) {
//logprintf("BOT: CONNECTION REJECTED. INCORRECT SA-MP VERSION!");
}
}
else if(byteRejectReason==REJECT_REASON_BAD_NICKNAME) {
//logprintf("BOT: CONNECTION REJECTED. BAD NICKNAME!");
}
@ -459,19 +466,19 @@ void WorldTime(RPCParameters *rpcParams)
//----------------------------------------------------
void Unk5F(RPCParameters *rpcParams)
void Pickup(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
void Unk3F(RPCParameters *rpcParams)
void DestroyPickup(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
void Unk97(RPCParameters *rpcParams)
void DestroyWeaponPickup(RPCParameters *rpcParams)
{
}
@ -489,13 +496,25 @@ void Weather(RPCParameters *rpcParams)
//----------------------------------------------------
void Unk1D(RPCParameters *rpcParams)
void SetTimeEx(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
void Unk1E(RPCParameters *rpcParams)
void ToggleClock(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
void VehicleDestroy(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
void ACServerProtected(RPCParameters *rpcParams)
{
}
@ -515,13 +534,13 @@ void RegisterRPCs(RakClientInterface * pRakClient)
REGISTER_STATIC_RPC(pRakClient,ConnectionRejected);
REGISTER_STATIC_RPC(pRakClient,ClientMessage);
REGISTER_STATIC_RPC(pRakClient,WorldTime);
REGISTER_STATIC_RPC(pRakClient,Unk5F);
REGISTER_STATIC_RPC(pRakClient,Unk3F);
REGISTER_STATIC_RPC(pRakClient,Unk97);
REGISTER_STATIC_RPC(pRakClient,Pickup);
REGISTER_STATIC_RPC(pRakClient,DestroyPickup);
REGISTER_STATIC_RPC(pRakClient,DestroyWeaponPickup);
REGISTER_STATIC_RPC(pRakClient,ScmEvent);
REGISTER_STATIC_RPC(pRakClient,Weather);
REGISTER_STATIC_RPC(pRakClient,Unk1D);
REGISTER_STATIC_RPC(pRakClient,Unk1E);
REGISTER_STATIC_RPC(pRakClient,SetTimeEx);
REGISTER_STATIC_RPC(pRakClient,ToggleClock);
REGISTER_STATIC_RPC(pRakClient,ServerJoin);
REGISTER_STATIC_RPC(pRakClient,ServerQuit);
REGISTER_STATIC_RPC(pRakClient,InitGame);
@ -551,13 +570,13 @@ void UnRegisterRPCs(RakClientInterface * pRakClient)
UNREGISTER_STATIC_RPC(pRakClient,ConnectionRejected);
UNREGISTER_STATIC_RPC(pRakClient,ClientMessage);
UNREGISTER_STATIC_RPC(pRakClient,WorldTime);
UNREGISTER_STATIC_RPC(pRakClient,Unk5F);
UNREGISTER_STATIC_RPC(pRakClient,Unk3F);
UNREGISTER_STATIC_RPC(pRakClient,Unk97);
UNREGISTER_STATIC_RPC(pRakClient,Pickup);
UNREGISTER_STATIC_RPC(pRakClient,DestroyPickup);
UNREGISTER_STATIC_RPC(pRakClient,DestroyWeaponPickup);
UNREGISTER_STATIC_RPC(pRakClient,ScmEvent);
UNREGISTER_STATIC_RPC(pRakClient,Weather);
UNREGISTER_STATIC_RPC(pRakClient,Unk1D);
UNREGISTER_STATIC_RPC(pRakClient,Unk1E);
UNREGISTER_STATIC_RPC(pRakClient,SetTimeEx);
UNREGISTER_STATIC_RPC(pRakClient,ToggleClock);
UNREGISTER_STATIC_RPC(pRakClient,WorldPlayerAdd);
UNREGISTER_STATIC_RPC(pRakClient,WorldPlayerDeath);
UNREGISTER_STATIC_RPC(pRakClient,WorldPlayerRemove);

View File

@ -19,7 +19,8 @@ public:
BOOL Process();
void SetLocalPlayerName(PCHAR szName) { strcpy(m_szLocalPlayerName,szName); };
PCHAR GetPlayerName(BYTE bytePlayerID) { return m_szPlayerNames[bytePlayerID]; };
PCHAR GetLocalPlayerName() { return m_szLocalPlayerName; };
PCHAR GetPlayerName(PLAYERID playerId) { return m_szPlayerNames[playerId]; };
CPlayerPool();
~CPlayerPool();

View File

@ -27,7 +27,7 @@ void ScrUnk45(RPCParameters *rpcParams)
//----------------------------------------------------
void ScrUnk0B(RPCParameters *rpcParams)
void ScrSetPlayerName(RPCParameters *rpcParams)
{
}
@ -142,13 +142,13 @@ void ScrSetInterior(RPCParameters *rpcParams)
//----------------------------------------------------
void ScrUnk9D(RPCParameters *rpcParams)
void ScrSetCameraPos(RPCParameters *rpcParams)
{
}
//----------------------------------------------------
void ScrUnk9E(RPCParameters *rpcParams)
void ScrSetCameraLookAt(RPCParameters *rpcParams)
{
}
@ -178,7 +178,7 @@ void ScrUnk41(RPCParameters *rpcParams)
//----------------------------------------------------
void ScrUnkA2(RPCParameters *rpcParams)
void ScrSetCameraBehindPlayer(RPCParameters *rpcParams)
{
}
@ -491,7 +491,7 @@ void RegisterScriptRPCs(RakClientInterface* pRakClient)
REGISTER_STATIC_RPC(pRakClient, ScrSetSpawnInfo);
REGISTER_STATIC_RPC(pRakClient, ScrUnk45);
REGISTER_STATIC_RPC(pRakClient, ScrUnk99);
REGISTER_STATIC_RPC(pRakClient, ScrUnk0B);
REGISTER_STATIC_RPC(pRakClient, ScrSetPlayerName);
REGISTER_STATIC_RPC(pRakClient, ScrSetPlayerPos);
REGISTER_STATIC_RPC(pRakClient, ScrUnk0D);
REGISTER_STATIC_RPC(pRakClient, ScrUnk0E);
@ -499,13 +499,13 @@ void RegisterScriptRPCs(RakClientInterface* pRakClient)
REGISTER_STATIC_RPC(pRakClient, ScrRemovePlayerFromVehicle);
REGISTER_STATIC_RPC(pRakClient, ScrSetPlayerColor);
REGISTER_STATIC_RPC(pRakClient, ScrDisplayGameText);
REGISTER_STATIC_RPC(pRakClient, ScrUnk9D);
REGISTER_STATIC_RPC(pRakClient, ScrUnk9E);
REGISTER_STATIC_RPC(pRakClient, ScrSetInterior);
REGISTER_STATIC_RPC(pRakClient, ScrSetCameraPos);
REGISTER_STATIC_RPC(pRakClient, ScrSetCameraLookAt);
REGISTER_STATIC_RPC(pRakClient, ScrUnk9F);
REGISTER_STATIC_RPC(pRakClient, ScrUnkA0);
REGISTER_STATIC_RPC(pRakClient, ScrUnkA1);
REGISTER_STATIC_RPC(pRakClient, ScrUnkA2);
REGISTER_STATIC_RPC(pRakClient, ScrSetCameraBehindPlayer);
REGISTER_STATIC_RPC(pRakClient, ScrUnk0F);
REGISTER_STATIC_RPC(pRakClient, ScrUnk10);
REGISTER_STATIC_RPC(pRakClient, ScrUnk11);
@ -564,7 +564,7 @@ void UnRegisterScriptRPCs(RakClientInterface* pRakClient)
{
UNREGISTER_STATIC_RPC(pRakClient, ScrSetSpawnInfo);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk45);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk0B);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetPlayerName);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk99);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetPlayerPos);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk0D);
@ -573,13 +573,13 @@ void UnRegisterScriptRPCs(RakClientInterface* pRakClient)
UNREGISTER_STATIC_RPC(pRakClient, ScrRemovePlayerFromVehicle);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetPlayerColor);
UNREGISTER_STATIC_RPC(pRakClient, ScrDisplayGameText);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk9D);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk9E);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetInterior);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetCameraPos);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetCameraLookAt);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk9F);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnkA0);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnkA1);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnkA2);
UNREGISTER_STATIC_RPC(pRakClient, ScrSetCameraBehindPlayer);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk0F);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk10);
UNREGISTER_STATIC_RPC(pRakClient, ScrUnk11);

View File

@ -3,6 +3,9 @@
#define CHECK_PARAMS(n) { if (params[0] != (n * sizeof(cell))) { logprintf("SCRIPT: Bad parameter count (Count is %d, Should be %d): ", params[0] / sizeof(cell), n); return 0; } }
char* format_amxstring(AMX *amx, cell *params, int parm, int &len);
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max);
extern CNetGame* pNetGame;
//----------------------------------------------------------------------------------
@ -93,8 +96,12 @@ static cell AMX_NATIVE_CALL n_atan2(AMX *amx, cell *params)
// native StartRecordingPlayback(playbacktype, recordname[])
static cell AMX_NATIVE_CALL n_StartRecordingPlayback(AMX *amx, cell *params)
{
// TODO: n_StartRecordingPlayback
return 0;
char *szRecordName;
amx_StrParam(amx, params[2], szRecordName);
if(params[1] == PLAYER_RECORDING_TYPE_DRIVER || params[1] == PLAYER_RECORDING_TYPE_ONFOOT) {
pNetGame->StartRecordingPlayback(params[1], szRecordName);
}
return 1;
}
// native StopRecordingPlayback()
@ -260,6 +267,18 @@ static cell AMX_NATIVE_CALL n_GetPlayerKeys(AMX *amx, cell *params)
return 0;
}
// native GetPlayerFacingAngle(playerid,&Float:ang);
static cell AMX_NATIVE_CALL n_GetPlayerFacingAngle(AMX *amx, cell *params)
{
if(!pNetGame->GetPlayerPool()->GetSlotState((PLAYERID)params[1])) return 0;
cell* cptr;
amx_GetAddr(amx, params[2], &cptr);
float fZAngle = pNetGame->GetPlayerFacingAngle((PLAYERID)params[1]);
*cptr = amx_ftoc(fZAngle);
return 1;
}
// native GetMyPos(&Float:x, &Float:y, &Float:z)
static cell AMX_NATIVE_CALL n_GetMyPos(AMX *amx, cell *params)

8
bot/unnamed_1.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "main.h"
int UpgradeRecordFile(char *szFileName, int iFileSize, int iPlaybackType)
{
// TODO: UpgradeRecordFile
return 0;
}

4
bot/unnamed_1.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
int UpgradeRecordFile(char *szFileName, int iFileSize, int iPlaybackType);

Binary file not shown.

BIN
exgui/ExportFavorites1.dfm Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -129,7 +129,6 @@ type
function GetToken(TokenData: String; ItemIndex: Integer; TokenDelimiter: String): String;
function GetClipBoardStr: String;
procedure SetClipBoardStr(Str: String);
procedure GetGTAExe(Owner: HWND);
procedure FormCreate(Sender: TObject);
procedure lbServersDrawItem(Control: TWinControl; Index: Integer;
@ -170,7 +169,7 @@ type
procedure AboutClick(Sender: TObject);
procedure tsServerListsChange(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean);
procedure QueryServerInfoParse(SrcIP: String; SrcPort: Word; Buf: PAnsiChar; DataLen: Integer);
procedure QueryServerInfoParse(a2: String; a3: Word; Buf: PAnsiChar; DataLen: Integer);
procedure QueryServerInfoError(SocketError: Integer);
procedure QueryServerInfo(Server: String; bPing: Boolean; bInfo: Boolean; bPlayers: Boolean; bRules: Boolean);
procedure ServerConnect(Server: String; Port: String; Password: String);
@ -218,10 +217,10 @@ type
TServerInfo = record
Address: String;
DottedAddress: String;
HasAddress: Boolean;
field_4: String;
field_8: Boolean;
Port: Integer;
Tag: Word;
field_10: Word;
HostName: String;
Passworded: Boolean;
@ -263,14 +262,13 @@ var
ServersTopIndex: Integer = -1;
byte_4ED6C4: Boolean = false;
dword_4EF08C: TStringList;
FavoritesChanged: Boolean;
byte_4EF090: Boolean;
implementation
uses
ImportFavorites, ExportFavorites, ServerProperties,
RconConfig, Settings, About, Rcon, MasterUpdate,
unit_webrunform;
About, Settings, RconConfig, Rcon, unit_webrunform, MasterUpdate;
{$R *.dfm}
@ -359,23 +357,22 @@ begin
end;
procedure sub_4E220C(a1: String);
function sub_4E2140(a1, a2: string): Integer;
var
v10: String;
v9: Integer;
function sub_4E2140(a1, a2: string): Integer;
var
v13: Integer;
begin
Result:= 0;
for v13:= (Length(a2) - Length(a1) + 1) downto 1 do begin
if Copy(a2, v13, Length(a1)) = a1 then begin
Result:= v13;
Exit;
end;
v13: Integer;
begin
Result:= 0;
for v13:= (Length(a2) - Length(a1) + 1) downto 1 do begin
if Copy(a2, v13, Length(a1)) = a1 then begin
Result:= v13;
Exit;
end;
end;
end;
var
v11: String;
v10: Integer;
begin
if (Copy(a1, 2, 1) <> ':') then begin
if (Copy(a1, 3, 1) <> '\') then begin
@ -388,11 +385,11 @@ begin
a1 := 'C:' + a1;
end;
end;
if not DirectoryExists(a1) then begin
v9:= sub_4E2140('\', a1);
v10:= Copy(a1, 1, v9 - 1);
if not DirectoryExists(v10) then
sub_4E220C(v10);
if DirectoryExists(a1) then begin
v10:= sub_4E2140('\', a1);
v11:= Copy(a1, 1, v10 - 1);
if not DirectoryExists(v11) then
sub_4E220C(v11);
CreateDir(a1);
end;
end;
@ -520,7 +517,7 @@ var
Reg: TRegistry;
begin
dword_4EF08C:= TStringList.Create;
FavoritesChanged:= false;
byte_4EF090:= false;
Reg:= TRegistry.Create;
Reg.RootKey:= HKEY_CURRENT_USER;
@ -791,9 +788,9 @@ begin
end;
if PingOnly then
QueryServerInfo(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port) + '#' + IntToStr(Servers[Idx].Tag), true, false, false, false)
QueryServerInfo(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port) + '#' + IntToStr(Servers[Idx].field_10), true, false, false, false)
else
QueryServerInfo(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port) + '#' + IntToStr(Servers[Idx].Tag), true, true, true, true);
QueryServerInfo(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port) + '#' + IntToStr(Servers[Idx].field_10), true, true, true, true);
end;
procedure TfmMain.lbServersClick(Sender: TObject);
@ -846,18 +843,18 @@ var
FilterList: TStringList;
ItemFiltered: Boolean;
Sorted: Boolean;
TrackingChanges: Boolean;
v162: Boolean;
TotServers, TotSlots, TotPlayers: Integer;
NewServs: TStringList;
TopIndexes: Array[1..3] of Integer;
TopIndexSaved: Integer;
v157: Integer;
begin
if QueryQueue.Count > 0 then begin
lbServers.Items.BeginUpdate;
TrackingChanges:= true;
v162:= true;
end;
TopIndexSaved:= lbServers.TopIndex;
v157:= lbServers.TopIndex;
NewServs:= TStringList.Create;
@ -1005,9 +1002,9 @@ begin
if lbServers.ItemIndex = -1 then
lbServers.ItemIndex:= 0;
if lbServers.Items.Count >= TopIndexSaved then
lbServers.TopIndex:= TopIndexSaved;
if TrackingChanges = true then
if lbServers.Items.Count >= v157 then
lbServers.TopIndex:= v157;
if v162 = true then
lbServers.Items.EndUpdate;
Application.ProcessMessages;
end;
@ -1113,12 +1110,12 @@ begin
BlockRead(ImportFile, Servers[i].RconPassword[1], Temp);
Servers[i].Ping:= 9999;
Servers[i].Tag:= Random($FFFF);
Servers[i].field_10:= Random($FFFF);
if Dubble then
SetLength(Servers, i)
else
QueryQueue.Add(Servers[i].Address + ':' + IntToStr(Servers[i].Port) + '#' + IntToStr(Servers[i].Tag));
QueryQueue.Add(Servers[i].Address + ':' + IntToStr(Servers[i].Port) + '#' + IntToStr(Servers[i].field_10));
//QueryServerInfo(Servers[i].Address + ':' + IntToStr(Servers[i].Port), true, true, false, false);
end;
CloseFile(ImportFile);
@ -1261,7 +1258,7 @@ end;
procedure TfmMain.AddServerClick(Sender: TObject);
var
Server: String;
Dummy: Boolean;
v22: Boolean;
begin
Server:= GetClipBoardStr;
if (MasterFile <> 0) and (lbServers.ItemIndex <> -1) then begin
@ -1269,7 +1266,7 @@ begin
IntToStr(Servers[StrToIntDef(lbServers.Items.Strings[lbServers.ItemIndex], 0)].Port);
tsServerLists.TabIndex:= 0;
tsServerListsChange(tsServerLists, 0, Dummy);
tsServerListsChange(tsServerLists, 0, v22);
end;
if InputQuery('Add Server', 'Enter new server HOST:PORT...', Server) then
if Server <> '' then begin
@ -1304,7 +1301,7 @@ begin
//QueryServerInfo(Server, true, true, false, false);
QueryQueue.Add(Server);
ExportFavorites(sub_4E1DA8 + 'USERDATA.DAT', true);
FavoritesChanged:= true;
byte_4EF090:= true;
end;
UpdateServers;
end;
@ -1324,7 +1321,7 @@ begin
UpdateServers;
ExportFavorites(sub_4E1DA8 + 'USERDATA.DAT', true);
FavoritesChanged:= true;
byte_4EF090:= true;
end;
procedure TfmMain.RefreshServerClick(Sender: TObject);
@ -1335,7 +1332,7 @@ begin
Idx:= StrToInt(lbServers.Items.Strings[lbServers.ItemIndex]);
if Idx >= Length(Servers) then Exit;
QueryServerInfo(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port) + '#' + IntToStr(Servers[Idx].Tag), true, true, true, true);
QueryServerInfo(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port) + '#' + IntToStr(Servers[Idx].field_10), true, true, true, true);
end;
procedure TfmMain.MasterServerUpdateClick(Sender: TObject);
@ -1401,10 +1398,10 @@ begin
Servers[i].Address:= Copy(SL.Strings[i], 1, Pos(':', SL.Strings[i])-1);
Servers[i].Port:= StrToIntDef(Copy(SL.Strings[i], Pos(':', SL.Strings[i])+1, 5), 7777);
Servers[i].Ping:= 9999;
Servers[i].Tag:= Random($FFFF);
Servers[i].field_10:= Random(65535);
//QueryServerInfo(SL.Strings[i], true, true, false, false);
//Sleep(10);
QueryQueue.Add(SL.Strings[i] + '#' + IntToStr(Servers[i].Tag));
QueryQueue.Add(SL.Strings[i] + '#' + IntToStr(Servers[i].field_10));
end;
tmrQueryQueueProcess.Enabled := true;
@ -1499,9 +1496,9 @@ end;
procedure TfmMain.tsServerListsChange(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean);
begin
if (tsServerLists.TabIndex = 0) and (FavoritesChanged = True) then begin
if (tsServerLists.TabIndex = 0) and (byte_4EF090 = True) then begin
ExportFavorites(sub_4E1DA8 + 'USERDATA.DAT', true);
FavoritesChanged:= False;
byte_4EF090:= False;
end;
QueryQueue.Clear;
@ -1542,10 +1539,10 @@ begin
dword_4EF08C.Clear;
end;
procedure TfmMain.QueryServerInfoParse(SrcIP: String; SrcPort: Word; Buf: PAnsiChar; DataLen: Integer);
procedure TfmMain.QueryServerInfoParse(a2: String; a3: Word; Buf: PAnsiChar; DataLen: Integer);
var
StrIP: String;
Tag: Word;
v144: Word;
i, j, Idx: Integer;
Magic: array[0..3] of char;
ping: Cardinal;
@ -1557,8 +1554,8 @@ var
RepaintServerList,
RepaintPlayerList,
RepaintRulesList: Boolean;
TempInt: Integer;
Port: Word;
v131: Integer;
v130: Word;
begin
@ -1570,27 +1567,27 @@ begin
StrIP:= IntToStr(Byte(Buf[4]))+'.'+IntToStr(Byte(Buf[5]))+'.'+
IntToStr(Byte(Buf[6]))+'.'+IntToStr(Byte(Buf[7]));
Move(Buf[8], Port, 2);
Move(Buf[8], v130, 2);
Tag:= SrcPort;
v144:= a3;
if SrcIP <> StrIP then Exit;
if a2 <> StrIP then Exit;
Idx:= -1;
for i:= 0 to Length(Servers)-1 do begin
if Servers[i].DottedAddress = '' then begin
if not Servers[i].HasAddress then begin
Servers[i].DottedAddress:= GetIPFromHost(Servers[i].Address);
Servers[i].HasAddress:= true;
if Servers[i].field_4 = '' then begin
if not Servers[i].field_8 then begin
Servers[i].field_4:= GetIPFromHost(Servers[i].Address);
Servers[i].field_8:= true;
end;
end;
if (Servers[i].Address = SrcIP) or (Servers[i].DottedAddress = SrcIP) then begin
if Servers[i].Port = SrcPort then begin
if (Servers[i].Address = a2) or (Servers[i].field_4 = a2) then begin
if Servers[i].Port = a3 then begin
Idx:= i;
break;
end;
end;
if (Servers[i].Address = SrcIP) and (Servers[i].Port = SrcPort) then begin
if (Servers[i].Address = a2) and (Servers[i].Port = a3) then begin
Idx:= i;
break;
end;
@ -1601,8 +1598,7 @@ begin
Exit;
end;
if (Servers[i].Tag <> 0) and (Servers[i].Tag <> Port) then begin
//fmMain.Caption:= 'Invalid tag for ' + StrIP;
if (Servers[i].field_10 <> 0) and (Servers[i].field_10 <> v130) then begin
Exit;
end;
@ -1690,7 +1686,7 @@ begin
RepaintServerList:= true;
QueryServerInfo(Servers[Idx].Address+':'+IntToStr(Servers[Idx].Port)+'#'+IntToStr(Servers[Idx].Tag), true, false, false, false);
QueryServerInfo(Servers[Idx].Address+':'+IntToStr(Servers[Idx].Port)+'#'+IntToStr(Servers[Idx].field_10), true, false, false, false);
end;
'c': // Players
@ -1711,10 +1707,10 @@ begin
Move(Buf[BufPos], Servers[Idx].aPlayers[i].Name[1], TempByte);
Inc(BufPos, TempByte);
if BufPos > DataLen then break;
Move(Buf[BufPos], TempInt, 4);
if TempInt > 1000000 then TempInt:= 1000000;
if TempInt < 0 then TempInt:= 0;
Servers[Idx].aPlayers[i].Score:= TempInt;
Move(Buf[BufPos], v131, 4);
if v131 > 1000000 then v131:= 1000000;
if v131 < 0 then v131:= 0;
Servers[Idx].aPlayers[i].Score:= v131;
Inc(BufPos, 4);
if BufPos > DataLen then break;
end;
@ -1783,33 +1779,33 @@ var
Host: String;
Port: Word;
Tag: Word;
v40: Word;
ColPos, TagPos: Integer;
v39, v38: Integer;
begin
Tag:= 0;
v40:= 0;
if Pos(':', Server) <> 0 then begin
if Pos('#', Server) <> 0 then begin
ColPos:= Pos(':', Server);
TagPos:= Pos('#', Server);
v39:= Pos(':', Server);
v38:= Pos('#', Server);
Host:= Copy(Server, 1, ColPos-1);
Port:= StrToIntDef(Copy(Server, ColPos+1, TagPos-(ColPos+1)), 7777);
Tag:= StrToIntDef(Copy(Server, TagPos+1, Length(Server)-TagPos), 0);
Host:= Copy(Server, 1, v39-1);
Port:= StrToIntDef(Copy(Server, v39+1, v38-(v39+1)), 7777);
v40:= StrToIntDef(Copy(Server, v38+1, Length(Server)-v38), 0);
end else begin
ColPos:= Pos(':', Server);
v39:= Pos(':', Server);
Host:= Copy(Server, 1, ColPos-1);
Port:= StrToIntDef(Copy(Server, ColPos+1, Length(Server)-ColPos+1), 7777);
Host:= Copy(Server, 1, v39-1);
Port:= StrToIntDef(Copy(Server, v39+1, Length(Server)-v39+1), 7777);
end;
end else begin
Host:= Server;
Port:= 7777;
end;
if Tag = 0 then
Tag:= Port;
if v40 = 0 then
v40:= Port;
Host:= GetIPFromHost(Host);
if (Length(Host) < 7) or (Length(Host) > 15) then
@ -1834,7 +1830,7 @@ begin
ToAddr.sin_addr.S_addr:= inet_addr(PChar(Host));
ToLen:= SizeOf(ToAddr);
Move(Tag, Buf[8], 2); // Tag
Move(v40, Buf[8], 2);
if bInfo = true then begin
Buf[10]:= Byte('i'); // Info Packet Id
@ -2083,30 +2079,28 @@ procedure TfmMain.WMRecv(var Message: TMessage);
var
lpBuffer: Array[0..2048] of Char;
BufLen: Integer;
FromAddr: TSockAddr;
FromLen: Integer;
SrcAddr: String;
SrcPort: Word;
v8: TSockAddr;
v13: Integer;
v12: String;
v11: Word;
begin
ZeroMemory(@lpBuffer, sizeof(lpBuffer));
ZeroMemory(@FromAddr, sizeof(FromAddr));
FromAddr.sin_family:= AF_INET;
FromLen:= SizeOf(FromAddr);
ZeroMemory(@v8, sizeof(v8));
v8.sin_family:= AF_INET;
BufLen:= recvfrom(QuerySocket, lpBuffer, 2048, 0, FromAddr, FromLen);
SrcAddr:= inet_ntoa(FromAddr.sin_addr);
SrcPort:= htons(FromAddr.sin_port);
v13:= SizeOf(v8);
BufLen:= recvfrom(QuerySocket, lpBuffer, 2048, 0, v8, v13);
v12:= inet_ntoa(v8.sin_addr);
v11:= htons(v8.sin_port);
while (BufLen > 0) do begin
//OutputDebugString( PChar('[*] of size ' + IntToStr(BufLen)) );
QueryServerInfoParse(SrcAddr,SrcPort,lpBuffer,BufLen);
QueryServerInfoParse(v12,v11,lpBuffer,BufLen);
ZeroMemory(@lpBuffer, sizeof(lpBuffer));
BufLen:= recvfrom(QuerySocket, lpBuffer, 2048, 0, FromAddr, FromLen);
SrcAddr:= inet_ntoa(FromAddr.sin_addr);
SrcPort:= htons(FromAddr.sin_port);
BufLen:= recvfrom(QuerySocket, lpBuffer, 2048, 0, v8, v13);
v12:= inet_ntoa(v8.sin_addr);
v11:= htons(v8.sin_port);
end;
end;
@ -2128,9 +2122,9 @@ begin
QueryQueue.Free;
if (tsServerLists.TabIndex = 0) and (FavoritesChanged = True) then begin
if (tsServerLists.TabIndex = 0) and (byte_4EF090 = True) then begin
ExportFavorites(sub_4E1DA8 + 'USERDATA.DAT', True);
FavoritesChanged:= False;
byte_4EF090:= False;
end;
Sleep(0);
@ -2139,7 +2133,7 @@ end;
procedure TfmMain.FormShow(Sender: TObject);
var
ServFull, ServAddr, ServPort, ServPass: String;
NewServer: String;
v37: String;
begin
//SetProcessAffinityMask(GetCurrentProcess(),1);
lbServers.DoubleBuffered:= true;
@ -2156,17 +2150,6 @@ begin
ServFull:= StringReplace(ServFull, '/', '', [rfReplaceAll, rfIgnoreCase]);
if Pos(':', ServFull) <> 0 then begin
ServAddr:= Copy(ServFull, 0, Pos(':', ServFull)-1);
///////////////////////////////////////////////
//
// Delphi 7 compiler bug(?)
//
// With this structure:
// ServPort:= IntToStr(StrToIntDef(Copy(ServFull, Pos(':', ServFull)+1, Length(ServFull)-Pos(':', ServFull)+1), 7777));
// the compiler seems to gets confused and will not generate
// LStrLAsg call after Sysutils::IntToStr to set ServPort variable.
// Workaround is to break down the structure.
//
///////////////////////////////////////////////
ServPort:= Copy(ServFull, Pos(':', ServFull)+1, Length(ServFull)-Pos(':', ServFull)+1);
ServPort:= IntToStr(StrToIntDef(ServPort, 7777));
end else begin
@ -2181,12 +2164,13 @@ begin
end;
mrYes: begin
sub_4E1CEC;
NewServer:= ServAddr + ':' + ServPort;
if InputQuery('Add Server', 'Enter new server HOST:PORT...', NewServer) <> False then
if NewServer <> '' then
AddServer(NewServer);
v37:= ServAddr + ':' + ServPort;
if InputQuery('Add Server', 'Enter new server HOST:PORT...', v37) <> False then
if v37 <> '' then
AddServer(v37);
end;
mrCancel: ;
mrCancel:
;
end;
end else begin
ServFull:= ParamStr(1);
@ -2264,14 +2248,14 @@ end;
procedure TfmMain.CreateFASTDesktoplink1Click(Sender: TObject);
var
Idx: Integer;
v17: Integer;
begin
if lbServers.ItemIndex = -1 then Exit;
Idx:= StrToInt(lbServers.Items.Strings[lbServers.ItemIndex]);
if Idx >= Length(Servers) then Exit;
v17:= StrToInt(lbServers.Items.Strings[lbServers.ItemIndex]);
if v17 >= Length(Servers) then Exit;
sub_4E1E6C(Servers[Idx].Address + ':' + IntToStr(Servers[Idx].Port), Servers[Idx].HostName);
sub_4E1E6C(Servers[v17].Address + ':' + IntToStr(Servers[v17].Port), Servers[v17].HostName);
end;
procedure TfmMain.FormResize(Sender: TObject);

Binary file not shown.

View File

@ -6,7 +6,7 @@
-$F-
-$G+
-$H+
-$I+
-$I-
-$J-
-$K-
-$L+
@ -14,8 +14,8 @@
-$N+
-$O-
-$P+
-$R-
-$Q+
-$R-
-$S-
-$T-
-$U-

View File

@ -9,15 +9,15 @@ E=0
F=0
G=1
H=1
I=1
I=0
J=0
K=0
L=1
M=0
N=1
O=1
O=0
P=1
Q=0
Q=1
R=0
S=0
T=0
@ -88,14 +88,14 @@ RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=
ExeDescription=San Andreas Multiplayer Server Browser
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=
Packages=vcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;dsnapcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband;vclshlctrls;dclOfficeXP
Conditionals=
DebugSourceDirs=
UsePackages=0
@ -121,7 +121,7 @@ PreRelease=0
Special=0
Private=0
DLL=0
Locale=1033
Locale=3081
CodePage=1252
[Version Info Keys]
CompanyName=
@ -134,3 +134,6 @@ OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlUnitAliases]
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;

Binary file not shown.

Binary file not shown.

0
nsis/CUSTOM.ide Normal file
View File

2069
nsis/SAMP.ide Normal file

File diff suppressed because it is too large Load Diff

BIN
nsis/SAMP.img Normal file

Binary file not shown.

63
nsis/SAMP.ipl Normal file
View File

@ -0,0 +1,63 @@
# ------------------------------------------------------
# ------------------------------------------------------
# SA:MP IPL File
# --------------
# This file was added to SA:MP to create some new cull
# zones for the enterable buildings. The cull zones
# prevent weather from appearing inside them.
#
# You should not need to edit this file.
#
# Cull zones in this file were created by:
# Matite (January and February 2015)
#
# Go to the SA:MP wiki for information about this file:
# http://wiki.sa-mp.com
# ------------------------------------------------------
inst
# LS BeachSide interior object
19597, SanCliffI05_LAw2, 0, 280.29688, -1606.20313, 72.39844, 0.00000, 0.00000, 0.00000, 1.00000, -1
# LS BeachSide carpark object
19800, SanCliffc05_LAw2, 0, 280.297, -1606.2, 22.3984, 0.00000, 0.00000, 0.00000, 1.00000, -1
end
cull
# ----------------------------------------------------------------------------------------
# CenterX, CenterY, CenterZ, SkewX, DistanceY, Bottom, DistanceX, SkewY, Top, Flag, 0
# ----------------------------------------------------------------------------------------
# LS BeachSide
287.916, -1608.9, 30.9127, 2.62643, 15.1336, 30.9127, 20.0683, -3.48285, 113.6127, 8, 0
# ----------------------------------------------------------------------------------------
# LS BeachSide Underground Car Park
275.75, -1621.74, 10.0, 0, 40.0, 10.0, 40.0, 0, 30.0, 8, 0
# ----------------------------------------------------------------------------------------
# LS Office
1803.7078, -1294.0806, 10.0, 0, 26.5, 10.0, 33.0, 0, 130.0, 8, 0
# ----------------------------------------------------------------------------------------
# LS Mall
1117.59, -1490.01, 10.0, 0, 77.0, 10.0, 73.0, 0, 29.0, 8, 0
# ----------------------------------------------------------------------------------------
# LS Apartments
1164.96, -1180.58, 15.0, 0, 21.0, 15.0, 44.0, 0, 92.0, 8, 0
# ----------------------------------------------------------------------------------------
# SF Building 1
-2712.04, 859.58, 65.0, 0, 8.0, 65.0, 13.0, 0, 80.0, 8, 0
# ----------------------------------------------------------------------------------------
end
path
end
grge
end
enex
end
pick
end
cars
end
jump
end
tcyc
end
auzo
end
mult
end

BIN
nsis/SAMPCOL.img Normal file

Binary file not shown.

BIN
nsis/bass.dll Normal file

Binary file not shown.

BIN
nsis/blanktex.txd Normal file

Binary file not shown.

BIN
nsis/custom.img Normal file

Binary file not shown.

BIN
nsis/gtaweap3.ttf Normal file

Binary file not shown.

BIN
nsis/mouse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

BIN
nsis/rcon.exe Normal file

Binary file not shown.

BIN
nsis/samaps.txd Normal file

Binary file not shown.

92
nsis/samp-license.txt Normal file
View File

@ -0,0 +1,92 @@
------------------------------------------------------------------------------------
The SA-MP modification for Grand Theft Auto: San Andreas (r) is a software project
aimed at extending the functionality of the Grand Theft Auto: San Andreas (r)
software for Microsoft Windows (r).
------------------------------------------------------------------------------------
SA-MP CLIENT AND SERVER SOFTWARE LICENSE AGREEMENT AND ATTRIBUTIONS
---- LICENSE TERMS ----
(a) You must have a valid license to use Grand Theft Auto: San Andreas (r) PC
in order for this license to be valid.
(b) The software contained herein is provided on an "as-is" basis without
any form of warranty.
(c) This software may not be exploited for personal, financial or
commercial gain.
(d) The author(s) of this software accept no liability for use/misuse of the
software.
(e) The SA-MP software package may not be distributed, sold, rented or
leased, without written permission of the software author(s).
(f) You may not create or distribute derivative works of the software or files
contained within the package.
(g) You may not use this software for any illegal purposes.
(h) The author(s) of this software retain the right to modify/revoke this license
at any time under any conditions seen appropriate by the author(s).
(i) Ideas expressed in this software by way of coding or configuration are
property of SA-MP.com.
------------------------------------------------------------------------------------
(c) 2005-2011 SA-MP.com team.
The SA-MP.com team is not affiliated with Rockstar Games, Rockstar North or
Take-Two Interactive Software Inc.
Grand Theft Auto and Grand Theft Auto: San Andreas are registered trademarks of
Take-Two Interactive Software Inc.
------------------------------------------------------------------------------------
---- ATTRIBUTIONS ----
- This software makes use of the RakNet networking library (c) 2003 Kevin Jenkins
- This software makes use of the Pawn language (c) ITB CompuPhase, 1997-2005
- This software makes use of the BASS audio library (c) Un4seen Developments Ltd
- This software makes use of the ttmath library (c) 2006-2009, Tomasz Sowa
*** ttmath LIBRARY LICENSE ***
Copyright (c) 2006-2009, Tomasz Sowa
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name Tomasz Sowa nor the names of contributors to this
project may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------------

BIN
nsis/samp.dll Normal file

Binary file not shown.

BIN
nsis/samp.saa Normal file

Binary file not shown.

BIN
nsis/samp_debug.exe Normal file

Binary file not shown.

BIN
nsis/sampaux3.ttf Normal file

Binary file not shown.

BIN
nsis/sampgui.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -33,12 +33,16 @@
#ifdef _COMPATIBILITY_1
#define DEFAULT_MTU_SIZE 1264
#else
#define DEFAULT_MTU_SIZE 1500
#define DEFAULT_MTU_SIZE 576
#endif
/// The largest value for an UDP datagram
/// \sa RakPeer::SetMTUSize()
#define MAXIMUM_MTU_SIZE 1500
#ifdef SAMPCLI
#define MAXIMUM_MTU_SIZE 1492
#else
#define MAXIMUM_MTU_SIZE 576
#endif
#endif

View File

@ -32,7 +32,7 @@ enum PacketPriority
/// \note Note to self: I write this with 3 bits in the stream. If I add more remember to change that
enum PacketReliability
{
UNRELIABLE, /// Same as regular UDP, except that it will also discard duplicate datagrams. RakNet adds (6 to 17) + 21 bits of overhead, 16 of which is used to detect duplicate packets and 6 to 17 of which is used for message length.
UNRELIABLE = 6, /// Same as regular UDP, except that it will also discard duplicate datagrams. RakNet adds (6 to 17) + 21 bits of overhead, 16 of which is used to detect duplicate packets and 6 to 17 of which is used for message length.
UNRELIABLE_SEQUENCED, /// Regular UDP with a sequence counter. Out of order messages will be discarded. This adds an additional 13 bits on top what is used for UNRELIABLE.
RELIABLE, /// The message is sent reliably, but not necessarily in any order. Same overhead as UNRELIABLE.
RELIABLE_ORDERED, /// This message is reliable and will arrive in the order you sent it. Messages will be delayed while waiting for out of order messages. Same overhead as UNRELIABLE_SEQUENCED.

View File

@ -41,7 +41,6 @@ public:
RPCIndex GetIndexFromFunctionName(unsigned char uniqueIdentifier);
void AddIdentifierWithFunction(unsigned char uniqueIdentifier, void *functionPointer, bool isPointerToMember);
protected:
DataStructures::List<RPCNode *> rpcSet;
RPCNode *rpcSet[RPC_SET_SIZE];
};

View File

@ -19,6 +19,10 @@
#include "BitStream.h" // BITS_TO_BYTES
#include "GetTime.h"
RakNetTime connectionStartTimeSaved=0;
uint64_t totalBitsSentSaved=0;
uint64_t bitsReceivedSaved=0;
// Verbosity level currently supports 0 (low), 1 (medium), 2 (high)
// Buffer must be hold enough to hold the output string. See the source to get an idea of how many bytes will be output
void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityLevel )
@ -29,29 +33,25 @@ void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityL
return ;
}
if ( verbosityLevel == 0 )
{
// Verbosity level 0
sprintf( buffer,
"Total bytes sent: %u\n"
"Total bytes received: %u\n"
"Packetloss: %.1f%%\n",
BITS_TO_BYTES( s->totalBitsSent ),
BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent );
}
else if ( verbosityLevel == 1 )
if ( verbosityLevel == 1 )
{
RakNetTime time = RakNet::GetTime();
double elapsedTime;
double bpsSent;
double bpsReceived;
elapsedTime = (time-s->connectionStartTime) / 1000.0f;
bpsSent = (double) s->totalBitsSent / elapsedTime;
bpsReceived= (double) s->bitsReceived / elapsedTime;
// Verbosity level 1
if ( connectionStartTimeSaved == 0 )
connectionStartTimeSaved = s->connectionStartTime;
elapsedTime = (time-connectionStartTimeSaved) / 1000.0f;
bpsSent = (double) ((unsigned)s->totalBitsSent-totalBitsSentSaved) / elapsedTime;
bpsReceived = (double) ((unsigned)s->bitsReceived-bitsReceivedSaved) / elapsedTime;
totalBitsSentSaved = s->totalBitsSent;
bitsReceivedSaved = s->bitsReceived;
connectionStartTimeSaved = RakNet::GetTime();
// Verbosity level 1
sprintf( buffer,
"Messages in Send buffer: %u\n"
"Messages sent: %u\n"
@ -67,26 +67,26 @@ void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityL
"Acks received: %u\n"
"Duplicate acks received: %u\n"
"Inst. KBits per second: %.1f\n"
"KBits per second sent:\t\t\t%.1f\n"
"KBits per second received:\t\t%.1f\n",
"KBits per second sent: %.1f\n"
"KBits per second received: %.1f\n",
s->messageSendBuffer[ SYSTEM_PRIORITY ] + s->messageSendBuffer[ HIGH_PRIORITY ] + s->messageSendBuffer[ MEDIUM_PRIORITY ] + s->messageSendBuffer[ LOW_PRIORITY ],
s->messagesSent[ SYSTEM_PRIORITY ] + s->messagesSent[ HIGH_PRIORITY ] + s->messagesSent[ MEDIUM_PRIORITY ] + s->messagesSent[ LOW_PRIORITY ],
BITS_TO_BYTES( s->totalBitsSent ),
( unsigned ) BITS_TO_BYTES( s->totalBitsSent ),
s->acknowlegementsSent,
s->acknowlegementsPending,
s->messagesOnResendQueue,
s->messageResends,
BITS_TO_BYTES( s->messagesTotalBitsResent ),
( unsigned ) BITS_TO_BYTES( s->messagesTotalBitsResent ),
100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
s->duplicateMessagesReceived + s->invalidMessagesReceived + s->messagesReceived,
BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
( unsigned ) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
s->acknowlegementsReceived,
s->duplicateAcknowlegementsReceived,
s->bitsPerSecond / 1000.0,
bpsSent / 1000.0,
bpsReceived / 1000.0);
}
else
else if ( verbosityLevel == 2 )
{
RakNetTime time = RakNet::GetTime();
double elapsedTime;
@ -169,7 +169,36 @@ void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityL
s->bitsPerSecond/1000.0,
elapsedTime,
bpsSent / 1000.0,
bpsReceived / 1000.0
);
bpsReceived / 1000.0);
}
}
else if ( verbosityLevel == 4 )
{
sprintf( buffer,
"Messages in Send buffer: %u\n"
"Messages sent: %u\n"
"Bytes sent: %u\n"
"Acks sent: %u\n"
"Acks in send buffer: %u\n"
"Messages waiting for ack: %u\n"
"Messages resent: %u\n"
"Bytes resent: %u\n"
"Packetloss: %.1f%%\n"
"Messages received: %u\n"
"Bytes received: %u\n"
"Acks received: %u\n"
"Duplicate acks received: %u\n",
s->messageSendBuffer[ SYSTEM_PRIORITY ] + s->messageSendBuffer[ HIGH_PRIORITY ] + s->messageSendBuffer[ MEDIUM_PRIORITY ] + s->messageSendBuffer[ LOW_PRIORITY ],
s->messagesSent[ SYSTEM_PRIORITY ] + s->messagesSent[ HIGH_PRIORITY ] + s->messagesSent[ MEDIUM_PRIORITY ] + s->messagesSent[ LOW_PRIORITY ],
( unsigned ) BITS_TO_BYTES( s->totalBitsSent ),
s->acknowlegementsSent,
s->acknowlegementsPending,
s->messagesOnResendQueue,
s->messageResends,
( unsigned ) BITS_TO_BYTES( s->messagesTotalBitsResent ),
100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
s->duplicateMessagesReceived + s->invalidMessagesReceived + s->messagesReceived,
( unsigned ) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
s->acknowlegementsReceived,
s->duplicateAcknowlegementsReceived);
}
}

View File

@ -23,20 +23,27 @@
#include "Export.h"
#include "NetworkTypes.h"
/// \brief Network Statisics Usage
typedef unsigned long long uint64_t;
/// \brief Network Statisics Usage
///
/// Store Statistics information related to network usage
/// Store Statistics information related to network usage
struct RAK_DLL_EXPORT RakNetStatisticsStruct
{
// TODO: RakNetStatisticsStruct
/// Number of Messages in the send Buffer (high, medium, low priority)
unsigned messageSendBuffer[ NUMBER_OF_PRIORITIES ];
/// Number of messages sent (high, medium, low priority)
unsigned messagesSent[ NUMBER_OF_PRIORITIES ];
char _gap20[16];
/// Number of data bits used for user messages
unsigned messageDataBitsSent[ NUMBER_OF_PRIORITIES ];
uint64_t messageDataBitsSent[ NUMBER_OF_PRIORITIES ];
/// Number of total bits used for user messages, including headers
unsigned messageTotalBitsSent[ NUMBER_OF_PRIORITIES ];
uint64_t messageTotalBitsSent[ NUMBER_OF_PRIORITIES ];
/// Number of packets sent containing only acknowledgements
unsigned packetsContainingOnlyAcknowlegements;
/// Number of acknowledgements sent
@ -44,53 +51,53 @@ struct RAK_DLL_EXPORT RakNetStatisticsStruct
/// Number of acknowledgements waiting to be sent
unsigned acknowlegementsPending;
/// Number of acknowledgements bits sent
unsigned acknowlegementBitsSent;
uint64_t acknowlegementBitsSent;
/// Number of packets containing only acknowledgements and resends
unsigned packetsContainingOnlyAcknowlegementsAndResends;
/// Number of messages resent
unsigned messageResends;
/// Number of bits resent of actual data
unsigned messageDataBitsResent;
uint64_t messageDataBitsResent;
/// Total number of bits resent, including headers
unsigned messagesTotalBitsResent;
uint64_t messagesTotalBitsResent;
/// Number of messages waiting for ack (// TODO - rename this)
unsigned messagesOnResendQueue;
/// Number of messages not split for sending
unsigned numberOfUnsplitMessages;
/// Number of messages split for sending
unsigned numberOfSplitMessages;
/// Total number of splits done for sending
unsigned totalSplits;
/// Total packets sent
unsigned packetsSent;
/// Number of bits added by encryption
unsigned encryptionBitsSent;
uint64_t encryptionBitsSent;
/// total bits sent
unsigned totalBitsSent;
uint64_t totalBitsSent;
/// Number of sequenced messages arrived out of order
unsigned sequencedMessagesOutOfOrder;
/// Number of sequenced messages arrived in order
unsigned sequencedMessagesInOrder;
/// Number of ordered messages arrived out of order
unsigned orderedMessagesOutOfOrder;
/// Number of ordered messages arrived in order
unsigned orderedMessagesInOrder;
/// Packets with a good CRC received
unsigned packetsReceived;
/// Packets with a bad CRC received
unsigned packetsWithBadCRCReceived;
/// Bits with a good CRC received
unsigned bitsReceived;
uint64_t bitsReceived;
/// Bits with a bad CRC received
unsigned bitsWithBadCRCReceived;
uint64_t bitsWithBadCRCReceived;
/// Number of acknowledgement messages received for packets we are resending
unsigned acknowlegementsReceived;
/// Number of acknowledgement messages received for packets we are not resending
@ -110,7 +117,14 @@ struct RAK_DLL_EXPORT RakNetStatisticsStruct
/// connection start time
RakNetTime connectionStartTime;
RakNetStatisticsStruct operator +=(const RakNetStatisticsStruct& other)
RakNetTime field_110;
unsigned field_114;
unsigned field_118;
RakNetTime field_11C;
unsigned field_120;
unsigned field_124;
void operator +=(const RakNetStatisticsStruct& other)
{
unsigned i;
for (i=0; i < NUMBER_OF_PRIORITIES; i++)
@ -151,18 +165,9 @@ struct RAK_DLL_EXPORT RakNetStatisticsStruct
duplicateMessagesReceived+=other.duplicateMessagesReceived;
messagesWaitingForReassembly+=other.messagesWaitingForReassembly;
internalOutputQueueSize+=other.internalOutputQueueSize;
return *this;
}
};
/// Verbosity level currently supports 0 (low), 1 (medium), 2 (high)
/// \param[in] s The Statistical information to format out
/// \param[in] buffer The buffer containing a formated report
/// \param[in] verbosityLevel
/// 0 low
/// 1 medium
/// 2 high
void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityLevel );
#endif
#endif

View File

@ -46,6 +46,12 @@
#include "RouterInterface.h"
#include "RakAssert.h"
#ifdef _WIN32
#include <windows.h>
#else
#define OutputDebugString NULL
#endif
#if !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ )
#include <malloc.h>
#endif
@ -1191,7 +1197,7 @@ bool RakPeer::RPC( char* uniqueID, const char *data, unsigned int bitLength, Pac
#else
sendList = new unsigned[1];
#endif
remoteSystemIndex=GetIndexFromPlayerID( playerId, false );
remoteSystemIndex=GetIndexFromPlayerID( playerId, false );
if (remoteSystemIndex!=(unsigned)-1 &&
remoteSystemList[remoteSystemIndex].connectMode!=RemoteSystemStruct::DISCONNECT_ASAP &&
remoteSystemList[remoteSystemIndex].connectMode!=RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY &&
@ -1763,7 +1769,7 @@ void RakPeer::SendStaticData( const PlayerID target )
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void RakPeer::SetOfflinePingResponse( const char *data, const unsigned int length )
{
assert(length < 400);
//assert(length < 400);
rakPeerMutexes[ offlinePingResponse_Mutex ].Lock();
offlinePingResponse.Reset();
@ -2053,7 +2059,7 @@ void RakPeer::AdvertiseSystem( const char *host, unsigned short remotePort, cons
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void RakPeer::SetSplitMessageProgressInterval(int interval)
{
RakAssert(interval>=0);
//RakAssert(interval>=0);
splitMessageProgressInterval=interval;
for ( unsigned short i = 0; i < maximumNumberOfPeers; i++ )
remoteSystemList[ i ].reliabilityLayer.SetSplitMessageProgressInterval(splitMessageProgressInterval);
@ -2067,7 +2073,7 @@ void RakPeer::SetSplitMessageProgressInterval(int interval)
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void RakPeer::SetUnreliableTimeout(RakNetTime timeoutMS)
{
RakAssert(timeoutMS>=0);
//RakAssert(timeoutMS>=0);
unreliableTimeout=timeoutMS;
for ( unsigned short i = 0; i < maximumNumberOfPeers; i++ )
remoteSystemList[ i ].reliabilityLayer.SetUnreliableTimeout(unreliableTimeout);
@ -2408,7 +2414,7 @@ int RakPeer::GetIndexFromPlayerID( const PlayerID playerId, bool calledFromNetwo
index = remoteSystemLookup.GetIndexFromKey(playerId, &objectExists);
if (objectExists)
{
assert(remoteSystemList[remoteSystemLookup[index].index].playerId==playerId);
//assert(remoteSystemList[remoteSystemLookup[index].index].playerId==playerId);
return remoteSystemLookup[index].index;
}
else
@ -2774,6 +2780,12 @@ RakNetTime RakPeer::GetBestClockDifferential( const PlayerID playerId ) const
return clockDifferential;
}
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
RakNetTime RakPeer::GetTimestampFromPlayerID( const PlayerID playerId, RakNetTime time ) const
{
return time - GetBestClockDifferential(playerId);
}
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Description:
// Handles an RPC packet. If you get a packet with the ID ID_RPC you should pass it to this function
@ -3743,197 +3755,14 @@ void ProcessNetworkPacket( const unsigned int binaryAddress, const unsigned shor
return;
}
// Connecting to a system we are already connected to.
else if ((unsigned char)(data)[0] == (unsigned char) ID_CONNECTION_ATTEMPT_FAILED && length <= sizeof(unsigned char)*2)
{
// Remove the connection attempt from the buffered commands
RakPeer::RequestedConnectionStruct *rcsFirst, *rcs;
rcsFirst = rakPeer->requestedConnectionList.ReadLock();
rcs=rcsFirst;
bool connectionAttemptCancelled=false;
while (rcs)
{
if (rcs->actionToTake==RakPeer::RequestedConnectionStruct::CONNECT && rcs->playerId==playerId)
{
connectionAttemptCancelled=true;
if (rcs==rcsFirst)
{
rakPeer->requestedConnectionList.ReadUnlock();
rcsFirst=rakPeer->requestedConnectionList.ReadLock();
rcs=rcsFirst;
}
else
{
// Hole in the middle
rcs->playerId=UNASSIGNED_PLAYER_ID;
rcs=rakPeer->requestedConnectionList.ReadLock();
}
continue;
}
ID_CONNECTION_ATTEMPT_FAILED;
ID_NO_FREE_INCOMING_CONNECTIONS;
ID_CONNECTION_BANNED;
rcs=rakPeer->requestedConnectionList.ReadLock();
}
if (rcsFirst)
rakPeer->requestedConnectionList.CancelReadLock(rcsFirst);
if (connectionAttemptCancelled)
{
// Tell user of connection attempt failed
packet=AllocPacket(sizeof( char ));
packet->data[ 0 ] = ID_CONNECTION_ATTEMPT_FAILED; // Attempted a connection and couldn't
packet->bitSize = ( sizeof( char ) * 8);
packet->playerId = playerId;
packet->playerIndex = 65535;
rakPeer->AddPacketToProducer(packet);
}
}
// We didn't check this datagram to see if it came from a connected system or not yet.
// Therefore, this datagram must be under 17 bits - otherwise it may be normal network traffic as the min size for a raknet send is 17 bits
else if ((unsigned char)(data)[0] == ID_OPEN_CONNECTION_REQUEST && length == sizeof(unsigned char)*2)
{
for (i=0; i < rakPeer->messageHandlerList.Size(); i++)
rakPeer->messageHandlerList[i]->OnDirectSocketReceive(data, length*8, playerId);
// If this guy is already connected and they initiated the connection, ignore the connection request
RakPeer::RemoteSystemStruct *rss = rakPeer->GetRemoteSystemFromPlayerID( playerId, true, true );
if (rss==0 || rss->weInitiatedTheConnection==true)
{
// Assign new remote system
if (rss==0)
rss=rakPeer->AssignPlayerIDToRemoteSystemList(playerId, RakPeer::RemoteSystemStruct::UNVERIFIED_SENDER);
unsigned char c[2];
if (rss) // If this guy is already connected remote system will be 0
c[0] = ID_OPEN_CONNECTION_REPLY;
else
c[0] = ID_NO_FREE_INCOMING_CONNECTIONS;
c[1] = 0; // Pad, some routers apparently block 1 byte packets
unsigned i;
for (i=0; i < rakPeer->messageHandlerList.Size(); i++)
rakPeer->messageHandlerList[i]->OnDirectSocketSend((char*)&c, 16, playerId);
SocketLayer::Instance()->SendTo( rakPeer->connectionSocket, (char*)&c, 2, playerId.binaryAddress, playerId.port );
return;
}
else if (rss!=0)
{
// If this is an existing connection, and they are already fully connected (not in progress), reply with connection attempt failed
if (rss->connectMode==RakPeer::RemoteSystemStruct::CONNECTED ||
rss->connectMode==RakPeer::RemoteSystemStruct::DISCONNECT_ASAP ||
rss->connectMode==RakPeer::RemoteSystemStruct::DISCONNECT_ASAP_SILENTLY)
{
char c[2];
c[0] = ID_CONNECTION_ATTEMPT_FAILED;
c[1] = 0; // Pad, some routers apparently block 1 byte packets
unsigned i;
for (i=0; i < rakPeer->messageHandlerList.Size(); i++)
rakPeer->messageHandlerList[i]->OnDirectSocketSend((char*)&c, 16, playerId);
SocketLayer::Instance()->SendTo( rakPeer->connectionSocket, (char*)&c, 2, playerId.binaryAddress, playerId.port );
}
}
}
// See if this datagram came from a connected system
remoteSystem = rakPeer->GetRemoteSystemFromPlayerID( playerId, true, true );
if ( remoteSystem )
{
if (remoteSystem->connectMode==RakPeer::RemoteSystemStruct::SET_ENCRYPTION_ON_MULTIPLE_16_BYTE_PACKET && (length%16)==0)
remoteSystem->reliabilityLayer.SetEncryptionKey( remoteSystem->AESKey );
// Handle regular incoming data
// HandleSocketReceiveFromConnectedPlayer is only safe to be called from the same thread as Update, which is this thread
if ( remoteSystem->reliabilityLayer.HandleSocketReceiveFromConnectedPlayer( data, length, playerId, rakPeer->messageHandlerList, rakPeer->MTUSize ) == false )
{
// These kinds of packets may have been duplicated and incorrectly determined to be
// cheat packets. Anything else really is a cheat packet
if ( !(
( (unsigned char)data[0] == ID_OPEN_CONNECTION_REQUEST && length <= 2 ) ||
( (unsigned char)data[0] == ID_OPEN_CONNECTION_REPLY && length <= 2 ) ||
( (unsigned char)data[0] == ID_CONNECTION_ATTEMPT_FAILED && length <= 2 ) ||
( ((unsigned char)data[0] == ID_PING_OPEN_CONNECTIONS || (unsigned char)data[0] == ID_PING || (unsigned char)data[0] == ID_PONG) && length >= sizeof(unsigned char)+sizeof(RakNetTime) ) ||
( (unsigned char)data[0] == ID_ADVERTISE_SYSTEM && length<MAX_OFFLINE_DATA_LENGTH )
) )
{
// Unknown message. Could be caused by old out of order stuff from unconnected or no longer connected systems, etc.
packet=AllocPacket(1);
packet->data[ 0 ] = ID_MODIFIED_PACKET;
packet->bitSize = sizeof( char ) * 8;
packet->playerId = playerId;
packet->playerIndex = ( PlayerIndex ) rakPeer->GetIndexFromPlayerID( playerId, true );
rakPeer->AddPacketToProducer(packet);
}
}
}
else
{
for (i=0; i < rakPeer->messageHandlerList.Size(); i++)
rakPeer->messageHandlerList[i]->OnDirectSocketReceive(data, length*8, playerId);
if (length > 512)
{
#if !defined(_COMPATIBILITY_1)
// Flood attack? Unknown systems should never send more than a small amount of data. Do a short ban
rakPeer->AddToBanList(rakPeer->PlayerIDToDottedIP(playerId), 10000);
#endif
return;
}
// These are all messages from unconnected systems. Messages here can be any size, but are never processed from connected systems.
if ( ( (unsigned char) data[ 0 ] == ID_PING_OPEN_CONNECTIONS
|| (unsigned char)(data)[0] == ID_PING) && length == sizeof(unsigned char)+sizeof(RakNetTime) )
{
if ( (unsigned char)(data)[0] == ID_PING ||
rakPeer->AllowIncomingConnections() ) // Open connections with players
{
#if !defined(_COMPATIBILITY_1)
RakNet::BitStream inBitStream( (unsigned char *) data, length, false );
inBitStream.IgnoreBits(8);
RakNetTime sendPingTime;
inBitStream.Read(sendPingTime);
RakNet::BitStream outBitStream;
outBitStream.Write((unsigned char)ID_PONG); // Should be named ID_UNCONNECTED_PONG eventually
outBitStream.Write(sendPingTime);
//tempBitStream.Write( data, UnconnectedPingStruct_Size );
rakPeer->rakPeerMutexes[ RakPeer::offlinePingResponse_Mutex ].Lock();
// They are connected, so append offline ping data
outBitStream.Write( (char*)rakPeer->offlinePingResponse.GetData(), rakPeer->offlinePingResponse.GetNumberOfBytesUsed() );
rakPeer->rakPeerMutexes[ RakPeer::offlinePingResponse_Mutex ].Unlock();
//SocketLayer::Instance()->SendTo( connectionSocket, ( char* ) outBitStream.GetData(), outBitStream.GetNumberOfBytesUsed(), playerId.binaryAddress, playerId.port );
unsigned i;
for (i=0; i < rakPeer->messageHandlerList.Size(); i++)
rakPeer->messageHandlerList[i]->OnDirectSocketSend((const char*)outBitStream.GetData(), outBitStream.GetNumberOfBytesUsed(), playerId);
SocketLayer::Instance()->SendTo( rakPeer->connectionSocket, (const char*)outBitStream.GetData(), outBitStream.GetNumberOfBytesUsed(), (char*)rakPeer->PlayerIDToDottedIP(playerId) , playerId.port );
#endif
}
}
// UNCONNECTED MESSAGE Pong with no data. TODO - Problem - this matches a reliable send of other random data.
else if ((unsigned char) data[ 0 ] == ID_PONG && length >= sizeof(unsigned char)+sizeof(RakNetTime) && length < sizeof(unsigned char)+sizeof(RakNetTime)+MAX_OFFLINE_DATA_LENGTH)
{
packet=AllocPacket(length);
memcpy(packet->data, data, length);
packet->bitSize = length * 8;
packet->playerId = playerId;
packet->playerIndex = ( PlayerIndex ) rakPeer->GetIndexFromPlayerID( playerId, true );
rakPeer->AddPacketToProducer(packet);
}
else if ((unsigned char) data[ 0 ] == ID_ADVERTISE_SYSTEM && length >= 2 && length < MAX_OFFLINE_DATA_LENGTH+2)
{
packet=AllocPacket(length);
memcpy(packet->data, data, length);
packet->bitSize = length * 8;
packet->playerId = playerId;
packet->playerIndex = ( PlayerIndex ) rakPeer->GetIndexFromPlayerID( playerId, true );
rakPeer->AddPacketToProducer(packet);
}
}
}
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -4452,6 +4281,7 @@ bool RakPeer::RunUpdateCycle( void )
inBitStream.IgnoreBits(8);
stringCompressor->DecodeString(output, 255, &inBitStream);
inBitStream.ReadCompressed(index);
//remoteSystem->rpcMap.AddIdentifierAtIndex((char*)output,index);
delete [] data;
}
else if ( (unsigned char) data[ 0 ] == ID_REQUEST_STATIC_DATA )

View File

@ -471,6 +471,8 @@ public:
/// \sa RakNetStatistics.h
RakNetStatisticsStruct * const GetStatistics( const PlayerID playerId );
RakNetTime GetTimestampFromPlayerID( const PlayerID playerId, RakNetTime time ) const;
// --------------------------------------------------------------------------------------------EVERYTHING AFTER THIS COMMENT IS FOR INTERNAL USE ONLY--------------------------------------------------------------------------------------------
/// \internal
RPCMap *GetRPCMap( const PlayerID playerId);

View File

@ -462,6 +462,8 @@ public:
/// \sa RakNetStatistics.h
virtual RakNetStatisticsStruct * const GetStatistics( const PlayerID playerId )=0;
virtual RakNetTime GetTimestampFromPlayerID( const PlayerID playerId, RakNetTime time ) const=0;
// --------------------------------------------------------------------------------------------EVERYTHING AFTER THIS COMMENT IS FOR INTERNAL USE ONLY--------------------------------------------------------------------------------------------
/// \internal
virtual RPCMap *GetRPCMap( const PlayerID playerId)=0;

View File

@ -111,50 +111,6 @@ Packet* RakServer::Receive( void )
{
Packet * packet = RakPeer::Receive();
// This is just a regular time based update. Nowhere else good to put it
if ( RakPeer::IsActive() && occasionalPing )
{
RakNetTime time = RakNet::GetTime();
if ( time > broadcastPingsTime || ( packet && packet->data[ 0 ] == ID_RECEIVED_STATIC_DATA ) )
{
if ( time > broadcastPingsTime )
broadcastPingsTime = time + 30000; // Broadcast pings every 30 seconds
unsigned i, count;
RemoteSystemStruct *remoteSystem;
RakNet::BitStream bitStream( ( PlayerID_Size + sizeof( short ) ) * 32 + sizeof(unsigned char) );
unsigned char typeId = ID_BROADCAST_PINGS;
bitStream.Write( typeId );
//for ( i = 0, count = 0; count < 32 && i < remoteSystemListSize; i++ )
for ( i = 0, count = 0; count < 32 && i < maximumNumberOfPeers; i++ )
{
remoteSystem = remoteSystemList + i;
if ( remoteSystem->playerId != UNASSIGNED_PLAYER_ID && remoteSystem->isActive)
{
bitStream.Write( remoteSystem->playerId.binaryAddress );
bitStream.Write( remoteSystem->playerId.port );
bitStream.Write( remoteSystem->pingAndClockDifferential[ remoteSystem->pingAndClockDifferentialWriteIndex ].pingTime );
count++;
}
}
if ( count > 0 ) // If we wrote anything
{
if ( packet && packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION ) // If this was a new connection
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false ); // Send to the new connection
else
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, UNASSIGNED_PLAYER_ID, true ); // Send to everyone
}
}
}
// This is just a regular time based update. Nowhere else good to put it
if ( RakPeer::IsActive() && synchronizedRandomInteger )
{
@ -172,17 +128,6 @@ Packet* RakServer::Receive( void )
if ( nextSeed % 2 == 0 ) // Even
nextSeed--; // make odd
/* SetRandomNumberSeedStruct s;
s.ts = ID_TIMESTAMP;
s.timeStamp = RakNet::GetTime();
s.typeId = ID_SET_RANDOM_NUMBER_SEED;
s.seed = seed;
s.nextSeed = nextSeed;
RakNet::BitStream s_BitS( SetRandomNumberSeedStruct_Size );
s.Serialize( s_BitS );
*/
RakNet::BitStream outBitStream(sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned int));
outBitStream.Write((unsigned char) ID_TIMESTAMP);
outBitStream.Write((unsigned int) RakNet::GetTime());
@ -197,84 +142,6 @@ Packet* RakServer::Receive( void )
}
}
if ( packet )
{
// Intercept specific client / server feature packets. This will do an extra send and still pass on the data to the user
if ( packet->data[ 0 ] == ID_RECEIVED_STATIC_DATA )
{
if ( relayStaticClientData )
{
// Relay static data to the other systems but the sender
RakNet::BitStream bitStream( packet->length + PlayerID_Size );
unsigned char typeId = ID_REMOTE_STATIC_DATA;
bitStream.Write( typeId );
bitStream.Write( packet->playerId.binaryAddress );
bitStream.Write( packet->playerId.port );
bitStream.Write( packet->playerIndex );
bitStream.Write( ( char* ) packet->data + sizeof(unsigned char), packet->length - sizeof(unsigned char) );
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, true );
}
}
else
if ( packet->data[ 0 ] == ID_DISCONNECTION_NOTIFICATION || packet->data[ 0 ] == ID_CONNECTION_LOST || packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION )
{
// Relay the disconnection
RakNet::BitStream bitStream( packet->length + PlayerID_Size );
unsigned char typeId;
if ( packet->data[ 0 ] == ID_DISCONNECTION_NOTIFICATION )
typeId = ID_REMOTE_DISCONNECTION_NOTIFICATION;
else
if ( packet->data[ 0 ] == ID_CONNECTION_LOST )
typeId = ID_REMOTE_CONNECTION_LOST;
else
typeId = ID_REMOTE_NEW_INCOMING_CONNECTION;
bitStream.Write( typeId );
bitStream.Write( packet->playerId.binaryAddress );
bitStream.Write( packet->playerId.port );
bitStream.Write( ( unsigned short& ) packet->playerIndex );
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, true );
if ( packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION )
{
unsigned i;
//for ( i = 0; i < remoteSystemListSize; i++ )
for ( i = 0; i < maximumNumberOfPeers; i++ )
{
if ( remoteSystemList[ i ].isActive && remoteSystemList[ i ].playerId != UNASSIGNED_PLAYER_ID && packet->playerId != remoteSystemList[ i ].playerId )
{
bitStream.Reset();
typeId = ID_REMOTE_EXISTING_CONNECTION;
bitStream.Write( typeId );
bitStream.Write( remoteSystemList[ i ].playerId.binaryAddress );
bitStream.Write( remoteSystemList[ i ].playerId.port );
bitStream.Write( ( unsigned short ) i );
// One send to tell them of the connection
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false );
if ( relayStaticClientData )
{
bitStream.Reset();
typeId = ID_REMOTE_STATIC_DATA;
bitStream.Write( typeId );
bitStream.Write( remoteSystemList[ i ].playerId.binaryAddress );
bitStream.Write( remoteSystemList[ i ].playerId.port );
bitStream.Write( (unsigned short) i );
bitStream.Write( ( char* ) remoteSystemList[ i ].staticData.GetData(), remoteSystemList[ i ].staticData.GetNumberOfBytesUsed() );
// Another send to tell them of the static data
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false );
}
}
}
}
}
}
return packet;
}
@ -397,6 +264,13 @@ bool RakServer::RPC( char* uniqueID, RakNet::BitStream *parameters, PacketPriori
return RakPeer::RPC( uniqueID, parameters, priority, reliability, orderingChannel, playerId, broadcast, shiftTimestamp, networkID, replyFromTarget );
}
// SAMPSRV (adding this just as a tag for next RakNet upgrade)
bool RakServer::RPC( char* uniqueID, RakNet::BitStream *parameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp)
{
return RakPeer::RPC( uniqueID, parameters, priority, reliability, orderingChannel, playerId, broadcast, shiftTimestamp, UNASSIGNED_NETWORK_ID, 0 );
}
// SAMPSRV end
void RakServer::SetTrackFrequencyTable( bool b )
{
RakPeer::SetCompileFrequencyTable( b );
@ -483,7 +357,7 @@ void RakServer::ChangeStaticClientData( const PlayerID playerChangedId, PlayerID
bitStream.Write( ( char* ) remoteSystem->staticData.GetData(), remoteSystem->staticData.GetNumberOfBytesUsed() );
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, playerToSendToId, true );
//Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, playerToSendToId, true );
}
unsigned int RakServer::GetNumberOfAddresses( void )
@ -524,9 +398,9 @@ PlayerID RakServer::GetPlayerIDFromIndex( int index )
return RakPeer::GetPlayerIDFromIndex( index );
}
void RakServer::AddToBanList( const char *IP )
void RakServer::AddToBanList( const char *IP, RakNetTime milliseconds )
{
RakPeer::AddToBanList( IP );
RakPeer::AddToBanList( IP, milliseconds );
}
void RakServer::RemoveFromBanList( const char *IP )

View File

@ -251,6 +251,10 @@ public:
/// \return True on a successful packet send (this does not indicate the recipient performed the call), false on failure
bool RPC( char* uniqueID, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp, NetworkID networkID, RakNet::BitStream *replyFromTarget );
// SAMPSRV (adding this just as a tag for next RakNet upgrade)
bool RPC( char* uniqueID, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp);
// SAMPSRV end
/// Enables or disables frequency table tracking. This is required to get a frequency table, which is used in GenerateCompressionLayer()
/// This value persists between connect calls and defaults to false (no frequency tracking)
/// \pre You can call this at any time - however you SHOULD only call it when disconnected. Otherwise you will only trackpart of the values sent over the network.
@ -377,7 +381,7 @@ public:
/// Bans an IP from connecting. Banned IPs persist between connections.
/// param[in] IP Dotted IP address. Can use * as a wildcard, such as 128.0.0.* will banAll IP addresses starting with 128.0.0
void AddToBanList( const char *IP );
void AddToBanList( const char *IP, RakNetTime milliseconds=0 );
/// Allows a previously banned IP to connect.
/// param[in] Dotted IP address. Can use * as a wildcard, such as 128.0.0.* will banAll IP addresses starting with 128.0.0

View File

@ -247,6 +247,10 @@ public:
/// \return True on a successful packet send (this does not indicate the recipient performed the call), false on failure
virtual bool RPC( char* uniqueID, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp, NetworkID networkID, RakNet::BitStream *replyFromTarget )=0;
// SAMPSRV (adding this just as a tag for next RakNet upgrade)
virtual bool RPC( char* uniqueID, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp)=0;
// SAMPSRV end
/// Enables or disables frequency table tracking. This is required to get a frequency table, which is used in GenerateCompressionLayer()
/// This value persists between connect calls and defaults to false (no frequency tracking)
/// \pre You can call this at any time - however you SHOULD only call it when disconnected. Otherwise you will only trackpart of the values sent over the network.
@ -373,7 +377,7 @@ public:
/// Bans an IP from connecting. Banned IPs persist between connections.
/// param[in] IP Dotted IP address. Can use * as a wildcard, such as 128.0.0.* will banAll IP addresses starting with 128.0.0
virtual void AddToBanList( const char *IP )=0;
virtual void AddToBanList( const char *IP, RakNetTime milliseconds=0 )=0;
/// Allows a previously banned IP to connect.
/// param[in] Dotted IP address. Can use * as a wildcard, such as 128.0.0.* will banAll IP addresses starting with 128.0.0

View File

@ -32,10 +32,18 @@
#include <stdlib.h>
#endif
#ifdef SAMPSRV
int GetPlayerTimeout();
#endif
static const int DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE=512;
static const float PACKETLOSS_TOLERANCE=.02f; // What percentile packetloss we are willing to accept as background noise.
static const double MINIMUM_SEND_BPS=14400.0; // Won't go below this send rate
#ifdef SAMPCLI
static const double STARTING_SEND_BPS=512000.0; // What send rate to start at.
#else
static const double STARTING_SEND_BPS=28800.0; // What send rate to start at.
#endif
static const float PING_MULTIPLIER_TO_RESEND=3.0; // So internet ping variation doesn't cause needless resends
static const RakNetTime MIN_PING_TO_RESEND=30; // So system timer changes and CPU lag don't send needless resends
static const RakNetTimeNS TIME_TO_NEW_SAMPLE=500000; // How many ns to wait before starting a new sample. This way buffers have time to overflow or relax at the new send rate, if they are indeed going to overflow.
@ -84,9 +92,13 @@ ReliabilityLayer::ReliabilityLayer() : updateBitStream( DEFAULT_MTU_SIZE ) //
#ifdef _DEBUG
// Wait longer to disconnect in debug so I don't get disconnected while tracing
timeoutTime=30000;
#else
#ifdef SAMPSRV
timeoutTime=GetPlayerTimeout();
#else
timeoutTime=10000;
#endif
#endif
#ifndef _RELEASE
maxSendBPS=minExtraPing=extraPingVariance=0;
@ -183,6 +195,13 @@ void ReliabilityLayer::InitializeVariables( void )
memset( waitingForSequencedPacketWriteIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
memset( &statistics, 0, sizeof( statistics ) );
statistics.connectionStartTime = RakNet::GetTime();
statistics.field_110 = RakNet::GetTime();
statistics.field_114 = 0;
statistics.field_118 = 0;
statistics.field_11C = RakNet::GetTime();
statistics.field_120 = 0;
statistics.field_124 = 0;
reliabilitySizeInBits = 4;
splitPacketId = 0;
messageNumber = 0;
availableBandwidth=0;
@ -1610,7 +1629,8 @@ int ReliabilityLayer::GetBitStreamHeaderLength( const InternalPacket *const inte
// Write the PacketReliability. This is encoded in 3 bits
//bitStream->WriteBits((unsigned char*)&(internalPacket->reliability), 3, true);
bitLength += 3;
//bitLength += 3;
bitLength += reliabilitySizeInBits;
// If the reliability requires an ordering channel and ordering index, we Write those.
if ( internalPacket->reliability == UNRELIABLE_SEQUENCED || internalPacket->reliability == RELIABLE_SEQUENCED || internalPacket->reliability == RELIABLE_ORDERED )
@ -1684,7 +1704,7 @@ int ReliabilityLayer::WriteToBitStreamFromInternalPacket( RakNet::BitStream *bit
#endif
// Write the PacketReliability. This is encoded in 3 bits
bitStream->WriteBits( (const unsigned char *)&c, 3, true );
bitStream->WriteBits( (const unsigned char *)&c, reliabilitySizeInBits, true );
// If the reliability requires an ordering channel and ordering index, we Write those.
if ( internalPacket->reliability == UNRELIABLE_SEQUENCED || internalPacket->reliability == RELIABLE_SEQUENCED || internalPacket->reliability == RELIABLE_ORDERED )
@ -1776,7 +1796,7 @@ InternalPacket* ReliabilityLayer::CreateInternalPacketFromBitStream( RakNet::Bit
// Read the PacketReliability. This is encoded in 3 bits
unsigned char reliability;
bitStreamSucceeded = bitStream->ReadBits( ( unsigned char* ) ( &( reliability ) ), 3 );
bitStreamSucceeded = bitStream->ReadBits( ( unsigned char* ) ( &( reliability ) ), reliabilitySizeInBits );
internalPacket->reliability = ( const PacketReliability ) reliability;
@ -1785,7 +1805,7 @@ InternalPacket* ReliabilityLayer::CreateInternalPacketFromBitStream( RakNet::Bit
// assert( bitStreamSucceeded );
#endif
if ( bitStreamSucceeded == false )
if ( internalPacket->reliability < UNRELIABLE || bitStreamSucceeded == false )
{
internalPacketPool.ReleasePointer( internalPacket );
return 0;
@ -2464,7 +2484,7 @@ void ReliabilityLayer::UpdateNextActionTime(void)
//-------------------------------------------------------------------------------------------------------
// Statistics
//-------------------------------------------------------------------------------------------------------
RakNetStatisticsStruct * const ReliabilityLayer::GetStatistics( void )
RakNetStatisticsStruct * const ReliabilityLayer::GetStatistics( bool includeResendListDataSize )
{
unsigned i;
@ -2482,7 +2502,11 @@ RakNetStatisticsStruct * const ReliabilityLayer::GetStatistics( void )
statistics.bitsPerSecond = currentBandwidth;
//statistics.lossySize = lossyWindowSize == MAXIMUM_WINDOW_SIZE + 1 ? 0 : lossyWindowSize;
// statistics.lossySize=0;
statistics.messagesOnResendQueue = GetResendListDataSize();
if (!includeResendListDataSize)
statistics.messagesOnResendQueue = GetResendListDataSize();
else
statistics.messagesOnResendQueue = 0;
return &statistics;
}

View File

@ -151,7 +151,7 @@ public:
/// Get Statistics
/// \return A pointer to a static struct, filled out with current statistical information.
RakNetStatisticsStruct * const GetStatistics( void );
RakNetStatisticsStruct * const GetStatistics( bool includeResendListDataSize = true );
///Are we waiting for any data to be sent out or be processed by the player?
bool IsDataWaiting(void);
@ -315,6 +315,8 @@ private:
unsigned int blockWindowIncreaseUntilTime;
RakNetStatisticsStruct statistics;
unsigned int reliabilitySizeInBits;
/// Memory-efficient receivedPackets algorithm:
/// receivedPacketsBaseIndex is the packet number we are expecting
/// Everything under receivedPacketsBaseIndex is a packet we already got

View File

@ -0,0 +1,130 @@
#include <string.h>
#include "SocketDataEncryptor.h"
unsigned short SocketDataEncryptor::session_key = 0;
static const unsigned char S[256] = {
#ifndef SAMPSRV
0x27,0x69,0xFD,0x87,0x60,0x7D,0x83,0x02,0xF2,0x3F,0x71,0x99,0xA3,0x7C,0x1B,0x9D,
0x76,0x30,0x23,0x25,0xC5,0x82,0x9B,0xEB,0x1E,0xFA,0x46,0x4F,0x98,0xC9,0x37,0x88,
0x18,0xA2,0x68,0xD6,0xD7,0x22,0xD1,0x74,0x7A,0x79,0x2E,0xD2,0x6D,0x48,0x0F,0xB1,
0x62,0x97,0xBC,0x8B,0x59,0x7F,0x29,0xB6,0xB9,0x61,0xBE,0xC8,0xC1,0xC6,0x40,0xEF,
0x11,0x6A,0xA5,0xC7,0x3A,0xF4,0x4C,0x13,0x6C,0x2B,0x1C,0x54,0x56,0x55,0x53,0xA8,
0xDC,0x9C,0x9A,0x16,0xDD,0xB0,0xF5,0x2D,0xFF,0xDE,0x8A,0x90,0xFC,0x95,0xEC,0x31,
0x85,0xC2,0x01,0x06,0xDB,0x28,0xD8,0xEA,0xA0,0xDA,0x10,0x0E,0xF0,0x2A,0x6B,0x21,
0xF1,0x86,0xFB,0x65,0xE1,0x6F,0xF6,0x26,0x33,0x39,0xAE,0xBF,0xD4,0xE4,0xE9,0x44,
0x75,0x3D,0x63,0xBD,0xC0,0x7B,0x9E,0xA6,0x5C,0x1F,0xB2,0xA4,0xC4,0x8D,0xB3,0xFE,
0x8F,0x19,0x8C,0x4D,0x5E,0x34,0xCC,0xF9,0xB5,0xF3,0xF8,0xA1,0x50,0x04,0x93,0x73,
0xE0,0xBA,0xCB,0x45,0x35,0x1A,0x49,0x47,0x6E,0x2F,0x51,0x12,0xE2,0x4A,0x72,0x05,
0x66,0x70,0xB8,0xCD,0x00,0xE5,0xBB,0x24,0x58,0xEE,0xB4,0x80,0x81,0x36,0xA9,0x67,
0x5A,0x4B,0xE8,0xCA,0xCF,0x9F,0xE3,0xAC,0xAA,0x14,0x5B,0x5F,0x0A,0x3B,0x77,0x92,
0x09,0x15,0x4E,0x94,0xAD,0x17,0x64,0x52,0xD3,0x38,0x43,0x0D,0x0C,0x07,0x3C,0x1D,
0xAF,0xED,0xE7,0x08,0xB7,0x03,0xE6,0x8E,0xAB,0x91,0x89,0x3E,0x2C,0x96,0x42,0xD9,
0x78,0xDF,0xD0,0x57,0x5D,0x84,0x41,0x7E,0xCE,0xF7,0x32,0xC3,0xD5,0x20,0x0B,0xA7,
#else
0xB4,0x62,0x07,0xE5,0x9D,0xAF,0x63,0xDD,0xE3,0xD0,0xCC,0xFE,0xDC,0xDB,0x6B,0x2E,
0x6A,0x40,0xAB,0x47,0xC9,0xD1,0x53,0xD5,0x20,0x91,0xA5,0x0E,0x4A,0xDF,0x18,0x89,
0xFD,0x6F,0x25,0x12,0xB7,0x13,0x77,0x00,0x65,0x36,0x6D,0x49,0xEC,0x57,0x2A,0xA9,
0x11,0x5F,0xFA,0x78,0x95,0xA4,0xBD,0x1E,0xD9,0x79,0x44,0xCD,0xDE,0x81,0xEB,0x09,
0x3E,0xF6,0xEE,0xDA,0x7F,0xA3,0x1A,0xA7,0x2D,0xA6,0xAD,0xC1,0x46,0x93,0xD2,0x1B,
0x9C,0xAA,0xD7,0x4E,0x4B,0x4D,0x4C,0xF3,0xB8,0x34,0xC0,0xCA,0x88,0xF4,0x94,0xCB,
0x04,0x39,0x30,0x82,0xD6,0x73,0xB0,0xBF,0x22,0x01,0x41,0x6E,0x48,0x2C,0xA8,0x75,
0xB1,0x0A,0xAE,0x9F,0x27,0x80,0x10,0xCE,0xF0,0x29,0x28,0x85,0x0D,0x05,0xF7,0x35,
0xBB,0xBC,0x15,0x06,0xF5,0x60,0x71,0x03,0x1F,0xEA,0x5A,0x33,0x92,0x8D,0xE7,0x90,
0x5B,0xE9,0xCF,0x9E,0xD3,0x5D,0xED,0x31,0x1C,0x0B,0x52,0x16,0x51,0x0F,0x86,0xC5,
0x68,0x9B,0x21,0x0C,0x8B,0x42,0x87,0xFF,0x4F,0xBE,0xC8,0xE8,0xC7,0xD4,0x7A,0xE0,
0x55,0x2F,0x8A,0x8E,0xBA,0x98,0x37,0xE4,0xB2,0x38,0xA1,0xB6,0x32,0x83,0x3A,0x7B,
0x84,0x3C,0x61,0xFB,0x8C,0x14,0x3D,0x43,0x3B,0x1D,0xC3,0xA2,0x96,0xB3,0xF8,0xC4,
0xF2,0x26,0x2B,0xD8,0x7C,0xFC,0x23,0x24,0x66,0xEF,0x69,0x64,0x50,0x54,0x59,0xF1,
0xA0,0x74,0xAC,0xC6,0x7D,0xB5,0xE6,0xE2,0xC2,0x7E,0x67,0x17,0x5E,0xE1,0xB9,0x3F,
0x6C,0x70,0x08,0x99,0x45,0x56,0x76,0xF9,0x9A,0x97,0x19,0x72,0x5C,0x02,0x8F,0x58,
#endif
};
//----------------------------------------------------
unsigned char SocketDataEncryptor::GetChecksum(unsigned char *data, int length)
{
unsigned char sum = 0;
for(int i = 0; i != length; i++)
{
sum ^= data[i] & 0xAA;
}
return sum;
}
//----------------------------------------------------
void SocketDataEncryptor::Process(unsigned char key1,
unsigned char key2,
unsigned char *data,
int length)
{
int counter = 0;
for(int i = 0; i != length; i++)
{
#ifndef SAMPSRV
data[i] = S[data[i]];
#endif
if(counter == 0)
{
data[i] ^= key1;
counter = 1;
}
else
{
data[i] ^= key2;
counter--;
}
#ifdef SAMPSRV
data[i] = S[data[i]];
#endif
}
}
//----------------------------------------------------
#ifndef SAMPSRV
void SocketDataEncryptor::Encrypt(unsigned char *destination,
unsigned char *source,
int *length)
{
unsigned char key = session_key;
*destination = GetChecksum(source, *length);
memcpy(destination + 1, source, *length);
Process(0, key, destination + 1, *length);
++*length;
}
#else
int SocketDataEncryptor::Decrypt(unsigned char *destination,
unsigned char *source,
int *length)
{
unsigned char key = session_key;
unsigned char sum = source[0];
*length--;
memcpy(destination, source + 1, *length);
Process(0, key, destination, *length);
return GetChecksum(destination, *length) == sum;
}
#endif
//----------------------------------------------------
void SocketDataEncryptor::SetKey(int key)
{
session_key = key ^ 0xCCCC;
}
//----------------------------------------------------
// EOF

View File

@ -0,0 +1,21 @@
#ifndef __SOCKET_DATA_ENCRYPTOR_H
#define __SOCKET_DATA_ENCRYPTOR_H
class SocketDataEncryptor
{
private:
static unsigned char GetChecksum(unsigned char *data, int length);
static void Process(unsigned char key1, unsigned char key2, unsigned char *data, int length);
static unsigned short session_key;
public:
static void Encrypt(unsigned char *destination, unsigned char *source, int *length);
static int Decrypt(unsigned char *destination, unsigned char *source, int *length);
static void SetKey(int key);
};
#endif

View File

@ -25,6 +25,8 @@
#include <assert.h>
#include "MTUSize.h"
#include "SocketDataEncryptor.h"
#ifdef _WIN32
#include <process.h>
#define COMPATIBILITY_2_RECV_FROM_FLAGS 0
@ -48,6 +50,9 @@ typedef int socklen_t;
#pragma warning( push )
#endif
unsigned char pDataBuffer[16384];
unsigned char pDataBuffer2[16384]; // unused
bool SocketLayer::socketLayerStarted = false;
#ifdef _WIN32
WSADATA SocketLayer::winsockInfo;
@ -370,6 +375,10 @@ bool SocketLayer::AssociateSocketWithCompletionPortAndRead( SOCKET readSocket, u
return true;
}
#ifdef SAMPSRV
int ProcessQueryPacket(unsigned int binaryAddress, unsigned short port, char *data, int length, SOCKET s);
#endif
int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode )
{
int len;
@ -396,6 +405,7 @@ int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode )
// if (len>0)
// printf("Got packet on port %i\n",ntohs(sa.sin_port));
/*
if ( len == 0 )
{
#ifdef _DEBUG
@ -405,7 +415,7 @@ int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode )
*errorCode = SOCKET_ERROR;
return SOCKET_ERROR;
}
}*/
if ( len != SOCKET_ERROR )
{
@ -414,8 +424,30 @@ int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode )
//strcpy(ip, inet_ntoa(sa.sin_addr));
//if (strcmp(ip, "0.0.0.0")==0)
// strcpy(ip, "127.0.0.1");
ProcessNetworkPacket( sa.sin_addr.s_addr, portnum, data, len, rakPeer );
if (len > 0)
{
#ifdef SAMPSRV
// QUERY PACKETS ARE NOT COMPRESSED
//logprintf("Raw ID: %c:%u",data[0],data[0]);
if(ProcessQueryPacket(sa.sin_addr.s_addr, portnum,(char*)data, len, s)) {
return 1;
}
if(!SocketDataEncryptor::Decrypt(pDataBuffer,(unsigned char *)data, &len) )
{
*errorCode = 0;
return 1;
}
ProcessNetworkPacket( sa.sin_addr.s_addr, portnum, (char*)pDataBuffer, len, rakPeer );
#else
ProcessNetworkPacket( sa.sin_addr.s_addr, portnum, data, len, rakPeer );
#endif
}
return 1;
}
else
@ -481,10 +513,19 @@ int SocketLayer::SendTo( SOCKET s, const char *data, int length, unsigned int bi
sa.sin_addr.s_addr = binaryAddress;
sa.sin_family = AF_INET;
#ifndef SAMPSRV
SocketDataEncryptor::Encrypt(pDataBuffer, (unsigned char *)data, &length);
#endif
do
{
// TODO - use WSASendTo which is faster.
#ifndef SAMPSRV
len = sendto( s, (char *)pDataBuffer, length, 0, ( const sockaddr* ) & sa, sizeof( struct sockaddr_in ) );
#else
len = sendto( s, data, length, 0, ( const sockaddr* ) & sa, sizeof( struct sockaddr_in ) );
#endif
}
while ( len == 0 );

View File

@ -1,42 +1,117 @@
#include "audiostream.h"
#include "main.h"
void CAudioStream::Reset()
extern CGame *pGame;
VECTOR g_vecStreamingPos;
//----------------------------------------------------
BOOL CAudioStream::Initialize()
{
// TODO: CAudioStream::sub_10066480 10066480
// TODO: CAudioStream::Initialize()
return FALSE;
}
void CAudioStream::Stop()
//----------------------------------------------------
BOOL CAudioStream::Stop(bool bWaitForThread)
{
// TODO: CAudioStream::sub_10066560 10066560
// TODO: CAudioStream::Stop()
return FALSE;
}
void CAudioStream::ConstructInfo()
//----------------------------------------------------
void CAudioStream::DoMeta()
{
// TODO: CAudioStream::sub_100665C0 100665C0
// TODO: CAudioStream::DoMeta
}
void CAudioStream::SyncProc()
//----------------------------------------------------
void CALLBACK CAudioStream::MetaSync(HSYNC handle, DWORD channel, DWORD data, void *user)
{
// TODO: CAudioStream::sub_100666F0 100666F0
DoMeta();
}
void CAudioStream::Process()
//----------------------------------------------------
void CAudioStream::ProcessThread(PVOID v)
{
// TODO: CAudioStream::sub_10066700 10066700
// TODO: CAudioStream::ProcessThread
}
void CAudioStream::Play()
//----------------------------------------------------
BOOL CAudioStream::Play(char *szURL, float fX, float fY, float fZ, float fDistance, bool bUsePos)
{
// TODO: CAudioStream::sub_10066960 10066960
// TODO: CAudioStream::Play
return FALSE;
}
void CAudioStream::ControlGameRadio()
//----------------------------------------------------
void CAudioStream::HandleGameAudio()
{
// TODO: CAudioStream::sub_10066A80 10066A80
// TODO: CAudioStream::HandleGameAudio()
}
void CAudioStream::DrawInfo()
//----------------------------------------------------
void CAudioStream::Draw()
{
// TODO: CAudioStream::sub_10066AB0 10066AB0
}
// TODO: CAudioStream::Draw()
}
//----------------------------------------------------
void FUNC_10066B90(PVECTOR in, PVECTOR out)
{
out->X = -in->X;
out->Y = in->Z;
out->Z = in->Y;
}
void FUNC_10066BB0(PVECTOR in, PVECTOR out)
{
out->X = in->X;
out->Y = -in->Z;
out->Z = -in->Y;
}
void CAudioStream::Test3D()
{
CPlayerPed* pPlayerPed = pGame->FindPlayerPed();
if(!pPlayerPed) return;
CAMERA_AIM *Aim = pPlayerPed->GetCurrentAim();
VECTOR vecResult;
VECTOR vecFront;
VECTOR vecPos;
BASS_3DVECTOR front;
BASS_3DVECTOR vel;
vecFront.X = Aim->f1x;
vecFront.Y = Aim->f1y;;
vecFront.Z = Aim->f1z;
vecPos.X = Aim->pos1x;
vecPos.Y = Aim->pos1y;
vecPos.Z = Aim->pos1z;
FUNC_10066BB0(&vecFront, &vecResult);
front.x = vecResult.X;
front.y = vecResult.Y;
front.z = vecResult.Z;
FUNC_10066B90(&vecPos, &vecResult);
vecFront.X = vecResult.X;
vecFront.Y = vecResult.Y;
vecFront.Z = vecResult.Z;
FUNC_10066B90(&g_vecStreamingPos, &vecResult);
}
//----------------------------------------------------

View File

@ -1,23 +1,34 @@
#pragma once
class CAudioStream // size=1
#include "bass.h"
//----------------------------------------------------
class CAudioStream
{
private:
char field_0;
bool field_0;
public:
CAudioStream() {
field_0 = 0;
}
void Reset();
void Stop();
void ConstructInfo();
void SyncProc();
void Process();
void Play();
void ControlGameRadio();
void DrawInfo();
BOOL Initialize();
BOOL Stop(bool bWaitForThread=true);
BOOL Play(char *szURL, float fX, float fY, float fZ, float fDistance, bool bUsePos);
void HandleGameAudio();
void Draw();
void Test3D();
static void DoMeta();
static void CALLBACK MetaSync(HSYNC handle, DWORD channel, DWORD data, void *user);
static void ProcessThread(PVOID v);
// Delete this:
void Process() {}
};
//----------------------------------------------------

963
saco/bass.h Normal file
View File

@ -0,0 +1,963 @@
/*
BASS 2.4 C/C++ header file
Copyright (c) 1999-2013 Un4seen Developments Ltd.
See the BASS.CHM file for more detailed documentation
*/
#ifndef BASS_H
#define BASS_H
#ifdef _WIN32
#include <wtypes.h>
typedef unsigned __int64 QWORD;
#else
#include <stdint.h>
#define WINAPI
#define CALLBACK
typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef uint64_t QWORD;
#ifndef __OBJC__
typedef int BOOL;
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define LOBYTE(a) (BYTE)(a)
#define HIBYTE(a) (BYTE)((a)>>8)
#define LOWORD(a) (WORD)(a)
#define HIWORD(a) (WORD)((a)>>16)
#define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8))
#define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16))
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define BASSVERSION 0x204 // API version
#define BASSVERSIONTEXT "2.4"
#ifndef BASSDEF
#define BASSDEF(f) WINAPI f
#endif
typedef DWORD HMUSIC; // MOD music handle
typedef DWORD HSAMPLE; // sample handle
typedef DWORD HCHANNEL; // playing sample's channel handle
typedef DWORD HSTREAM; // sample stream handle
typedef DWORD HRECORD; // recording handle
typedef DWORD HSYNC; // synchronizer handle
typedef DWORD HDSP; // DSP handle
typedef DWORD HFX; // DX8 effect handle
typedef DWORD HPLUGIN; // Plugin handle
// Error codes returned by BASS_ErrorGetCode
#define BASS_OK 0 // all is OK
#define BASS_ERROR_MEM 1 // memory error
#define BASS_ERROR_FILEOPEN 2 // can't open the file
#define BASS_ERROR_DRIVER 3 // can't find a free/valid driver
#define BASS_ERROR_BUFLOST 4 // the sample buffer was lost
#define BASS_ERROR_HANDLE 5 // invalid handle
#define BASS_ERROR_FORMAT 6 // unsupported sample format
#define BASS_ERROR_POSITION 7 // invalid position
#define BASS_ERROR_INIT 8 // BASS_Init has not been successfully called
#define BASS_ERROR_START 9 // BASS_Start has not been successfully called
#define BASS_ERROR_ALREADY 14 // already initialized/paused/whatever
#define BASS_ERROR_NOCHAN 18 // can't get a free channel
#define BASS_ERROR_ILLTYPE 19 // an illegal type was specified
#define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified
#define BASS_ERROR_NO3D 21 // no 3D support
#define BASS_ERROR_NOEAX 22 // no EAX support
#define BASS_ERROR_DEVICE 23 // illegal device number
#define BASS_ERROR_NOPLAY 24 // not playing
#define BASS_ERROR_FREQ 25 // illegal sample rate
#define BASS_ERROR_NOTFILE 27 // the stream is not a file stream
#define BASS_ERROR_NOHW 29 // no hardware voices available
#define BASS_ERROR_EMPTY 31 // the MOD music has no sequence data
#define BASS_ERROR_NONET 32 // no internet connection could be opened
#define BASS_ERROR_CREATE 33 // couldn't create the file
#define BASS_ERROR_NOFX 34 // effects are not available
#define BASS_ERROR_NOTAVAIL 37 // requested data is not available
#define BASS_ERROR_DECODE 38 // the channel is a "decoding channel"
#define BASS_ERROR_DX 39 // a sufficient DirectX version is not installed
#define BASS_ERROR_TIMEOUT 40 // connection timedout
#define BASS_ERROR_FILEFORM 41 // unsupported file format
#define BASS_ERROR_SPEAKER 42 // unavailable speaker
#define BASS_ERROR_VERSION 43 // invalid BASS version (used by add-ons)
#define BASS_ERROR_CODEC 44 // codec is not available/supported
#define BASS_ERROR_ENDED 45 // the channel/file has ended
#define BASS_ERROR_BUSY 46 // the device is busy
#define BASS_ERROR_UNKNOWN -1 // some other mystery problem
// BASS_SetConfig options
#define BASS_CONFIG_BUFFER 0
#define BASS_CONFIG_UPDATEPERIOD 1
#define BASS_CONFIG_GVOL_SAMPLE 4
#define BASS_CONFIG_GVOL_STREAM 5
#define BASS_CONFIG_GVOL_MUSIC 6
#define BASS_CONFIG_CURVE_VOL 7
#define BASS_CONFIG_CURVE_PAN 8
#define BASS_CONFIG_FLOATDSP 9
#define BASS_CONFIG_3DALGORITHM 10
#define BASS_CONFIG_NET_TIMEOUT 11
#define BASS_CONFIG_NET_BUFFER 12
#define BASS_CONFIG_PAUSE_NOPLAY 13
#define BASS_CONFIG_NET_PREBUF 15
#define BASS_CONFIG_NET_PASSIVE 18
#define BASS_CONFIG_REC_BUFFER 19
#define BASS_CONFIG_NET_PLAYLIST 21
#define BASS_CONFIG_MUSIC_VIRTUAL 22
#define BASS_CONFIG_VERIFY 23
#define BASS_CONFIG_UPDATETHREADS 24
#define BASS_CONFIG_DEV_BUFFER 27
#define BASS_CONFIG_VISTA_TRUEPOS 30
#define BASS_CONFIG_IOS_MIXAUDIO 34
#define BASS_CONFIG_DEV_DEFAULT 36
#define BASS_CONFIG_NET_READTIMEOUT 37
#define BASS_CONFIG_VISTA_SPEAKERS 38
#define BASS_CONFIG_IOS_SPEAKER 39
#define BASS_CONFIG_HANDLES 41
#define BASS_CONFIG_UNICODE 42
#define BASS_CONFIG_SRC 43
#define BASS_CONFIG_SRC_SAMPLE 44
#define BASS_CONFIG_ASYNCFILE_BUFFER 45
#define BASS_CONFIG_OGG_PRESCAN 47
// BASS_SetConfigPtr options
#define BASS_CONFIG_NET_AGENT 16
#define BASS_CONFIG_NET_PROXY 17
#define BASS_CONFIG_IOS_NOTIFY 46
// BASS_Init flags
#define BASS_DEVICE_8BITS 1 // 8 bit resolution, else 16 bit
#define BASS_DEVICE_MONO 2 // mono, else stereo
#define BASS_DEVICE_3D 4 // enable 3D functionality
#define BASS_DEVICE_LATENCY 0x100 // calculate device latency (BASS_INFO struct)
#define BASS_DEVICE_CPSPEAKERS 0x400 // detect speakers via Windows control panel
#define BASS_DEVICE_SPEAKERS 0x800 // force enabling of speaker assignment
#define BASS_DEVICE_NOSPEAKER 0x1000 // ignore speaker arrangement
#define BASS_DEVICE_DMIX 0x2000 // use ALSA "dmix" plugin
#define BASS_DEVICE_FREQ 0x4000 // set device sample rate
// DirectSound interfaces (for use with BASS_GetDSoundObject)
#define BASS_OBJECT_DS 1 // IDirectSound
#define BASS_OBJECT_DS3DL 2 // IDirectSound3DListener
// Device info structure
typedef struct {
#ifdef _WIN32_WCE
const wchar_t *name; // description
const wchar_t *driver; // driver
#else
const char *name; // description
const char *driver; // driver
#endif
DWORD flags;
} BASS_DEVICEINFO;
// BASS_DEVICEINFO flags
#define BASS_DEVICE_ENABLED 1
#define BASS_DEVICE_DEFAULT 2
#define BASS_DEVICE_INIT 4
typedef struct {
DWORD flags; // device capabilities (DSCAPS_xxx flags)
DWORD hwsize; // size of total device hardware memory
DWORD hwfree; // size of free device hardware memory
DWORD freesam; // number of free sample slots in the hardware
DWORD free3d; // number of free 3D sample slots in the hardware
DWORD minrate; // min sample rate supported by the hardware
DWORD maxrate; // max sample rate supported by the hardware
BOOL eax; // device supports EAX? (always FALSE if BASS_DEVICE_3D was not used)
DWORD minbuf; // recommended minimum buffer length in ms (requires BASS_DEVICE_LATENCY)
DWORD dsver; // DirectSound version
DWORD latency; // delay (in ms) before start of playback (requires BASS_DEVICE_LATENCY)
DWORD initflags; // BASS_Init "flags" parameter
DWORD speakers; // number of speakers available
DWORD freq; // current output rate
} BASS_INFO;
// BASS_INFO flags (from DSOUND.H)
#define DSCAPS_CONTINUOUSRATE 0x00000010 // supports all sample rates between min/maxrate
#define DSCAPS_EMULDRIVER 0x00000020 // device does NOT have hardware DirectSound support
#define DSCAPS_CERTIFIED 0x00000040 // device driver has been certified by Microsoft
#define DSCAPS_SECONDARYMONO 0x00000100 // mono
#define DSCAPS_SECONDARYSTEREO 0x00000200 // stereo
#define DSCAPS_SECONDARY8BIT 0x00000400 // 8 bit
#define DSCAPS_SECONDARY16BIT 0x00000800 // 16 bit
// Recording device info structure
typedef struct {
DWORD flags; // device capabilities (DSCCAPS_xxx flags)
DWORD formats; // supported standard formats (WAVE_FORMAT_xxx flags)
DWORD inputs; // number of inputs
BOOL singlein; // TRUE = only 1 input can be set at a time
DWORD freq; // current input rate
} BASS_RECORDINFO;
// BASS_RECORDINFO flags (from DSOUND.H)
#define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER // device does NOT have hardware DirectSound recording support
#define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED // device driver has been certified by Microsoft
// defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H)
#ifndef WAVE_FORMAT_1M08
#define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */
#define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */
#define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */
#define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */
#define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */
#define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */
#define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */
#define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */
#define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */
#define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */
#define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */
#define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */
#endif
// Sample info structure
typedef struct {
DWORD freq; // default playback rate
float volume; // default volume (0-1)
float pan; // default pan (-1=left, 0=middle, 1=right)
DWORD flags; // BASS_SAMPLE_xxx flags
DWORD length; // length (in bytes)
DWORD max; // maximum simultaneous playbacks
DWORD origres; // original resolution bits
DWORD chans; // number of channels
DWORD mingap; // minimum gap (ms) between creating channels
DWORD mode3d; // BASS_3DMODE_xxx mode
float mindist; // minimum distance
float maxdist; // maximum distance
DWORD iangle; // angle of inside projection cone
DWORD oangle; // angle of outside projection cone
float outvol; // delta-volume outside the projection cone
DWORD vam; // voice allocation/management flags (BASS_VAM_xxx)
DWORD priority; // priority (0=lowest, 0xffffffff=highest)
} BASS_SAMPLE;
#define BASS_SAMPLE_8BITS 1 // 8 bit
#define BASS_SAMPLE_FLOAT 256 // 32-bit floating-point
#define BASS_SAMPLE_MONO 2 // mono
#define BASS_SAMPLE_LOOP 4 // looped
#define BASS_SAMPLE_3D 8 // 3D functionality
#define BASS_SAMPLE_SOFTWARE 16 // not using hardware mixing
#define BASS_SAMPLE_MUTEMAX 32 // mute at max distance (3D only)
#define BASS_SAMPLE_VAM 64 // DX7 voice allocation & management
#define BASS_SAMPLE_FX 128 // old implementation of DX8 effects
#define BASS_SAMPLE_OVER_VOL 0x10000 // override lowest volume
#define BASS_SAMPLE_OVER_POS 0x20000 // override longest playing
#define BASS_SAMPLE_OVER_DIST 0x30000 // override furthest from listener (3D only)
#define BASS_STREAM_PRESCAN 0x20000 // enable pin-point seeking/length (MP3/MP2/MP1)
#define BASS_MP3_SETPOS BASS_STREAM_PRESCAN
#define BASS_STREAM_AUTOFREE 0x40000 // automatically free the stream when it stop/ends
#define BASS_STREAM_RESTRATE 0x80000 // restrict the download rate of internet file streams
#define BASS_STREAM_BLOCK 0x100000 // download/play internet file stream in small blocks
#define BASS_STREAM_DECODE 0x200000 // don't play the stream, only decode (BASS_ChannelGetData)
#define BASS_STREAM_STATUS 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC
#define BASS_MUSIC_FLOAT BASS_SAMPLE_FLOAT
#define BASS_MUSIC_MONO BASS_SAMPLE_MONO
#define BASS_MUSIC_LOOP BASS_SAMPLE_LOOP
#define BASS_MUSIC_3D BASS_SAMPLE_3D
#define BASS_MUSIC_FX BASS_SAMPLE_FX
#define BASS_MUSIC_AUTOFREE BASS_STREAM_AUTOFREE
#define BASS_MUSIC_DECODE BASS_STREAM_DECODE
#define BASS_MUSIC_PRESCAN BASS_STREAM_PRESCAN // calculate playback length
#define BASS_MUSIC_CALCLEN BASS_MUSIC_PRESCAN
#define BASS_MUSIC_RAMP 0x200 // normal ramping
#define BASS_MUSIC_RAMPS 0x400 // sensitive ramping
#define BASS_MUSIC_SURROUND 0x800 // surround sound
#define BASS_MUSIC_SURROUND2 0x1000 // surround sound (mode 2)
#define BASS_MUSIC_FT2MOD 0x2000 // play .MOD as FastTracker 2 does
#define BASS_MUSIC_PT1MOD 0x4000 // play .MOD as ProTracker 1 does
#define BASS_MUSIC_NONINTER 0x10000 // non-interpolated sample mixing
#define BASS_MUSIC_SINCINTER 0x800000 // sinc interpolated sample mixing
#define BASS_MUSIC_POSRESET 0x8000 // stop all notes when moving position
#define BASS_MUSIC_POSRESETEX 0x400000 // stop all notes and reset bmp/etc when moving position
#define BASS_MUSIC_STOPBACK 0x80000 // stop the music on a backwards jump effect
#define BASS_MUSIC_NOSAMPLE 0x100000 // don't load the samples
// Speaker assignment flags
#define BASS_SPEAKER_FRONT 0x1000000 // front speakers
#define BASS_SPEAKER_REAR 0x2000000 // rear/side speakers
#define BASS_SPEAKER_CENLFE 0x3000000 // center & LFE speakers (5.1)
#define BASS_SPEAKER_REAR2 0x4000000 // rear center speakers (7.1)
#define BASS_SPEAKER_N(n) ((n)<<24) // n'th pair of speakers (max 15)
#define BASS_SPEAKER_LEFT 0x10000000 // modifier: left
#define BASS_SPEAKER_RIGHT 0x20000000 // modifier: right
#define BASS_SPEAKER_FRONTLEFT BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT
#define BASS_SPEAKER_FRONTRIGHT BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT
#define BASS_SPEAKER_REARLEFT BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT
#define BASS_SPEAKER_REARRIGHT BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT
#define BASS_SPEAKER_CENTER BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT
#define BASS_SPEAKER_LFE BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT
#define BASS_SPEAKER_REAR2LEFT BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT
#define BASS_SPEAKER_REAR2RIGHT BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT
#define BASS_ASYNCFILE 0x40000000
#define BASS_UNICODE 0x80000000
#define BASS_RECORD_PAUSE 0x8000 // start recording paused
// DX7 voice allocation & management flags
#define BASS_VAM_HARDWARE 1
#define BASS_VAM_SOFTWARE 2
#define BASS_VAM_TERM_TIME 4
#define BASS_VAM_TERM_DIST 8
#define BASS_VAM_TERM_PRIO 16
// Channel info structure
typedef struct {
DWORD freq; // default playback rate
DWORD chans; // channels
DWORD flags; // BASS_SAMPLE/STREAM/MUSIC/SPEAKER flags
DWORD ctype; // type of channel
DWORD origres; // original resolution
HPLUGIN plugin; // plugin
HSAMPLE sample; // sample
const char *filename; // filename
} BASS_CHANNELINFO;
// BASS_CHANNELINFO types
#define BASS_CTYPE_SAMPLE 1
#define BASS_CTYPE_RECORD 2
#define BASS_CTYPE_STREAM 0x10000
#define BASS_CTYPE_STREAM_OGG 0x10002
#define BASS_CTYPE_STREAM_MP1 0x10003
#define BASS_CTYPE_STREAM_MP2 0x10004
#define BASS_CTYPE_STREAM_MP3 0x10005
#define BASS_CTYPE_STREAM_AIFF 0x10006
#define BASS_CTYPE_STREAM_CA 0x10007
#define BASS_CTYPE_STREAM_MF 0x10008
#define BASS_CTYPE_STREAM_WAV 0x40000 // WAVE flag, LOWORD=codec
#define BASS_CTYPE_STREAM_WAV_PCM 0x50001
#define BASS_CTYPE_STREAM_WAV_FLOAT 0x50003
#define BASS_CTYPE_MUSIC_MOD 0x20000
#define BASS_CTYPE_MUSIC_MTM 0x20001
#define BASS_CTYPE_MUSIC_S3M 0x20002
#define BASS_CTYPE_MUSIC_XM 0x20003
#define BASS_CTYPE_MUSIC_IT 0x20004
#define BASS_CTYPE_MUSIC_MO3 0x00100 // MO3 flag
typedef struct {
DWORD ctype; // channel type
#ifdef _WIN32_WCE
const wchar_t *name; // format description
const wchar_t *exts; // file extension filter (*.ext1;*.ext2;etc...)
#else
const char *name; // format description
const char *exts; // file extension filter (*.ext1;*.ext2;etc...)
#endif
} BASS_PLUGINFORM;
typedef struct {
DWORD version; // version (same form as BASS_GetVersion)
DWORD formatc; // number of formats
const BASS_PLUGINFORM *formats; // the array of formats
} BASS_PLUGININFO;
// 3D vector (for 3D positions/velocities/orientations)
typedef struct BASS_3DVECTOR {
#ifdef __cplusplus
BASS_3DVECTOR() {};
BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {};
#endif
float x; // +=right, -=left
float y; // +=up, -=down
float z; // +=front, -=behind
} BASS_3DVECTOR;
// 3D channel modes
#define BASS_3DMODE_NORMAL 0 // normal 3D processing
#define BASS_3DMODE_RELATIVE 1 // position is relative to the listener
#define BASS_3DMODE_OFF 2 // no 3D processing
// software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM)
#define BASS_3DALG_DEFAULT 0
#define BASS_3DALG_OFF 1
#define BASS_3DALG_FULL 2
#define BASS_3DALG_LIGHT 3
// EAX environments, use with BASS_SetEAXParameters
enum
{
EAX_ENVIRONMENT_GENERIC,
EAX_ENVIRONMENT_PADDEDCELL,
EAX_ENVIRONMENT_ROOM,
EAX_ENVIRONMENT_BATHROOM,
EAX_ENVIRONMENT_LIVINGROOM,
EAX_ENVIRONMENT_STONEROOM,
EAX_ENVIRONMENT_AUDITORIUM,
EAX_ENVIRONMENT_CONCERTHALL,
EAX_ENVIRONMENT_CAVE,
EAX_ENVIRONMENT_ARENA,
EAX_ENVIRONMENT_HANGAR,
EAX_ENVIRONMENT_CARPETEDHALLWAY,
EAX_ENVIRONMENT_HALLWAY,
EAX_ENVIRONMENT_STONECORRIDOR,
EAX_ENVIRONMENT_ALLEY,
EAX_ENVIRONMENT_FOREST,
EAX_ENVIRONMENT_CITY,
EAX_ENVIRONMENT_MOUNTAINS,
EAX_ENVIRONMENT_QUARRY,
EAX_ENVIRONMENT_PLAIN,
EAX_ENVIRONMENT_PARKINGLOT,
EAX_ENVIRONMENT_SEWERPIPE,
EAX_ENVIRONMENT_UNDERWATER,
EAX_ENVIRONMENT_DRUGGED,
EAX_ENVIRONMENT_DIZZY,
EAX_ENVIRONMENT_PSYCHOTIC,
EAX_ENVIRONMENT_COUNT // total number of environments
};
// EAX presets, usage: BASS_SetEAXParameters(EAX_PRESET_xxx)
#define EAX_PRESET_GENERIC EAX_ENVIRONMENT_GENERIC,0.5F,1.493F,0.5F
#define EAX_PRESET_PADDEDCELL EAX_ENVIRONMENT_PADDEDCELL,0.25F,0.1F,0.0F
#define EAX_PRESET_ROOM EAX_ENVIRONMENT_ROOM,0.417F,0.4F,0.666F
#define EAX_PRESET_BATHROOM EAX_ENVIRONMENT_BATHROOM,0.653F,1.499F,0.166F
#define EAX_PRESET_LIVINGROOM EAX_ENVIRONMENT_LIVINGROOM,0.208F,0.478F,0.0F
#define EAX_PRESET_STONEROOM EAX_ENVIRONMENT_STONEROOM,0.5F,2.309F,0.888F
#define EAX_PRESET_AUDITORIUM EAX_ENVIRONMENT_AUDITORIUM,0.403F,4.279F,0.5F
#define EAX_PRESET_CONCERTHALL EAX_ENVIRONMENT_CONCERTHALL,0.5F,3.961F,0.5F
#define EAX_PRESET_CAVE EAX_ENVIRONMENT_CAVE,0.5F,2.886F,1.304F
#define EAX_PRESET_ARENA EAX_ENVIRONMENT_ARENA,0.361F,7.284F,0.332F
#define EAX_PRESET_HANGAR EAX_ENVIRONMENT_HANGAR,0.5F,10.0F,0.3F
#define EAX_PRESET_CARPETEDHALLWAY EAX_ENVIRONMENT_CARPETEDHALLWAY,0.153F,0.259F,2.0F
#define EAX_PRESET_HALLWAY EAX_ENVIRONMENT_HALLWAY,0.361F,1.493F,0.0F
#define EAX_PRESET_STONECORRIDOR EAX_ENVIRONMENT_STONECORRIDOR,0.444F,2.697F,0.638F
#define EAX_PRESET_ALLEY EAX_ENVIRONMENT_ALLEY,0.25F,1.752F,0.776F
#define EAX_PRESET_FOREST EAX_ENVIRONMENT_FOREST,0.111F,3.145F,0.472F
#define EAX_PRESET_CITY EAX_ENVIRONMENT_CITY,0.111F,2.767F,0.224F
#define EAX_PRESET_MOUNTAINS EAX_ENVIRONMENT_MOUNTAINS,0.194F,7.841F,0.472F
#define EAX_PRESET_QUARRY EAX_ENVIRONMENT_QUARRY,1.0F,1.499F,0.5F
#define EAX_PRESET_PLAIN EAX_ENVIRONMENT_PLAIN,0.097F,2.767F,0.224F
#define EAX_PRESET_PARKINGLOT EAX_ENVIRONMENT_PARKINGLOT,0.208F,1.652F,1.5F
#define EAX_PRESET_SEWERPIPE EAX_ENVIRONMENT_SEWERPIPE,0.652F,2.886F,0.25F
#define EAX_PRESET_UNDERWATER EAX_ENVIRONMENT_UNDERWATER,1.0F,1.499F,0.0F
#define EAX_PRESET_DRUGGED EAX_ENVIRONMENT_DRUGGED,0.875F,8.392F,1.388F
#define EAX_PRESET_DIZZY EAX_ENVIRONMENT_DIZZY,0.139F,17.234F,0.666F
#define EAX_PRESET_PSYCHOTIC EAX_ENVIRONMENT_PSYCHOTIC,0.486F,7.563F,0.806F
typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user);
/* User stream callback function. NOTE: A stream function should obviously be as quick
as possible, other streams (and MOD musics) can't be mixed until it's finished.
handle : The stream that needs writing
buffer : Buffer to write the samples in
length : Number of bytes to write
user : The 'user' parameter value given when calling BASS_StreamCreate
RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end
the stream. */
#define BASS_STREAMPROC_END 0x80000000 // end of user stream flag
// special STREAMPROCs
#define STREAMPROC_DUMMY (STREAMPROC*)0 // "dummy" stream
#define STREAMPROC_PUSH (STREAMPROC*)-1 // push stream
// BASS_StreamCreateFileUser file systems
#define STREAMFILE_NOBUFFER 0
#define STREAMFILE_BUFFER 1
#define STREAMFILE_BUFFERPUSH 2
// User file stream callback functions
typedef void (CALLBACK FILECLOSEPROC)(void *user);
typedef QWORD (CALLBACK FILELENPROC)(void *user);
typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user);
typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user);
typedef struct {
FILECLOSEPROC *close;
FILELENPROC *length;
FILEREADPROC *read;
FILESEEKPROC *seek;
} BASS_FILEPROCS;
// BASS_StreamPutFileData options
#define BASS_FILEDATA_END 0 // end & close the file
// BASS_StreamGetFilePosition modes
#define BASS_FILEPOS_CURRENT 0
#define BASS_FILEPOS_DECODE BASS_FILEPOS_CURRENT
#define BASS_FILEPOS_DOWNLOAD 1
#define BASS_FILEPOS_END 2
#define BASS_FILEPOS_START 3
#define BASS_FILEPOS_CONNECTED 4
#define BASS_FILEPOS_BUFFER 5
#define BASS_FILEPOS_SOCKET 6
typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user);
/* Internet stream download callback function.
buffer : Buffer containing the downloaded data... NULL=end of download
length : Number of bytes in the buffer
user : The 'user' parameter value given when calling BASS_StreamCreateURL */
// BASS_ChannelSetSync types
#define BASS_SYNC_POS 0
#define BASS_SYNC_END 2
#define BASS_SYNC_META 4
#define BASS_SYNC_SLIDE 5
#define BASS_SYNC_STALL 6
#define BASS_SYNC_DOWNLOAD 7
#define BASS_SYNC_FREE 8
#define BASS_SYNC_SETPOS 11
#define BASS_SYNC_MUSICPOS 10
#define BASS_SYNC_MUSICINST 1
#define BASS_SYNC_MUSICFX 3
#define BASS_SYNC_OGG_CHANGE 12
#define BASS_SYNC_MIXTIME 0x40000000 // FLAG: sync at mixtime, else at playtime
#define BASS_SYNC_ONETIME 0x80000000 // FLAG: sync only once, else continuously
typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user);
/* Sync callback function. NOTE: a sync callback function should be very
quick as other syncs can't be processed until it has finished. If the sync
is a "mixtime" sync, then other streams and MOD musics can't be mixed until
it's finished either.
handle : The sync that has occured
channel: Channel that the sync occured in
data : Additional data associated with the sync's occurance
user : The 'user' parameter given when calling BASS_ChannelSetSync */
typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user);
/* DSP callback function. NOTE: A DSP function should obviously be as quick as
possible... other DSP functions, streams and MOD musics can not be processed
until it's finished.
handle : The DSP handle
channel: Channel that the DSP is being applied to
buffer : Buffer to apply the DSP to
length : Number of bytes in the buffer
user : The 'user' parameter given when calling BASS_ChannelSetDSP */
typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user);
/* Recording callback function.
handle : The recording handle
buffer : Buffer containing the recorded sample data
length : Number of bytes
user : The 'user' parameter value given when calling BASS_RecordStart
RETURN : TRUE = continue recording, FALSE = stop */
// BASS_ChannelIsActive return values
#define BASS_ACTIVE_STOPPED 0
#define BASS_ACTIVE_PLAYING 1
#define BASS_ACTIVE_STALLED 2
#define BASS_ACTIVE_PAUSED 3
// Channel attributes
#define BASS_ATTRIB_FREQ 1
#define BASS_ATTRIB_VOL 2
#define BASS_ATTRIB_PAN 3
#define BASS_ATTRIB_EAXMIX 4
#define BASS_ATTRIB_NOBUFFER 5
#define BASS_ATTRIB_CPU 7
#define BASS_ATTRIB_SRC 8
#define BASS_ATTRIB_MUSIC_AMPLIFY 0x100
#define BASS_ATTRIB_MUSIC_PANSEP 0x101
#define BASS_ATTRIB_MUSIC_PSCALER 0x102
#define BASS_ATTRIB_MUSIC_BPM 0x103
#define BASS_ATTRIB_MUSIC_SPEED 0x104
#define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105
#define BASS_ATTRIB_MUSIC_VOL_CHAN 0x200 // + channel #
#define BASS_ATTRIB_MUSIC_VOL_INST 0x300 // + instrument #
// BASS_ChannelGetData flags
#define BASS_DATA_AVAILABLE 0 // query how much data is buffered
#define BASS_DATA_FLOAT 0x40000000 // flag: return floating-point sample data
#define BASS_DATA_FFT256 0x80000000 // 256 sample FFT
#define BASS_DATA_FFT512 0x80000001 // 512 FFT
#define BASS_DATA_FFT1024 0x80000002 // 1024 FFT
#define BASS_DATA_FFT2048 0x80000003 // 2048 FFT
#define BASS_DATA_FFT4096 0x80000004 // 4096 FFT
#define BASS_DATA_FFT8192 0x80000005 // 8192 FFT
#define BASS_DATA_FFT16384 0x80000006 // 16384 FFT
#define BASS_DATA_FFT_INDIVIDUAL 0x10 // FFT flag: FFT for each channel, else all combined
#define BASS_DATA_FFT_NOWINDOW 0x20 // FFT flag: no Hanning window
#define BASS_DATA_FFT_REMOVEDC 0x40 // FFT flag: pre-remove DC bias
#define BASS_DATA_FFT_COMPLEX 0x80 // FFT flag: return complex data
// BASS_ChannelGetTags types : what's returned
#define BASS_TAG_ID3 0 // ID3v1 tags : TAG_ID3 structure
#define BASS_TAG_ID3V2 1 // ID3v2 tags : variable length block
#define BASS_TAG_OGG 2 // OGG comments : series of null-terminated UTF-8 strings
#define BASS_TAG_HTTP 3 // HTTP headers : series of null-terminated ANSI strings
#define BASS_TAG_ICY 4 // ICY headers : series of null-terminated ANSI strings
#define BASS_TAG_META 5 // ICY metadata : ANSI string
#define BASS_TAG_APE 6 // APE tags : series of null-terminated UTF-8 strings
#define BASS_TAG_MP4 7 // MP4/iTunes metadata : series of null-terminated UTF-8 strings
#define BASS_TAG_VENDOR 9 // OGG encoder : UTF-8 string
#define BASS_TAG_LYRICS3 10 // Lyric3v2 tag : ASCII string
#define BASS_TAG_CA_CODEC 11 // CoreAudio codec info : TAG_CA_CODEC structure
#define BASS_TAG_MF 13 // Media Foundation tags : series of null-terminated UTF-8 strings
#define BASS_TAG_WAVEFORMAT 14 // WAVE format : WAVEFORMATEEX structure
#define BASS_TAG_RIFF_INFO 0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings
#define BASS_TAG_RIFF_BEXT 0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure
#define BASS_TAG_RIFF_CART 0x102 // RIFF/BWF "cart" tags : TAG_CART structure
#define BASS_TAG_RIFF_DISP 0x103 // RIFF "DISP" text tag : ANSI string
#define BASS_TAG_APE_BINARY 0x1000 // + index #, binary APE tag : TAG_APE_BINARY structure
#define BASS_TAG_MUSIC_NAME 0x10000 // MOD music name : ANSI string
#define BASS_TAG_MUSIC_MESSAGE 0x10001 // MOD message : ANSI string
#define BASS_TAG_MUSIC_ORDERS 0x10002 // MOD order list : BYTE array of pattern numbers
#define BASS_TAG_MUSIC_INST 0x10100 // + instrument #, MOD instrument name : ANSI string
#define BASS_TAG_MUSIC_SAMPLE 0x10300 // + sample #, MOD sample name : ANSI string
// ID3v1 tag structure
typedef struct {
char id[3];
char title[30];
char artist[30];
char album[30];
char year[4];
char comment[30];
BYTE genre;
} TAG_ID3;
// Binary APE tag structure
typedef struct {
const char *key;
const void *data;
DWORD length;
} TAG_APE_BINARY;
// BWF "bext" tag structure
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4200)
#endif
#pragma pack(push,1)
typedef struct {
char Description[256]; // description
char Originator[32]; // name of the originator
char OriginatorReference[32]; // reference of the originator
char OriginationDate[10]; // date of creation (yyyy-mm-dd)
char OriginationTime[8]; // time of creation (hh-mm-ss)
QWORD TimeReference; // first sample count since midnight (little-endian)
WORD Version; // BWF version (little-endian)
BYTE UMID[64]; // SMPTE UMID
BYTE Reserved[190];
#if defined(__GNUC__) && __GNUC__<3
char CodingHistory[0]; // history
#elif 1 // change to 0 if compiler fails the following line
char CodingHistory[]; // history
#else
char CodingHistory[1]; // history
#endif
} TAG_BEXT;
#pragma pack(pop)
// BWF "cart" tag structures
typedef struct
{
DWORD dwUsage; // FOURCC timer usage ID
DWORD dwValue; // timer value in samples from head
} TAG_CART_TIMER;
typedef struct
{
char Version[4]; // version of the data structure
char Title[64]; // title of cart audio sequence
char Artist[64]; // artist or creator name
char CutID[64]; // cut number identification
char ClientID[64]; // client identification
char Category[64]; // category ID, PSA, NEWS, etc
char Classification[64]; // classification or auxiliary key
char OutCue[64]; // out cue text
char StartDate[10]; // yyyy-mm-dd
char StartTime[8]; // hh:mm:ss
char EndDate[10]; // yyyy-mm-dd
char EndTime[8]; // hh:mm:ss
char ProducerAppID[64]; // name of vendor or application
char ProducerAppVersion[64]; // version of producer application
char UserDef[64]; // user defined text
DWORD dwLevelReference; // sample value for 0 dB reference
TAG_CART_TIMER PostTimer[8]; // 8 time markers after head
char Reserved[276];
char URL[1024]; // uniform resource locator
#if defined(__GNUC__) && __GNUC__<3
char TagText[0]; // free form text for scripts or tags
#elif 1 // change to 0 if compiler fails the following line
char TagText[]; // free form text for scripts or tags
#else
char TagText[1]; // free form text for scripts or tags
#endif
} TAG_CART;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
// CoreAudio codec info structure
typedef struct {
DWORD ftype; // file format
DWORD atype; // audio format
const char *name; // description
} TAG_CA_CODEC;
#ifndef _WAVEFORMATEX_
#define _WAVEFORMATEX_
#pragma pack(push,1)
typedef struct tWAVEFORMATEX
{
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX;
typedef const WAVEFORMATEX *LPCWAVEFORMATEX;
#pragma pack(pop)
#endif
// BASS_ChannelGetLength/GetPosition/SetPosition modes
#define BASS_POS_BYTE 0 // byte position
#define BASS_POS_MUSIC_ORDER 1 // order.row position, MAKELONG(order,row)
#define BASS_POS_OGG 3 // OGG bitstream number
#define BASS_POS_DECODE 0x10000000 // flag: get the decoding (not playing) position
#define BASS_POS_DECODETO 0x20000000 // flag: decode to the position instead of seeking
// BASS_RecordSetInput flags
#define BASS_INPUT_OFF 0x10000
#define BASS_INPUT_ON 0x20000
#define BASS_INPUT_TYPE_MASK 0xff000000
#define BASS_INPUT_TYPE_UNDEF 0x00000000
#define BASS_INPUT_TYPE_DIGITAL 0x01000000
#define BASS_INPUT_TYPE_LINE 0x02000000
#define BASS_INPUT_TYPE_MIC 0x03000000
#define BASS_INPUT_TYPE_SYNTH 0x04000000
#define BASS_INPUT_TYPE_CD 0x05000000
#define BASS_INPUT_TYPE_PHONE 0x06000000
#define BASS_INPUT_TYPE_SPEAKER 0x07000000
#define BASS_INPUT_TYPE_WAVE 0x08000000
#define BASS_INPUT_TYPE_AUX 0x09000000
#define BASS_INPUT_TYPE_ANALOG 0x0a000000
// DX8 effect types, use with BASS_ChannelSetFX
enum
{
BASS_FX_DX8_CHORUS,
BASS_FX_DX8_COMPRESSOR,
BASS_FX_DX8_DISTORTION,
BASS_FX_DX8_ECHO,
BASS_FX_DX8_FLANGER,
BASS_FX_DX8_GARGLE,
BASS_FX_DX8_I3DL2REVERB,
BASS_FX_DX8_PARAMEQ,
BASS_FX_DX8_REVERB
};
typedef struct {
float fWetDryMix;
float fDepth;
float fFeedback;
float fFrequency;
DWORD lWaveform; // 0=triangle, 1=sine
float fDelay;
DWORD lPhase; // BASS_DX8_PHASE_xxx
} BASS_DX8_CHORUS;
typedef struct {
float fGain;
float fAttack;
float fRelease;
float fThreshold;
float fRatio;
float fPredelay;
} BASS_DX8_COMPRESSOR;
typedef struct {
float fGain;
float fEdge;
float fPostEQCenterFrequency;
float fPostEQBandwidth;
float fPreLowpassCutoff;
} BASS_DX8_DISTORTION;
typedef struct {
float fWetDryMix;
float fFeedback;
float fLeftDelay;
float fRightDelay;
BOOL lPanDelay;
} BASS_DX8_ECHO;
typedef struct {
float fWetDryMix;
float fDepth;
float fFeedback;
float fFrequency;
DWORD lWaveform; // 0=triangle, 1=sine
float fDelay;
DWORD lPhase; // BASS_DX8_PHASE_xxx
} BASS_DX8_FLANGER;
typedef struct {
DWORD dwRateHz; // Rate of modulation in hz
DWORD dwWaveShape; // 0=triangle, 1=square
} BASS_DX8_GARGLE;
typedef struct {
int lRoom; // [-10000, 0] default: -1000 mB
int lRoomHF; // [-10000, 0] default: 0 mB
float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0
float flDecayTime; // [0.1, 20.0] default: 1.49s
float flDecayHFRatio; // [0.1, 2.0] default: 0.83
int lReflections; // [-10000, 1000] default: -2602 mB
float flReflectionsDelay; // [0.0, 0.3] default: 0.007 s
int lReverb; // [-10000, 2000] default: 200 mB
float flReverbDelay; // [0.0, 0.1] default: 0.011 s
float flDiffusion; // [0.0, 100.0] default: 100.0 %
float flDensity; // [0.0, 100.0] default: 100.0 %
float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz
} BASS_DX8_I3DL2REVERB;
typedef struct {
float fCenter;
float fBandwidth;
float fGain;
} BASS_DX8_PARAMEQ;
typedef struct {
float fInGain; // [-96.0,0.0] default: 0.0 dB
float fReverbMix; // [-96.0,0.0] default: 0.0 db
float fReverbTime; // [0.001,3000.0] default: 1000.0 ms
float fHighFreqRTRatio; // [0.001,0.999] default: 0.001
} BASS_DX8_REVERB;
#define BASS_DX8_PHASE_NEG_180 0
#define BASS_DX8_PHASE_NEG_90 1
#define BASS_DX8_PHASE_ZERO 2
#define BASS_DX8_PHASE_90 3
#define BASS_DX8_PHASE_180 4
typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status);
/* iOS notification callback function.
status : The notification (BASS_IOSNOTIFY_xxx) */
#define BASS_IOSNOTIFY_INTERRUPT 1 // interruption started
#define BASS_IOSNOTIFY_INTERRUPT_END 2 // interruption ended
BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value);
DWORD BASSDEF(BASS_GetConfig)(DWORD option);
BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value);
void *BASSDEF(BASS_GetConfigPtr)(DWORD option);
DWORD BASSDEF(BASS_GetVersion)();
int BASSDEF(BASS_ErrorGetCode)();
BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info);
#if defined(_WIN32) && !defined(_WIN32_WCE)
BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const GUID *dsguid);
#else
BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, void *dsguid);
#endif
BOOL BASSDEF(BASS_SetDevice)(DWORD device);
DWORD BASSDEF(BASS_GetDevice)();
BOOL BASSDEF(BASS_Free)();
#if defined(_WIN32) && !defined(_WIN32_WCE)
void *BASSDEF(BASS_GetDSoundObject)(DWORD object);
#endif
BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info);
BOOL BASSDEF(BASS_Update)(DWORD length);
float BASSDEF(BASS_GetCPU)();
BOOL BASSDEF(BASS_Start)();
BOOL BASSDEF(BASS_Stop)();
BOOL BASSDEF(BASS_Pause)();
BOOL BASSDEF(BASS_SetVolume)(float volume);
float BASSDEF(BASS_GetVolume)();
HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags);
BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle);
const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle);
BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf);
BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf);
BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top);
BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top);
void BASSDEF(BASS_Apply3D)();
#if defined(_WIN32) && !defined(_WIN32_WCE)
BOOL BASSDEF(BASS_SetEAXParameters)(int env, float vol, float decay, float damp);
BOOL BASSDEF(BASS_GetEAXParameters)(DWORD *env, float *vol, float *decay, float *damp);
#endif
HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq);
BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle);
HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags);
HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags);
BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle);
BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer);
BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer);
BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info);
BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info);
HCHANNEL BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, BOOL onlynew);
DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels);
BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle);
HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user);
HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags);
HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user);
HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user);
BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle);
QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode);
DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length);
DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length);
BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info);
BOOL BASSDEF(BASS_RecordInit)(int device);
BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device);
DWORD BASSDEF(BASS_RecordGetDevice)();
BOOL BASSDEF(BASS_RecordFree)();
BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info);
const char *BASSDEF(BASS_RecordGetInputName)(int input);
BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume);
DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume);
HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user);
double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos);
QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos);
DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle);
BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device);
DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle);
BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info);
const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags);
DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask);
BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length);
BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock);
BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart);
BOOL BASSDEF(BASS_ChannelStop)(DWORD handle);
BOOL BASSDEF(BASS_ChannelPause)(DWORD handle);
BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value);
BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value);
BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time);
BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib);
BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol);
BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol);
BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel);
BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel);
QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode);
BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode);
QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode);
DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle);
DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length);
HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user);
BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync);
HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority);
BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp);
BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan);
BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan);
HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority);
BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx);
BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params);
BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params);
BOOL BASSDEF(BASS_FXReset)(HFX handle);
#ifdef __cplusplus
}
#endif
#endif

BIN
saco/bass.lib Normal file

Binary file not shown.

View File

@ -1,6 +1,8 @@
#include "main.h"
DWORD FUNC_100B6100(char *szString, int nMaxLen);
//----------------------------------------------------
CChatWindow::CChatWindow(IDirect3DDevice9 *pD3DDevice, CFontRender *pFontRender, CHAR *szChatLogFile)
@ -78,12 +80,84 @@ void CChatWindow::ResetDialogControls(CDXUTDialog *pGameUI)
}
//----------------------------------------------------
void CChatWindow::AddChatMessage(CHAR *szNick, DWORD dwNickColor, CHAR *szMessage)
{
FilterInvalidChars(szMessage);
AddToChatWindowBuffer(CHAT_TYPE_CHAT,szMessage,szNick,m_dwChatTextColor,dwNickColor);
}
//----------------------------------------------------
void CChatWindow::AddInfoMessage(CHAR * szFormat, ...)
{
char tmp_buf[512];
memset(tmp_buf,0,512);
va_list args;
va_start(args, szFormat);
vsprintf(tmp_buf, szFormat, args);
va_end(args);
FilterInvalidChars(tmp_buf);
AddToChatWindowBuffer(CHAT_TYPE_INFO,tmp_buf,NULL,m_dwChatInfoColor,0);
}
//----------------------------------------------------
void CChatWindow::AddDebugMessage(CHAR * szFormat, ...)
{
// TODO: CChatWindow::AddDebugMessage .text:100680F0
char tmp_buf[512];
memset(tmp_buf,0,512);
va_list args;
va_start(args, szFormat);
vsprintf(tmp_buf, szFormat, args);
va_end(args);
FilterInvalidChars(tmp_buf);
AddToChatWindowBuffer(CHAT_TYPE_DEBUG,tmp_buf,NULL,m_dwChatDebugColor,0);
OutputDebugString(tmp_buf);
}
//----------------------------------------------------
void CChatWindow::AddClientMessage(DWORD dwColor, PCHAR szStr)
{
dwColor = (dwColor >> 8) | 0xFF000000; // convert to ARGB
if(strlen(szStr) > 144) return;
FUNC_100B6100(szStr, 255);
FilterInvalidChars(szStr);
AddToChatWindowBuffer(CHAT_TYPE_INFO,szStr,NULL,dwColor,0);
}
//----------------------------------------------------
void CChatWindow::FilterInvalidChars(PCHAR szString)
{
while(*szString) {
if(*szString > 0 && *szString < ' ') {
*szString = ' ';
}
szString++;
}
}
//----------------------------------------------------
void CChatWindow::AddToChatWindowBuffer(eChatMessageType eType,
PCHAR szString,
PCHAR szNick,
DWORD dwTextColor,
DWORD dwChatColor)
{
// TODO: CChatWindow::AddToChatWindowBuffer
}
//----------------------------------------------------
// MATCH
void CChatWindow::FUNC_10067200()
{

View File

@ -1,13 +1,28 @@
#pragma once
#define MAX_MESSAGE_LENGTH 144
#define MAX_LINE_LENGTH MAX_MESSAGE_LENGTH / 2
#define MAX_MESSAGES 100
enum eChatMessageType {
CHAT_TYPE_NONE=0,
CHAT_TYPE_CHAT=2,
CHAT_TYPE_INFO=4,
CHAT_TYPE_DEBUG=8,
};
#pragma pack(1)
typedef struct _CHAT_WINDOW_ENTRY
{
char _gap0[252];
//char _gap0[252];
time_t field_0;
char _gap4[236];
eChatMessageType eType;
DWORD dwTextColor;
DWORD dwNickColor;
} CHAT_WINDOW_ENTRY;
class CChatWindow // size: 25578
@ -27,6 +42,7 @@ private:
DWORD m_dwChatInfoColor;
DWORD m_dwChatDebugColor;
char _gap12E[4];
//char field_132[25200];
CHAT_WINDOW_ENTRY m_ChatWindowEntries[MAX_MESSAGES];
CFontRender *m_pFontRender;
ID3DXSprite *field_63A6;
@ -44,14 +60,21 @@ private:
int field_63E2;
char _gap63E6[4];
void FilterInvalidChars(PCHAR szString);
void AddToChatWindowBuffer(eChatMessageType eType,PCHAR szString,
PCHAR szNick,DWORD dwTextColor,DWORD dwChatColor);
void CreateFonts();
void FUNC_10067200();
public:
CChatWindow();
void AddChatMessage(CHAR *szNick, DWORD dwNickColor, CHAR *szMessage);
void AddInfoMessage(CHAR *szFormat, ...);
void AddDebugMessage(CHAR *szFormat, ...);
void AddClientMessage(DWORD dwColor, PCHAR szStr);
void ResetDialogControls(CDXUTDialog *pGameUI);

View File

@ -9,6 +9,14 @@ extern GAME_SETTINGS tSettings;
extern bool bShowDebugLabels;
//////////////////////////////////////////////////////
//
// -------R E L E A S E C O M M A N D S--------
//
// (INCLUDES SCRIPTING UTILS)
//
//////////////////////////////////////////////////////
void cmdDefaultCmdProc(PCHAR szCmd)
{
if(pNetGame) {
@ -18,6 +26,8 @@ void cmdDefaultCmdProc(PCHAR szCmd)
}
}
//----------------------------------------------------
void cmdTestDeathWindow(PCHAR szCmd)
{
if(pDeathWindow) {
@ -32,6 +42,8 @@ void cmdTestDeathWindow(PCHAR szCmd)
}
}
//----------------------------------------------------
void cmdCameraTargetDebug(PCHAR szCmd)
{
// TODO: cmdCameraTargetDebug .text:100685E0
@ -49,7 +61,8 @@ void cmdFontSize(PCHAR szCmd)
void cmdNameTagStatus(PCHAR szCmd)
{
// TODO: cmdNameTagStatus .text:10068720
if(pNetGame)
pNetGame->TogglePlayerTagStatus();
}
void cmdTimestamp(PCHAR szCmd)
@ -72,11 +85,15 @@ void cmdHudScaleFix(PCHAR szCmd)
// TODO: cmdHudScaleFix .text:10068870
}
//----------------------------------------------------
void cmdMem(PCHAR szCmd)
{
pChatWindow->AddDebugMessage("Memory: %u",*(DWORD *)0x8A5A80);
}
//----------------------------------------------------
void cmdSetFrameLimit(PCHAR szCmd)
{
// TODO: cmdSetFrameLimit .text:100688D0
@ -142,18 +159,22 @@ void cmdToggleObjectLight(PCHAR szCmd)
// TODO: cmdToggleObjectLight .text:10069000
}
//----------------------------------------------------
void cmdDebugLabels(PCHAR szCmd)
{
bShowDebugLabels = !bShowDebugLabels;
}
//----------------------------------------------------
void cmdRcon(PCHAR szCmd)
{
// TODO: cmdRcon .text:10069030
}
//----------------------------------------------------
// MATCH
void SetupCommands()
{
// RELEASE COMMANDS

0
saco/cmdprocs.h Normal file
View File

View File

@ -550,6 +550,29 @@ int CDXUTDialogResourceManager::AddFont( LPCTSTR strFaceName, LONG height, LONG
}
//--------------------------------------------------------------------------------------
int CDXUTDialogResourceManager::SetFont(UINT iFont, LPCTSTR strFaceName, LONG height, LONG weight)
{
DXUTFontNode* pFontNode = m_FontCache.GetAt(iFont);
if( pFontNode != NULL )
{
StringCchCopy( pFontNode->strFace, MAX_PATH, strFaceName );
pFontNode->nHeight = height;
pFontNode->nWeight = weight;
// If a device is available, try to create immediately
if( m_pd3dDevice )
CreateFont( iFont );
return iFont;
}
else
{
return -1;
}
}
//--------------------------------------------------------------------------------------
// MATCH
HRESULT CDXUTDialog::SetFont( UINT index, LPCTSTR strFaceName, LONG height, LONG weight )
@ -5650,7 +5673,7 @@ BOOL (APIENTRY * CDXUTIMEEditBox::_VerQueryValueA)( const LPVOID, LPSTR, LPVOID
BOOL (APIENTRY * CDXUTIMEEditBox::_GetFileVersionInfoA)( LPSTR, DWORD, DWORD, LPVOID )= CDXUTIMEEditBox::Dummy_GetFileVersionInfoA;
DWORD (APIENTRY * CDXUTIMEEditBox::_GetFileVersionInfoSizeA)( LPSTR, LPDWORD ) = CDXUTIMEEditBox::Dummy_GetFileVersionInfoSizeA;
DWORD dwImeWaitTick;
int nImeWaitTick;
HINSTANCE CDXUTIMEEditBox::s_hDllImm32; // IMM32 DLL handle
HINSTANCE CDXUTIMEEditBox::s_hDllVer; // Version DLL handle
@ -6694,7 +6717,7 @@ bool CDXUTIMEEditBox::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
s_bHideCaret = false;
// Hide reading window
s_bShowReadingWindow = false;
dwImeWaitTick = GetTickCount();
nImeWaitTick = GetTickCount();
break;
case WM_IME_NOTIFY:
@ -7811,7 +7834,7 @@ void CDXUTIMEEditBox::Initialize()
FARPROC Temp;
dwImeWaitTick = GetTickCount();
nImeWaitTick = GetTickCount();
s_CompString.SetBufferSize( MAX_COMPSTRING_SIZE );
@ -7906,6 +7929,18 @@ void CDXUTIMEEditBox::Uninitialize()
}
//--------------------------------------------------------------------------------------
bool CDXUTIMEEditBox::FUNC_100863E0()
{
if(s_CandList.bShowWindow) return true;
if(s_bShowReadingWindow) return true;
if(((int)GetTickCount() - nImeWaitTick) < 300)
return true;
return false;
}
//--------------------------------------------------------------------------------------
// MATCH
void DXUTBlendColor::Init( D3DCOLOR defaultColor, D3DCOLOR disabledColor, D3DCOLOR hiddenColor )

View File

@ -327,6 +327,7 @@ public:
bool MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
int AddFont( LPCTSTR strFaceName, LONG height, LONG weight );
int SetFont(UINT iFont, LPCTSTR strFaceName, LONG height, LONG weight);
int AddTexture( LPCTSTR strFilename );
DXUTFontNode* GetFontNode( int iIndex ) { return m_FontCache.GetAt( iIndex ); };
@ -765,11 +766,12 @@ protected:
bool m_bPressed;
RECT m_rcButton;
bool field_76;
D3DXCOLOR field_77;
bool field_76;
D3DXCOLOR field_77;
public:
void SetColor(D3DXCOLOR c) { field_76 = true; field_77 = c; };
void SetColor(D3DXCOLOR c) { field_76 = true; field_77 = c; };
D3DXCOLOR* GetColor() { return &field_77; };
};
@ -1010,6 +1012,8 @@ public:
virtual void RenderComposition( IDirect3DDevice9* pd3dDevice, float fElapsedTime );
virtual void RenderIndicator( IDirect3DDevice9* pd3dDevice, float fElapsedTime );
static bool FUNC_100863E0();
protected:
static WORD GetLanguage() { return LOWORD( s_hklCurrent ); }
static WORD GetPrimaryLanguage() { return PRIMARYLANGID( LOWORD( s_hklCurrent ) ); }

787
saco/d3d9/d3dfont.cpp Normal file
View File

@ -0,0 +1,787 @@
//-----------------------------------------------------------------------------
// File: D3DFont.cpp
//
// Desc: Texture-based font class
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <D3DX9.h>
#include "include/D3DFont.h"
#include "include/DXUtil.h"
//-----------------------------------------------------------------------------
// Custom vertex types for rendering text
//-----------------------------------------------------------------------------
#define MAX_NUM_VERTICES 50*6
struct FONT2DVERTEX { D3DXVECTOR4 p; DWORD color; FLOAT tu, tv; };
struct FONT3DVERTEX { D3DXVECTOR3 p; D3DXVECTOR3 n; FLOAT tu, tv; };
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
inline FONT2DVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,
FLOAT tu, FLOAT tv )
{
FONT2DVERTEX v; v.p = p; v.color = color; v.tu = tu; v.tv = tv;
return v;
}
inline FONT3DVERTEX InitFont3DVertex( const D3DXVECTOR3& p, const D3DXVECTOR3& n,
FLOAT tu, FLOAT tv )
{
FONT3DVERTEX v; v.p = p; v.n = n; v.tu = tu; v.tv = tv;
return v;
}
//-----------------------------------------------------------------------------
// Name: CD3DFont()
// Desc: Font class constructor
//-----------------------------------------------------------------------------
CD3DFont::CD3DFont( const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags )
{
_tcsncpy( m_strFontName, strFontName, sizeof(m_strFontName) / sizeof(TCHAR) );
m_strFontName[sizeof(m_strFontName) / sizeof(TCHAR) - 1] = _T('\0');
m_dwFontHeight = dwHeight;
m_dwFontFlags = dwFlags;
m_dwSpacing = 0;
m_pd3dDevice = NULL;
m_pTexture = NULL;
m_pVB = NULL;
m_pStateBlockSaved = NULL;
m_pStateBlockDrawText = NULL;
}
//-----------------------------------------------------------------------------
// Name: ~CD3DFont()
// Desc: Font class destructor
//-----------------------------------------------------------------------------
CD3DFont::~CD3DFont()
{
InvalidateDeviceObjects();
DeleteDeviceObjects();
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initializes device-dependent objects, including the vertex buffer used
// for rendering text and the texture map which stores the font image.
//-----------------------------------------------------------------------------
HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
{
HRESULT hr;
// Keep a local copy of the device
m_pd3dDevice = pd3dDevice;
// Establish the font and texture size
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
// Large fonts need larger textures
if( m_dwFontHeight > 50 )
m_dwTexWidth = m_dwTexHeight = 2048;
else if( m_dwFontHeight > 30 )
m_dwTexWidth = m_dwTexHeight = 1024;
else if( m_dwFontHeight > 10 )
m_dwTexWidth = m_dwTexHeight = 512;
else
m_dwTexWidth = m_dwTexHeight = 256;
// If requested texture is too big, use a smaller texture and smaller font,
// and scale up when rendering.
D3DCAPS9 d3dCaps;
m_pd3dDevice->GetDeviceCaps( &d3dCaps );
if( m_dwTexWidth > d3dCaps.MaxTextureWidth )
{
m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwTexWidth;
m_dwTexWidth = m_dwTexHeight = d3dCaps.MaxTextureWidth;
}
// Create a new texture for the font
hr = m_pd3dDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
0, D3DFMT_A4R4G4B4,
D3DPOOL_MANAGED, &m_pTexture, NULL );
if( FAILED(hr) )
return hr;
// Prepare to create a bitmap
DWORD* pBitmapBits;
BITMAPINFO bmi;
ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 32;
// Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC( NULL );
HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
(void**)&pBitmapBits, NULL, 0 );
SetMapMode( hDC, MM_TEXT );
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
// antialiased font, but this is not guaranteed.
INT nHeight = -MulDiv( m_dwFontHeight,
(INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
DWORD dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE;
HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold, dwItalic,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
VARIABLE_PITCH, m_strFontName );
if( NULL==hFont )
return E_FAIL;
SelectObject( hDC, hbmBitmap );
SelectObject( hDC, hFont );
// Set text properties
SetTextColor( hDC, RGB(255,255,255) );
SetBkColor( hDC, 0x00000000 );
SetTextAlign( hDC, TA_TOP );
// Loop through all printable character and output them to the bitmap..
// Meanwhile, keep track of the corresponding tex coords for each character.
DWORD x = 0;
DWORD y = 0;
BYTE str[2] = _T("x");
SIZE size;
// Calculate the spacing between characters based on line height
GetTextExtentPoint32( hDC, TEXT(" "), 1, &size );
x = m_dwSpacing = (DWORD) ceil(size.cy * 0.25f);
for( DWORD c=32; c<256; c++ )
{
str[0] = (BYTE)c;
GetTextExtentPoint32( hDC, (LPCSTR)str, 1, &size );
if( (DWORD)(x + size.cx + m_dwSpacing) > m_dwTexWidth )
{
x = m_dwSpacing;
y += size.cy+1;
}
ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, (LPCSTR)str, 1, NULL );
m_fTexCoords[c-32][0] = ((FLOAT)(x + 0 - m_dwSpacing))/m_dwTexWidth;
m_fTexCoords[c-32][1] = ((FLOAT)(y + 0 + 0 ))/m_dwTexHeight;
m_fTexCoords[c-32][2] = ((FLOAT)(x + size.cx + m_dwSpacing))/m_dwTexWidth;
m_fTexCoords[c-32][3] = ((FLOAT)(y + size.cy + 0 ))/m_dwTexHeight;
x += size.cx + (2 * m_dwSpacing);
}
#ifdef _DEBUG
char szBuffer[1024];
sprintf(szBuffer, "c:\\bmp-%s-%d.bmp", m_strFontName, nHeight);
FILE *pFile = fopen(szBuffer, "wb");
BITMAPFILEHEADER bmfh;
int nBitsOffset = sizeof(BITMAPFILEHEADER) + bmi.bmiHeader.biSize;
LONG lImageSize = m_dwTexWidth * m_dwTexHeight * (bmi.bmiHeader.biBitCount/8);
LONG lFileSize = nBitsOffset + lImageSize;
bmfh.bfType = 'B'+('M'<<8);
bmfh.bfOffBits = nBitsOffset;
bmfh.bfSize = lFileSize;
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
//Write the bitmap file header
UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1,
sizeof(BITMAPFILEHEADER), pFile);
//And then the bitmap info header
UINT nWrittenInfoHeaderSize = fwrite(&bmi.bmiHeader,
1, sizeof(BITMAPINFOHEADER), pFile);
//Finally, write the image data itself
//-- the data represents our drawing
UINT nWrittenDIBDataSize =
fwrite(pBitmapBits, 1, lImageSize, pFile);
fclose(pFile);
#endif
// Lock the surface and write the alpha values for the set pixels
D3DLOCKED_RECT d3dlr;
m_pTexture->LockRect( 0, &d3dlr, 0, 0 );
BYTE* pDstRow = (BYTE*)d3dlr.pBits;
WORD* pDst16;
BYTE bAlpha; // 4-bit measure of pixel intensity
for( y=0; y < m_dwTexHeight; y++ )
{
pDst16 = (WORD*)pDstRow;
for( x=0; x < m_dwTexWidth; x++ )
{
bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
if (bAlpha > 0)
{
*pDst16++ = (WORD) ((bAlpha << 12) | 0x0fff);
}
else
{
*pDst16++ = 0x0000;
}
}
pDstRow += d3dlr.Pitch;
}
// Done updating texture, so clean up used objects
m_pTexture->UnlockRect(0);
DeleteObject( hbmBitmap );
DeleteDC( hDC );
DeleteObject( hFont );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CD3DFont::RestoreDeviceObjects()
{
HRESULT hr;
// Create vertex buffer for the letters
int vertexSize = max( sizeof(FONT2DVERTEX), sizeof(FONT3DVERTEX ) );
if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( MAX_NUM_VERTICES * vertexSize,
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
D3DPOOL_DEFAULT, &m_pVB, NULL ) ) )
{
return hr;
}
// Create the state blocks for rendering text
for( UINT which=0; which<2; which++ )
{
m_pd3dDevice->BeginStateBlock();
m_pd3dDevice->SetTexture( 0, m_pTexture );
if ( D3DFONT_ZENABLE & m_dwFontFlags )
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
else
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_DISABLE );
m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE,
D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN |
D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
if( which==0 )
m_pd3dDevice->EndStateBlock( &m_pStateBlockSaved );
else
m_pd3dDevice->EndStateBlock( &m_pStateBlockDrawText );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: Destroys all device-dependent objects
//-----------------------------------------------------------------------------
HRESULT CD3DFont::InvalidateDeviceObjects()
{
SAFE_RELEASE( m_pVB );
SAFE_RELEASE( m_pStateBlockSaved );
SAFE_RELEASE( m_pStateBlockDrawText );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Destroys all device-dependent objects
//-----------------------------------------------------------------------------
HRESULT CD3DFont::DeleteDeviceObjects()
{
SAFE_RELEASE( m_pTexture );
m_pd3dDevice = NULL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: GetTextExtent()
// Desc: Get the dimensions of a text string
//-----------------------------------------------------------------------------
HRESULT CD3DFont::GetTextExtent( const TCHAR* strText, SIZE* pSize )
{
if( NULL==strText || NULL==pSize )
return E_FAIL;
FLOAT fRowWidth = 0.0f;
FLOAT fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
FLOAT fWidth = 0.0f;
FLOAT fHeight = fRowHeight;
while( *strText )
{
BYTE c = *(BYTE*)strText++;
if( c == _T('\n') )
{
fRowWidth = 0.0f;
fHeight += fRowHeight;
}
if( (c-32) < 0 || (c-32) >= 256-32 )
continue;
FLOAT tx1 = m_fTexCoords[c-32][0];
FLOAT tx2 = m_fTexCoords[c-32][2];
fRowWidth += (tx2-tx1)*m_dwTexWidth - 2*m_dwSpacing;
if( fRowWidth > fWidth )
fWidth = fRowWidth;
}
pSize->cx = (int)fWidth;
pSize->cy = (int)fHeight;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DrawTextScaled()
// Desc: Draws scaled 2D text. Note that x and y are in viewport coordinates
// (ranging from -1 to +1). fXScale and fYScale are the size fraction
// relative to the entire viewport. For example, a fXScale of 0.25 is
// 1/8th of the screen width. This allows you to output text at a fixed
// fraction of the viewport, even if the screen or window size changes.
//-----------------------------------------------------------------------------
HRESULT CD3DFont::DrawTextScaled( FLOAT x, FLOAT y, FLOAT z,
FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
const TCHAR* strText, DWORD dwFlags )
{
if( m_pd3dDevice == NULL )
return E_FAIL;
// Set up renderstate
m_pStateBlockSaved->Capture();
m_pStateBlockDrawText->Apply();
m_pd3dDevice->SetFVF( D3DFVF_FONT2DVERTEX );
m_pd3dDevice->SetPixelShader( NULL );
m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT2DVERTEX) );
// Set filter states
if( dwFlags & D3DFONT_FILTERED )
{
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
}
D3DVIEWPORT9 vp;
m_pd3dDevice->GetViewport( &vp );
FLOAT fLineHeight = ( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight;
// Center the text block in the viewport
if( dwFlags & D3DFONT_CENTERED_X )
{
const BYTE* strTextTmp = (BYTE*)strText;
float xFinal = 0.0f;
while( *strTextTmp )
{
BYTE c = *strTextTmp++;
if( c == _T('\n') )
break; // Isn't supported.
if( (c-32) < 0 || (c-32) >= 256-32 )
continue;
FLOAT tx1 = m_fTexCoords[c-32][0];
FLOAT tx2 = m_fTexCoords[c-32][2];
FLOAT w = (tx2-tx1)*m_dwTexWidth;
w *= (fXScale*vp.Height)/fLineHeight;
xFinal += w - (2 * m_dwSpacing) * (fXScale*vp.Height)/fLineHeight;
}
x = -xFinal/vp.Width;
}
if( dwFlags & D3DFONT_CENTERED_Y )
{
y = -fLineHeight/vp.Height;
}
FLOAT sx = (x+1.0f)*vp.Width/2;
FLOAT sy = (y+1.0f)*vp.Height/2;
FLOAT sz = z;
FLOAT rhw = 1.0f;
// Adjust for character spacing
sx -= m_dwSpacing * (fXScale*vp.Height)/fLineHeight;
FLOAT fStartX = sx;
// Fill vertex buffer
FONT2DVERTEX* pVertices;
DWORD dwNumTriangles = 0L;
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
while( *strText )
{
BYTE c = *(BYTE*)strText++;
if( c == _T('\n') )
{
sx = fStartX;
sy += fYScale*vp.Height;
}
if( (c-32) < 0 || (c-32) >= 256-32 )
continue;
FLOAT tx1 = m_fTexCoords[c-32][0];
FLOAT ty1 = m_fTexCoords[c-32][1];
FLOAT tx2 = m_fTexCoords[c-32][2];
FLOAT ty2 = m_fTexCoords[c-32][3];
FLOAT w = (tx2-tx1)*m_dwTexWidth;
FLOAT h = (ty2-ty1)*m_dwTexHeight;
w *= (fXScale*vp.Height)/fLineHeight;
h *= (fYScale*vp.Height)/fLineHeight;
if( c != _T(' ') )
{
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx1, ty2 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,sz,rhw), dwColor, tx2, ty1 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
dwNumTriangles += 2;
if( dwNumTriangles*3 > (MAX_NUM_VERTICES-6) )
{
// Unlock, render, and relock the vertex buffer
m_pVB->Unlock();
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
dwNumTriangles = 0L;
}
}
sx += w - (2 * m_dwSpacing) * (fXScale*vp.Height)/fLineHeight;
}
// Unlock and render the vertex buffer
m_pVB->Unlock();
if( dwNumTriangles > 0 )
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
// Restore the modified renderstates
m_pStateBlockSaved->Apply();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DrawText()
// Desc: Draws 2D text. Note that sx and sy are in pixels
//-----------------------------------------------------------------------------
HRESULT CD3DFont::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor,
const TCHAR* strText, DWORD dwFlags )
{
if( m_pd3dDevice == NULL )
return E_FAIL;
// Setup renderstate
m_pStateBlockSaved->Capture();
m_pStateBlockDrawText->Apply();
m_pd3dDevice->SetFVF( D3DFVF_FONT2DVERTEX );
m_pd3dDevice->SetPixelShader( NULL );
m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT2DVERTEX) );
// Set filter states
if( dwFlags & D3DFONT_FILTERED )
{
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
}
// Center the text block in the viewport
if( dwFlags & D3DFONT_CENTERED_X )
{
D3DVIEWPORT9 vp;
m_pd3dDevice->GetViewport( &vp );
const BYTE* strTextTmp = (BYTE*)strText;
float xFinal = 0.0f;
while( *strTextTmp )
{
BYTE c = *(BYTE*)strTextTmp++;
if( c == _T('\n') )
break; // Isn't supported.
if( (c-32) < 0 || (c-32) >= 256-32 )
continue;
FLOAT tx1 = m_fTexCoords[c-32][0];
FLOAT tx2 = m_fTexCoords[c-32][2];
FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
xFinal += w - (2 * m_dwSpacing);
}
sx = (vp.Width-xFinal)/2.0f;
}
if( dwFlags & D3DFONT_CENTERED_Y )
{
D3DVIEWPORT9 vp;
m_pd3dDevice->GetViewport( &vp );
float fLineHeight = ((m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight);
sy = (vp.Height-fLineHeight)/2;
}
// Adjust for character spacing
sx -= m_dwSpacing;
FLOAT fStartX = sx;
// Fill vertex buffer
FONT2DVERTEX* pVertices = NULL;
DWORD dwNumTriangles = 0;
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
while( *strText )
{
BYTE c = *(BYTE*)strText++;
if( c == _T('\n') )
{
sx = fStartX;
sy += (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
}
if( (c-32) < 0 || (c-32) >= 256-32 )
continue;
FLOAT tx1 = m_fTexCoords[c-32][0];
FLOAT ty1 = m_fTexCoords[c-32][1];
FLOAT tx2 = m_fTexCoords[c-32][2];
FLOAT ty2 = m_fTexCoords[c-32][3];
FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
FLOAT h = (ty2-ty1) * m_dwTexHeight / m_fTextScale;
if( c != _T(' ') )
{
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
dwNumTriangles += 2;
if( dwNumTriangles*3 > (MAX_NUM_VERTICES-6) )
{
// Unlock, render, and relock the vertex buffer
m_pVB->Unlock();
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
pVertices = NULL;
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
dwNumTriangles = 0L;
}
}
sx += w - (2 * m_dwSpacing);
}
// Unlock and render the vertex buffer
m_pVB->Unlock();
if( dwNumTriangles > 0 )
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
// Restore the modified renderstates
m_pStateBlockSaved->Apply();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render3DText()
// Desc: Renders 3D text
//-----------------------------------------------------------------------------
HRESULT CD3DFont::Render3DText( const TCHAR* strText, DWORD dwFlags )
{
if( m_pd3dDevice == NULL )
return E_FAIL;
// Setup renderstate
m_pStateBlockSaved->Capture();
m_pStateBlockDrawText->Apply();
m_pd3dDevice->SetFVF( D3DFVF_FONT3DVERTEX );
m_pd3dDevice->SetPixelShader( NULL );
m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT3DVERTEX) );
// Set filter states
if( dwFlags & D3DFONT_FILTERED )
{
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
}
// Position for each text element
FLOAT x = 0.0f;
FLOAT y = 0.0f;
// Center the text block at the origin (not the viewport)
if( dwFlags & D3DFONT_CENTERED_X )
{
SIZE sz;
GetTextExtent( strText, &sz );
x = -(((FLOAT)sz.cx)/10.0f)/2.0f;
}
if( dwFlags & D3DFONT_CENTERED_Y )
{
SIZE sz;
GetTextExtent( strText, &sz );
y = -(((FLOAT)sz.cy)/10.0f)/2.0f;
}
// Turn off culling for two-sided text
if( dwFlags & D3DFONT_TWOSIDED )
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Adjust for character spacing
x -= m_dwSpacing / 10.0f;
FLOAT fStartX = x;
BYTE c;
// Fill vertex buffer
FONT3DVERTEX* pVertices;
DWORD dwNumTriangles = 0L;
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
while( (c = *(BYTE*)strText++) != 0 )
{
if( c == '\n' )
{
x = fStartX;
y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
}
if( (c-32) < 0 || (c-32) >= 256-32 )
continue;
FLOAT tx1 = m_fTexCoords[c-32][0];
FLOAT ty1 = m_fTexCoords[c-32][1];
FLOAT tx2 = m_fTexCoords[c-32][2];
FLOAT ty2 = m_fTexCoords[c-32][3];
FLOAT w = (tx2-tx1) * m_dwTexWidth / ( 10.0f * m_fTextScale );
FLOAT h = (ty2-ty1) * m_dwTexHeight / ( 10.0f * m_fTextScale );
if( c != _T(' ') )
{
*pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+0,0), D3DXVECTOR3(0,0,-1), tx1, ty2 );
*pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
*pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
*pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+h,0), D3DXVECTOR3(0,0,-1), tx2, ty1 );
*pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
*pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
dwNumTriangles += 2;
if( dwNumTriangles*3 > (MAX_NUM_VERTICES-6) )
{
// Unlock, render, and relock the vertex buffer
m_pVB->Unlock();
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
dwNumTriangles = 0L;
}
}
x += w - (2 * m_dwSpacing) / 10.0f;
}
// Unlock and render the vertex buffer
m_pVB->Unlock();
if( dwNumTriangles > 0 )
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
// Restore the modified renderstates
m_pStateBlockSaved->Apply();
return S_OK;
}

311
saco/d3d9/d3dutil.cpp Normal file
View File

@ -0,0 +1,311 @@
//-----------------------------------------------------------------------------
// File: D3DUtil.cpp
//
// Desc: Shortcut macros and functions for using DirectX objects
//
// Copyright (c) Microsoft Corporation. All rights reserved
//-----------------------------------------------------------------------------
#define D3D_OVERLOADS
#include <math.h>
#include "include/D3DUtil.h"
#ifndef _T
#define _T TEXT
#endif
//-----------------------------------------------------------------------------
// Name: D3DUtil_GetDXSDKMediaPath()
// Desc: Returns the DirectX SDK media path, as stored in the system registry
// during the SDK install.
//-----------------------------------------------------------------------------
// MATCH
const TCHAR* D3DUtil_GetDXSDKMediaPath()
{
static TCHAR strNull[2] = _T("");
static TCHAR strPath[MAX_PATH + 20];
HKEY hKey;
DWORD type, size=MAX_PATH;
// Open the appropriate registry key
LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\DirectX SDK"),
0, KEY_READ, &hKey );
if( ERROR_SUCCESS != result )
return strNull;
result = RegQueryValueEx( hKey, _T("DX9S4SDK Samples Path"), NULL,
&type, (BYTE*)strPath, &size );
if( ERROR_SUCCESS != result )
{
result = RegQueryValueEx( hKey, _T("DX81SDK Samples Path"), NULL,
&type, (BYTE*)strPath, &size );
if( ERROR_SUCCESS != result )
{
result = RegQueryValueEx( hKey, _T("DX8SDK Samples Path"), NULL,
&type, (BYTE*)strPath, &size );
if( ERROR_SUCCESS != result )
{
RegCloseKey( hKey );
return strNull;
}
}
}
RegCloseKey( hKey );
lstrcat( strPath, _T("\\D3DIM\\Media\\") );
return strPath;
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_InitSurfaceDesc()
// Desc: Helper function called to build a DDSURFACEDESC2 structure,
// typically before calling CreateSurface() or GetSurfaceDesc()
//-----------------------------------------------------------------------------
// MATCH
VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags,
DWORD dwCaps )
{
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = dwFlags;
ddsd.ddsCaps.dwCaps = dwCaps;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_InitMaterial()
// Desc: Helper function called to build a D3DMATERIAL7 structure
//-----------------------------------------------------------------------------
VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r, FLOAT g, FLOAT b,
FLOAT a )
{
ZeroMemory( &mtrl, sizeof(D3DMATERIAL7) );
mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r;
mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g;
mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b;
mtrl.dcvDiffuse.a = mtrl.dcvAmbient.a = a;
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_InitLight()
// Desc: Initializes a D3DLIGHT7 structure
//-----------------------------------------------------------------------------
VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType,
FLOAT x, FLOAT y, FLOAT z )
{
ZeroMemory( &light, sizeof(D3DLIGHT7) );
light.dltType = ltType;
light.dcvDiffuse.r = 1.0f;
light.dcvDiffuse.g = 1.0f;
light.dcvDiffuse.b = 1.0f;
light.dcvSpecular = light.dcvDiffuse;
light.dvPosition.x = light.dvDirection.x = x;
light.dvPosition.y = light.dvDirection.y = y;
light.dvPosition.z = light.dvDirection.z = z;
light.dvAttenuation0 = 1.0f;
light.dvRange = D3DLIGHT_RANGE_MAX;
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_SetViewMatrix()
// Desc: Given an eye point, a lookat point, and an up vector, this
// function builds a 4x4 view matrix.
//-----------------------------------------------------------------------------
// MATCH
HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom,
D3DVECTOR& vAt, D3DVECTOR& vWorldUp )
{
// Get the z basis vector, which points straight ahead. This is the
// difference from the eyepoint to the lookat point.
D3DVECTOR vView = vAt - vFrom;
FLOAT fLength = Magnitude( vView );
if( fLength < 1e-6f )
return E_INVALIDARG;
// Normalize the z basis vector
vView /= fLength;
// Get the dot product, and calculate the projection of the z basis
// vector onto the up vector. The projection is the y basis vector.
FLOAT fDotProduct = DotProduct( vWorldUp, vView );
D3DVECTOR vUp = vWorldUp - fDotProduct * vView;
// If this vector has near-zero length because the input specified a
// bogus up vector, let's try a default up vector
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
{
vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView;
// If we still have near-zero length, resort to a different axis.
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
{
vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView;
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
return E_INVALIDARG;
}
}
// Normalize the y basis vector
vUp /= fLength;
// The x basis vector is found simply with the cross product of the y
// and z basis vectors
D3DVECTOR vRight = CrossProduct( vUp, vView );
// Start building the matrix. The first three rows contains the basis
// vectors used to rotate the view to point at the lookat point
D3DUtil_SetIdentityMatrix( mat );
mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x;
mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y;
mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z;
// Do the translation values (rotations are still about the eyepoint)
mat._41 = - DotProduct( vFrom, vRight );
mat._42 = - DotProduct( vFrom, vUp );
mat._43 = - DotProduct( vFrom, vView );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_SetProjectionMatrix()
// Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built
// from the field-of-view (fov, in y), aspect ratio, near plane (D),
// and far plane (F). Note that the projection matrix is normalized for
// element [3][4] to be 1.0. This is performed so that W-based range fog
// will work correctly.
//-----------------------------------------------------------------------------
// MATCH
HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect,
FLOAT fNearPlane, FLOAT fFarPlane )
{
if( fabs(fFarPlane-fNearPlane) < 0.01f )
return E_INVALIDARG;
if( fabs(sin(fFOV/2)) < 0.01f )
return E_INVALIDARG;
FLOAT w = fAspect * ( cosf(fFOV/2)/sinf(fFOV/2) );
FLOAT h = 1.0f * ( cosf(fFOV/2)/sinf(fFOV/2) );
FLOAT Q = fFarPlane / ( fFarPlane - fNearPlane );
ZeroMemory( &mat, sizeof(D3DMATRIX) );
mat._11 = w;
mat._22 = h;
mat._33 = Q;
mat._34 = 1.0f;
mat._43 = -Q*fNearPlane;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotateXMatrix()
// Desc: Create Rotation matrix about X axis
//-----------------------------------------------------------------------------
// MATCH
VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads )
{
D3DUtil_SetIdentityMatrix( mat );
mat._22 = cosf( fRads );
mat._23 = sinf( fRads );
mat._32 = -sinf( fRads );
mat._33 = cosf( fRads );
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotateYMatrix()
// Desc: Create Rotation matrix about Y axis
//-----------------------------------------------------------------------------
// MATCH
VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads )
{
D3DUtil_SetIdentityMatrix( mat );
mat._11 = cosf( fRads );
mat._13 = -sinf( fRads );
mat._31 = sinf( fRads );
mat._33 = cosf( fRads );
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotateZMatrix()
// Desc: Create Rotation matrix about Z axis
//-----------------------------------------------------------------------------
// MATCH
VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads )
{
D3DUtil_SetIdentityMatrix( mat );
mat._11 = cosf( fRads );
mat._12 = sinf( fRads );
mat._21 = -sinf( fRads );
mat._22 = cosf( fRads );
}
//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotationMatrix
// Desc: Create a Rotation matrix about vector direction
//-----------------------------------------------------------------------------
// MATCH
VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads )
{
FLOAT fCos = cosf( fRads );
FLOAT fSin = sinf( fRads );
D3DVECTOR v = Normalize( vDir );
mat._11 = ( v.x * v.x ) * ( 1.0f - fCos ) + fCos;
mat._12 = ( v.x * v.y ) * ( 1.0f - fCos ) - (v.z * fSin);
mat._13 = ( v.x * v.z ) * ( 1.0f - fCos ) + (v.y * fSin);
mat._21 = ( v.y * v.x ) * ( 1.0f - fCos ) + (v.z * fSin);
mat._22 = ( v.y * v.y ) * ( 1.0f - fCos ) + fCos ;
mat._23 = ( v.y * v.z ) * ( 1.0f - fCos ) - (v.x * fSin);
mat._31 = ( v.z * v.x ) * ( 1.0f - fCos ) - (v.y * fSin);
mat._32 = ( v.z * v.y ) * ( 1.0f - fCos ) + (v.x * fSin);
mat._33 = ( v.z * v.z ) * ( 1.0f - fCos ) + fCos;
mat._14 = mat._24 = mat._34 = 0.0f;
mat._41 = mat._42 = mat._43 = 0.0f;
mat._44 = 1.0f;
}
//-----------------------------------------------------------------------------
// Name: _DbgOut()
// Desc: Outputs a message to the debug stream
//-----------------------------------------------------------------------------
// MATCH
HRESULT _DbgOut( CHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg )
{
TCHAR buffer[256];
wsprintf( buffer, _T("%hs(%ld): "), strFile, dwLine );
OutputDebugString( buffer );
OutputDebugString( strMsg );
if( hr != (HRESULT) S_OK )
{
wsprintf( buffer, _T("(hr=%08lx)\n"), hr );
OutputDebugString( buffer );
}
OutputDebugString( _T("\n") );
return hr;
}

1381
saco/d3d9/dxutil.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
Changes found:
Changes in:
IDirect3DDevice9Hook::Present
IDirect3DDevice9Hook::Reset
IDirect3DDevice9Hook::CreateDepthStencilSurface
@ -14,6 +14,8 @@
extern IDirect3DDevice9 *pD3DDevice;
D3DXMATRIX matView, matProj, matWorld;
extern void d3d9DestroyDeviceObjects();
extern void d3d9RestoreDeviceObjects();
//-------------------------------------------
@ -106,9 +108,25 @@ UINT __stdcall IDirect3DDevice9Hook::GetNumberOfSwapChains()
HRESULT __stdcall IDirect3DDevice9Hook::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters)
{
// TODO: IDirect3DDevice9Hook::Reset
d3d9DestroyDeviceObjects();
return pD3DDevice->Reset(pPresentationParameters);
/*
// Done through ALT+ENTER now
if (tSettings.bWindowedMode) {
pPresentationParameters->Windowed = 1;
pPresentationParameters->Flags = 0;
SetWindowPos(pPresentationParameters->hDeviceWindow, HWND_NOTOPMOST, 0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight, SWP_SHOWWINDOW);
}
*/
HRESULT hr = pD3DDevice->Reset(pPresentationParameters);
if (SUCCEEDED(hr))
{
d3d9RestoreDeviceObjects();
}
return hr;
}
HRESULT __stdcall IDirect3DDevice9Hook::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer)
@ -240,6 +258,7 @@ HRESULT __stdcall IDirect3DDevice9Hook::EndScene()
HRESULT __stdcall IDirect3DDevice9Hook::Clear(DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil)
{
// +172
return pD3DDevice->Clear(Count, pRects, Flags, Color, Z, Stencil);
}

201
saco/events.cpp Normal file
View File

@ -0,0 +1,201 @@
#include "main.h"
#include "game/util.h"
extern CNetGame *pNetGame;
extern CGame *pGame;
#define NUDE void _declspec(naked)
DWORD dwParams[4];
#define EVENT_TYPE_PAINTJOB 1
#define EVENT_TYPE_CARCOMPONENT 2
#define EVENT_TYPE_CARCOLOR 3
#define EVENT_ENTEREXIT_MODSHOP 4
extern BOOL bFirstSpawn;
//----------------------------------------------------------
void ProcessIncommingEvent(PLAYERID playerId, int iEventType, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
CVehicle *pVehicle;
if(!pNetGame) return;
if(bFirstSpawn) return; // Local player has never spawned.
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
if(!pPlayerPool) return;
if(!pVehiclePool) return;
switch(iEventType) {
case EVENT_TYPE_PAINTJOB:
pVehicle = pVehiclePool->GetAt(dwParam1);
if(pVehicle) pVehicle->SetPaintJob(dwParam2);
break;
case EVENT_TYPE_CARCOMPONENT:
pVehicle = pVehiclePool->GetAt(dwParam1);
if(pVehicle) pVehicle->AddComponent(dwParam2);
break;
case EVENT_TYPE_CARCOLOR:
pVehicle = pVehiclePool->GetAt(dwParam1);
if(pVehicle) pVehicle->SetColor(dwParam2,dwParam3);
break;
case EVENT_ENTEREXIT_MODSHOP:
if(playerId > MAX_PLAYERS) return;
break;
}
// TODO: ProcessIncommingEvent
}
//----------------------------------------------------------
VOID ProcessOutgoingEvent(DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, int iEventType)
{
if(!pNetGame) return;
int iVehicleID;
CVehicle *pVehicle;
VEHICLE_TYPE *pVehiclePtr;
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
RakNet::BitStream bsSend;
switch(iEventType) {
case EVENT_TYPE_PAINTJOB:
iVehicleID = pVehiclePool->FindIDFromGtaPtr(GamePool_Vehicle_GetAt(dwParam1));
if(iVehicleID != INVALID_VEHICLE_ID) {
bsSend.Write(iVehicleID);
bsSend.Write(dwParam2);
bsSend.Write(dwParam3);
bsSend.Write(iEventType);
pNetGame->GetRakClient()->RPC(RPC_ScmEvent,&bsSend,HIGH_PRIORITY,RELIABLE_SEQUENCED,0,false);
}
break;
case EVENT_TYPE_CARCOMPONENT:
iVehicleID = pVehiclePool->FindIDFromGtaPtr(GamePool_Vehicle_GetAt(dwParam1));
if(iVehicleID != INVALID_VEHICLE_ID) {
bsSend.Write(iVehicleID);
bsSend.Write(dwParam2);
bsSend.Write(dwParam3);
bsSend.Write(iEventType);
pNetGame->GetRakClient()->RPC(RPC_ScmEvent,&bsSend,HIGH_PRIORITY,RELIABLE_SEQUENCED,0,false);
}
break;
case EVENT_TYPE_CARCOLOR:
iVehicleID = pVehiclePool->FindIDFromGtaPtr(GamePool_Vehicle_GetAt(dwParam1));
if(iVehicleID != INVALID_VEHICLE_ID) {
bsSend.Write(iVehicleID);
bsSend.Write(dwParam2);
bsSend.Write(dwParam3);
bsSend.Write(iEventType);
pNetGame->GetRakClient()->RPC(RPC_ScmEvent,&bsSend,HIGH_PRIORITY,RELIABLE_SEQUENCED,0,false);
pVehicle = pVehiclePool->GetAt(iVehicleID);
if(pVehicle) {
pVehicle->SetColor(dwParam2,dwParam3);
}
}
break;
case EVENT_ENTEREXIT_MODSHOP:
iVehicleID = pVehiclePool->FindIDFromGtaPtr(GamePool_Vehicle_GetAt(dwParam1));
pVehicle = pVehiclePool->GetAt(iVehicleID);
if(iVehicleID != INVALID_VEHICLE_ID) {
bsSend.Write(iVehicleID);
bsSend.Write(dwParam2);
bsSend.Write(dwParam3);
bsSend.Write(iEventType);
pNetGame->GetRakClient()->RPC(RPC_ScmEvent,&bsSend,HIGH_PRIORITY,RELIABLE_SEQUENCED,0,false);
if(pVehicle) {
pVehiclePtr = pVehicle->m_pVehicle;
if(pVehiclePtr) {
if(dwParam2 == 0) {
pVehicle->SetColor(pVehiclePtr->byteColor1,pVehiclePtr->byteColor2);
pVehicle->field_71 = 0;
} else {
pVehicle->field_71 = 1;
}
}
pVehicle->SetColor(dwParam2,dwParam3);
}
}
break;
}
}
//----------------------------------------------------------
NUDE SetEventCustomOpcode()
{
_asm pushad
_asm push 4
_asm mov ecx, esi
_asm mov ebx, 0x464080 // CRunningScript::CollectParamaters()
_asm call ebx
dwParams[1] = *(PDWORD)0xA43C7C;
dwParams[2] = *(PDWORD)0xA43C80;
dwParams[3] = *(PDWORD)0xA43C84;
dwParams[0] = *(PDWORD)0xA43C78;
ProcessOutgoingEvent(dwParams[1],dwParams[2],dwParams[3],dwParams[0]);
_asm popad
_asm mov ebx, 0x47BF2B // return to ProcessCommands2500To2600
_asm jmp ebx
}
//----------------------------------------------------------
int IsDriving;
DWORD ScmInst;
CPlayerPed *pDriverPed;
NUDE PlayerDriverCustomOpcode()
{
_asm pushad
_asm mov ScmInst, esi
IsDriving = 1;
if(pGame) {
pDriverPed = pGame->FindPlayerPed();
if(pDriverPed->IsInVehicle() && !pDriverPed->IsAPassenger()) {
IsDriving = 0;
}
}
_asm push IsDriving
_asm mov ecx, ScmInst
_asm mov ebx, 0x4859D0 // CRunningScript::UpdateCompareFlag
_asm call ebx
_asm popad
_asm mov ebx, 0x47BF2B // return to ProcessCommands2500To2600
_asm jmp ebx
}
//----------------------------------------------------------
void InstallSCMEventsProcessor()
{
*(DWORD *)0x47BF54 = (DWORD)SetEventCustomOpcode; // opcode 09C6 - 2502
*(DWORD *)0x47BF88 = (DWORD)PlayerDriverCustomOpcode; // opcode 09D3 - 2515
}
//----------------------------------------------------------

View File

@ -27,13 +27,13 @@ int dword_10125A58=0;
void DumpNetworkStateInformation(PCHAR sz)
{
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
PLAYERID playerId=0;
sz[0] = '\0';
sprintf(sz,"\r\nState Information: Ped Context: %u\r\n",*pbyteCurrentPlayer);
// TODO: DumpNetworkStateInformation 10060160
}
//----------------------------------------------------

229
saco/game/actorped.cpp Normal file
View File

@ -0,0 +1,229 @@
#include "../main.h"
#include "game.h"
#include "util.h"
extern CGame *pGame;
//-----------------------------------------------------------
// This is the constructor for creating new player.
CActorPed::CActorPed(int iSkin, float fX, float fY,float fZ,float fRotation)
{
m_pPed=0;
m_dwGTAId=0;
m_byteImmune=0;
int iCounter=0;
DWORD dwActorID=0;
if(!pGame->IsModelLoaded(iSkin)) {
pGame->RequestModel(iSkin);
pGame->LoadRequestedModels();
while(!pGame->IsModelLoaded(iSkin)) Sleep(1);
}
ScriptCommand(&create_actor,5,iSkin,fX,fY,fZ-1.0f,&dwActorID);
ScriptCommand(&set_actor_z_angle,dwActorID,fRotation);
m_dwGTAId = dwActorID;
m_pPed = GamePool_Ped_GetAt(m_dwGTAId);
m_pEntity = (ENTITY_TYPE *)m_pPed;
ScriptCommand(&set_actor_can_be_decapitated,m_dwGTAId,0);
ScriptCommand(&set_actor_dicision,m_dwGTAId,65542);
}
//-----------------------------------------------------------
CActorPed::~CActorPed()
{
Destroy();
}
//-----------------------------------------------------------
void CActorPed::Destroy()
{
DWORD dwPedPtr = (DWORD)m_pPed;
// If it points to the CPlaceable vtable it's not valid
if(!m_pPed || !GamePool_Ped_GetAt(m_dwGTAId) || m_pPed->entity.vtable == 0x863C40)
{
m_pPed = NULL;
m_pEntity = NULL;
m_dwGTAId = 0;
return;
}
// DESTROY METHOD
_asm mov ecx, dwPedPtr
_asm mov ebx, [ecx] ; vtable
_asm push 1
_asm call [ebx] ; destroy
m_pPed = NULL;
m_pEntity = NULL;
}
//-----------------------------------------------------------
void CActorPed::ApplyAnimation( char *szAnimName, char *szAnimFile, float fT,
int opt1, int opt2, int opt3, int opt4, int iUnk )
{
int iWaitAnimLoad=0;
if(!m_pPed) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
// Can't allow 'naughty' anims!
if( !stricmp(szAnimFile,"SEX") )
return;
if (!pGame->IsAnimationLoaded(szAnimFile)) {
pGame->RequestAnimation(szAnimFile);
while(!pGame->IsAnimationLoaded(szAnimFile)) {
Sleep(1);
iWaitAnimLoad++;
if(iWaitAnimLoad == 15) return; // we can't wait forever
}
}
ScriptCommand(&apply_animation,m_dwGTAId,szAnimName,szAnimFile,fT,opt1,opt2,opt3,opt4,iUnk);
}
//-----------------------------------------------------------
DWORD dwActorPed=0;
BOOL __declspec(naked) FlushPedIntelligence()
{
_asm mov edx, dwActorPed
_asm mov ecx, [edx+0x47C]
_asm push 1
_asm mov eax, 0x601640
_asm call eax
_asm mov eax, 1
_asm ret
}
void CActorPed::ClearAnimations()
{
dwActorPed = (DWORD)m_pPed;
if(dwActorPed) {
FlushPedIntelligence();
}
}
//-----------------------------------------------------------
void CActorPed::SetTargetRotation(float fRotation)
{
if(!m_pPed) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
m_pPed->fRotation2 = DegToRad(fRotation);
}
//-----------------------------------------------------------
float CActorPed::GetHealth()
{
if(!m_pPed) return 0.0f;
return m_pPed->fHealth;
}
//-----------------------------------------------------------
void CActorPed::SetHealth(float fHealth)
{
if(!m_pPed) return;
m_pPed->fHealth = fHealth;
if(m_pPed->fHealth <= 0.0f) {
ScriptCommand(&kill_actor,m_dwGTAId);
}
}
//-----------------------------------------------------------
float CActorPed::GetArmour()
{
if(!m_pPed) return 0.0f;
return m_pPed->fArmour;
}
//-----------------------------------------------------------
void CActorPed::SetArmour(float fArmour)
{
if(!m_pPed) return;
m_pPed->fArmour = fArmour;
}
//-----------------------------------------------------------
DWORD CActorPed::GetStateFlags()
{
if(!m_pPed) return 0;
return m_pPed->dwStateFlags;
}
//-----------------------------------------------------------
void CActorPed::SetStateFlags(DWORD dwState)
{
if(!m_pPed) return;
m_pPed->dwStateFlags = dwState;
}
//-----------------------------------------------------------
BOOL CActorPed::IsDead()
{
if(!m_pPed) return TRUE;
if(m_pPed->fHealth > 0.0f) return FALSE;
return TRUE;
}
//-----------------------------------------------------------
BYTE CActorPed::GetActionTrigger()
{
return (BYTE)m_pPed->dwAction;
}
//-----------------------------------------------------------
void CActorPed::SetActionTrigger(BYTE byteTrigger)
{
if(!m_pPed) return;
m_pPed->dwAction = byteTrigger;
}
//-----------------------------------------------------------
BOOL CActorPed::IsInVehicle()
{
if(!m_pPed) return FALSE;
if(IN_VEHICLE(m_pPed)) {
return TRUE;
}
return FALSE;
}
//-----------------------------------------------------------
void CActorPed::ToggleImmunity(BYTE byteEnable)
{
if(!m_pPed) return;
m_byteImmune = byteEnable;
if(byteEnable)
ScriptCommand(&set_actor_immunities,m_dwGTAId,1,1,1,1,1);
else
ScriptCommand(&set_actor_immunities,m_dwGTAId,0,0,0,1,0);
}
//-----------------------------------------------------------

43
saco/game/actorped.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
//-----------------------------------------------------------
class CActorPed : public CEntity
{
public:
// Constructor/Destructor.
CActorPed(int iSkin, float fPosX, float fPosY, float fPosZ, float fRotation = 0.0f);
virtual ~CActorPed();
void Destroy();
void SetTargetRotation(float fRotation);
float GetHealth();
void SetHealth(float fHealth);
float GetArmour();
void SetArmour(float fArmour);
DWORD GetStateFlags();
void SetStateFlags(DWORD dwStateFlags);
BOOL IsDead();
BYTE GetActionTrigger();
void SetActionTrigger(BYTE byteTrigger);
BOOL IsInVehicle();
void ApplyAnimation(char *szAnimName, char *szAnimFile, float fT,
int opt1, int opt2, int opt3, int opt4, int iUnk);
void ClearAnimations();
void ToggleImmunity(BYTE byteEnable);
PED_TYPE * GetGtaActor() { return m_pPed; };
PED_TYPE *m_pPed;
DWORD m_dwMarkerID;
DWORD m_dwArrow;
BYTE m_byteCreateMarker;
BYTE m_byteImmune;
};
//-----------------------------------------------------------

View File

@ -22,6 +22,7 @@
#define ADDR_ENABLE_HUD 0xBA6769
//#define ADDR_ID_FROM_ACTOR 0x451CF0
#define ADDR_ID_FROM_ACTOR 0x4442D0
#define ADDR_ACTOR_FROM_ID 0x404910 // Converts id to actor ptr
#define ADDR_PED_TABLE 0xB74490 // Contains ptr to actor/ped table

View File

@ -232,7 +232,6 @@ void __stdcall GameResetLocalPlayerWeaponSkills()
pfStats[78] = 999.0f; // m4
pfStats[79] = 999.0f; // sniper
GameStoreLocalPlayerWeaponSkills();
}

View File

@ -1,5 +1,6 @@
#include "../main.h"
#include "../runutil.h"
#include "util.h"
DWORD dwAnimNameHashes[1812];
@ -1819,6 +1820,35 @@ char szAnimNames[1812][36] = {
"SAMP:FISHINGIDLE", // (1811)
};
short GetAnimIndexByName(char *szAnimLib, char *szAnimName)
{
short j = 0;
if(!szAnimLib || !szAnimName) return -1;
if(strlen(szAnimLib) + strlen(szAnimName) > 36) return -1;
char szSearch[40];
sprintf(szSearch, "%s:%s", szAnimLib, szAnimName);
Util_strupr(szSearch);
int i = 0;
while(j != 1812) {
if(!strcmp(szSearch, szAnimNames[i])) {
return j + 1;
}
i++;
j++;
}
return -1;
}
char *GetAnimNameByIndex(short index)
{
if(index > 1812 || index < 1) return NULL;
return szAnimNames[index];
}
void InitAnimNameHashes()
{
char szAnimLib[32];
@ -1840,3 +1870,15 @@ void InitAnimNameHashes()
}
}
short GetAnimIndexByHash(DWORD dwAnimHash)
{
short x = 0;
while(x != 1812) {
if(dwAnimNameHashes[x] == dwAnimHash) {
return x;
}
x++;
}
return -1;
}

View File

@ -2,7 +2,7 @@
#include "game.h"
//-----------------------------------------------------------
// MATCH
void CAudio::FUNC_100A21D0()
{
if(field_0 && field_0 == 1)
@ -16,7 +16,7 @@ void CAudio::FUNC_100A21D0()
}
//-----------------------------------------------------------
// MATCH
int CAudio::GetRadioStation()
{
int iRadioStation = 0;
@ -32,7 +32,7 @@ int CAudio::GetRadioStation()
}
//-----------------------------------------------------------
// MATCH
void CAudio::StartRadio(int iStation)
{
_asm push 0
@ -43,7 +43,7 @@ void CAudio::StartRadio(int iStation)
}
//-----------------------------------------------------------
// MATCH
void CAudio::StopRadio()
{
_asm push 0
@ -54,14 +54,14 @@ void CAudio::StopRadio()
}
//-----------------------------------------------------------
// MATCH
float CAudio::GetRadioVolume()
{
return *(float*)0xB5FCC8;
}
//-----------------------------------------------------------
// MATCH
void CAudio::StopOutdoorAmbienceTrack()
{
_asm mov ecx, 0x8AC15C
@ -70,7 +70,7 @@ void CAudio::StopOutdoorAmbienceTrack()
}
//-----------------------------------------------------------
// MATCH
void CAudio::SetOutdoorAmbienceTrack(int iTrack)
{
_asm push iTrack
@ -80,7 +80,7 @@ void CAudio::SetOutdoorAmbienceTrack(int iTrack)
}
//-----------------------------------------------------------
// MATCH
void CAudio::PlaySound(int iSound, float fX, float fY, float fZ)
{
if(iSound == 0)
@ -114,7 +114,7 @@ void CAudio::PlaySound(int iSound, float fX, float fY, float fZ)
}
//-----------------------------------------------------------
// MATCH
bool CAudio::IsOutdoorAmbienceTrackDisabled()
{
return field_4;

View File

@ -58,6 +58,7 @@ typedef struct _MATRIX4X4 {
#define IN_VEHICLE(x) ((x->dwStateFlags & 256) >> 8)
//-----------------------------------------------------------
#pragma pack(1)
typedef struct _WEAPON_SLOT_TYPE
{
DWORD dwType;
@ -70,11 +71,24 @@ typedef struct _WEAPON_SLOT_TYPE
} WEAPON_SLOT_TYPE; // MUST BE EXACTLY ALIGNED TO 28 bytes
//-----------------------------------------------------------
#pragma pack(1)
typedef struct _PED_TASKS_TYPE
{
char _gap0[16];
DWORD * pdwPed;
// Basic Tasks
DWORD * pdwDamage;
DWORD * pdwFallEnterExit;
DWORD * pdwSwimWasted;
DWORD * pdwJumpJetPack;
DWORD * pdwAction;
// Extended Tasks
DWORD * pdwFighting;
DWORD * pdwCrouching;
DWORD * pdwSay;
DWORD * pdwFacialComplex;
DWORD * pdwPartialAnim;
DWORD * pdwIK;
} PED_TASKS_TYPE;
//-----------------------------------------------------------
@ -88,8 +102,8 @@ typedef struct _ENTITY_TYPE
MATRIX4X4 *mat; // 20-24
DWORD *pdwRenderWare; // 24-28
char _gap1C[6];
DWORD dwProcessingFlags; // 28-32
char _gap20[2];
WORD nModelIndex; // 34-36
@ -117,6 +131,7 @@ typedef struct _PED_TYPE
PED_TASKS_TYPE *Tasks; // 1148-1152
DWORD dwPlayerInfoOffset; // 1152-1156
char _gap484[124];
DWORD dwActiveVision; // 1280-1284
@ -138,7 +153,15 @@ typedef struct _PED_TYPE
float fRotation1; // 1368-1372
float fRotation2; // 1372-1376
char _gap560[44];
char _gap560[8];
DWORD pContactVehicle; // 1384 - 1388
char _gap56C[24];
DWORD pContactEntity; // 1412 - 1416
char _gap588[4];
DWORD pVehicle; // 1420-1424
@ -154,6 +177,10 @@ typedef struct _PED_TYPE
BYTE byteCurWeaponSlot; // 1816-1817
char _gap719[20];
BYTE byteFightingStyle; // 1837-1838
} PED_TYPE;
//-----------------------------------------------------------
@ -230,7 +257,12 @@ typedef struct _VEHICLE_TYPE
};
};
char _pad5BA[162];
char _gap5BA[142];
float fBikeBankingAngle1; // 1608-1612
float fBikeBankingAngle2; // 1612-1616
char _gap650[12];
BYTE bBikeWheelPopped[2]; // 1628-1630

201
saco/game/debug.cpp Normal file
View File

@ -0,0 +1,201 @@
#include "../main.h"
#include "keystuff.h"
extern CChatWindow *pChatWindow;
extern CGame *pGame;
int iGameDebugType=0;
DWORD dwDebugEntity1=0;
DWORD dwDebugEntity2=0;
//----------------------------------------------------------
// Switches on the debug screen for debugging raw vehicles/actors
// MATCH
void GameDebugEntity(DWORD dwEnt1, DWORD dwEnt2, int type)
{
iGameDebugType=type;
dwDebugEntity1=dwEnt1;
dwDebugEntity2=dwEnt2;
}
//----------------------------------------------------------
// Switches off any driver debug screen or sync sequence
// MATCH
void GameDebugScreensOff()
{
iGameDebugType=0;
}
//----------------------------------------------------------
BOOL bSelVehicleInit=FALSE;
CVehicle *pVehicle=NULL;
int iSelection = 400;
GTA_CONTROLSET *pControls;
CCamera *pCam;
void GameBuildRecreateVehicle()
{
if(pVehicle) delete pVehicle;
pVehicle = pGame->NewVehicle(iSelection,5.0f,5.0f,500.0f,0.0f,NULL);
}
void GameBuildSelectVehicle()
{
if(!bSelVehicleInit) {
pControls = GameGetInternalKeys();
pCam = pGame->GetCamera();
pCam->SetPosition(-4.0f,-4.0f,502.0f,0.0f,0.0f,0.0f);
pCam->LookAtPoint(5.0f,5.0f,500.0f,1);
pGame->FindPlayerPed()->TogglePlayerControllable(0);
pGame->DisplayGameText("Vehicle Select",4000,6);
GameBuildRecreateVehicle();
bSelVehicleInit = TRUE;
}
pGame->DisplayHud(FALSE);
if(pVehicle && pVehicle->m_pEntity) {
VECTOR vecTurn = { 0.0f, 0.0f, 0.03f };
VECTOR vecMove = { 0.0f, 0.0f, 0.0f };
pVehicle->SetTurnSpeedVector(vecTurn);
pVehicle->SetMoveSpeedVector(vecMove);
MATRIX4X4 mat;
pVehicle->GetMatrix(&mat);
mat.pos.X = 5.0f;
mat.pos.Y = 5.0f;
mat.pos.Z = 500.0f;
pVehicle->SetMatrix(mat);
}
if(pControls->wKeys1[14] && !pControls->wKeys2[14]) {
iSelection--;
if(iSelection==538) iSelection-=2; // trains
if(iSelection==399) iSelection=611;
GameBuildRecreateVehicle();
return;
}
if(pControls->wKeys1[16] && !pControls->wKeys2[16]) {
iSelection++;
if(iSelection==537) iSelection+=2; // trains
if(iSelection==612) iSelection=400;
GameBuildRecreateVehicle();
return;
}
if(pControls->wKeys1[15] && !pControls->wKeys2[15]) {
delete pVehicle;
pVehicle = NULL;
pCam->SetBehindPlayer();
GameDebugEntity(0,0,0);
// place this vehicle near the player.
CPlayerPed *pPlayer = pGame->FindPlayerPed();
if(pPlayer)
{
MATRIX4X4 matPlayer;
pPlayer->GetMatrix(&matPlayer);
CHAR blank[9] = "";
sprintf(blank, "TYPE_%d", iSelection);
CVehicle *pTestVehicle = pGame->NewVehicle(iSelection,
(matPlayer.pos.X - 5.0f), (matPlayer.pos.Y - 5.0f),
matPlayer.pos.Z+1.0f,0.0f,NULL);
if(pTestVehicle) {
pPlayer->PutDirectlyInVehicle(pTestVehicle->m_dwGTAId,0);
}
}
pCam->Restore();
pCam->SetBehindPlayer();
pGame->FindPlayerPed()->TogglePlayerControllable(1);
pGame->DisplayHud(TRUE);
bSelVehicleInit=FALSE;
return;
}
}
//----------------------------------------------------------
VECTOR vecSpawnPoint;
CObjectPool *pObjectPool=NULL;
// MATCH
char* GetFunctionParams(char *szScriptLine)
{
char *szParamsStart = strchr(szScriptLine, '(');
char *szParamsEnd = strchr(szScriptLine, ')');
if(szParamsStart && szParamsEnd)
{
strncpy(szScriptLine, szParamsStart + 1, szParamsEnd - szParamsStart - 1);
szScriptLine[szParamsEnd - szParamsStart] = 0;
return szScriptLine;
}
return NULL;
}
void GameDebugProcessScriptLine(char *szScriptLine)
{
if(!strncmp(szScriptLine, "CreateObject", 12))
{
}
else if(!strncmp(szScriptLine, "CreateVehicle", 13) || !strncmp(szScriptLine, "AddStaticVehicle", 16))
{
}
else if (!strncmp(szScriptLine, "SetPlayerCameraPos", 18))
{
}
else if(!strncmp(szScriptLine, "SetPlayerCameraLookAt", 21))
{
}
else if(!strncmp(szScriptLine, "RemoveBuildingForPlayer", 23))
{
}
else if (!strncmp(szScriptLine, "SetPlayerInterior", 17))
{
}
}
void GameDebugLoadScript(char *szFileName)
{
pGame->SetWorldTime(12, 0);
pChatWindow->AddDebugMessage("DEBUGSCRIPT: Loading %s", szFileName);
pObjectPool = new CObjectPool();
FILE *pScriptFile = fopen(szFileName, "r");
if(pScriptFile) {
while(!feof(pScriptFile)) {
char szScriptLine[257];
fgets(szScriptLine,256,pScriptFile);
GameDebugProcessScriptLine(szScriptLine);
}
fclose(pScriptFile);
CPlayerPed *pPlayerPed = pGame->FindPlayerPed();
if(pPlayerPed) {
pPlayerPed->TeleportTo(vecSpawnPoint.X, vecSpawnPoint.Y, vecSpawnPoint.Z);
}
} else {
pChatWindow->AddDebugMessage("DEBUGSCRIPT: I can't open %s", szFileName);
}
}
//----------------------------------------------------------

0
saco/game/debug.h Normal file
View File

View File

@ -12,7 +12,7 @@ extern CNetGame *pNetGame;
extern CChatWindow *pChatWindow;
//-----------------------------------------------------------
// MATCH
void CEntity::GetMatrix(PMATRIX4X4 Matrix)
{
if (!m_pEntity || !m_pEntity->mat) return;
@ -35,7 +35,7 @@ void CEntity::GetMatrix(PMATRIX4X4 Matrix)
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetMatrix(MATRIX4X4 Matrix)
{
if (!m_pEntity || !m_pEntity->mat) return;
@ -59,32 +59,36 @@ void CEntity::SetMatrix(MATRIX4X4 Matrix)
//-----------------------------------------------------------
void CEntity::FUNC_1009EC80()
void CEntity::UpdateRwMatrixAndFrame()
{
if(!m_pEntity || m_pEntity->vtable == 0x863C40) return;
if(!m_pEntity) return;
if(m_pEntity->vtable == 0x863C40) return;
if(!m_pEntity) return;
DWORD dwRenderWare = (DWORD)m_pEntity->pdwRenderWare;
DWORD dwMatrix = (DWORD)m_pEntity->mat;
DWORD dwEntity = (DWORD)m_pEntity;
if(dwEntity && dwRenderWare && dwMatrix)
{
_asm mov edx, dwRenderWare
_asm mov eax, [edx+4]
_asm add eax, 16
_asm push eax
_asm mov ecx, dwMatrix
_asm mov edx, 0x59AD70
_asm call edx
if(!m_pEntity) return;
if(!m_pEntity->pdwRenderWare) return;
if(!m_pEntity->mat) return;
_asm mov ecx, dwEntity
_asm mov edx, 0x532B00
_asm call edx
}
_asm mov edx, dwRenderWare
_asm mov eax, [edx+4]
_asm add eax, 16
_asm push eax
_asm mov ecx, dwMatrix
_asm mov edx, 0x59AD70 ; CMatrix__UpdateRwMatrix
_asm call edx
_asm mov ecx, dwEntity
_asm mov edx, 0x532B00 ; CEntity__UpdateRwFrame
_asm call edx
}
//-----------------------------------------------------------
// MATCH
void CEntity::GetMoveSpeedVector(PVECTOR Vector)
{
Vector->X = m_pEntity->vecMoveSpeed.X;
@ -93,7 +97,7 @@ void CEntity::GetMoveSpeedVector(PVECTOR Vector)
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetMoveSpeedVector(VECTOR Vector)
{
m_pEntity->vecMoveSpeed.X = Vector.X;
@ -117,16 +121,58 @@ void CEntity::FUNC_1009ED40(float fX, float fY, float fZ)
field_4[4].Y = fY;
field_4[4].Z = fZ;
m_pEntity->vecMoveSpeed.X =
(field_4[0].X + field_4[1].X + field_4[2].X + field_4[3].X + field_4[4].X) * 0.2f;
m_pEntity->vecMoveSpeed.Y =
(field_4[0].Y + field_4[1].Y + field_4[2].Y + field_4[3].Y + field_4[4].Y) * 0.2f;
m_pEntity->vecMoveSpeed.Z =
(field_4[0].Z + field_4[1].Z + field_4[2].Z + field_4[3].Z + field_4[4].Z) * 0.2f;
fX = field_4[0].X;
fY = field_4[0].Y;
fZ = field_4[0].Z;
fX += field_4[1].X;
fY += field_4[1].Y;
fZ += field_4[1].Z;
fX += field_4[2].X;
fY += field_4[2].Y;
fZ += field_4[2].Z;
fX += field_4[3].X;
fY += field_4[3].Y;
fZ += field_4[3].Z;
fX += field_4[4].X;
fY += field_4[4].Y;
fZ += field_4[4].Z;
fX *= 0.2f;
fY *= 0.2f;
fZ *= 0.2f;
m_pEntity->vecMoveSpeed.X = fX;
m_pEntity->vecMoveSpeed.Y = fY;
m_pEntity->vecMoveSpeed.Z = fZ;
/*fX = field_4[0].X;
fY = field_4[0].Y;
fZ = field_4[0].Z;
fX += field_4[1].X;
fY += field_4[1].Y;
fZ += field_4[1].Z;
fX += field_4[2].X;
fY += field_4[2].Y;
fZ += field_4[2].Z;
float fRX = (field_4[0].X + field_4[1].X + field_4[2].X + field_4[3].X + field_4[4].X) * 0.2f;
float fRY = (field_4[0].Y + field_4[1].Y + field_4[2].Y + field_4[3].Y + field_4[4].Y) * 0.2f;
float fRZ = (field_4[0].Z + field_4[1].Z + field_4[2].Z + field_4[3].Z + field_4[4].Z) * 0.2f;
m_pEntity->vecMoveSpeed.X = fX;
m_pEntity->vecMoveSpeed.Y = fY;
m_pEntity->vecMoveSpeed.Z = fZ;
*/
}
//-----------------------------------------------------------
// MATCH
void CEntity::GetTurnSpeedVector(PVECTOR Vector)
{
Vector->X = m_pEntity->vecTurnSpeed.X;
@ -135,7 +181,7 @@ void CEntity::GetTurnSpeedVector(PVECTOR Vector)
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetTurnSpeedVector(VECTOR Vector)
{
m_pEntity->vecTurnSpeed.X = Vector.X;
@ -144,7 +190,7 @@ void CEntity::SetTurnSpeedVector(VECTOR Vector)
}
//-----------------------------------------------------------
// MATCH
void CEntity::ApplyTurnSpeed()
{
DWORD dwEnt = (DWORD)m_pEntity;
@ -156,7 +202,7 @@ void CEntity::ApplyTurnSpeed()
}
//-----------------------------------------------------------
// MATCH
float CEntity::GetDistanceFromCentreOfMassToBaseOfModel()
{
DWORD dwEnt = (DWORD)m_pEntity;
@ -173,7 +219,7 @@ float CEntity::GetDistanceFromCentreOfMassToBaseOfModel()
}
//-----------------------------------------------------------
// MATCH
void CEntity::GetBoundCentre(PVECTOR Vector)
{
DWORD dwEnt = (DWORD)m_pEntity;
@ -186,7 +232,7 @@ void CEntity::GetBoundCentre(PVECTOR Vector)
}
//-----------------------------------------------------------
// MATCH
void CEntity::GetBoundRect(PFRECT Rect)
{
DWORD dwEnt = (DWORD)m_pEntity;
@ -199,14 +245,57 @@ void CEntity::GetBoundRect(PFRECT Rect)
}
//-----------------------------------------------------------
// MATCH
BOOL CEntity::SetModelIndex(UINT uiModel)
{
if(!m_pEntity) return FALSE;
BOOL bResult=FALSE;
int iCounter=0;
if(!pGame->IsModelLoaded(uiModel) && !GetModelRwObject(uiModel)) {
pGame->RequestModel(uiModel);
pGame->LoadRequestedModels();
while(!pGame->IsModelLoaded(uiModel)) {
Sleep(1);
iCounter++;
if(iCounter>200) {
if(pChatWindow)
pChatWindow->AddDebugMessage("Warning: Model %u wouldn't load in time!", uiModel);
return FALSE;
}
}
bResult = TRUE;
}
DWORD dwThisEntity = (DWORD)m_pEntity;
_asm {
mov esi, dwThisEntity
mov edi, uiModel
mov edx, [esi]
mov ecx, esi
call dword ptr [edx+32] ; destroy RW
mov eax, [esi]
mov edx, edi
push edi
mov ecx, esi
mov word ptr [esi+34], dx
call dword ptr [eax+20] ; SetModelIndex
}
return bResult;
}
//-----------------------------------------------------------
// MATCH
UINT CEntity::GetModelIndex()
{
return m_pEntity->nModelIndex;
}
//-----------------------------------------------------------
// MATCH
void CEntity::TeleportTo(float x, float y, float z)
{
DWORD dwThisEntity = (DWORD)m_pEntity;
@ -229,7 +318,7 @@ void CEntity::TeleportTo(float x, float y, float z)
}
//-----------------------------------------------------------
// MATCH
float CEntity::GetDistanceFromLocalPlayerPed()
{
MATRIX4X4 matFromPlayer;
@ -262,7 +351,7 @@ float CEntity::GetDistanceFromLocalPlayerPed()
}
//-----------------------------------------------------------
// MATCH
float CEntity::GetDistanceFromCamera()
{
if(!m_pEntity || m_pEntity->vtable == 0x863C40) return 100000.0f;
@ -279,7 +368,7 @@ float CEntity::GetDistanceFromCamera()
}
//-----------------------------------------------------------
// MATCH
float CEntity::Get2DDistanceFromLocalPlayerPed()
{
MATRIX4X4 matFromPlayer;
@ -311,7 +400,7 @@ float CEntity::Get2DDistanceFromLocalPlayerPed()
}
//-----------------------------------------------------------
// MATCH
float CEntity::GetDistanceFromPoint(float X, float Y, float Z)
{
MATRIX4X4 matThis;
@ -326,7 +415,7 @@ float CEntity::GetDistanceFromPoint(float X, float Y, float Z)
}
//-----------------------------------------------------------
// MATCH
void CEntity::Add()
{
// Check for CPlaceable messup
@ -362,7 +451,7 @@ void CEntity::Add()
}
//-----------------------------------------------------------
// MATCH
BOOL CEntity::IsAdded()
{
// Check for CPlaceable messup
@ -377,7 +466,7 @@ BOOL CEntity::IsAdded()
}
//-----------------------------------------------------------
// MATCH
void CEntity::Remove()
{
// Check for CPlaceable messup
@ -402,7 +491,7 @@ void CEntity::Remove()
}
//-----------------------------------------------------------
// MATCH
BOOL CEntity::EnforceWorldBoundries(float fPX, float fZX, float fPY, float fNY)
{
MATRIX4X4 matWorld;
@ -464,7 +553,7 @@ BOOL CEntity::EnforceWorldBoundries(float fPX, float fZX, float fPY, float fNY)
}
//-----------------------------------------------------------
// MATCH
BOOL CEntity::HasExceededWorldBoundries(float fPX, float fZX, float fPY, float fNY)
{
MATRIX4X4 matWorld;
@ -489,7 +578,7 @@ BOOL CEntity::HasExceededWorldBoundries(float fPX, float fZX, float fPY, float f
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetCollisionChecking(int iCheck)
{
if(!m_pEntity) return;
@ -503,7 +592,7 @@ void CEntity::SetCollisionChecking(int iCheck)
}
//-----------------------------------------------------------
// MATCH
BOOL CEntity::IsCollisionCheckingEnabled()
{
if(m_pEntity && m_pEntity->vtable != 0x863C40)
@ -514,7 +603,7 @@ BOOL CEntity::IsCollisionCheckingEnabled()
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetGravityProcessing(int iState)
{
if(!m_pEntity) return;
@ -528,7 +617,7 @@ void CEntity::SetGravityProcessing(int iState)
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetWaitingForCollision(int iState)
{
if(!m_pEntity) return;
@ -543,7 +632,7 @@ void CEntity::SetWaitingForCollision(int iState)
}
//-----------------------------------------------------------
// MATCH
void CEntity::DisableStreaming()
{
if(!m_pEntity) return;
@ -553,7 +642,7 @@ void CEntity::DisableStreaming()
}
//-----------------------------------------------------------
// MATCH
void CEntity::EnableTunnelTransition()
{
if(!m_pEntity) return;
@ -563,7 +652,7 @@ void CEntity::EnableTunnelTransition()
}
//-----------------------------------------------------------
// MATCH
void CEntity::SetApplySpeed(int iState)
{
if(!m_pEntity) return;
@ -592,7 +681,7 @@ void CEntity::SetApplySpeed(int iState)
//-----------------------------------------------------------
// MATCH
BOOL CEntity::IsStationary()
{
if (!IsAdded()) return FALSE; // movespeed vectors are invalid if its not added

View File

@ -1,6 +1,8 @@
#pragma once
#include "game.h"
//----------------------------------------------------------
class CEntity
@ -13,7 +15,7 @@ public:
void GetMatrix(PMATRIX4X4 Matrix);
void SetMatrix(MATRIX4X4 Matrix);
void FUNC_1009EC80();
void UpdateRwMatrixAndFrame();
void GetMoveSpeedVector(PVECTOR Vector);
void SetMoveSpeedVector(VECTOR Vector);
void FUNC_1009ED40(float fX, float fY, float fZ); // unused
@ -24,6 +26,7 @@ public:
void GetBoundCentre(PVECTOR Vector);
void GetBoundRect(PFRECT Rect); // unused
UINT GetModelIndex();
BOOL SetModelIndex(UINT uiModel);
void TeleportTo(float x, float y, float z);
float GetDistanceFromLocalPlayerPed();
float GetDistanceFromCamera();

View File

@ -1,5 +1,6 @@
#include "../main.h"
#include "game.h"
#include "util.h"
#include "keystuff.h"
#include "aimstuff.h"
@ -18,15 +19,9 @@ DWORD dwDummyActiveMouseState;
unsigned char *szGameTextMessage;
HWND hWindowHandle;
int unnamed_10150340[210];
BOOL bUsedPlayerSlots[PLAYER_PED_SLOTS];
IDirectInputDevice8 *pDirectInputMouse;
BYTE unnamed_10150688;
int unnamed_1015068C;
float unnamed_10116718 = 2.0f;
BOOL ApplyPreGamePatches();
bool GLOBAL_101506A4;
typedef void (*DrawZone_t)(float *fPos, DWORD *dwColor, BYTE byteMenu);
@ -38,80 +33,77 @@ CGame::CGame()
m_pGameAudio = new CAudio();
m_pGameCamera = new CCamera();
m_pGamePlayer = NULL;
field_4D = 0;
m_bCheckpointsEnabled = FALSE;
m_bRaceCheckpointsEnabled = FALSE;
m_dwRaceCheckpointHandle = NULL;
field_61 = 0;
field_65 = 0;
field_69 = FALSE;
field_6D = 0;
memset(unnamed_10150340, 0, sizeof(unnamed_10150340));
memset(field_6E, 0, sizeof(field_6E));
memset(bUsedPlayerSlots,0,sizeof(BOOL)*PLAYER_PED_SLOTS);
memset(m_byteKeepLoadedVehicles,0,sizeof(BYTE)*212);
field_55 = 0;
field_59 = 1;
field_5D = 90;
}
void CGame::sub_100A0010()
{
int time = (int)RakNet::GetTime();
if(unnamed_1015068C)
{
if((time - unnamed_1015068C) > 30)
{
unnamed_10150688++;
if(unnamed_10150688 == 5)
unnamed_10150688 = 0;
unnamed_1015068C = time;
}
*(BYTE*)0xB7356E = unnamed_10150688;
}
else
{
unnamed_1015068C = time;
}
}
//-----------------------------------------------------------
void unnamed_100A0060(float a1)
{
*(float*)0xB7CB5C = a1;
*(float*)0xB7CB58 = a1;
unnamed_10116718 = a1 * 3.0f;
}
void CGame::sub_100A0090(int a1, int a2)
{
if(a1 && a2 && a1 < 1000 / a2)
Sleep(1000 / a2 - a1 - 1);
}
BYTE CGame::sub_100A00C0()
//-----------------------------------------------------------
BYTE CGame::FindFirstFreePlayerPedSlot()
{
BYTE result = 2;
while(result != 210)
{
if(!unnamed_10150340[result])
return result;
result++;
BYTE x=2;
while(x!=PLAYER_PED_SLOTS) {
if(!bUsedPlayerSlots[x]) return x;
x++;
}
return 0;
}
BYTE CGame::sub_100A00F0()
//-----------------------------------------------------------
//-----------------------------------------------------------
BOOL CGame::DeletePlayer(CPlayerPed *pPlayerPed)
{
BYTE result = 0;
BYTE v1 = 2;
while(v1 != 210)
if(pPlayerPed)
{
if(unnamed_10150340[v1] == 1)
{
result++;
}
v1++;
BYTE bytePlayerNumber = pPlayerPed->m_bytePlayerNumber;
delete pPlayerPed;
bUsedPlayerSlots[bytePlayerNumber] = FALSE;
return TRUE;
}
return result;
return FALSE;
}
//-----------------------------------------------------------
CVehicle *CGame::NewVehicle(int iType, float fPosX, float fPosY,
float fPosZ, float fRotation, int a7)
{
BOOL bKeepModelLoaded=FALSE;
if(m_byteKeepLoadedVehicles[iType-400]) {
bKeepModelLoaded=TRUE;
}
CVehicle *pVehicleNew = new CVehicle(iType,fPosX,fPosY,fPosZ,fRotation,bKeepModelLoaded,a7);
if(pVehicleNew->m_pVehicle) return pVehicleNew;
return NULL;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
@ -146,13 +138,14 @@ float CGame::FindGroundZForCoord(float x, float y, float z)
void DIReleaseMouse()
{
pDirectInputMouse = *(IDirectInputDevice8**)0xC8CFA4;
//SAFE_RELEASE(pDirectInputMouse);
if(pDirectInputMouse) {
pDirectInputMouse->Release();
*(IDirectInputDevice8**)0xC8CFA4 = NULL;
}
}
void DIInitMouse()
{
pDirectInputMouse = *(IDirectInputDevice8**)0xC8CFA4;
@ -165,6 +158,7 @@ void DIInitMouse()
pDirectInputMouse->Acquire();
}
void DIResetMouse()
{
*(DWORD*)0xB73424 = 0;
@ -174,17 +168,16 @@ void DIResetMouse()
_asm call edx
}
void UpdatePads()
{
_asm mov edx, 0x541DD0
_asm call edx
}
void DisableMousePositionUpdate()
{
//*(DWORD*)0xB7340C = 0;
//*(DWORD*)0xB73410 = 0;
//*(DWORD*)0xB73414 = 0;
memset((PVOID)0xB7340C,0,12);
UnFuck(0x53F47A,4);
@ -195,6 +188,7 @@ void DisableMousePositionUpdate()
*(DWORD*)0x53F4B3 = (DWORD)&dwDummyActiveMouseState;
}
void RestoreMousePositionUpdate()
{
UnFuck(0x53F47A,4);
@ -205,6 +199,7 @@ void RestoreMousePositionUpdate()
*(DWORD*)0x53F4B3 = 0xB7340C;
}
void DisableMouseProcess()
{
UnFuck(0x53F417,5);
@ -378,73 +373,12 @@ void CGame::StartGame()
//-----------------------------------------------------------
void CGame::sub_100A0110()
BOOL CGame::IsMenuActive()
{
// TODO: CGame::sub_100A0110() .text:100A0110
if(*(PDWORD)ADDR_MENU) return TRUE;
return FALSE;
}
void CGame::sub_100A0210()
{
// TODO: CGame::sub_100A0210() .text:100A0210
}
void CGame::sub_100A0250()
{
// TODO: CGame::sub_100A0250() .text:100A0250
}
void CGame::sub_100A02E0()
{
// TODO: CGame::sub_100A02E0() .text:100A02E0 (unused)
}
void CGame::sub_100A0310()
{
// TODO: CGame::sub_100A0310() .text:100A0310 (unused)
}
void CGame::sub_100A0330()
{
// TODO: CGame::sub_100A0330() .text:100A0330
}
void CGame::sub_100A1C10()
{
// TODO: CGame::sub_100A1C10() .text:100A1C10
}
//-----------------------------------------------------------
// Return TRUE if the world has been loaded.
@ -458,14 +392,6 @@ BOOL CGame::IsGameLoaded()
void CGame::RequestModel(int iModelID, int iLoadingStream)
{
/*
_asm push iLoadingStream
_asm push iModelID
_asm mov edx, 0x4087E0
_asm call edx
_asm pop edx
_asm pop edx*/
ScriptCommand(&request_model,iModelID);
}
@ -473,12 +399,6 @@ void CGame::RequestModel(int iModelID, int iLoadingStream)
void CGame::LoadRequestedModels()
{
/*
_asm push 0
_asm mov edx, 0x40EA10
_asm call edx
_asm add esp, 4*/
ScriptCommand(&load_requested_models);
}
@ -493,6 +413,13 @@ BOOL CGame::IsModelLoaded(int iModelID)
//-----------------------------------------------------------
void CGame::RemoveModel(int iModelID, bool a2)
{
// TODO: CGame::RemoveModel .text:100A09A0
}
//-----------------------------------------------------------
BOOL CGame::SetModelDeletable(int iModelID)
{
BYTE * pStreamingModelInfo = (BYTE*)(iModelID * 20);
@ -616,7 +543,7 @@ void CGame::SetFrameLimiterOn(BOOL bLimiter)
BOOL CGame::IsFrameLimiterEnabled()
{
if(*(PBYTE)0xBA6794) return TRUE;
if(*(BYTE*)0xBA6794) return TRUE;
return FALSE;
}
@ -698,14 +625,14 @@ void CGame::ToggleRadar(int iToggle)
}
//-----------------------------------------------------------
// MATCH
void CGame::DisplayGameText(char *szStr,int iTime,int iSize)
{
if(iSize > 200) return;
ScriptCommand(&text_clear_all);
memset(szGameTextMessage,0,sizeof(szGameTextMessage)); // not a typo
memset(szGameTextMessage,0,sizeof(szGameTextMessage));
strncpy((char*)szGameTextMessage,szStr,512);
@ -726,6 +653,59 @@ void CGame::DisplayGameText(char *szStr,int iTime,int iSize)
//-----------------------------------------------------------
void CGame::SetCheckpointInformation(VECTOR *pos, VECTOR *extent)
{
memcpy(&m_vecCheckpointPos,pos,sizeof(VECTOR));
memcpy(&m_vecCheckpointExtent,extent,sizeof(VECTOR));
if(m_dwCheckpointMarker) {
DisableMarker(m_dwCheckpointMarker);
m_dwCheckpointMarker = NULL;
DWORD dwMarkerID = 0;
ScriptCommand(&create_radar_marker_without_sphere, m_vecCheckpointPos.X, m_vecCheckpointPos.Y, m_vecCheckpointPos.Z, 0, &dwMarkerID);
ScriptCommand(&set_marker_color, dwMarkerID, 1005);
ScriptCommand(&show_on_radar, dwMarkerID, 3);
m_dwCheckpointMarker = dwMarkerID;
}
}
//-----------------------------------------------------------
void CGame::SetRaceCheckpointInformation(BYTE byteType, VECTOR *pos, VECTOR *next, float fSize) //VECTOR *extent)
{
memcpy(&m_vecRaceCheckpointPos,pos,sizeof(VECTOR));
memcpy(&m_vecRaceCheckpointNext,next,sizeof(VECTOR));
m_fRaceCheckpointSize = fSize;
m_byteRaceType = byteType;
if(m_dwRaceCheckpointMarker)
{
DisableMarker(m_dwRaceCheckpointMarker);
m_dwRaceCheckpointMarker = NULL;
DWORD dwMarkerID = 0;
ScriptCommand(&create_radar_marker_without_sphere, m_vecRaceCheckpointPos.X, m_vecRaceCheckpointPos.Y, m_vecRaceCheckpointPos.Z, 0, &dwMarkerID);
ScriptCommand(&set_marker_color, dwMarkerID, 1005);
ScriptCommand(&show_on_radar, dwMarkerID, 3);
m_dwRaceCheckpointMarker = dwMarkerID;
}
MakeRaceCheckpoint();
}
//-----------------------------------------------------------
void CGame::MakeRaceCheckpoint()
{
DisableRaceCheckpoint();
ScriptCommand(&create_racing_checkpoint, (int)m_byteRaceType,
m_vecRaceCheckpointPos.X, m_vecRaceCheckpointPos.Y, m_vecRaceCheckpointPos.Z,
m_vecRaceCheckpointNext.X, m_vecRaceCheckpointNext.Y, m_vecRaceCheckpointNext.Z,
m_fRaceCheckpointSize, &m_dwRaceCheckpointHandle);
m_bRaceCheckpointsEnabled = true;
}
void CGame::DisableRaceCheckpoint()
{
if (m_dwRaceCheckpointHandle)
@ -738,6 +718,56 @@ void CGame::DisableRaceCheckpoint()
//-----------------------------------------------------------
void CGame::UpdateCheckpoints()
{
DWORD dwMarkerID;
if(m_bCheckpointsEnabled) {
CPlayerPed *pPlayerPed = this->FindPlayerPed();
if(pPlayerPed) {
ScriptCommand(&is_actor_near_point_3d,pPlayerPed->m_dwGTAId,
m_vecCheckpointPos.X,m_vecCheckpointPos.Y,m_vecCheckpointPos.Z,
m_vecCheckpointExtent.X,m_vecCheckpointExtent.Y,m_vecCheckpointExtent.Z,1);
if (!m_dwCheckpointMarker)
{
dwMarkerID = 0;
ScriptCommand(&create_radar_marker_without_sphere,
m_vecCheckpointPos.X, m_vecCheckpointPos.Y, m_vecCheckpointPos.Z, 0, &dwMarkerID);
ScriptCommand(&set_marker_color, dwMarkerID, 1005);
ScriptCommand(&show_on_radar, dwMarkerID, 3);
m_dwCheckpointMarker = dwMarkerID;
}
}
}
else if(m_dwCheckpointMarker) {
DisableMarker(m_dwCheckpointMarker);
m_dwCheckpointMarker = NULL;
}
if(m_bRaceCheckpointsEnabled) {
CPlayerPed *pPlayerPed = this->FindPlayerPed();
if(pPlayerPed)
{
if (!m_dwRaceCheckpointMarker)
{
dwMarkerID = 0;
ScriptCommand(&create_radar_marker_without_sphere,
m_vecRaceCheckpointPos.X,m_vecRaceCheckpointPos.Y,m_vecRaceCheckpointPos.Z,0,&dwMarkerID);
ScriptCommand(&set_marker_color, dwMarkerID, 1005);
ScriptCommand(&show_on_radar, dwMarkerID, 3);
m_dwRaceCheckpointMarker = dwMarkerID;
}
}
}
else if(m_dwRaceCheckpointMarker) {
DisableMarker(m_dwRaceCheckpointMarker);
DisableRaceCheckpoint();
m_dwRaceCheckpointMarker = NULL;
}
}
//-----------------------------------------------------------
DWORD CGame::CreateRadarMarkerIcon(int iMarkerType, float fX, float fY, float fZ, DWORD dwColor, int iStyle)
{
DWORD dwMarkerID=0;
@ -816,6 +846,20 @@ void CGame::AddToLocalMoney(int iAmount)
//-----------------------------------------------------------
void CGame::ResetLocalMoney()
{
int iMoney = GetLocalMoney();
if(!iMoney) return;
if(iMoney < 0) {
AddToLocalMoney(abs(iMoney));
} else {
AddToLocalMoney(-(iMoney));
}
}
//-----------------------------------------------------------
int CGame::GetLocalMoney()
{
return *(int *)0xB7CE50;
@ -921,6 +965,14 @@ const PCHAR CGame::GetWeaponName(int iWeaponID)
//-----------------------------------------------------------
DWORD CGame::CreatePickup(int iModel, int iType, float fX, float fY, float fZ)
{
// TODO: CGame::CreatePickup .text:100A11F0
return 0;
}
//-----------------------------------------------------------
DWORD CGame::CreateWeaponPickup(int iModel, DWORD dwAmmo, float fX, float fY, float fZ)
{
DWORD hnd;
@ -1030,6 +1082,24 @@ void CGame::DrawGangZone(float fPos[], DWORD dwColor)
//-----------------------------------------------------------
void CGame::EnableClock(BYTE byteClock)
{
BYTE byteClockData[] = {'%', '0', '2', 'd', ':', '%', '0', '2', 'd', 0};
UnFuck(0x859A6C,10);
if (byteClock)
{
ToggleThePassingOfTime(1);
memcpy((PVOID)0x859A6C, byteClockData, 10);
}
else
{
ToggleThePassingOfTime(0);
memset((PVOID)0x859A6C,0,10);
}
}
//-----------------------------------------------------------
void CGame::EnableZoneNames(BYTE byteEnable)
{
ScriptCommand(&enable_zone_names, byteEnable);
@ -1113,6 +1183,13 @@ int CGame::GetLoadedVehicleModelCount()
//-----------------------------------------------------------
void CGame::SetRequiredVehicleModels(BYTE *ModelCounts)
{
// TODO: CGame::SetRequiredVehicleModels .text:100A1610
}
//-----------------------------------------------------------
void CGame::SetTimeInMilliseconds(DWORD dwTimeInMs)
{
if(!field_69) {
@ -1137,6 +1214,13 @@ int CGame::GetRwObjectsCount()
//-----------------------------------------------------------
void CGame::FUNC_100A1790(int a1, int a2, BOOL bIncludeVehicle, int iModelID, char a5)
{
// TODO: CGame::FUNC_100A1790 .text:100A1790
}
//-----------------------------------------------------------
void CGame::RequestAnimationsAndModels()
{
if(!IsAnimationLoaded("PARACHUTE"))
@ -1225,3 +1309,11 @@ void CGame::DisableWeaponLockOnTarget()
//-----------------------------------------------------------
void CGame::FUNC_100A1C10()
{
int iTimeNow = (int)RakNet::GetTime();
// TODO: CGame::FUNC_100A1C10() .text:100A1C10
}
//-----------------------------------------------------------

View File

@ -3,50 +3,69 @@
#include "address.h"
#include "common.h"
#include "vehicle.h"
#include "playerped.h"
#include "audio.h"
#include "actorped.h"
#include "object.h"
#include "camera.h"
#include "scripting.h"
#include "menu.h"
#include "textdraw.h"
#include "audio.h"
#include "modelinfo.h"
//-----------------------------------------------------------
class CGame // size: 322
class CGame
{
private:
CAudio *m_pGameAudio;
CCamera *m_pGameCamera;
CPlayerPed *m_pGamePlayer;
char gapC[29];
VECTOR m_vecRaceCheckpointPos;
VECTOR m_vecRaceCheckpointNext;
float m_fRaceCheckpointSize;
BYTE m_byteRaceType;
BOOL m_bRaceCheckpointsEnabled;
char gap2D[4];
DWORD m_dwRaceCheckpointMarker;
DWORD m_dwRaceCheckpointHandle;
char gap35[24];
int field_4D;
char gap51[4];
VECTOR m_vecCheckpointPos;
VECTOR m_vecCheckpointExtent;
BOOL m_bCheckpointsEnabled;
DWORD m_dwCheckpointMarker;
int field_55;
int field_59;
DWORD field_5D;
int field_5D;
int field_61;
int field_65;
BOOL field_69;
char field_6D;
char field_6E[212];
BYTE m_byteKeepLoadedVehicles[212];
public:
BYTE FindFirstFreePlayerPedSlot();
BOOL DeletePlayer(CPlayerPed *pPlayerPed);
CVehicle *NewVehicle(int iType,float fPosX,float fPosY,float fPosZ,float fRotation,int a7);
int GetWeaponModelIDFromWeapon(int iWeaponID);
BOOL IsKeyPressed(int iKeyIdentifier);
float FindGroundZForCoord(float x, float y, float z);
void ToggleKeyInputsDisabled(int a2, BOOL a3);
void StartGame();
void InitGame();
BOOL IsMenuActive();
BOOL IsGameLoaded();
void RequestModel(int iModelID, int iLoadingStream = 2);
void LoadRequestedModels();
BOOL IsModelLoaded(int iModelID);
void RemoveModel(int iModelID, bool a2 = false);
BOOL SetModelDeletable(int iModelID);
void SetWorldTime(int iHour, int iMinute);
@ -69,18 +88,25 @@ public:
void ToggleRadar(int iToggle);
void DisplayGameText(char *szStr,int iTime,int iSize);
void SetGravity(float fGravity);
void EnableClock(BYTE byteClock);
void EnableZoneNames(BYTE byteEnable);
void SetWantedLevel(BYTE byteLevel);
void SetGameTextCount(WORD wCount);
void DrawGangZone(float* fPos, DWORD dwColor);
void EnableStuntBonus(bool bEnable);
void UpdateCheckpoints();
void SetCheckpointInformation(VECTOR *pos, VECTOR *extent);
void MakeRaceCheckpoint();
void DisableRaceCheckpoint();
void SetRaceCheckpointInformation(BYTE byteType, VECTOR *pos, VECTOR *next, float fSize);
DWORD CreateRadarMarkerIcon(int iMarkerType, float fX, float fY, float fZ, DWORD dwColor, int iStyle);
void DisableMarker(DWORD dwMarkerID);
void AddToLocalMoney(int iAmount);
void ResetLocalMoney();
int GetLocalMoney();
BYTE GetActiveInterior();
@ -89,15 +115,13 @@ public:
DWORD GetD3DDevice();
DWORD GetD3D() { return *(DWORD *)ADDR_ID3D9DEVICE; };
HWND GetMainWindowHwnd() { return *(HWND *)ADDR_HWND; };
void RestartEverything();
void ProcessInputDisabling();
//-----------------------------------------------------------
void FUNC_10062570() { field_55++; };
CAudio *GetAudio() { return m_pGameAudio; };
CCamera *GetCamera() { return m_pGameCamera; };
CPlayerPed *FindPlayerPed() {
if(m_pGamePlayer==NULL) m_pGamePlayer = new CPlayerPed();
@ -106,41 +130,36 @@ public:
const PCHAR GetWeaponName(int iWeaponID);
DWORD CreatePickup(int iModel, int iType, float fX, float fY, float fZ);
DWORD CreateWeaponPickup(int iModel, DWORD dwAmmo, float fX, float fY, float fZ);
int GetScreenWidth() { return *(int*)0xC17044; };
int GetScreenHeight() { return *(int*)0xC17048; };
float GetHudVertScale() { return *(float *)0x859524; };
float GetHudHorizScale() { return *(float *)0x859520; };
DWORD GetWeaponInfo(int iWeapon, int iUnk);
void DisableEnterExits();
CGame();
void sub_100A0010();
void sub_100A0090(int a1, int a2);
BYTE sub_100A00C0();
BYTE sub_100A00F0();
void sub_100A0110();
void sub_100A0210();
void sub_100A0250();
void sub_100A02E0();
void sub_100A0310();
void sub_100A0330();
void sub_100A1C10();
void FUNC_10062570() { field_55++; };
void LoadScene(char* szScene);
int GetMemoryUsedForStreaming();
int GetMemoryAvailableForStreaming();
int GetLoadedVehicleModelCount();
void SetRequiredVehicleModels(BYTE *ModelCounts);
void SetTimeInMilliseconds(DWORD dwTimeInMs);
DWORD GetTimeInMilliseconds();
int GetRwObjectsCount();
void FUNC_100A1790(int a1, int a2, BOOL bIncludeVehicle, int iModelID, char a5);
void RequestAnimationsAndModels();
void LoadCollisionFile(char *szFileName);
void LoadCullZone(char *szLine);
BOOL IsUsingController();
void DisableWeaponLockOnTarget();
void FUNC_100A1C10();
};
//-----------------------------------------------------------

View File

@ -1,39 +1,74 @@
#include "../main.h"
#include "game.h"
#include "util.h"
#include "keystuff.h"
#include "aimstuff.h"
extern int iGtaVersion;
extern CNetGame* pNetGame;
extern CGame* pGame;
extern CChatWindow *pChatWindow;
extern DWORD dwGraphicsLoop; // Used for the external dll game loop.
#define NUDE void _declspec(naked)
int WINAPI exc_filter(unsigned int code, struct _EXCEPTION_POINTERS *ep, char *what);
#define NUDE void _declspec(naked)
//-----------------------------------------------------------
// Globals which are used to avoid stack frame alteration
// inside the following hook procedures.
GTA_CONTROLSET *pGcsKeys;
DWORD dwFarClipHookAddr=0;
DWORD dwFarClipReturnAddr=0;
// used generically
PED_TYPE *_pPlayer;
BYTE byteInternalPlayer=0;
DWORD dwCurPlayerActor=0;
BYTE byteCurPlayer=0;
BYTE byteSavedCameraMode;
WORD wSavedCameraMode2;
BYTE *pbyteCameraMode = (BYTE *)0xB6F1A8;
BYTE *pbyteCurrentPlayer = (BYTE *)0xB7CD74;
WORD *wCameraMode2 = (WORD*)0xB6F858;
DWORD *pdwVehicleEnginePed = (DWORD *)0xB6B990;
float fHealth;
float fFarClip=1400.0f;
DWORD unnamed_101516D4;
//-----------------------------------------------------------
// currently unknown where would it be placed
DWORD GLOBAL_101516D4;
WORD wLastRendObj;
CPlayerPool *_pPlayerPool;
WORD wLastRendObj=0;
//-----------------------------------------------------------
// x86 codes to perform our unconditional jmp for detour entries.
BYTE Unk1_JmpCode[] = {0xFF,25,0xD1,0xBE,53,0x00};
BYTE TaskEnterVehicleDriver_HookJmpCode[] = {0xFF,0x25,0xBB,0x19,0x69,0x00,0x90};
BYTE TaskExitVehicle_HookJmpCode[] = {0xFF,0x25,0xBA,0xB8,0x63,0x00,0x90};
BYTE RadarTranslateColor_HookJmpCode[] = {0xFF,0x25,0x79,0x4A,0x58,0x00,0x90};
BYTE CheatProcessHook_JmpCode[] = {0xFF,0x25,0xAA,0x85,0x43,0x00,0x90};
BYTE Unk2_JmpCode[] = {0xFF,0x25,0x33,0x14,0x42,0x00};
BYTE Unk3_JmpCode[] = {0xFF,0x25,0x61,0x36,0x53,0x00,0x90,0x90,0x90};
BYTE CGameShutdown_HookJmpCode[] = {0xFF,0x25,0xF1,0xC8,0x53,0x00,0x90};
BYTE PedDamage_HookJmpCode[] = {0xFF,0x25,0xBC,0x5A,0x4B,0x00};
BYTE Unk4_JmpCode[] = {0xFF,0x25,0x74,0x22,0x50,0x00,0x90,0x90,0x90,0x90};
BYTE Unk5_JmpCode[] = {0xFF,0x25,0x61,0x38,0x4C,0x00};
BYTE GetText_HookJmpCode[] = {0xFF,0x25,0x43,0x00,0x6A,0x00,0x90,0x90,0x90};
BYTE Unk6_JmpCode[] = {0xFF,0x25,0xD8,0xFF,0x5E,0x00,0x90};
BYTE CProjectileInfo_Update_HookJmpCode[] = {0xFF,0x25,0x1B,0x8B,0x73,0x00};
BYTE CWeapon__Satchel__Activate_HookJmpCode[] = {0xFF,0x25,0x5B,0x88,0x73,0x00};
BYTE Unk7_JmpCode[] = {0xFF,0x25,0x36,0xA0,0x63,0x00,0x90};
BYTE Unk8_JmpCode[] = {0xFF,0x25,0x77,0xAB,0x5E,0x00,0x90};
BYTE Unk9_JmpCode[] = {0xFF,0x25,0x39,0x88,0x4C,0x00,0x90,0x90};
BYTE GameProcess_HookJmpCode[] = {0xFF,0x25,0xD1,0xBE,0x53,0x00}; //53BED1
BYTE TaskEnterVehicleDriver_HookJmpCode[] = {0xFF,0x25,0xBB,0x19,0x69,0x00,0x90};//0x6919BB
BYTE TaskExitVehicle_HookJmpCode[] = {0xFF,0x25,0xBA,0xB8,0x63,0x00,0x90};//0x63B8BA
BYTE RadarTranslateColor_HookJmpCode[] = {0xFF,0x25,0x79,0x4A,0x58,0x00,0x90}; // 584A79
BYTE CheatProcessHook_JmpCode[] = {0xFF,0x25,0xAA,0x85,0x43,0x00,0x90}; // 4385AA
BYTE AddVehicleHook_HookJmpCode[] = {0xFF,0x25,0x33,0x14,0x42,0x00}; // 421433
BYTE SetFarClip_HookJmpCode[] = {0xFF,0x25,0x61,0x36,0x53,0x00,0x90,0x90,0x90}; // 533661
BYTE CGameShutdown_HookJmpCode[] = {0xFF,0x25,0xF1,0xC8,0x53,0x00,0x90}; // 53C8F1
BYTE PedDamage_HookJmpCode[] = {0xFF,0x25,0xBC,0x5A,0x4B,0x00}; // 4B5ABC
BYTE VehicleAudio_HookJmpCode[] = {0xFF,0x25,0x74,0x22,0x50,0x00,0x90,0x90,0x90,0x90}; // 502274
BYTE GenTaskAlloc_HookJmpCode[] = {0xFF,0x25,0x61,0x38,0x4C,0x00}; // 4C3861
BYTE GetText_HookJmpCode[] = {0xFF,0x25,0x43,0x00,0x6A,0x00,0x90,0x90,0x90}; // 0x6A004325
BYTE PedSay_HookJmpCode[] = {0xFF,0x25,0xD8,0xFF,0x5E,0x00,0x90}; //5EFFD8
BYTE CProjectileInfo_Update_HookJmpCode[] = {0xFF,0x25,0x1B,0x8B,0x73,0x00}; //00738B1B
BYTE CWeapon__Satchel__Activate_HookJmpCode[] = {0xFF,0x25,0x5B,0x88,0x73,0x00}; // 0073885B
BYTE SetColor_HookJmpCode[] = {0xFF,0x25,0x36,0xA0,0x63,0x00,0x90};
BYTE Rand_HookJmpCode[] = {0xFF,0x25,0x77,0xAB,0x5E,0x00,0x90}; // 5EAB77
BYTE VehicleModel_SetEnvironmentMap_JmpCode[] = {0xFF,0x25,0x39,0x88,0x4C,0x00,0x90,0x90}; // 4C8839
BYTE HOOK_7_JmpCode[] = {0xFF,0x25,0x34,0x39,0x4D,0x00,0x90,0x90,0x90,0x90};
BYTE HOOK_8_JmpCode[] = {0xFF,0x25,0x09,0x46,0x4D,0x00,0x90};
BYTE Unk10_JmpCode[] = {0xFF,0x25,0xE5,0x42,0x4D,0x00,0x90};
@ -48,23 +83,23 @@ BYTE HOOK_60_JmpCode[] = {0xFF,0x25,0xDB,0x74,0x56,0x00};
//-----------------------------------------------------------
// TODO: HOOK_*() functions
NUDE HOOK_1() {}
NUDE HOOK_2() {}
NUDE HOOK_3() {}
NUDE HOOK_4() {}
NUDE CPed_Render_Hook() {}
NUDE HOOK_7() {}
NUDE HOOK_8() {}
NUDE CPlayerPed_ProcessControl_Hook() {}
NUDE HOOK_10() {}
NUDE TaskUseGun_Hook() {}
NUDE HOOK_12() {}
NUDE CPlayerPed_ProcessCollision_Hook() {}
NUDE HOOK_14() {}
NUDE HOOK_15() {}
NUDE AllVehicles_ProcessControl_Hook() {}
NUDE HOOK_17() {}
NUDE VehicleHorn_Hook() {}
NUDE ZoneOverlay_Hook() {}
NUDE PlayerWalk_Hook() {}
NUDE PickUpPickup_Hook() {}
@ -115,7 +150,7 @@ NUDE HOOK_64() {}
NUDE HOOK_65() {}
NUDE HOOK_66() {}
//-----------------------------------------------------------
NUDE HOOK_6()
{
@ -125,81 +160,126 @@ NUDE HOOK_6()
_asm jmp edx
}
//-----------------------------------------------------------
DWORD dwRandCaller;
NUDE Rand_Hook()
NUDE GameProcessHook()
{
_asm mov eax, [esp+0]
_asm mov dwRandCaller, eax
/*
if(dwRandCaller > 0x73FB10 && dwRandCaller < 0x74132E) {
_asm mov eax, iSyncedRandomNumber
_asm ret
}*/
rand();
_asm add esp, 190h
_asm ret
}
//-----------------------------------------------------------
// We use a special bit (32) on dwProcFlags (+28) to indicate
// whether we should process gravity/collisions on this PlayerPed.
// A hook function that switches keys for
// CPlayerPed::ProcessControl(void)
NUDE CPlayerPed_ProcessCollision_Hook()
BYTE bytePatchPedRot[6] = { 0xD9,0x96,0x5C,0x05,0x00,0x00 };
BYTE bytePatchPedRot2[6] = { 0xD9,0x96,0x5C,0x05,0x00,0x00 };
BYTE bytePatchPedPos[5] = { 0xE8,0x17,0x88,0xFF,0xFF };
void TryProcessPedControl()
{
_asm test ecx, ecx
_asm jnz ptr_is_ok
__try
{
// call the internal CPlayerPed:ProcessControl
_asm mov ecx, dwCurPlayerActor
_asm mov edx, 0x60EA90
_asm call edx
}
__except(exc_filter(GetExceptionCode(), GetExceptionInformation(), "opcode"))
{
if(*pbyteCurrentPlayer != 0 && pNetGame) {
_pPlayerPool = pNetGame->GetPlayerPool();
// TODO: TryProcessPedControl()
}
}
}
void DisablePedRotationFromCamera()
{
// Reapply the no ped rots from Cam patch
memset((PVOID)0x6884C4,0x90,6);
memset((PVOID)0x688200,0x90,6);
}
void EnablePedRotationFromCamera()
{
// Apply the original code to set ped rot from Cam
memcpy((PVOID)0x6884C4,bytePatchPedRot,6);
memcpy((PVOID)0x688200,bytePatchPedRot2,6);
}
void DisablePedPositionUpdate()
{
UnFuck(0x5E92F4,5);
memset((PVOID)0x5E92F4,0x90,5);
}
void EnablePedPositionUpdate()
{
memcpy((PVOID)0x5E92F4,bytePatchPedPos,5);
}
NUDE CPlayerPed_ProcessControl_Hook()
{
_asm mov dwCurPlayerActor, ecx // store the passed actor
_asm pushad
_pPlayer = (PED_TYPE *)dwCurPlayerActor;
byteInternalPlayer = *pbyteCurrentPlayer; // get the current internal player number
byteCurPlayer = FindPlayerNumFromPedPtr(dwCurPlayerActor); // get the ordinal of the passed actor
if( dwCurPlayerActor &&
(byteCurPlayer != 0) &&
(byteInternalPlayer == 0) ) // not local player and local player's keys set.
{
// key switching
GameStoreLocalPlayerKeys(); // remember local player's keys
GameSetRemotePlayerKeys(byteCurPlayer); // set remote player's keys
// save the internal cammode, apply the context.
byteSavedCameraMode = *pbyteCameraMode;
*pbyteCameraMode = GameGetPlayerCameraMode(byteCurPlayer);
// save the second internal cammode, apply the context
wSavedCameraMode2 = *wCameraMode2;
*wCameraMode2 = GameGetPlayerCameraMode(byteCurPlayer);
if(*wCameraMode2 == 4) *wCameraMode2 = 0;
// save the camera zoom factor, apply the context
GameStoreLocalPlayerCameraExtZoom();
GameSetRemotePlayerCameraExtZoom(byteCurPlayer);
// aim switching
GameStoreLocalPlayerAim();
GameSetRemotePlayerAim(byteCurPlayer);
GameStoreLocalPlayerWeaponSkills();
GameSetRemotePlayerWeaponSkills(byteCurPlayer);
*pbyteCurrentPlayer = byteCurPlayer; // Set the internal player to the passed actor
fHealth = _pPlayer->fHealth;
DisablePedPositionUpdate();
TryProcessPedControl();
EnablePedPositionUpdate();
}
else // it's the local player or keys have already been set.
{
// TODO: CPlayerPed_ProcessControl_Hook()
}
_asm popad
_asm ret
ptr_is_ok:
_asm mov eax, [ecx+28]
_asm shr eax, 31
_asm cmp eax, 1
_asm jne do_process_cols
_asm ret // we set top bit so don't process this
do_process_cols:
_asm mov edx, 0x54DFB0
_asm jmp edx
}
//-----------------------------------------------------------
DWORD dwMat;
DWORD dwMatEffects;
DWORD dwDataParam;
NUDE VehicleModel_SetEnvironmentMapHook()
{
_asm mov eax, [esp+4]
_asm mov dwMat, eax
_asm mov eax, [esp+8]
_asm mov dwDataParam, eax
UnFuck(0x6D64F0,1);
*(PBYTE)0x6D64F0 = 0xC3;
/*
_asm push dwMat
_asm mov edx, 0x812140 // _RpMatFXMaterialGetEffects
_asm call edx
_asm pop edx
_asm mov dwMatEffects, eax*/
_asm push 0
_asm push dwMat
_asm mov edx, 0x811C80 // _RpMatFXMaterialSetEffects
_asm call edx
_asm pop edx
_asm pop edx
//pChatWindow->AddDebugMessage("SetEnvironmentMapCB(0x%X,0x%X,%d)",dwMat,dwDataParam,dwMatEffects);
_asm mov edx, 0x4C8848
_asm cmp [esp+8], 0FFFFh
_asm jmp edx
}
//-----------------------------------------------------------
@ -306,11 +386,11 @@ void GameInstallHooks()
InstallMethodHook(0x872398,(DWORD)AllVehicles_ProcessControl_Hook); // train
InstallMethodHook(0x871C50,(DWORD)AllVehicles_ProcessControl_Hook);
InstallCallHook(0x501B1D,(DWORD)HOOK_17);
InstallCallHook(0x501B42,(DWORD)HOOK_17);
InstallCallHook(0x501FC2,(DWORD)HOOK_17);
InstallCallHook(0x502067,(DWORD)HOOK_17);
InstallCallHook(0x5021AE,(DWORD)HOOK_17);
InstallCallHook(0x501B1D,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x501B42,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x501FC2,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x502067,(DWORD)VehicleHorn_Hook);
InstallCallHook(0x5021AE,(DWORD)VehicleHorn_Hook);
// Radar and map hooks for gang zones
InstallCallHook(0x5869BF,(DWORD)ZoneOverlay_Hook);
@ -361,12 +441,12 @@ void GameInstallHooks()
if(iGtaVersion == GTASA_VERSION_USA10)
{
InstallHook(0x7FB020,(DWORD)HOOK_36,0x59C721,HOOK_36_JmpCode,sizeof(HOOK_36_JmpCode));
unnamed_101516D4 = 0x7FB026;
GLOBAL_101516D4 = 0x7FB026;
}
else
{
InstallHook(0x7FB060,(DWORD)HOOK_36,0x59C721,HOOK_36_JmpCode,sizeof(HOOK_36_JmpCode));
unnamed_101516D4 = 0x7FB066;
GLOBAL_101516D4 = 0x7FB066;
}
InstallCallHook(0x6D0E7E,(DWORD)HOOK_37);
@ -431,14 +511,14 @@ void GameInstallHooks()
//-----------------------------------------------------------
void unnamed_100A6FF0()
void FUNC_100A6FF0()
{
InstallHook(0x4087EA,(DWORD)HOOK_61,0x4087D7,HOOK_61_JmpCode,sizeof(HOOK_61_JmpCode));
}
//-----------------------------------------------------------
void unnamed_100A7010()
void FUNC_100A7010()
{
InstallCallHook(0x742495,(DWORD)HOOK_62);
InstallCallHook(0x7424EC,(DWORD)HOOK_62);
@ -455,7 +535,7 @@ void unnamed_100A7010()
//-----------------------------------------------------------
void unnamed_100A71C0()
void FUNC_100A71C0()
{
InstallCallHook(0x6D7C90,(DWORD)HOOK_66,0xE9);
}

1514
saco/game/modelinfo.cpp Normal file

File diff suppressed because it is too large Load Diff

26
saco/game/modelinfo.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
// size must be exactly 68 bytes
typedef struct _MODEL_INFO_TYPE {
DWORD vtable; // 0-4
char _gap4[24];
DWORD *pdwRenderWare; // 28-32
char _gap20[4];
DWORD dwAnimType; // 36-40
DWORD dwPedType; // 40-44
DWORD dwStatType; // 44-48
char _pad30[20];
} MODEL_INFO_TYPE;
BOOL RelocateModelInfoHack();
BOOL InitModelInfoHack();
MODEL_INFO_TYPE* __stdcall GetModelInfo(int iModelID);
void FreeModelInfo(int iModelID); // unused

8
saco/game/object.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "../main.h"
CObject::CObject(int iModel, float fPosX, float fPosY, float fPosZ)
{
}

12
saco/game/object.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include "entity.h"
//----------------------------------------------------
class CObject : public CEntity
{
public:
CObject(int iModel, float fPosX, float fPosY, float fPosZ);
};

View File

@ -4,6 +4,7 @@
DWORD dwSystemMemory;
DWORD dwStreamingMemory;
void InstallSCMEventsProcessor();
void RelocateScanListHack();
void RelocatePedsListHack();
void RelocateBaseModelInfoHack();
@ -440,6 +441,42 @@ void ApplyVehicleColorPatches()
//----------------------------------------------------------
void InstallGameAndGraphicsLoopHooks();
void ApplyDebugLevelPatches()
{
// hack to remove motion blur in high speed vehicle
UnFuck(0x704E8A,5);
memset((PVOID)0x704E8A,0x90,5);
// Don't go back to player anims, use the peds IDE
UnFuck(0x609A4E,6);
memset((PVOID)0x609A4E, 0x90, 6);
InstallGameAndGraphicsLoopHooks();
RelocateScanListHack();
RelocatePedsListHack();
ApplyVehicleColorPatches();
RelocateBaseModelInfoHack();
ApplyGameLimitPatches();
UnFuck(0x47BF54,4);
InstallSCMEventsProcessor();
}
//----------------------------------------------------------
BYTE pbyteTrainDelrailmentPatch[] = {
0xB8, 0x89, 0x8F, 0x6F, 0x00, 0xFF, 0xE0
};
float GLOBAL_101166F0 = 20000.0f;
float GLOBAL_101166F4 = -20000.0f;
float GLOBAL_10116714 = 0.14f;
float GLOBAL_10116718 = 2.0f;
float GLOBAL_1011671C = 10000.0f;
extern DWORD dwFarClipHookAddr;
extern DWORD dwFarClipReturnAddr;
@ -455,9 +492,331 @@ void ApplyInGamePatches()
RelocateScanListHack();
RelocatePedsListHack(); // allows us to use all 300 ped model slots
ApplyVehicleColorPatches();
RelocateBaseModelInfoHack();
ApplyGameLimitPatches();
UnFuck(0x4DF7E2,2);
memset((PVOID)0x4DF7E2,0x90,5);
// VehicleStruct increase
UnFuck(0x5B8FE4,1);
*(BYTE*)0x5B8FE4 = 127;
UnFuck(0x5720A5,5);
memset((PVOID)0x5720A5,0x90,5);
// Remove random procedural geometry like plants/rocks etc.
UnFuck(0x53C159,5);
memset((PVOID)0x53C159,0x90,5);
UnFuck(0x53C136,5);
memset((PVOID)0x53C136,0x90,5);
// Automatic go-to-menu on alt+tab
if(iGtaVersion == GTASA_VERSION_USA10) {
UnFuck(0x748063, 5);
memset((PVOID)0x748063, 0x90, 5);
} else {
UnFuck(0x7480B3, 5);
memset((PVOID)0x7480B3, 0x90, 5);
}
// No vehicle name rendering
UnFuck(0x58FBE9,5);
memset((PVOID)0x58FBE9,0x90,5);
// No playidles anim loading.
UnFuck(0x86D1EC,1);
*(BYTE*)0x86D1EC = '\0';
// Prevent replays
UnFuck(0x53C090,5);
memset((PVOID)0x53C090,0x90,5);
// NO MORE INTERIOR PEDS
UnFuck(0x440833,8);
memset((PVOID)0x440833,0x90,8);
// caused 0x706B2E crash (This seems to be ped shadow rendering)
UnFuck(0x53EA08,10);
memset((PVOID)0x53EA08,0x90,10);
// Make the shadows slightly darker by increasing the alpha
UnFuck(0x71162C,1);
*(PBYTE)0x71162C = 80;
// Unknown from CPlayerPed::ProcessControl causes crash
UnFuck(0x609C08,39);
memset((PVOID)0x609C08,0x90,39);
// FindPlayerVehicle (Always use nPlayerPed)
UnFuck(0x56E0FA,18);
memset((PVOID)0x56E0FA,0x90,18);
// CMotorBike::ProcessControlInputs.. why oh why..
UnFuck(0x6BC9EB,2);
memset((PVOID)0x6BC9EB,0x90,2);
// Smallish patch to fix the drown-in-vehicle crash
UnFuck(0x4BC6C1,3);
*(BYTE*)0x4BC6C1 = 0xB0;
*(BYTE*)0x4BC6C2 = 0x00;
*(BYTE*)0x4BC6C3 = 0x90;
// Allow all vehicles to be sprayed;
UnFuck(0x44AC75,5);
memset((PVOID)0x44AC75,0x90,5);
*(BYTE*)0x44AC75 = 0xB0;
*(BYTE*)0x44AC76 = 0x01;
// This removes the random weapon pickups (e.g. on the hill near chilliad)
UnFuck(0x5B47B0,1);
memset((PVOID)0x5B47B0,0xC3,1);
// Removes the FindPlayerInfoForThisPlayerPed at these locations.
UnFuck(0x5E63A6,19);
memset((PVOID)0x5E63A6,0x90,19);
UnFuck(0x621AEA,12);
memset((PVOID)0x621AEA,0x90,12);
UnFuck(0x62D331,11);
memset((PVOID)0x62D331,0x90,11);
UnFuck(0x741FFF,27);
memset((PVOID)0x741FFF,0x90,27);
// hack to remove motion blur in high speed vehicle
UnFuck(0x704E8A,5);
memset((PVOID)0x704E8A,0x90,5);
// Respawn and Interior
UnFuck(0x4090A0,1);
*(BYTE*)0x4090A0 = 0xC3;
// Respawn and Interior
UnFuck(0x441482,5);
memset((void*)0x441482, 0x90, 5);
// No MessagePrint
UnFuck(0x588BE0,1);
*(BYTE*)0x588BE0 = 0xC3;
// No IPL vehicle
UnFuck(0x53C06A,5);
memset((PVOID)0x53C06A,0x90,5);
// SomeCarGenerator (0x41a8b3 crash)
UnFuck(0x434272,5);
memset((PVOID)0x434272,0x90,5);
// CPlayerPed_CPlayerPed .. task system corrupts some shit
UnFuck(0x60D64D,2);
*(PBYTE)0x60D64E = 0x84; // jnz to jz
// CPhysical Destructor (705b3b crash)
UnFuck(0x542485,11);
memset((PVOID)0x542485,0x90,11);
// No peds kthx. (CPopulation::AddPed() nulled)
UnFuck(0x612710,3);
*(BYTE*)0x612710 = 0x33;
*(BYTE*)0x612711 = 0xC0; // xor eax, eax
*(BYTE*)0x612712 = 0xC3; // ret
// Fuck the call to CPopulation::AddPed() for create_train off to kingdom kong
UnFuck(0x613BA7, 5);
memset((PVOID)0x613BA7, 0x90, 5);
// Don't go back to player anims, use the peds IDE
UnFuck(0x609A4E,6);
memset((PVOID)0x609A4E, 0x90, 6);
// Train derailment
UnFuck(0x006F8CF8, 12);
memset((PVOID)0x006F8CF8, 0x90, 5); // (Actual hook is installed in hooks.cpp)
memcpy((PVOID)(0x006F8CF8+5), pbyteTrainDelrailmentPatch, sizeof(pbyteTrainDelrailmentPatch));
// CarCtl::GenerateRandomCars nulled from CGame::Process (firetrucks etc)
UnFuck(0x53C1C1,5);
memset((PVOID)0x53C1C1,0x90,5);
// (540040 bug), test ecx for 0 instead of [ecx+270]
UnFuck(0x540040,10);
// nop the first 8 bytes
memset((PVOID)0x540040,0x90,6);
*(PBYTE)0x540046 = 0x85;
*(PBYTE)0x540047 = 0xC9; // test ecx, ecx
*(PBYTE)0x540048 = 0x74; // jz
// No wasted message
UnFuck(0x56E5AD,5);
memset((PVOID)0x56E5AD,0x90,5);
// For the input disabling in CGame.
UnFuck(0x541DF5,5);
// Ret at CCamera::ClearPlayerWeaponMode
UnFuck(0x609CB4,5);
memset((PVOID)0x609CB4,0x90,5);
// PlayerInfo checks in CPlayerPed::ProcessControl
UnFuck(0x60F2C4,25);
memset((PVOID)0x60F2C4,0x90,25);
// No Vehicle Audio Processing (done manually from the hooks)
UnFuck(0x6B18F1,5);
memset((PVOID)0x6B18F1,0x90,5);
UnFuck(0x6B9298,5);
memset((PVOID)0x6B9298,0x90,5);
UnFuck(0x6F1793,5);
memset((PVOID)0x6F1793,0x90,5);
UnFuck(0x6F86B6,5);
memset((PVOID)0x6F86B6,0x90,5);
// camera_on_actor patch, tsk tsk R*
UnFuck(0x0047C477,1);
*(BYTE*)0x0047C477 = 0xEB;
// CPushBike fires set on CPed patch
UnFuck(0x0053A984,2);
*(BYTE*)0x0053A984 = 0xEB; // jmp
*(BYTE*)0x0053A985 = 0x77; // +77h = 0x0053A9FD
// Stop sniper clicking
UnFuck(0x0060F289, 8);
memset((PVOID)0x0060F289, 0x90, 8);
UnFuck(0x0060F29D, 19);
memset((PVOID)0x0060F29D, 0x90, 19);
// Wanted level hook
UnFuck(0x58DB5F, 9);
*(BYTE*)0x58DB5F = 0xBD;
*(BYTE*)0x58DB60 = 0x00;
*(BYTE*)0x58DB61 = 0x00;
*(BYTE*)0x58DB62 = 0x00;
*(BYTE*)0x58DB63 = 0x00;
*(BYTE*)0x58DB64 = 0x90;
*(BYTE*)0x58DB65 = 0x90;
*(BYTE*)0x58DB66 = 0x90;
*(BYTE*)0x58DB67 = 0x90;
// Remove the blue(-ish) fog in the map
UnFuck(0x00575B0E, 5);
memset((PVOID)0x00575B0E, 0x90, 5);
// Remove the CReferences call from CTaskEnterVehicleDriver ctor
UnFuck(0x63ADC8,6);
memset((PVOID)0x63ADC8,0x90,6);
UnFuck(0x58FC2E,30);
memset((PVOID)0x58FC2E,0x90,30);
UnFuck(0x5E1E70,2);
*(BYTE*)0x5E1E70 = 0x33;
*(BYTE*)0x5E1E71 = 0xC0;
UnFuck(0x6A8500,119);
memset((PVOID)0x6A8500,0xC3,119);
UnFuck(0x593D7C,5);
memset((PVOID)0x593D7C,0x90,5);
if(iGtaVersion == GTASA_VERSION_USA10) {
UnFuck(0x7469AF,2);
*(BYTE*)0x7469AF = 0x33;
*(BYTE*)0x7469B0 = 0xC0;
} else {
UnFuck(0x7469FF,2);
*(BYTE*)0x7469FF = 0x33;
*(BYTE*)0x746A00 = 0xC0;
}
UnFuck(0x61E0C2,4);
*(DWORD*)0x61E0C2 = (DWORD)&GLOBAL_10116718;
UnFuck(0x454CC9,4);
*(DWORD*)0x454CC9 = (DWORD)&GLOBAL_1011671C;
UnFuck(0x5952A6,5);
memset((PVOID)0x5952A6,0x90,5);
// Stop ped rotations from the camera
UnFuck(0x6884C4,6);
UnFuck(0x688200,6);
memset((PVOID)0x6884C4,0x90,6);
memset((PVOID)0x688200,0x90,6);
UnFuck(0x570535,15);
memset((PVOID)0x570535,0x90,15);
UnFuck(0x5E7847,17);
memset((PVOID)0x5E7847,0x90,17);
UnFuck(0x570546,175);
memset((PVOID)0x570546,0x90,175);
UnFuck(0x6D1874,24);
*(DWORD*)0x6D1874 = 0x6D17D5;
*(DWORD*)0x6D1878 = 0x6D17D5;
*(DWORD*)0x6D187C = 0x6D17D5;
*(DWORD*)0x6D1880 = 0x6D17D5;
*(DWORD*)0x6D1884 = 0x6D17D5;
*(DWORD*)0x6D1888 = 0x6D17D5;
UnFuck(0x64DB49,9);
memset((PVOID)0x64DB49,0x90,9);
UnFuck(0x64BC9F,9);
memset((PVOID)0x64BC9F,0x90,9);
UnFuck(0x64B872,9);
memset((PVOID)0x64B872,0x90,9);
UnFuck(0x5E7D62,5);
*(BYTE*)0x5E7D62 = 0x5E;
*(BYTE*)0x5E7D63 = 0x5D;
*(BYTE*)0x5E7D64 = 0xC2;
*(BYTE*)0x5E7D65 = 0x1C;
*(BYTE*)0x5E7D66 = 0x00;
UnFuck(0x6348F6,4);
*(DWORD*)0x6348F6 = 0xFFFFFFFF;
UnFuck(0x634DE2,4);
*(DWORD*)0x634DE2 = 0xFFFFFFFF;
UnFuck(0x71A220,1024);
FUNC_100AA540();
UnFuck(0x7361B2,4);
*(DWORD*)0x7361B2 = (DWORD)&GLOBAL_101166F4;
UnFuck(0x7361CB,4);
*(DWORD*)0x7361CB = (DWORD)&GLOBAL_101166F0;
UnFuck(0x7361E0,4);
*(DWORD*)0x7361E0 = (DWORD)&GLOBAL_101166F4;
UnFuck(0x7361F5,4);
*(DWORD*)0x7361F5 = (DWORD)&GLOBAL_101166F0;
UnFuck(0x524582,5);
memset((PVOID)0x524582,0x90,5);
UnFuck(0x712025,1);
*(BYTE*)0x712025 = 1;
UnFuck(0x858B90,4);
UnFuck(0x53BF28,5);
memset((PVOID)0x53BF28,0x90,5);
UnFuck(0x859520,8);
UnFuck(0xC17044,8);
UnFuck(0x4C3A5B,10);
memset((PVOID)0x4C3A5B,0x90,10);
UnFuck(0x47BF54,4);
InstallSCMEventsProcessor();
}
//----------------------------------------------------------

View File

@ -1,16 +1,22 @@
#include <windows.h>
#include <assert.h>
#define _ASSERT assert
#include "../main.h"
#include "game.h"
#include "util.h"
#include "keystuff.h"
#include "task.h"
extern CGame *pGame;
extern CNetGame *pNetGame;
extern BYTE *pbyteCurrentPlayer;
//-----------------------------------------------------------
// Used for instancing the local player.
// MATCH
CPlayerPed::CPlayerPed()
{
m_dwGTAId = 1; // 0x001
@ -26,11 +32,11 @@ CPlayerPed::CPlayerPed()
field_2AC = 1;
m_dwArrow = 0;
field_2B9 = 0;
field_2F2 = 0;
field_2D2 = 0;
m_iPissingState = 0;
m_iDanceState = 0;
field_2DE = 0;
field_2E2 = 0;
field_48 = 0;
m_iCellPhoneEnabled = 0;
m_bGoggleState = FALSE;
field_2C1 = 0;
field_2C5 = 0;
@ -54,10 +60,12 @@ CPlayerPed::CPlayerPed()
//-----------------------------------------------------------
// If the game has internally destroyed the ped
// during this frame, the ped pointer should become 0
// MATCH
void CPlayerPed::ResetPointers()
{
m_pPed = GamePool_Ped_GetAt(m_dwGTAId);
@ -65,7 +73,7 @@ void CPlayerPed::ResetPointers()
}
//-----------------------------------------------------------
// MATCH
void CPlayerPed::SetInitialState()
{
DWORD dwPedPtr = (DWORD)m_pPed;
@ -77,7 +85,7 @@ void CPlayerPed::SetInitialState()
}
//-----------------------------------------------------------
// MATCH
BYTE CPlayerPed::GetSpecialKey()
{
GTA_CONTROLSET *pInternalKeys = GameGetInternalKeys();
@ -92,23 +100,27 @@ BYTE CPlayerPed::GetSpecialKey()
return 0;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
// MATCH
CAMERA_AIM * CPlayerPed::GetCurrentAim()
{
return GameGetInternalAim();
}
//-----------------------------------------------------------
// MATCH
void CPlayerPed::SetCurrentAim(CAMERA_AIM *pAim)
{
GameStoreRemotePlayerAim(m_bytePlayerNumber, pAim);
}
//-----------------------------------------------------------
// MATCH
BYTE CPlayerPed::GetCurrentWeapon()
{
if(!m_pPed) return 0;
@ -120,7 +132,7 @@ BYTE CPlayerPed::GetCurrentWeapon()
}
//-----------------------------------------------------------
// MATCH
int CPlayerPed::GetCurrentVehicleID()
{
if(!m_pPed) return 0;
@ -129,6 +141,12 @@ int CPlayerPed::GetCurrentVehicleID()
return GamePool_Vehicle_GetIndex(pVehicle);
}
//-----------------------------------------------------------
//-----------------------------------------------------------
void CPlayerPed::HideMarker()
@ -311,6 +329,10 @@ VEHICLE_TYPE * CPlayerPed::GetGtaVehicle()
return (VEHICLE_TYPE *)m_pPed->pVehicle;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
void CPlayerPed::GiveWeapon(int iWeaponID, int iAmmo)
@ -458,52 +480,197 @@ float CPlayerPed::GetDistanceFromVehicle(CVehicle *pVehicle)
//-----------------------------------------------------------
WORD CPlayerPed::GetAmmo()
int CPlayerPed::GetVehicleSeatID()
{
if(m_pPed) {
WEAPON_SLOT_TYPE * WeaponSlot = GetCurrentWeaponSlot();
VEHICLE_TYPE *pVehicle;
if(!WeaponSlot) return -1;
// Melee types always have ammo.
if( WeaponSlot->dwType <= WEAPON_CANE ||
WeaponSlot->dwType == WEAPON_PARACHUTE ) return -1;
return (WORD)WeaponSlot->dwAmmo;
if( GetActionTrigger() == ACTION_INCAR && (pVehicle = (VEHICLE_TYPE *)m_pPed->pVehicle) != 0 ) {
if(pVehicle->pDriver == m_pPed) return 0;
if(pVehicle->pPassengers[0] == m_pPed) return 1;
if(pVehicle->pPassengers[1] == m_pPed) return 2;
if(pVehicle->pPassengers[2] == m_pPed) return 3;
if(pVehicle->pPassengers[3] == m_pPed) return 4;
if(pVehicle->pPassengers[4] == m_pPed) return 5;
if(pVehicle->pPassengers[5] == m_pPed) return 6;
if(pVehicle->pPassengers[6] == m_pPed) return 7;
}
return 0;
return (-1);
}
//-----------------------------------------------------------
WEAPON_SLOT_TYPE * CPlayerPed::FindWeaponSlot(DWORD dwWeapon)
void CPlayerPed::PutDirectlyInVehicle(int iVehicleID, int iSeat)
{
if (m_pPed)
{
BYTE i;
for (i = 0; i < 13; i++)
{
if (m_pPed->WeaponSlots[i].dwType == dwWeapon) return &m_pPed->WeaponSlots[i];
if(!m_pPed) return;
if(!GamePool_Vehicle_GetAt(iVehicleID)) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
if(GetCurrentWeapon() == WEAPON_PARACHUTE) {
SetArmedWeapon(0, false);
}
VEHICLE_TYPE *pVehicle = GamePool_Vehicle_GetAt(iVehicleID);
if(pVehicle->fHealth == 0.0f) return;
// Check to make sure internal data structure of the vehicle hasn't been deleted
// by checking if the vtbl points to CPlaceable_vtbl
if (pVehicle->entity.vtable == 0x863C40) return;
if(GetVehicleSubtypeFromVehiclePtr(pVehicle) == VEHICLE_SUBTYPE_CAR || GetVehicleSubtypeFromVehiclePtr(pVehicle) == VEHICLE_SUBTYPE_BIKE) return;
if(iSeat > pVehicle->byteMaxPassengers) return;
if(iSeat==0) {
if(pVehicle->pDriver && IN_VEHICLE(pVehicle->pDriver)) return;
ScriptCommand(&put_actor_in_car,m_dwGTAId,iVehicleID);
} else {
iSeat--;
ScriptCommand(&put_actor_in_car2,m_dwGTAId,iVehicleID,iSeat);
}
if(m_pPed == GamePool_FindPlayerPed() && IN_VEHICLE(m_pPed)) {
pGame->GetCamera()->SetBehindPlayer();
}
if(pNetGame) {
CVehiclePool* pVehiclePool = pNetGame->GetVehiclePool();
// TODO: CPlayerPed::PutDirectlyInVehicle
}
}
//-----------------------------------------------------------
//-----------------------------------------------------------
// Forceful removal
void CPlayerPed::RemoveFromVehicleAndPutAt(float fX, float fY, float fZ)
{
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
if(m_pPed && IN_VEHICLE(m_pPed)) {
ScriptCommand(&remove_actor_from_car_and_put_at,m_dwGTAId,fX,fY,fZ);
}
}
//-----------------------------------------------------------
void CPlayerPed::TogglePlayerControllable(int iControllable)
{
MATRIX4X4 mat;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
if(!iControllable) {
ScriptCommand(&toggle_player_controllable,m_bytePlayerNumber,0);
ScriptCommand(&lock_actor,m_dwGTAId,1);
} else {
ScriptCommand(&toggle_player_controllable,m_bytePlayerNumber,1);
ScriptCommand(&lock_actor,m_dwGTAId,0);
if(!IsInVehicle()) {
GetMatrix(&mat);
TeleportTo(mat.pos.X,mat.pos.Y,mat.pos.Z);
}
}
return NULL;
}
//-----------------------------------------------------------
void CPlayerPed::SetAnimationSet(PCHAR szAnim)
//-----------------------------------------------------------
void CPlayerPed::HandsUp()
{
if(m_pPed) {
ScriptCommand(&set_actor_animation_set,m_dwGTAId,szAnim);
if(!m_pPed || IN_VEHICLE(m_pPed)) return;
if(!IsAdded()) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
ScriptCommand(&actor_task_handsup,m_dwGTAId,-2);
}
//-----------------------------------------------------------
BOOL CPlayerPed::HasHandsUp()
{
if(!m_pPed || IN_VEHICLE(m_pPed)) return FALSE;
if(!IsAdded()) return FALSE;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return FALSE;
if(m_pPed->Tasks->pdwJumpJetPack == NULL) return FALSE;
DWORD dwJmpVtbl = m_pPed->Tasks->pdwJumpJetPack[0];
if(dwJmpVtbl == 0x85A29C) return TRUE;
return FALSE;
}
//-----------------------------------------------------------
void CPlayerPed::HoldItem(int iObject)
{
if(!m_pPed) return;
if(!IsAdded()) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
DWORD dwPed = (DWORD)m_pPed;
_asm push 1
_asm push iObject
_asm mov ecx, dwPed
_asm mov ebx, 0x5E4390
_asm call ebx
}
//-----------------------------------------------------------
BOOL CPlayerPed::IsJumpTask()
{
if(m_pPed && !IN_VEHICLE(m_pPed) && m_pPed->Tasks->pdwJumpJetPack)
{
return GetTaskTypeFromTask(m_pPed->Tasks->pdwJumpJetPack) == 211;
}
return FALSE;
}
//-----------------------------------------------------------
void CPlayerPed::SetMoney(int iAmount)
BOOL CPlayerPed::IsFightTask()
{
ScriptCommand(&set_actor_money,m_dwGTAId,0);
ScriptCommand(&set_actor_money,m_dwGTAId,iAmount);
if(m_pPed && !IN_VEHICLE(m_pPed) && m_pPed->Tasks->pdwFighting)
{
return GetTaskTypeFromTask(m_pPed->Tasks->pdwFighting) == 1016;
}
return FALSE;
}
//-----------------------------------------------------------
BOOL CPlayerPed::IsTakeFallDamageTask()
{
if(m_pPed && !IN_VEHICLE(m_pPed) && m_pPed->Tasks->pdwDamage)
{
return GetTaskTypeFromTask(m_pPed->Tasks->pdwDamage) == 208;
}
return FALSE;
}
//-----------------------------------------------------------
BOOL CPlayerPed::IsSwimTask()
{
if(m_pPed && !IN_VEHICLE(m_pPed) && m_pPed->Tasks->pdwSwimWasted)
{
return GetTaskTypeFromTask(m_pPed->Tasks->pdwSwimWasted) == 268;
}
return FALSE;
}
//-----------------------------------------------------------
@ -592,3 +759,329 @@ BOOL CPlayerPed::HasGoggles()
}
//-----------------------------------------------------------
//-----------------------------------------------------------
WORD CPlayerPed::GetAmmo()
{
if(m_pPed) {
WEAPON_SLOT_TYPE * WeaponSlot = GetCurrentWeaponSlot();
if(!WeaponSlot) return -1;
// Melee types always have ammo.
if( WeaponSlot->dwType <= WEAPON_CANE ||
WeaponSlot->dwType == WEAPON_PARACHUTE ) return -1;
return (WORD)WeaponSlot->dwAmmo;
}
return 0;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
WEAPON_SLOT_TYPE * CPlayerPed::FindWeaponSlot(DWORD dwWeapon)
{
if (m_pPed)
{
BYTE i;
for (i = 0; i < 13; i++)
{
if (m_pPed->WeaponSlots[i].dwType == dwWeapon) return &m_pPed->WeaponSlots[i];
}
}
return NULL;
}
//-----------------------------------------------------------
void CPlayerPed::SetAnimationSet(PCHAR szAnim)
{
if(m_pPed) {
ScriptCommand(&set_actor_animation_set,m_dwGTAId,szAnim);
}
}
//-----------------------------------------------------------
void CPlayerPed::SetMoney(int iAmount)
{
ScriptCommand(&set_actor_money,m_dwGTAId,0);
ScriptCommand(&set_actor_money,m_dwGTAId,iAmount);
}
//-----------------------------------------------------------
void CPlayerPed::ApplyAnimation( char *szAnimName, char *szAnimFile, float fT,
int opt1, int opt2, int opt3, int opt4, int iUnk )
{
int iWaitAnimLoad=0;
if(!m_pPed) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
// Can't allow 'naughty' anims!
if( !stricmp(szAnimFile,"SEX") )
return;
if (!pGame->IsAnimationLoaded(szAnimFile)) {
pGame->RequestAnimation(szAnimFile);
while(!pGame->IsAnimationLoaded(szAnimFile)) {
Sleep(1);
iWaitAnimLoad++;
if(iWaitAnimLoad == 15) return; // we can't wait forever
}
}
ScriptCommand(&apply_animation,m_dwGTAId,szAnimName,szAnimFile,fT,opt1,opt2,opt3,opt4,iUnk);
}
//-----------------------------------------------------------
BOOL CPlayerPed::IsPerformingAnimation(char *szAnimName)
{
if(m_pPed && ScriptCommand(&is_actor_performing_anim,m_dwGTAId,szAnimName)) {
return TRUE;
}
return FALSE;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
ENTITY_TYPE* CPlayerPed::GetGtaContactEntity()
{
return (ENTITY_TYPE*)m_pPed->pContactEntity;
}
//-----------------------------------------------------------
VEHICLE_TYPE* CPlayerPed::GetGtaContactVehicle()
{
return (VEHICLE_TYPE*)m_pPed->pContactVehicle;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
char DanceStyleLibs[4][16] = {"WOP","GFUNK","RUNNINGMAN","STRIP"};
char DanceIdleLoops[4][16] = {"DANCE_LOOP","DANCE_LOOP","DANCE_LOOP","STR_Loop_B"};
void CPlayerPed::StartDancing(int iStyle)
{
if(iStyle < 0 || iStyle > 3) return;
m_iDanceState = 1;
m_iDanceStyle = iStyle;
if(m_bytePlayerNumber == 0) {
ApplyAnimation(DanceIdleLoops[m_iDanceStyle],DanceStyleLibs[m_iDanceStyle],16.0,1,0,0,0,-1);
}
}
//-----------------------------------------------------------
void CPlayerPed::StopDancing()
{
m_iDanceState = 0;
MATRIX4X4 mat;
GetMatrix(&mat);
TeleportTo(mat.pos.X,mat.pos.Y,mat.pos.Z);
}
//-----------------------------------------------------------
BOOL CPlayerPed::IsDancing()
{
if(m_iDanceState) return TRUE;
return FALSE;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
void CPlayerPed::ProcessMarkers(BOOL bMarkerStreamingEnabled, float fMarkerStreamRadius, BOOL bVisible)
{
if(!m_pPed) return;
}
//-----------------------------------------------------------
void CPlayerPed::ApplyCommandTask(char *szTaskName, int p1, int p2, int p3,
VECTOR *p4, int p5, float p6, int p7, int p8, int p9)
{
DWORD dwPed = (DWORD)m_pPed;
if(!dwPed) return;
_asm push p9
_asm push p8
_asm push p7
_asm push p6
_asm push p5
_asm push p4
_asm push p3
_asm push p2
_asm push p1
_asm push dwPed
_asm push szTaskName
_asm mov ecx, 0xC15448
_asm mov edx, 0x618970
_asm call edx
}
//-----------------------------------------------------------
DWORD dwExt4;
void CPlayerPed::DestroyFollowPedTask()
{
if(!m_pPed) return;
dwExt4 = (DWORD)m_pPed->Tasks->pdwIK;
if(!dwExt4) return;
_asm mov ecx, dwExt4
_asm mov edx, 0x639330
_asm push 1
_asm call edx
m_pPed->Tasks->pdwIK = 0;
}
//-----------------------------------------------------------
void CPlayerPed::ToggleCellphone(int iOn)
{
if(!m_pPed) return;
m_iCellPhoneEnabled = iOn;
ScriptCommand(&toggle_actor_cellphone,m_dwGTAId,iOn);
}
//-----------------------------------------------------------
int CPlayerPed::IsCellphoneEnabled()
{
return m_iCellPhoneEnabled;
}
//-----------------------------------------------------------
int CPlayerPed::GetFightingStyle()
{
if (!m_pPed) return 0;
return m_pPed->byteFightingStyle;
}
//-----------------------------------------------------------
void CPlayerPed::SetFightingStyle(int iStyle)
{
if (!m_pPed) return;
ScriptCommand( &set_fighting_style, m_dwGTAId, iStyle, 6 );
}
//-----------------------------------------------------------
void CPlayerPed::StartPissing()
{
if(!m_pPed) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
if(m_iPissingState != 0) {
// already started
return;
}
if (!m_bytePlayerNumber) {
ApplyAnimation("PISS_LOOP","PAULNMAC", 4.0f, 1, 0, 0, 0, -1);
}
ScriptCommand(&attach_particle_to_actor2,"PETROLCAN",m_dwGTAId,
0.0f, 0.58f, -0.08f, 0.0f, 0.01f, 0.0f, 1, &m_dwPissParticlesHandle);
ScriptCommand(&make_particle_visible,m_dwPissParticlesHandle);
m_iPissingState = 1;
}
//-----------------------------------------------------------
void CPlayerPed::StopPissing()
{
if(!m_pPed) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
if(!m_iPissingState) return;
if(m_dwPissParticlesHandle) {
ScriptCommand(&destroy_particle,m_dwPissParticlesHandle);
m_dwPissParticlesHandle = 0;
}
MATRIX4X4 mat;
GetMatrix(&mat);
TeleportTo(mat.pos.X,mat.pos.Y,mat.pos.Z);
m_iPissingState = 0;
}
//-----------------------------------------------------------
int CPlayerPed::IsPissing()
{
return m_iPissingState;
}
//-----------------------------------------------------------
void CPlayerPed::ProcessVehicleHorn()
{
if(!m_pPed) return;
if(!GamePool_Ped_GetAt(m_dwGTAId)) return;
GTA_CONTROLSET *pPlayerControls;
if(!m_bytePlayerNumber) {
pPlayerControls = GameGetInternalKeys();
} else {
pPlayerControls = GameGetPlayerKeys(m_bytePlayerNumber);
}
VEHICLE_TYPE *pGtaVehicle = (VEHICLE_TYPE *)m_pPed->pVehicle;
if(pGtaVehicle) {
if(IN_VEHICLE(m_pPed) && (pGtaVehicle->pDriver == m_pPed)) {
if(pPlayerControls->wKeys1[18]) {
pGtaVehicle->byteHorn2 = 1;
} else {
pGtaVehicle->byteHorn2 = 0;
}
}
}
}
//-----------------------------------------------------------

View File

@ -24,6 +24,26 @@ public:
CAMERA_AIM * GetCurrentAim();
void SetCurrentAim(CAMERA_AIM *pAim);
BYTE GetCameraMode() {
if(m_bytePlayerNumber)
return GameGetPlayerCameraMode(m_bytePlayerNumber);
else
return GameGetLocalPlayerCameraMode();
};
void SetCameraMode(BYTE byteCamMode) {
GameSetPlayerCameraMode(byteCamMode,m_bytePlayerNumber);
};
void GetCameraExtendedZoom(float *pfZoom, float *pfRatio) {
*pfZoom = GameGetLocalPlayerCameraExtZoom();
*pfRatio = GameGetLocalPlayerAspectRatio();
}
void SetCameraExtendedZoom(float fZoom, float fRatio) {
GameSetPlayerCameraExtZoom(m_bytePlayerNumber,fZoom,fRatio);
};
void HideMarker();
BYTE GetCurrentWeapon();
int GetCurrentVehicleID();
@ -38,16 +58,18 @@ public:
BOOL IsInVehicle();
BYTE GetActionTrigger();
void SetActionTrigger(BYTE byteTrigger);
WORD GetAmmo();
int GetFightingStyle();
void SetFightingStyle(int iStyle);
float GetTargetRotation();
void SetTargetRotation(float fRotation);
void ForceTargetRotation(float fRotation);
void GiveWeapon(int iWeaponID, int iAmmo);
void SetArmedWeapon(int iWeaponType, bool bUnk);
void ClearAllWeapons();
void SetArmedWeapon(int iWeaponType, bool bUnk=false);
void RemoveWeaponWhenEnteringVehicle();
WEAPON_SLOT_TYPE * GetCurrentWeaponSlot();
WEAPON_SLOT_TYPE * FindWeaponSlot(DWORD dwWeapon);
@ -55,9 +77,17 @@ public:
void SetImmunities(BOOL bBullet, BOOL bFire, BOOL bExplosion, BOOL bDamage, BOOL bUnknown);
void PutDirectlyInVehicle(int iVehicleID, int iSeat);
void RemoveFromVehicleAndPutAt(float fX, float fY, float fZ);
BOOL IsAPassenger();
VEHICLE_TYPE * GetGtaVehicle();
VEHICLE_TYPE * GetGtaContactVehicle();
ENTITY_TYPE * GetGtaContactEntity();
int GetVehicleSeatID();
void TogglePlayerControllable(int iControllable);
float GetDistanceFromVehicle(CVehicle *pVehicle);
@ -71,12 +101,41 @@ public:
void SetAnimationSet(PCHAR szAnim);
void SetMoney(int iAmount);
void ApplyAnimation(char *szAnimName, char *szAnimFile, float fT,
int opt1, int opt2, int opt3, int opt4, int iUnk);
BOOL IsPerformingAnimation(char *szAnimName);
CPlayerPed();
//char _gap0[813];
//char _gap0[741];
int field_48;
void ProcessVehicleHorn();
void StartDancing(int iStyle);
void StopDancing();
BOOL IsDancing();
void HandsUp();
BOOL HasHandsUp();
void HoldItem(int iObject);
void ProcessMarkers(BOOL bMarkerStreamingEnabled, float fMarkerStreamRadius, BOOL bVisible);
void ApplyCommandTask(char *szTaskName, int p1, int p2, int p3,
VECTOR *p4, int p5, float p6, int p7, int p8, int p9);
void DestroyFollowPedTask();
void ToggleCellphone(int iOn);
int IsCellphoneEnabled();
void StartPissing();
void StopPissing();
int IsPissing();
BOOL IsJumpTask();
BOOL IsFightTask();
BOOL IsTakeFallDamageTask();
BOOL IsSwimTask();
int m_iCellPhoneEnabled;
int field_4C[10];
struc_97 field_74[10];
int field_27C[10];
@ -86,25 +145,25 @@ public:
BYTE m_bytePlayerNumber;
char _gap2B1[8];
int field_2B9;
char _gap2BD[4];
DWORD m_dwPissParticlesHandle;
int field_2C1;
int field_2C5;
int field_2C9;
DWORD m_dwArrow;
char _gap2D1[1];
int field_2D2;
char _gap2D6[8];
char _gap2D1;
int m_iDanceState;
int m_iDanceStyle;
char _gap2DA[4];
int field_2DE;
int field_2E2;
BOOL m_bGoggleState;
char _gap2EA[8];
int field_2F2;
int m_iPissingState;
char field_2F6;
char field_2F7;
char field_2F8;
int field_2F9;
char _gap2FD[48];
};
//-----------------------------------------------------------

View File

@ -443,3 +443,73 @@ void RwFrameRotate(RwFrame* frame, int axis, float angle)
_asm pop edx
}
void RpHAnimHierarchyUpdateMatrices(RpClump *clump)
{
_asm push clump
_asm mov edx, 0x734A40 ; GetAnimHierarchyFromSkinClump
_asm call edx
_asm pop edx
_asm push eax
_asm mov edx, 0x7C51D0 ; RpHAnimHierarchyUpdateMatrices
_asm call edx
_asm pop edx
}
void RpAnimBlendClumpUpdateAnimations(RpClump *pClump, float fStep, int iOnScreen)
{
_asm push iOnScreen
_asm push fStep
_asm push pClump
_asm mov edx, 0x4D34F0
_asm call edx
_asm pop edx
_asm pop edx
_asm pop edx
}
RwStream * RwStreamOpen(int iStreamType, int iAccessType, void *pData)
{
RwStream *pResult = NULL;
DWORD dwFunc = (iGtaVersion != GTASA_VERSION_USA10) ? 0x7ECF30 : 0x7ECEF0;
_asm push pData
_asm push iAccessType
_asm push iStreamType
_asm mov eax, dwFunc
_asm call eax
_asm mov pResult, eax
_asm pop eax
_asm pop eax
_asm pop eax
return pResult;
}
int RwStreamClose(RwStream *pStream, void *pData)
{
int bResult = 0;
DWORD dwFunc = (iGtaVersion != GTASA_VERSION_USA10) ? 0x7ECE60 : 0x7ECE20;
_asm push pData
_asm push pStream
_asm mov eax, dwFunc
_asm call eax
_asm mov bResult, eax
_asm pop eax
_asm pop eax
return bResult;
}
/*UINT RwStreamRead(RwStream *pStream, void *pBuffer, UINT uiLength)
{
return ((int (__cdecl *)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(iGtaVersion != 1 ? 0x7ECA10 : 0x7EC9D0))(
pStream,
pBuffer,
uiLength,
iGtaVersion != 1 ? 0x7ECA10 : 0x7EC9D0,
0);
}*/

View File

@ -10,6 +10,7 @@ struct RwRGBAReal { float r, g, b, a; };
struct RpAtomic { char _gap0; };
struct RwRGBA { char _gap0; };
struct RpClump { char _gap0; };
struct RwStream { char _gap0; };
RwRaster* RwRasterCreate(int width, int height, int depth, int flags);
RwTexture* RwTextureCreate(RwRaster *raster);
@ -44,3 +45,9 @@ int RpClumpDestroy(RpClump *clump);
void RwCameraSetProjection(RwCamera *camera, int projection);
void RwFrameTranslate(RwFrame *frame, VECTOR *v, int combine);
void RwFrameRotate(RwFrame* frame, int axis, float angle);
void RpHAnimHierarchyUpdateMatrices(RpClump *clump);
void RpAnimBlendClumpUpdateAnimations(RpClump *pClump, float fStep, int iOnScreen);
RwStream * RwStreamOpen(int iStreamType, int iAccessType, void *pData);
int RwStreamClose(RwStream *pStream, void *pData);

View File

@ -28,72 +28,156 @@ struct SCRIPT_COMMAND // Params
void InitScripting();
int ScriptCommand(const SCRIPT_COMMAND* pScriptCommand, ...); // The main scripting function. See notes.
const SCRIPT_COMMAND create_arrow_above_actor = { 0x0187, "iv" };
const SCRIPT_COMMAND request_model = { 0x0247, "i" }; // (CAR_*|BIKE_*|BOAT_*|WEAPON_*|OBJECT_*)
const SCRIPT_COMMAND load_requested_models = { 0x038B, "" }; // -/-
const SCRIPT_COMMAND create_car = { 0x00A5, "ifffv" }; // (CAR_*|BIKE_*|BOAT_*), x, y, z, var_car
const SCRIPT_COMMAND create_actor = { 0x009A, "iifffv" }; // PEDTYPE_*, #MODEL, x, y, z, var_actor
const SCRIPT_COMMAND fade = { 0x016A, "ii" }; // (time in ms), FADE_*
const SCRIPT_COMMAND set_current_time = { 0x00C0, "ii" }; // Hours, Minutes
const SCRIPT_COMMAND create_player = { 0x0053, "vfffv" }; // 0, x, y, z, PLAYER_CHAR
const SCRIPT_COMMAND create_actor_from_player = { 0x01F5, "vv" }; // PLAYER_CHAR, PLAYER_ACTOR
const SCRIPT_COMMAND select_interior = { 0x04BB, "i" }; // INTERIOR_*
const SCRIPT_COMMAND destroy_car = { 0x00A6, "i" }; // var_car
const SCRIPT_COMMAND set_car_z_angle = { 0x0175, "if" }; // var_car, angle
const SCRIPT_COMMAND is_model_available = { 0x0248, "i" }; // #MODEL
const SCRIPT_COMMAND toggle_widescreen = { 0x02A3, "i" }; // widescreen(1/0)
const SCRIPT_COMMAND set_camera_behind_player = { 0x0373, "" }; // -/-
const SCRIPT_COMMAND camera_on_vehicle = { 0x0158, "iii" }; // var_car, ukn, ukn
const SCRIPT_COMMAND camera_on_actor = { 0x0159, "iii" }; // var_actor, ukn, ukn
const SCRIPT_COMMAND point_camera = { 0x0160, "fffi" }; // x, y, z, type
const SCRIPT_COMMAND restore_camera_jumpcut = { 0x02EB, "" }; // -/-
const SCRIPT_COMMAND set_camera_position = { 0x015F, "ffffff" }; // x, y, z, vx, vy, vz
const SCRIPT_COMMAND tie_marker_to_car = { 0x0161, "iiiv" }; // var_car, ukn, ukn, var_marker
const SCRIPT_COMMAND disable_marker = { 0x0164, "i" }; // var_marker
const SCRIPT_COMMAND set_marker_color = { 0x0165, "ii" }; // var_marker, color
const SCRIPT_COMMAND enable_zone_names = { 0x09BA, "i" };
const SCRIPT_COMMAND create_radar_marker_without_sphere = { 0x04CE, "fffiv" }; // x, y, z, marker_type, var_marker
const SCRIPT_COMMAND show_on_radar = { 0x0168, "ii" }; // var_marker, size
const SCRIPT_COMMAND create_icon_marker_sphere = { 0x02A7, "fffiv" };
const SCRIPT_COMMAND is_actor_near_point_3d = { 0x00FE, "iffffffi" };// var_actor, x, y, z, rx, ry, rz, b
const SCRIPT_COMMAND get_line_of_sight = { 0x06BD, "ffffffiiiii" }; // x1, y1, z1, x2, y2, z2, solid, vehicle, actor, obj, fx
const SCRIPT_COMMAND add_to_player_money = { 0x0109, "ii" }; // PLAYER_CHAR, money
const SCRIPT_COMMAND has_car_sunk = { 0x02bf, "i" }; // CarID
const SCRIPT_COMMAND is_car_wrecked = { 0x0119, "i" }; // CarID
const SCRIPT_COMMAND get_ground_z = { 0x02ce, "fffv" }; // x, y, z, var_ground_z
const SCRIPT_COMMAND create_racing_checkpoint = { 0x06d5, "ifffffffv"}; // type, x, y, z, nx, ny. nz, size, $id (n=next checkpoint)
/* 0 = Street Checkpoint with arrow to the next checkpoint
1 and 2 = Street Checkpoint
3 and 4 = Flight Checkpoint (circle) */
const SCRIPT_COMMAND destroy_racing_checkpoint = { 0x06d6, "i" };
const SCRIPT_COMMAND toggle_player_controllable = { 0x01B4, "ii" };
const SCRIPT_COMMAND set_actor_armed_weapon = { 0x01b9, "ii" };
const SCRIPT_COMMAND get_actor_armed_weapon = { 0x0470, "iv" };
const SCRIPT_COMMAND set_actor_immunities = { 0x02ab, "iiiiii" };
const SCRIPT_COMMAND put_actor_in_car = { 0x036A, "ii" };
const SCRIPT_COMMAND set_actor_immunities = { 0x02ab, "iiiiii" };
const SCRIPT_COMMAND set_car_immunities = { 0x02ac, "iiiiii" };
const SCRIPT_COMMAND set_actor_can_be_decapitated = { 0x0446, "ii" };
const SCRIPT_COMMAND create_object = { 0x0107, "ifffv" };
const SCRIPT_COMMAND set_object_rotation = { 0x0453, "ifff" };
const SCRIPT_COMMAND play_sound = { 0x018c, "fffi" };
const SCRIPT_COMMAND remove_actor_from_car_and_put_at = { 0x0362, "ifff" };
const SCRIPT_COMMAND send_actor_to_car_driverseat = { 0x05CB, "iii" };
const SCRIPT_COMMAND send_actor_to_car_passenger = { 0x05CA, "iiii" };
const SCRIPT_COMMAND make_actor_leave_car = { 0x05CD, "ii" };
const SCRIPT_COMMAND get_car_z_angle = { 0x0174, "iv" };
const SCRIPT_COMMAND create_train = { 0x06D8, "ifffiv" };
const SCRIPT_COMMAND destroy_train = { 0x07bd, "i" };
const SCRIPT_COMMAND enable_train_traffic = { 0x06d7, "i" };
const SCRIPT_COMMAND lock_car = { 0x0519, "ii" };
const SCRIPT_COMMAND put_train_at = { 0x07c7, "ifff" };
const SCRIPT_COMMAND release_model = { 0x0249, "i" };
const SCRIPT_COMMAND get_active_interior = { 0x077e, "v" };
const SCRIPT_COMMAND get_actor_z_angle = { 0x0172, "iv" };
const SCRIPT_COMMAND set_actor_z_angle = { 0x0173, "if" };
const SCRIPT_COMMAND enter_passenger_driveby = { 0x0713, "iiiffffiii" };
const SCRIPT_COMMAND lock_actor = { 0x04d7, "ii" };
const SCRIPT_COMMAND refresh_streaming_at = { 0x04E4, "ff" };
const SCRIPT_COMMAND put_actor_in_car2 = { 0x0430, "iii" };
const SCRIPT_COMMAND kill_actor = { 0x0321, "i" };
const SCRIPT_COMMAND set_actor_animation_set = { 0x0245, "is" };
const SCRIPT_COMMAND request_animation = { 0x04ED, "s" };
const SCRIPT_COMMAND is_animation_loaded = { 0x04EE, "s" };
const SCRIPT_COMMAND release_animation = { 0x04EF, "s" };
const SCRIPT_COMMAND apply_animation = { 0x0812, "issfiiiii" }; // actor,animation,library,floatunk,bool,bool,bool,bool,int
const SCRIPT_COMMAND is_actor_performing_anim = { 0x0611, "is" };
const SCRIPT_COMMAND set_actor_weapon_droppable = { 0x087e, "ii" };
const SCRIPT_COMMAND set_actor_money = { 0x03fe, "ii" };
const SCRIPT_COMMAND text_clear_all = { 0x00be, "" };
const SCRIPT_COMMAND set_car_hydraulics = { 0x07FF, "ii" }; //iCar, i (0=off/1=on)
const SCRIPT_COMMAND attach_object_to_actor = { 0x069b, "iiffffff" };
const SCRIPT_COMMAND set_object_scaling = { 0x08d2, "if" };
const SCRIPT_COMMAND create_pickup = { 0x0213, "iifffv" };
const SCRIPT_COMMAND create_pickup_with_ammo = { 0x032b, "iiifffv" };
const SCRIPT_COMMAND is_pickup_picked_up = { 0x0214, "i" };
const SCRIPT_COMMAND destroy_pickup = { 0x0215, "i" };
const SCRIPT_COMMAND change_car_skin = { 0x06ED, "ii" };
const SCRIPT_COMMAND add_car_component = { 0x06E7, "iiv" }; // CAR, COMPONENT, COMPONENT VAR NAME
const SCRIPT_COMMAND is_component_available = { 0x06EA, "i" };
const SCRIPT_COMMAND request_car_component = { 0x06E9, "i" };
const SCRIPT_COMMAND remove_component = { 0x06E8, "ii" };
const SCRIPT_COMMAND show_on_radar2 = { 0x018b, "ii" };
const SCRIPT_COMMAND find_ground_z = { 0x02CE, "fffv" };
const SCRIPT_COMMAND toggle_actor_cellphone = { 0x0729, "ii" };
const SCRIPT_COMMAND actor_task_handsup = { 0x5c4, "ii" };
const SCRIPT_COMMAND toggle_car_tires_vulnerable = { 0x053f, "ii" };
const SCRIPT_COMMAND set_fighting_style = { 0x07fe, "iii" };
const SCRIPT_COMMAND link_vehicle_to_interior = { 0x0840, "ii" };
const SCRIPT_COMMAND destroy_object = { 0x0108, "i" };
const SCRIPT_COMMAND create_radar_marker_icon = { 0x0570, "fffiv" };
const SCRIPT_COMMAND put_trailer_on_cab = { 0x893, "ii" };
const SCRIPT_COMMAND detach_trailer_from_cab = { 0x7AC, "ii" };
const SCRIPT_COMMAND create_explosion_with_radius = { 0x0948, "fffii" };
const SCRIPT_COMMAND enable_zone_names = { 0x09BA, "i" };
const SCRIPT_COMMAND remove_panel = { 0x08DA, "i" };
const SCRIPT_COMMAND create_panel = { 0x08D4, "sfffiiiiv" };
@ -103,23 +187,34 @@ const SCRIPT_COMMAND set_panel_row_enable = { 0x08D9, "iii" };
const SCRIPT_COMMAND get_panel_active_row = { 0x08D7, "iv" };
const SCRIPT_COMMAND destroy_particle = { 0x650, "i" };
const SCRIPT_COMMAND attach_particle_to_actor2 = { 0x066a, "siffffffiv" };
const SCRIPT_COMMAND make_particle_visible = { 0x64c, "i" };
const SCRIPT_COMMAND restore_camera_to_user_defined = { 0x925, "" };
const SCRIPT_COMMAND set_camera_position_to = { 0x936, "ffffffii" };
const SCRIPT_COMMAND point_camera_transverse_to = { 0x920, "ffffffii" };
const SCRIPT_COMMAND lock_camera_target_point = { 0x92F, "i" };
const SCRIPT_COMMAND lock_camera_position = { 0x930, "i" };
const SCRIPT_COMMAND set_actor_dicision = { 0x60B, "ii" };
const SCRIPT_COMMAND create_marker_at = { 0x2A8, "fffiv" };
const SCRIPT_COMMAND set_player_drunk_visuals = { 0x052c, "ii" }; // player, severity (0-255)
const SCRIPT_COMMAND handling_responsiveness = { 0x03fd, "ii" }; // player, severity (0-255)
// ---
const SCRIPT_COMMAND load_wav = { 0x3CF, "ii" };
const SCRIPT_COMMAND is_wav_loaded = { 0x3D0, "i" };
const SCRIPT_COMMAND play_wav = { 0x3D1, "i" };
const SCRIPT_COMMAND unload_wav = { 0x40D, "i" };
const SCRIPT_COMMAND set_wav_at_location = { 0x3D7, "ifff" };
const SCRIPT_COMMAND restore_camera_to_user_defined = { 0x0925, "" };
const SCRIPT_COMMAND set_camera_position_to = { 0x0936, "ffffffii" };
const SCRIPT_COMMAND point_camera_transverse_to = { 0x0920, "ffffffii" };
const SCRIPT_COMMAND lock_camera_target_point = { 0x092F, "i" };
const SCRIPT_COMMAND lock_camera_position = { 0x0930, "i" };
const SCRIPT_COMMAND load_wav = { 0x03CF, "ii" };
const SCRIPT_COMMAND is_wav_loaded = { 0x03D0, "i" };
const SCRIPT_COMMAND play_wav = { 0x03D1, "i" };
const SCRIPT_COMMAND unload_wav = { 0x040D, "i" };
const SCRIPT_COMMAND set_wav_at_location = { 0x03D7, "ifff" };
const SCRIPT_COMMAND create_marker_at = { 0x02A8, "fffiv" };
const SCRIPT_COMMAND attach_object_to_car = { 0x0681, "iiffffff" };
const SCRIPT_COMMAND is_object_attached = { 0x0685, "i" };
const SCRIPT_COMMAND attach_object_to_object = { 0x069A, "iiffffff" };
const SCRIPT_COMMAND task_pick_up_object = { 0x070A, "iifffiissi" };

View File

@ -396,4 +396,3 @@ CTaskKillPedOnFootArmed::CTaskKillPedOnFootArmed( int unk, int unk2, int unk3, i
}
//==========================================================

205
saco/game/textdraw.cpp Normal file
View File

@ -0,0 +1,205 @@
#include "../main.h"
#include "font.h"
#include "util.h"
#include "textures.h"
extern CGame *pGame;
DWORD unnamed_1026B568[200];
BOOL unnamed_1026B888[200];
void CallRwRenderStateSet(int state, int option);
BOOL unnamed_100B2AF0()
{
memset(unnamed_1026B888, 0, sizeof(unnamed_1026B888));
memset(unnamed_1026B568, 0, sizeof(unnamed_1026B568));
return TRUE;
}
int unnamed_100B2B20()
{
int x=0;
while(x!=200) {
if(unnamed_1026B888[x] == FALSE) {
unnamed_1026B888[x] = TRUE;
return x;
}
x++;
}
return (-1);
}
void unnamed_100B2B50(int iSlot)
{
if(iSlot < 0 || iSlot >= 200) return;
unnamed_1026B888[iSlot] = FALSE;
if(unnamed_1026B568[iSlot])
DestroyTexture(unnamed_1026B568[iSlot]);
unnamed_1026B568[iSlot] = 0;
}
BOOL unnamed_100B2B90(char *a1, char *a2, bool a3)
{
char v5[64];
if(a3)
strcpy(v5, "SAMP\\");
else
strcpy(v5, "models\\txd");
if(FindTextureSlot(a1) != -1)
return TRUE;
int v3 = AddTextureSlot(a1);
char v9[64];
sprintf(v9, "%s\\%s.txd", v5, a2);
if(IsFileOrDirectoryExists(v9))
{
LoadTexture(v3, v9);
AddTextureRef(v3);
return TRUE;
}
return FALSE;
}
DWORD unnamed_100B2C60(char *a1, char *a2)
{
int v1 = FindTextureSlot(a1);
if(v1 == -1) return 0;
PushCurrentTexture();
SetCurrentTexture(v1);
DWORD v4 = ReloadTexture(a2);
PopCurrentTexture();
return v4;
}
void unnamed_100B2CA0(DWORD a1, int a2, int a3)
{
if(!a1) return;
CallRwRenderStateSet(9, 2);
_asm push a3
_asm push a2
_asm mov ecx, a1
_asm mov edx, 0x728350
_asm call edx
}
CTextDraw::CTextDraw(TEXT_DRAW_TRANSMIT *TextDrawTransmit, PCHAR szText)
{
memset(&m_TextDrawData,0,sizeof(TEXT_DRAW_DATA));
m_TextDrawData.field_0 = TextDrawTransmit->field_1;
m_TextDrawData.field_4 = TextDrawTransmit->field_5;
m_TextDrawData.field_8 = TextDrawTransmit->field_9;
m_TextDrawData.field_C = 0;
m_TextDrawData.field_D = ((unsigned __int8)TextDrawTransmit->field_0 >> 3) & 1;
m_TextDrawData.field_E = TextDrawTransmit->field_0 & 1;
m_TextDrawData.field_F = TextDrawTransmit->field_D;
m_TextDrawData.field_13 = TextDrawTransmit->field_11;
m_TextDrawData.field_17 = TextDrawTransmit->field_15;
m_TextDrawData.field_1B = ((unsigned __int8)TextDrawTransmit->field_0 >> 4) & 1;
m_TextDrawData.field_1C = TextDrawTransmit->field_1B;
m_TextDrawData.field_20 = TextDrawTransmit->field_19;
m_TextDrawData.field_21 = TextDrawTransmit->field_1A;
m_TextDrawData.field_22 = ((unsigned __int8)TextDrawTransmit->field_0 >> 1) & 1;
m_TextDrawData.field_23 = ((unsigned __int8)TextDrawTransmit->field_0 >> 2) & 1;
m_TextDrawData.field_24 = TextDrawTransmit->field_1F;
m_TextDrawData.field_28 = TextDrawTransmit->field_21;
m_TextDrawData.field_2C = TextDrawTransmit->field_25;
m_TextDrawData.field_38 = -1;
m_TextDrawData.field_3C = -1;
m_TextDrawData.field_44 = TextDrawTransmit->field_20;
m_TextDrawData.field_45 = TextDrawTransmit->field_29;
m_TextDrawData.field_47 = TextDrawTransmit->field_2B;
m_TextDrawData.field_4B = TextDrawTransmit->field_2F;
m_TextDrawData.field_4F = TextDrawTransmit->field_33;
m_TextDrawData.field_53 = TextDrawTransmit->field_37;
m_TextDrawData.field_57 = TextDrawTransmit->field_3B;
m_TextDrawData.field_59 = TextDrawTransmit->field_3D;
field_9C0 = 0;
m_TextDrawData.field_40 = -1;
SetText(szText);
if(m_TextDrawData.field_24 == 4)
{
m_TextDrawData.field_40 = unnamed_100B2B20();
FUNC_100B2CD0();
}
field_9BF = 0;
field_9C1 = 0;
field_9C9 = 0;
field_9C5 = 0;
field_9CD = 0;
field_9D1 = 0;
field_9D2 = 0;
}
CTextDraw::~CTextDraw()
{
unnamed_100B2B50(m_TextDrawData.field_40);
}
void CTextDraw::SetText(char* szText)
{
// TODO: CTextDraw::SetText .text:100B2F60
}
void CTextDraw::FUNC_100B2CD0()
{
// TODO: CTextDraw::FUNC_100B2CD0 .text:100B2CD0
}

98
saco/game/textdraw.h Normal file
View File

@ -0,0 +1,98 @@
#pragma once
#define MAX_TEXT_DRAW_LINE 800
//-----------------------------------------------------------
typedef struct _TEXT_DRAW_DATA
{
int field_0;
int field_4;
int field_8;
char field_C;
char field_D;
char field_E;
int field_F;
int field_13;
int field_17;
char field_1B;
int field_1C;
char field_20;
char field_21;
char field_22;
char field_23;
int field_24;
int field_28;
int field_2C;
char _gap30[8];
int field_38;
int field_3C;
int field_40;
char field_44;
short field_45;
int field_47;
int field_4B;
int field_4F;
int field_53;
short field_57;
short field_59;
} TEXT_DRAW_DATA;
//-----------------------------------------------------------
typedef struct _TEXT_DRAW_TRANSMIT
{
char field_0;
int field_1;
int field_5;
int field_9;
int field_D;
int field_11;
int field_15;
char field_19;
char field_1A;
int field_1B;
char field_1F;
char field_20;
int field_21;
int field_25;
short field_29;
int field_2B;
int field_2F;
int field_33;
int field_37;
short field_3B;
short field_3D;
} TEXT_DRAW_TRANSMIT;
//----------------------------------------------------
class CTextDraw
{
private:
CHAR m_szText[MAX_TEXT_DRAW_LINE];
TEXT_DRAW_DATA m_TextDrawData;
char field_9BF;
char field_9C0;
int field_9C1;
int field_9C5;
int field_9C9;
int field_9CD;
char field_9D1;
int field_9D2;
public:
CTextDraw(TEXT_DRAW_TRANSMIT *TextDrawTransmit, PCHAR szText);
~CTextDraw();
void SetText(char* szText);
void FUNC_100B2CD0();
};
//----------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More