Merge pull request #20 from ricardoofnl/main

[saco] implement/match some func on saco
This commit is contained in:
RD42
2026-10-04 18:38:39 +02:00
committed by GitHub
70 changed files with 14840 additions and 1083 deletions
+86 -1
View File
@@ -33,4 +33,89 @@ Status values may not be 100% accurate and will fluctuate during the analyzation
## Building ## Building
TODO ### Toolchain
The client library is built with **Microsoft Visual C++ 7.1 (`cl.exe` 13.10.3077)**, the compiler that ships
with Visual Studio .NET 2003. This is not a preference. A matching decompilation only reproduces the original
bytes if the original compiler produces them, and no later MSVC release generates the same code for this
source. Building with a modern toolset may well succeed and will not match.
Two flags worth knowing before you start: `/GS-` does not exist in VC7.1 (buffer security checks are off by
default, and `BufferSecurityCheck="FALSE"` in the project reflects that), and `__thiscall` is not a usable
keyword in this compiler version.
### On Windows
Open `saco.sln` in Visual Studio .NET 2003 and build the `Release` configuration of the `saco` project. The
output is `saco/Release/samp.dll`. The `Debug` configuration exists but produces nothing comparable to the
original binary.
Other components have their own solutions: `announce/announce.sln`, `arctool2/arctool2.sln`, `bot/bot.sln`
and `server/server.sln`.
### On Linux
VC7.1 runs well under Wine. Install Visual Studio .NET 2003 into a Wine prefix, then invoke `cl.exe`
directly. Two things are easy to get wrong: the working directory has to be `saco/`, and `INCLUDE` has to be
set explicitly, because the Wine environment does not inherit the compiler's own registry settings.
```sh
export WINEPREFIX="$HOME/.wine"
VC='C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7'
export INCLUDE="$VC\\include;$VC\\PlatformSDK\\Include"
cd saco
wine "$VC\\bin\\cl.exe" /c /Ox /Og /Ob1 /Oi /Ot /Oy /MT /Zp1 /EHsc /GF \
/D WIN32 /D NDEBUG /D _WINDOWS /D _USRDLL /D SACO_EXPORTS /D SAMPCLI \
/I "d3d9\\include" /I "." net\\netgame.cpp /Fo"Z:\\tmp\\netgame.obj"
```
### Release settings
These are the settings the `Release` configuration in `saco/saco.vcproj` expands to. They matter because
changing any of them changes the generated code, so a function that matched before may stop matching.
| Flag | Project property |
| --- | --- |
| `/Ox` | `Optimization="3"` |
| `/Og` | `GlobalOptimizations="TRUE"` |
| `/Ob1` | `InlineFunctionExpansion="1"` |
| `/Oi` | `EnableIntrinsicFunctions="TRUE"` |
| `/Ot` | `FavorSizeOrSpeed="1"` |
| `/Oy` | `OmitFramePointers="TRUE"` |
| `/GF` | `StringPooling="TRUE"` |
| `/EHsc` | `ExceptionHandling="TRUE"` |
| `/MT` | `RuntimeLibrary="0"` |
| `/Zp1` | `StructMemberAlignment="1"` |
Preprocessor definitions are `WIN32`, `NDEBUG`, `_WINDOWS`, `_USRDLL`, `SACO_EXPORTS` and `SAMPCLI`, and the
only additional include directory is `d3d9\include`.
Five files carry per-file overrides, and compiling them with the defaults above will not match:
| File | Override |
| --- | --- |
| `game/entity.cpp` | `/O2` |
| `game/keystuff.cpp` | `/O2` |
| `game/patches.cpp` | `/O2` |
| `httpclient.cpp` | `/O2` |
| `d3d9/dxutil.cpp` | `/Ob2` |
The link is `/SUBSYSTEM:WINDOWS /MACHINE:X86` against `dxguid.lib`, `d3d9.lib`, `d3dx9.lib`, `comctl32.lib`,
`wsock32.lib`, `winmm.lib` and `bass.lib`, with `d3d9` as an additional library directory. Both
`/OPT:NOREF` and `/OPT:NOICF` are in effect (`OptimizeReferences="0"` and `EnableCOMDATFolding="0"`), so the
linker neither strips unreferenced functions nor folds identical ones. Identical functions therefore appear
separately in the original binary, which is why byte-identical siblings are expected rather than suspicious.
### Current state of the build
`samp.dll` does not link yet. `raknet/SocketDataEncryptor.cpp` is referenced by the project but is not
present in the tree, and it is the only such file. Every other translation unit the project lists compiles
cleanly.
Because of that, progress is measured per function rather than per binary. A function counts as done when the
bytes the compiler emits for it are identical to the bytes at the corresponding address in the original
`samp.dll`, after masking the four-byte slots that COFF marks as relocations. Masking is what makes an
unlinked object file comparable to a linked binary: call targets, global addresses and string addresses are
resolved at link time and cannot agree, while every other byte must.
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// only SetKey is reconstructed; it is all `CNetGame::CNetGame` needs
class SocketDataEncryptor
{
public:
static void SetKey(int iPort);
};
+111 -7
View File
@@ -1,19 +1,98 @@
#include "audiostream.h" #include "main.h"
#include "bass.h"
void CAudioStream::Reset() extern CGame *pGame;
extern CConfig *pConfig;
extern CFontRender *pDefaultFont;
// stream state (file scope)
HSTREAM g_hStream = 0;
volatile BYTE g_bPlaying = 0;
BYTE g_bStopRequested = 0;
float g_fPosX = 0.0f;
float g_fPosY = 0.0f;
float g_fPosZ = 0.0f;
float g_fDistance = 0.0f;
BYTE g_bIs3D = 0;
char g_szUrl[257];
char g_szMeta[257];
char g_szName[257];
char g_szUrlInfo[257];
int CAudioStream::Reset()
{ {
// TODO: CAudioStream::sub_10066480 10066480 g_hStream = 0;
BASS_Free();
if(BASS_Init(-1, 44100, 0, 0, 0))
{
BASS_SetConfigPtr(BASS_CONFIG_NET_AGENT, "SA-MP/0.3");
BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, (DWORD)(pGame->m_pGameAudio->GetRadioVolume() * 7000.0f));
BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1);
BASS_SetConfig(BASS_CONFIG_NET_TIMEOUT, 10000);
if(!pConfig->IsVariableExist("audioproxyoff"))
pConfig->SetIntVariable("audioproxyoff", 0, 0);
if(pConfig->GetIntVariable("audioproxyoff"))
BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, 0);
BASS_SetEAXParameters(-1, 0, -1.0f, -1.0f);
field_0 = 1;
return 1;
}
return 0;
} }
void CAudioStream::Stop() void CAudioStream::Stop(char byteResetRadio)
{ {
// TODO: CAudioStream::sub_10066560 10066560 // TODO: CAudioStream::sub_10066560 10066560
} }
void CAudioStream::ConstructInfo() void CAudioStream::ConstructInfo()
{ {
// TODO: CAudioStream::sub_100665C0 100665C0 const char *pTags;
memset(g_szMeta, 0, 257);
pTags = (const char *)BASS_ChannelGetTags(g_hStream, BASS_TAG_META);
if(pTags)
{
char *p = strstr((char *)pTags, "StreamTitle='");
if(p)
{
char *pDup = _strdup(p + 13);
*(strchr(pDup, ';') - 1) = 0;
_snprintf(g_szMeta, 256, "%s", pDup);
free(pDup);
}
}
else
{
pTags = (const char *)BASS_ChannelGetTags(g_hStream, BASS_TAG_OGG);
if(pTags)
{
char *pArtist = 0;
char *pTitle = 0;
char *p = (char *)pTags;
if(*p)
{
do
{
if(!_strnicmp(p, "artist=", 7)) pArtist = p + 7;
if(!_strnicmp(p, "title=", 6)) pTitle = p + 6;
p += strlen(p) + 1;
}
while(*p);
if(pArtist)
_snprintf(g_szMeta, 256, "%s - %s", pArtist, pTitle);
else if(pTitle)
_snprintf(g_szMeta, 256, "%s", pTitle);
}
}
}
} }
void CAudioStream::SyncProc() void CAudioStream::SyncProc()
@@ -33,10 +112,35 @@ void CAudioStream::Play()
void CAudioStream::ControlGameRadio() void CAudioStream::ControlGameRadio()
{ {
// TODO: CAudioStream::sub_10066A80 10066A80 if(field_0 && g_bPlaying)
{
pGame->m_pGameAudio->StartRadio(-1);
pGame->m_pGameAudio->StopRadio();
}
} }
void CAudioStream::DrawInfo() void CAudioStream::DrawInfo()
{ {
// TODO: CAudioStream::sub_10066AB0 10066AB0 char szString[264];
if(field_0 && g_bPlaying)
{
memset(szString, 0, 257);
if(strlen(g_szMeta) && strlen(g_szName))
{
RECT rc;
int iTop;
_snprintf(szString, 256, "%s - %s", g_szMeta, g_szName);
iTop = pGame->GetScreenHeight() - 20;
rc.left = 15;
rc.top = iTop;
rc.bottom = iTop + 30;
rc.right = pGame->GetScreenWidth();
pDefaultFont->RenderText(NULL, szString, rc, DT_NOCLIP, 0x99FFFFFF, FALSE);
}
}
} }
+3 -2
View File
@@ -12,12 +12,13 @@ public:
field_0 = 0; field_0 = 0;
} }
void Reset(); int Reset();
void Stop(); void Stop(char byteResetRadio);
void ConstructInfo(); void ConstructInfo();
void SyncProc(); void SyncProc();
void Process(); void Process();
void Play(); void Play();
void FUNC_10066960(char *szURL, float fX, float fY, float fZ, float fRadius, char bUsePos); // .text:10066960
void ControlGameRadio(); void ControlGameRadio();
void DrawInfo(); void DrawInfo();
}; };
+548 -4
View File
@@ -1,5 +1,17 @@
#include <time.h>
#include "main.h" #include "main.h"
#include "game/util.h"
extern CConfig *pConfig;
extern CCmdWindow *pCmdWindow;
extern CGame *pGame;
typedef char AssertEntrySize[sizeof(CHAT_WINDOW_ENTRY) == 252 ? 1 : -1];
typedef char AssertEntryText[offsetof(CHAT_WINDOW_ENTRY, szText) == 0x20 ? 1 : -1];
typedef char AssertEntryType[offsetof(CHAT_WINDOW_ENTRY, iType) == 0xF0 ? 1 : -1];
typedef char AssertChatWindowSize[sizeof(CChatWindow) == 25578 ? 1 : -1];
typedef char AssertTimestampWidth[offsetof(CChatWindow, field_63E6) == 0x63E6 ? 1 : -1];
//---------------------------------------------------- //----------------------------------------------------
@@ -26,7 +38,7 @@ CChatWindow::CChatWindow(IDirect3DDevice9 *pD3DDevice, CFontRender *pFontRender,
m_dwChatDebugColor = D3DCOLOR_ARGB(255,169,196,228); m_dwChatDebugColor = D3DCOLOR_ARGB(255,169,196,228);
field_0 = 10; field_0 = 10;
field_C = 0; m_bTimestamp = 0;
if(szChatLogFile && strlen(szChatLogFile)) if(szChatLogFile && strlen(szChatLogFile))
{ {
@@ -57,8 +69,66 @@ CChatWindow::CChatWindow(IDirect3DDevice9 *pD3DDevice, CFontRender *pFontRender,
void CChatWindow::CreateFonts() void CChatWindow::CreateFonts()
{ {
D3DSURFACE_DESC desc;
HRESULT hr;
// TODO: CChatWindow::CreateFonts .text:100681D0 field_63B2 = 1;
if(field_63BE) {
field_63BE->Release();
field_63BE = NULL;
}
if(field_63BA) {
field_63BA->Release();
field_63BA = NULL;
}
if(field_63B6) {
field_63B6->Release();
field_63B6 = NULL;
}
m_pD3DDevice->GetDisplayMode(0,&field_63C2);
if(pConfig->GetIntVariable("directmode")) {
AddDebugMessage("ChatWindow: Using direct drawing mode.");
FUNC_10067120();
field_63B2 = 0;
return;
}
// the render target has to cover the whole screen
if(field_63C2.Width <= 1024) {
hr = D3DXCreateTexture(m_pD3DDevice,1024,512,1,D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&field_63BA);
} else {
hr = D3DXCreateTexture(m_pD3DDevice,2048,1024,1,D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&field_63BA);
}
if(hr < 0) {
AddDebugMessage("ChatWindow: Can't create a render surface texture. Will use direct mode.");
field_63B2 = 0;
return;
}
field_63BA->GetSurfaceLevel(0,&field_63BE);
field_63BE->GetDesc(&desc);
if(D3DXCreateRenderToSurface(m_pD3DDevice,desc.Width,desc.Height,desc.Format,
TRUE,D3DFMT_D16,&field_63B6) < 0)
{
AddDebugMessage("ChatWindow: Can't create a render to surface. Will use direct mode.");
FUNC_10067120();
field_63B2 = 0;
return;
}
FUNC_10067120();
field_63D6 = 0;
m_bRedraw = 1;
} }
//---------------------------------------------------- //----------------------------------------------------
@@ -80,9 +150,26 @@ void CChatWindow::ResetDialogControls(CDXUTDialog *pGameUI)
//---------------------------------------------------- //----------------------------------------------------
//---------------------------------------------------- //----------------------------------------------------
void CChatWindow::AddDebugMessage(CHAR * szFormat, ...) int CChatWindow::AddDebugMessage(CHAR * szFormat, ...)
{ {
// TODO: CChatWindow::AddDebugMessage .text:100680F0 char szBuffer[512];
va_list va;
va_start(va, szFormat);
memset(szBuffer, 0, sizeof(szBuffer));
vsprintf(szBuffer, szFormat, va);
char *p = szBuffer;
if(szBuffer[0])
{
do
{
if(*p > 0 && *p < 32)
*p = 32;
}
while(*++p);
}
return sub_10067BE0(8, szBuffer, 0, m_dwChatDebugColor, 0);
} }
// MATCH // MATCH
void CChatWindow::FUNC_10067200() void CChatWindow::FUNC_10067200()
@@ -96,3 +183,460 @@ void CChatWindow::FUNC_10067200()
} }
} }
//----------------------------------------------------
void CChatWindow::SetPageSize(int iPageSize)
{
if(iPageSize >= 10 && iPageSize <= MAX_MESSAGES) {
field_0 = iPageSize;
FUNC_10067200();
m_bRedraw = 1;
}
}
//----------------------------------------------------
void CChatWindow::ReplaceControlChars(char *szString)
{
if(*szString)
{
do
{
if(*szString > 0 && *szString < 32)
*szString = 32;
}
while(*++szString);
}
}
//----------------------------------------------------
void CChatWindow::PageUp()
{
if(field_8 && m_pScrollBar && !pGame->sub_100A0920() && !pCmdWindow->IsImeActive()) {
int iPos = m_pScrollBar->GetTrackPos()-field_0;
if(iPos < 1) iPos = 1;
m_pScrollBar->SetTrackPos(iPos);
}
}
//----------------------------------------------------
void CChatWindow::PageDown()
{
if(field_8 && m_pScrollBar && !pGame->sub_100A0920() && !pCmdWindow->IsImeActive()) {
int iPos = m_pScrollBar->GetTrackPos();
if(iPos == 1)
iPos = field_0;
else
iPos += field_0;
if(iPos > MAX_MESSAGES) iPos = MAX_MESSAGES;
m_pScrollBar->SetTrackPos(iPos);
}
}
//----------------------------------------------------
void CChatWindow::FUNC_10067390()
{
if(m_pScrollBar)
m_pScrollBar->SetTrackPos(MAX_MESSAGES-10);
}
//----------------------------------------------------
void CChatWindow::OnMouseWheel(int nDelta)
{
if(field_8 && m_pScrollBar) {
int nScrollLines;
SystemParametersInfo(SPI_GETWHEELSCROLLLINES,0,&nScrollLines,0);
m_pScrollBar->Scroll(-(nDelta*nScrollLines));
}
}
//----------------------------------------------------
void CChatWindow::AddChatMessage(PCHAR szName, DWORD dwColor, PCHAR szText)
{
char *p = szText;
if(szText[0])
{
do
{
if(*p > 0 && *p < 32)
*p = 32;
}
while(*++p);
}
sub_10067BE0(2, szText, szName, m_dwChatTextColor, dwColor);
}
//----------------------------------------------------
void CChatWindow::AddClientMessage(DWORD dwColor, CHAR *szMessage)
{
if(strlen(szMessage) <= 144)
{
unnamed_100B6100(szMessage,255);
ReplaceControlChars(szMessage);
sub_10067BE0(4, szMessage, 0, (dwColor >> 8)|0xFF000000, 0);
}
}
//----------------------------------------------------
void CChatWindow::AddInfoMessage(CHAR * szFormat, ...)
{
char szBuffer[512];
va_list va;
va_start(va, szFormat);
memset(szBuffer, 0, sizeof(szBuffer));
vsprintf(szBuffer, szFormat, va);
char *p = szBuffer;
if(szBuffer[0])
{
do
{
if(*p > 0 && *p < 32)
*p = 32;
}
while(*++p);
}
sub_10067BE0(4, szBuffer, 0, m_dwChatInfoColor, 0);
}
//----------------------------------------------------
void CChatWindow::ReleaseTextures()
{
if(field_63BE) {
field_63BE->Release();
field_63BE = NULL;
}
if(field_63BA) {
field_63BA->Release();
field_63BA = NULL;
}
if(field_63B6) {
field_63B6->Release();
field_63B6 = NULL;
}
}
//----------------------------------------------------
void CChatWindow::FUNC_10067410()
{
ReleaseTextures();
}
//----------------------------------------------------
// measures the line height and the width of a timestamp with DT_CALCRECT
void CChatWindow::FUNC_10067120()
{
RECT rect;
m_pFontRender->field_0->DrawTextA(NULL,"Y",-1,&rect,DT_CALCRECT|DT_SINGLELINE,0xFF000000);
field_63E2 = rect.bottom-rect.top;
m_pFontRender->field_0->DrawTextA(NULL,"[19:58:34]",-1,&rect,DT_CALCRECT|DT_SINGLELINE,0xFF000000);
field_63E6 = rect.right-rect.left;
}
//----------------------------------------------------
void CChatWindow::FUNC_10067E00()
{
if(m_pScrollBar)
{
if(field_8 && (m_pScrollBar->GetTrackPos() != MAX_MESSAGES-field_0 || pCmdWindow->m_bEnabled))
m_pScrollBar->SetVisible(true);
else
m_pScrollBar->SetVisible(false);
if(field_8)
{
if(field_63B2 && field_63D6)
{
field_63AA->Begin(D3DXSPRITE_ALPHABLEND);
field_63AA->Draw(field_63BA,NULL,NULL,NULL,0xFFFFFFFF);
field_63AA->End();
}
else
{
field_63A6->Begin(D3DXSPRITE_ALPHABLEND);
FUNC_10067940();
field_63A6->End();
}
}
}
}
//----------------------------------------------------
void CChatWindow::WriteChatLog(int iType, char *szText, char *szName)
{
time_t curTime = time(NULL);
if(field_D)
{
FILE *f = fopen(field_11,"a");
if(f)
{
// the frame reserves 68 bytes for this, strftime is still capped at 64
char szTimestamp[68];
strftime(szTimestamp,64,"[%H:%M:%S]",localtime(&curTime));
switch(iType)
{
case 2:
fprintf(f,"%s <%s> %s\r\n",szTimestamp,szName,szText);
break;
case 4:
case 8:
fprintf(f,"%s %s\r\n",szTimestamp,szText);
break;
}
fclose(f);
}
}
}
//----------------------------------------------------
// redraws the chat into the render target texture when it is dirty
void CChatWindow::FUNC_10067ED0()
{
if(field_63B2 && m_pD3DDevice && field_63B6 && field_63BA && field_63BE && m_pFontRender->field_0)
{
if(pGame->sub_100A0920())
{
field_63D6 = 0;
m_bRedraw = 1;
}
else if(field_8)
{
if(m_bRedraw || field_63DE != m_pScrollBar->GetTrackPos())
{
field_63B6->BeginScene(field_63BE,NULL);
m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0,0,0);
field_63A6->Begin(D3DXSPRITE_ALPHABLEND);
m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_BLENDFACTOR);
FUNC_10067940();
field_63A6->End();
field_63B6->EndScene(0);
m_bRedraw = 0;
field_63D6 = 1;
field_63D2 = GetTickCount();
field_63DE = m_pScrollBar->GetTrackPos();
}
}
}
}
//----------------------------------------------------
// lays out the visible page of chat lines
void CChatWindow::FUNC_10067940()
{
int x = 0;
int iEntry;
RECT rect, rectName;
char szTimestamp[72];
struct tm *pTime;
int iPos;
memset(szTimestamp,0,64);
rect.top = 10;
rect.left = 45;
rect.right = 550;
rect.bottom = 110;
if(m_pScrollBar->GetTrackPos() < 1)
m_pScrollBar->SetTrackPos(1);
iPos = m_pScrollBar->GetTrackPos();
if(iPos < 1)
iPos = 1;
iEntry = iPos;
while(x != field_0)
{
if(m_bTimestamp)
{
pTime = localtime(&m_ChatWindowEntries[iEntry].tTime);
memset(szTimestamp,0,64);
if(pTime)
strftime(szTimestamp,64,"[%H:%M:%S]",pTime);
}
switch(m_ChatWindowEntries[iEntry].iType)
{
case 2:
if(m_bTimestamp)
{
if(strlen(szTimestamp) && m_ChatWindowEntries[iEntry].szName[0])
{
FUNC_10067470(szTimestamp,rect,m_ChatWindowEntries[iEntry].dwTextColor);
rect.left = field_63E6+50;
}
}
if(strlen(m_ChatWindowEntries[iEntry].szName))
{
m_pFontRender->field_0->DrawTextA(NULL,m_ChatWindowEntries[iEntry].szName,-1,&rectName,DT_CALCRECT,0xFF000000);
FUNC_10067470(m_ChatWindowEntries[iEntry].szName,rect,m_ChatWindowEntries[iEntry].dwNameColor);
rect.left += rectName.right-rectName.left+5;
}
FUNC_10067470(m_ChatWindowEntries[iEntry].szText,rect,m_ChatWindowEntries[iEntry].dwTextColor);
break;
case 4:
case 8:
if(m_bTimestamp)
{
if(strlen(szTimestamp))
{
FUNC_10067470(szTimestamp,rect,m_ChatWindowEntries[iEntry].dwTextColor);
rect.left = field_63E6+50;
}
}
FUNC_10067470(m_ChatWindowEntries[iEntry].szText,rect,m_ChatWindowEntries[iEntry].dwTextColor);
break;
}
iEntry++;
rect.top += field_63E2+1;
rect.bottom = rect.top+field_63E2+1;
rect.left = 45;
x++;
}
field_12E = rect.bottom;
}
//----------------------------------------------------
// draws the text with a black outline, thicker over 1280 wide
void CChatWindow::FUNC_10067470(char *szText, RECT rect, DWORD dwColor)
{
ID3DXFontHook *pFont;
ID3DXFont *pShadow;
int iLen;
pShadow = m_pFontRender->field_8;
pFont = m_pFontRender->field_0;
iLen = strlen(szText);
if(field_8 == 2)
{
char szBuffer[512] = {0};
int iShadowLen;
strncpy(szBuffer,szText,511);
RemoveColorEmbedsFromString(szBuffer);
iShadowLen = strlen(szBuffer);
if(*(int *)0xC17044 > 1280)
{
rect.top -= 2;
rect.bottom -= 2;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.top++;
rect.bottom++;
rect.left--;
rect.right--;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left++;
rect.right++;
rect.left++;
rect.right++;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left--;
rect.right--;
rect.top++;
rect.bottom++;
rect.top += 2;
rect.bottom += 2;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.top--;
rect.bottom--;
rect.left--;
rect.right--;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left++;
rect.right++;
rect.left++;
rect.right++;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left--;
rect.right--;
rect.top--;
rect.bottom--;
rect.left -= 2;
rect.right -= 2;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left += 2;
rect.right += 2;
rect.left += 2;
rect.right += 2;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left -= 2;
rect.right -= 2;
}
else
{
rect.top--;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.top += 2;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.top--;
rect.left--;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left += 2;
pShadow->DrawTextA(field_63A6,szBuffer,iShadowLen,&rect,DT_NOCLIP|DT_SINGLELINE,0xFF000000);
rect.left--;
}
}
pFont->DrawTextA(field_63A6,szText,iLen,&rect,DT_NOCLIP|DT_SINGLELINE,dwColor|0xFF000000);
}
+50 -9
View File
@@ -7,17 +7,22 @@
#pragma pack(1) #pragma pack(1)
typedef struct _CHAT_WINDOW_ENTRY typedef struct _CHAT_WINDOW_ENTRY
{ {
char _gap0[252]; time_t tTime;
char szName[28];
char szText[208];
int iType;
DWORD dwTextColor;
DWORD dwNameColor;
} CHAT_WINDOW_ENTRY; } CHAT_WINDOW_ENTRY;
class CChatWindow // size: 25578 class CChatWindow // size: 25578
{ {
private: public:
int field_0; int field_0;
char _gap4[4]; char _gap4[4];
int field_8; int field_8;
char field_C; char m_bTimestamp;
int field_D; int field_D;
char field_11[261]; char field_11[261];
CDXUTDialog *m_pGameUI; CDXUTDialog *m_pGameUI;
@@ -26,7 +31,7 @@ private:
DWORD m_dwChatTextColor; DWORD m_dwChatTextColor;
DWORD m_dwChatInfoColor; DWORD m_dwChatInfoColor;
DWORD m_dwChatDebugColor; DWORD m_dwChatDebugColor;
char _gap12E[4]; int field_12E;
CHAT_WINDOW_ENTRY m_ChatWindowEntries[MAX_MESSAGES]; CHAT_WINDOW_ENTRY m_ChatWindowEntries[MAX_MESSAGES];
CFontRender *m_pFontRender; CFontRender *m_pFontRender;
ID3DXSprite *field_63A6; ID3DXSprite *field_63A6;
@@ -35,23 +40,59 @@ private:
int field_63B2; int field_63B2;
ID3DXRenderToSurface *field_63B6; ID3DXRenderToSurface *field_63B6;
IDirect3DTexture9* field_63BA; IDirect3DTexture9* field_63BA;
int field_63BE; IDirect3DSurface9 *field_63BE;
D3DDISPLAYMODE field_63C2; D3DDISPLAYMODE field_63C2;
DWORD field_63D2; DWORD field_63D2;
int field_63D6; int field_63D6;
int field_63DA; int m_bRedraw;
int field_63DE; int field_63DE;
int field_63E2; int field_63E2;
char _gap63E6[4]; int field_63E6;
void CreateFonts(); void CreateFonts(); // .text:100681D0
void FUNC_10067120(); // .text:10067120
void FUNC_10067200(); void FUNC_10067200();
void FUNC_10067390(); // .text:10067390
void OnMouseWheel(int nDelta); // .text:100673C0
void PageUp(); // .text:100672D0
void PageDown(); // .text:10067330
void ReplaceControlChars(char *szString); // .text:10067420
void ReleaseTextures(); // .text:100671A0
void FUNC_10067410(); // .text:10067410
void FUNC_10067470(char *szText, RECT rect, DWORD dwColor); // .text:10067470
void FUNC_10067940(); // .text:10067940
void FUNC_10067E00(); // .text:10067E00
void FUNC_10067ED0(); // .text:10067ED0
public: public:
void AddDebugMessage(CHAR *szFormat, ...); void WriteChatLog(int iType, char *szText, char *szName); // .text:100677D0
int sub_10067BE0(int a1, char *a2, char *a3, DWORD a4, DWORD a5); // .text:10067BE0
void AddChatMessage(PCHAR szName, DWORD dwColor, PCHAR szText); // .text:10068020
int AddDebugMessage(CHAR *szFormat, ...);
void AddInfoMessage(CHAR *szFormat, ...); // .text:10068070
void AddClientMessage(DWORD dwColor, CHAR *szMessage); // .text:10068170
void SetPageSize(int iPageSize); // .text:100672A0
void ResetDialogControls(CDXUTDialog *pGameUI); void ResetDialogControls(CDXUTDialog *pGameUI);
+289 -21
View File
@@ -1,15 +1,25 @@
#include "main.h" #include "main.h"
#include "game/util.h"
extern CChatWindow *pChatWindow; extern CChatWindow *pChatWindow;
extern CGame *pGame;
extern CCmdWindow *pCmdWindow; extern CCmdWindow *pCmdWindow;
extern CDeathWindow *pDeathWindow; extern CDeathWindow *pDeathWindow;
extern CNetGame *pNetGame; extern CNetGame *pNetGame;
extern GAME_SETTINGS tSettings; extern GAME_SETTINGS tSettings;
extern CConfig *pConfig; extern CConfig *pConfig;
extern CFontRender *pDefaultFont;
extern bool bShowDebugLabels; extern bool bShowDebugLabels;
extern bool bHudScaleFix; extern bool bHudScaleFix;
extern bool bCameraTargetDebug;
extern BOOL bToggleObjectLight;
void ShutdownGame(); // .text:100C3E80
int VehicleSelect(int a1, int a2, int a3); // .text:1009E0A0
void sub_100C5430(); // .text:100C5430
char *sub_100C3AD0(); // .text:100C3AD0
void cmdDefaultCmdProc(PCHAR szCmd) void cmdDefaultCmdProc(PCHAR szCmd)
{ {
@@ -36,37 +46,95 @@ void cmdTestDeathWindow(PCHAR szCmd)
void cmdCameraTargetDebug(PCHAR szCmd) void cmdCameraTargetDebug(PCHAR szCmd)
{ {
// TODO: cmdCameraTargetDebug .text:100685E0 bCameraTargetDebug = !bCameraTargetDebug;
} }
void cmdPageSize(PCHAR szCmd) void cmdPageSize(PCHAR szCmd)
{ {
// TODO: cmdPageSize .text:100685F0 int iPageSize;
if(strlen(szCmd) && (iPageSize = atoi(szCmd)) >= 10 && iPageSize <= 20)
{
if(pChatWindow) pChatWindow->SetPageSize(iPageSize);
if(pConfig) pConfig->SetIntVariable("pagesize", iPageSize);
}
else
{
if(pChatWindow) pChatWindow->AddDebugMessage("pagesize [10-20] (lines)");
}
} }
void cmdFontSize(PCHAR szCmd) void cmdFontSize(PCHAR szCmd)
{ {
// TODO: cmdFontSize .text:10068670 int iSize;
if(strlen(szCmd) && (iSize = atoi(szCmd)) >= -3 && iSize <= 5)
{
if(pConfig) pConfig->SetIntVariable("fontsize", iSize);
if(pDefaultFont) pDefaultFont->CreateFonts();
if(pChatWindow)
{
pChatWindow->CreateFonts();
pChatWindow->FUNC_10067200();
}
if(pDeathWindow) pDeathWindow->CreateFonts();
sub_100C5430();
}
else
{
if(pChatWindow) pChatWindow->AddDebugMessage("Valid fontsize: -3 to 5");
}
} }
void cmdNameTagStatus(PCHAR szCmd) void cmdNameTagStatus(PCHAR szCmd)
{ {
// TODO: cmdNameTagStatus .text:10068720 if(pNetGame) pNetGame->ToggleNameTagStatus();
} }
void cmdTimestamp(PCHAR szCmd) void cmdTimestamp(PCHAR szCmd)
{ {
// TODO: cmdTimestamp .text:10068730 CChatWindow *pChatWindow = ::pChatWindow;
if(pChatWindow)
{
if(pChatWindow->m_bTimestamp)
{
pChatWindow->m_bTimestamp = 0;
pChatWindow->m_bRedraw = 1;
if(pConfig) pConfig->SetIntVariable("timestamp", 0);
}
else
{
pChatWindow->m_bTimestamp = 1;
pChatWindow->m_bRedraw = 1;
if(pConfig) pConfig->SetIntVariable("timestamp", 1);
}
}
} }
void cmdAudioMsg(PCHAR szCmd) void cmdAudioMsg(PCHAR szCmd)
{ {
// TODO: cmdAudioMsg .text:10068790 if(pConfig->GetIntVariable("audiomsgoff") == 1)
{
pConfig->SetIntVariable("audiomsgoff", 0);
if(pChatWindow) pChatWindow->AddInfoMessage("Audio messages: On");
}
else
{
pConfig->SetIntVariable("audiomsgoff", 1);
if(pChatWindow) pChatWindow->AddInfoMessage("Audio messages: Off");
}
} }
void cmdLogUrls(PCHAR szCmd) void cmdLogUrls(PCHAR szCmd)
{ {
// TODO: cmdLogUrls .text:10068800 if(pConfig->GetIntVariable("logurls") == 1)
{
pConfig->SetIntVariable("logurls", 0);
if(pChatWindow) pChatWindow->AddInfoMessage("URL messages: Off");
}
else
{
pConfig->SetIntVariable("logurls", 1);
if(pChatWindow) pChatWindow->AddInfoMessage("URL messages: On");
}
} }
void cmdHudScaleFix(PCHAR szCmd) void cmdHudScaleFix(PCHAR szCmd)
@@ -92,67 +160,256 @@ void cmdMem(PCHAR szCmd)
void cmdSetFrameLimit(PCHAR szCmd) void cmdSetFrameLimit(PCHAR szCmd)
{ {
// TODO: cmdSetFrameLimit .text:100688D0 if(strlen(szCmd))
{
unsigned int uiLimit = atoi(szCmd);
if(uiLimit >= 20 && uiLimit <= 90)
{
pGame->SetFrameLimit(uiLimit);
if(pConfig) pConfig->SetIntVariable("fpslimit", uiLimit);
pChatWindow->AddInfoMessage("-> Frame Limiter: %u", uiLimit);
}
else
{
pChatWindow->AddInfoMessage("-> Frame Limiter: valid amounts are 20-90", uiLimit);
}
}
} }
void cmdHeadMove(PCHAR szCmd) void cmdHeadMove(PCHAR szCmd)
{ {
// TODO: cmdSetFrameLimit .text:10068960 CGame *pGame = ::pGame;
if(pGame)
{
if(pGame->m_bHeadMove)
{
pGame->m_bHeadMove = 0;
if(pConfig) pConfig->SetIntVariable("disableheadmove", 1);
pChatWindow->AddInfoMessage("-> Head movements disabled");
}
else
{
pGame->m_bHeadMove = 1;
if(pConfig) pConfig->SetIntVariable("disableheadmove", 0);
pChatWindow->AddInfoMessage("-> Head movements enabled");
}
}
} }
void cmdQuit(PCHAR szCmd) void cmdQuit(PCHAR szCmd)
{ {
// TODO: cmdQuit .text:100689E0 ShutdownGame();
} }
void cmdCmpStat(PCHAR szCmd) void cmdCmpStat(PCHAR szCmd)
{ {
// TODO: cmdCmpStat .text:100689F0
} }
void cmdSavePos(PCHAR szCmd) void cmdSavePos(PCHAR szCmd)
{ {
// TODO: cmdSavePos .text:10068A00 CPlayerPed *pPlayerPed = pGame->FindPlayerPed();
char szString[264];
sprintf(szString, "%s\\savedpositions.txt", sub_100C3AD0());
FILE *f = fopen(szString, "a");
if(!f)
{
pChatWindow->AddDebugMessage("I can't open the savepositions.txt file for append.");
return;
}
if(pPlayerPed->IsInVehicle())
{
VEHICLE_TYPE *pVehicle = pPlayerPed->GetGtaVehicle();
int iIndex = GamePool_Vehicle_GetIndex(pVehicle);
float fAngle;
ScriptCommand(&get_car_z_angle, iIndex, &fAngle);
fprintf(f, "AddStaticVehicle(%u,%.4f,%.4f,%.4f,%.4f,%u,%u); // %s\n",
pVehicle->entity.nModelIndex,
pVehicle->entity.mat->pos.X,
pVehicle->entity.mat->pos.Y,
pVehicle->entity.mat->pos.Z,
fAngle,
pVehicle->byteColor1,
pVehicle->byteColor2,
szCmd);
fclose(f);
pChatWindow->AddInfoMessage("-> InCar position saved");
}
else
{
PED_TYPE *pPed = pPlayerPed->m_pPed;
float fAngle;
ScriptCommand(&get_actor_z_angle, pPlayerPed->m_dwGTAId, &fAngle);
fprintf(f, "AddPlayerClass(%u,%.4f,%.4f,%.4f,%.4f,0,0,0,0,0,0); // %s\n",
pPlayerPed->GetModelIndex(),
pPed->entity.mat->pos.X,
pPed->entity.mat->pos.Y,
pPed->entity.mat->pos.Z,
fAngle,
szCmd);
fclose(f);
pChatWindow->AddInfoMessage("-> OnFoot position saved");
}
} }
void cmdRawSavePos(PCHAR szCmd) void cmdRawSavePos(PCHAR szCmd)
{ {
// TODO: cmdRawSavePos .text:10068B80 CPlayerPed *pPlayerPed = pGame->FindPlayerPed();
float fAngle;
FILE *f;
PED_TYPE *pPed;
char szString[264];
if(pPlayerPed->IsInVehicle())
{
f = fopen("rawvehicles.txt", "a");
if(!f) goto cant_open;
VEHICLE_TYPE *pVehicle = pPlayerPed->GetGtaVehicle();
int iIndex = GamePool_Vehicle_GetIndex(pVehicle);
ScriptCommand(&get_car_z_angle, iIndex, &fAngle);
fprintf(f, "%u,%.4f,%.4f,%.4f,%.4f,%u,%u ; %s\n",
pVehicle->entity.nModelIndex,
pVehicle->entity.mat->pos.X,
pVehicle->entity.mat->pos.Y,
pVehicle->entity.mat->pos.Z,
fAngle,
pVehicle->byteColor1,
pVehicle->byteColor2,
szCmd);
fclose(f);
pChatWindow->AddDebugMessage("-> InCar pos saved");
return;
}
pPed = pPlayerPed->m_pPed;
ScriptCommand(&get_actor_z_angle, pPlayerPed->m_dwGTAId, &fAngle);
sprintf(szString, "%s\\rawpositions.txt", sub_100C3AD0());
f = fopen(szString, "a");
if(!f)
{
cant_open:
pChatWindow->AddDebugMessage("I can't open the rawvehicles.txt file for append.");
return;
}
fprintf(f, "%.4f,%.4f,%.4f,%.4f ; %s\n",
pPed->entity.mat->pos.X,
pPed->entity.mat->pos.Y,
pPed->entity.mat->pos.Z,
fAngle,
szCmd);
fclose(f);
pChatWindow->AddDebugMessage("-> OnFoot pos saved");
} }
void cmdPlayerSkin(PCHAR szCmd) void cmdPlayerSkin(PCHAR szCmd)
{ {
// TODO: cmdPlayerSkin .text:10068D00 if(tSettings.bDebug)
{
if(!strlen(szCmd))
{
pChatWindow->AddDebugMessage("Usage: player_skin (skin number).");
}
else
{
int iSkin = atoi(szCmd);
if(pGame->sub_100A0930())
{
CPlayerPed *pPlayerPed = pGame->FindPlayerPed();
if(pPlayerPed)
{
pPlayerPed->SetSkin(iSkin);
}
}
}
}
} }
void cmdCreateVehicle(PCHAR szCmd) void cmdCreateVehicle(PCHAR szCmd)
{ {
// TODO: cmdCreateVehicle .text:10068D70 if(tSettings.bDebug)
{
if(!strlen(szCmd))
{
pChatWindow->AddDebugMessage("Usage: /v (vehicle id).");
}
else
{
int iModel = atoi(szCmd);
if(pGame->sub_100A0930())
{
pGame->sub_100A0940(iModel, 2);
pGame->sub_100A0960();
CPlayerPed *pPlayerPed = pGame->FindPlayerPed();
if(pPlayerPed)
{
MATRIX4X4 mat;
pPlayerPed->GetMatrix(&mat);
char szName[9] = {0};
sprintf(szName, "TYPE_%d", iModel);
pGame->sub_100A0250(iModel, mat.pos.X - 5.0f, mat.pos.Y - 5.0f, mat.pos.Z + 1.0f, 0, 0)->Add();
}
else
{
pChatWindow->AddDebugMessage("I couldn't find the player actor.");
}
}
else
{
pChatWindow->AddDebugMessage("game not loaded.");
}
}
}
} }
void cmdSelectVehicle(PCHAR szCmd) void cmdSelectVehicle(PCHAR szCmd)
{ {
// TODO: cmdSelectVehicle .text:10068EB0 if(tSettings.bDebug)
{
VehicleSelect(0, 0, 10);
}
} }
void cmdSetWeather(PCHAR szCmd) void cmdSetWeather(PCHAR szCmd)
{ {
// TODO: cmdSetWeather .text:10068ED0 if(!strlen(szCmd))
{
pChatWindow->AddDebugMessage("Usage: set_weather (weather number)");
return;
}
pGame->SetWorldWeather(atoi(szCmd));
} }
void cmdSetTime(PCHAR szCmd) void cmdSetTime(PCHAR szCmd)
{ {
// TODO: cmdSetTime .text:10068F20 if(!strlen(szCmd))
{
pChatWindow->AddDebugMessage("Usage: set_time (hour) (minute)");
return;
}
int iHour = 0, iMinute = 0;
sscanf(szCmd, "%d%d", &iHour, &iMinute);
if(iHour < 0 || iHour > 23 || iMinute < 0 || iMinute > 59)
{
pChatWindow->AddDebugMessage("Invalid Time. Use /set_time (hour 0-23) (minute 0-59)");
}
else
{
pGame->SetWorldTime(iHour, iMinute);
}
} }
void cmdShowInterior(PCHAR szCmd) void cmdShowInterior(PCHAR szCmd)
{ {
// TODO: cmdShowInterior .text:10068FD0 int iInterior;
ScriptCommand(&get_active_interior, &iInterior);
pChatWindow->AddDebugMessage("Current Interior: %u", iInterior);
} }
void cmdToggleObjectLight(PCHAR szCmd) void cmdToggleObjectLight(PCHAR szCmd)
{ {
// TODO: cmdToggleObjectLight .text:10069000 bToggleObjectLight = !bToggleObjectLight;
} }
void cmdDebugLabels(PCHAR szCmd) void cmdDebugLabels(PCHAR szCmd)
@@ -162,7 +419,18 @@ void cmdDebugLabels(PCHAR szCmd)
void cmdRcon(PCHAR szCmd) void cmdRcon(PCHAR szCmd)
{ {
// TODO: cmdRcon .text:10069030 if(szCmd)
{
if(pNetGame)
{
RakNet::BitStream bsSend;
bsSend.Write((BYTE)201);
int iStrlen = strlen(szCmd);
bsSend.Write(iStrlen);
bsSend.Write(szCmd, iStrlen);
pNetGame->GetRakClient()->Send(&bsSend, HIGH_PRIORITY, RELIABLE, 0);
}
}
} }
//---------------------------------------------------- //----------------------------------------------------
+13 -1
View File
@@ -3,6 +3,7 @@
extern CGame *pGame; extern CGame *pGame;
extern CConfig *pConfig; extern CConfig *pConfig;
extern CChatWindow *pChatWindow;
//---------------------------------------------------- //----------------------------------------------------
@@ -70,10 +71,21 @@ void CCmdWindow::Enable()
RECT rect; RECT rect;
GetClientRect(pGame->GetMainWindowHwnd(), &rect); GetClientRect(pGame->GetMainWindowHwnd(), &rect);
int iWidth = (int)(rect.right * 0.6f);
if(iWidth > 800) iWidth = 800;
m_pEditControl->SetEnabled(true); m_pEditControl->SetEnabled(true);
m_pEditControl->SetVisible(true); m_pEditControl->SetVisible(true);
// TODO: CCmdWindow::Enable() m_pEditControl->SetLocation(40, pChatWindow->field_12E);
m_pEditControl->SetSize(iWidth, 14 - (int)(m_pGameUI->GetFont(0)->nHeight * -1.5f));
m_pGameUI->RequestFocus(m_pEditControl);
m_pEditControl->OnFocusIn();
int iField = pChatWindow->field_12E;
CDXUTDialog *pUI = m_pGameUI;
*(int *)((char *)pUI + 0x11E) = iWidth + 100;
*(int *)((char *)pUI + 0x122) = iField + 50;
} }
m_bEnabled = TRUE; m_bEnabled = TRUE;
+5
View File
@@ -35,6 +35,11 @@ public:
void GetDialogSize(RECT *pRect); void GetDialogSize(RECT *pRect);
// 0x14E0 falls inside m_szCmdNames, so the accessor reaches it by a cast
int GetField14E0() { return *(int *)((char *)this + 0x14E0); }; // .text:10002E50, out of line copy
bool IsImeActive(); // .text:10069810
void Enable(); void Enable();
void Disable(); void Disable();
+6 -4
View File
@@ -1946,7 +1946,9 @@ float DXUTRankDeviceCombo( CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo,
} }
else else
{ {
int nBitDepthDelta = abs( (long) DXUTColorChannelBits(pDeviceSettingsCombo->AdapterFormat) - // hoisted: retail evaluates the combo side first here (unlike the back buffer block below)
long nAdapterBits = (long) DXUTColorChannelBits(pDeviceSettingsCombo->AdapterFormat);
int nBitDepthDelta = abs( nAdapterBits -
(long) DXUTColorChannelBits(pOptimalDeviceSettings->AdapterFormat) ); (long) DXUTColorChannelBits(pOptimalDeviceSettings->AdapterFormat) );
float fScale = __max(0.9f - (float)nBitDepthDelta*0.2f, 0.0f); float fScale = __max(0.9f - (float)nBitDepthDelta*0.2f, 0.0f);
fCurRanking += fScale * fAdapterFormatWeight; fCurRanking += fScale * fAdapterFormatWeight;
@@ -2713,11 +2715,11 @@ HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, IDirect3DDevic
// If different device windows are used for windowed mode and fullscreen mode, // If different device windows are used for windowed mode and fullscreen mode,
// hide the fullscreen window so that it doesn't obscure the screen. // hide the fullscreen window so that it doesn't obscure the screen.
if( DXUTGetHWNDDeviceFullScreen() != DXUTGetHWNDDeviceWindowed() ) if( DXUTGetHWNDDeviceWindowed() != DXUTGetHWNDDeviceFullScreen() )
ShowWindow( DXUTGetHWNDDeviceFullScreen(), SW_HIDE ); ShowWindow( DXUTGetHWNDDeviceFullScreen(), SW_HIDE );
// If using the same window for windowed and fullscreen mode, reattach menu if one exists // If using the same window for windowed and fullscreen mode, reattach menu if one exists
if( DXUTGetHWNDDeviceFullScreen() == DXUTGetHWNDDeviceWindowed() ) if( DXUTGetHWNDDeviceWindowed() == DXUTGetHWNDDeviceFullScreen() )
{ {
if( GetDXUTState().GetMenu() != NULL ) if( GetDXUTState().GetMenu() != NULL )
SetMenu( DXUTGetHWNDDeviceWindowed(), GetDXUTState().GetMenu() ); SetMenu( DXUTGetHWNDDeviceWindowed(), GetDXUTState().GetMenu() );
@@ -2752,7 +2754,7 @@ HRESULT DXUTChangeDevice( DXUTDeviceSettings* pNewDeviceSettings, IDirect3DDevic
SetWindowLong( DXUTGetHWNDDeviceFullScreen(), GWL_STYLE, WS_POPUP|WS_SYSMENU ); SetWindowLong( DXUTGetHWNDDeviceFullScreen(), GWL_STYLE, WS_POPUP|WS_SYSMENU );
// If using the same window for windowed and fullscreen mode, save and remove menu // If using the same window for windowed and fullscreen mode, save and remove menu
if( DXUTGetHWNDDeviceFullScreen() == DXUTGetHWNDDeviceWindowed() ) if( DXUTGetHWNDDeviceWindowed() == DXUTGetHWNDDeviceFullScreen() )
{ {
HMENU hMenu = GetMenu( DXUTGetHWNDDeviceFullScreen() ); HMENU hMenu = GetMenu( DXUTGetHWNDDeviceFullScreen() );
GetDXUTState().SetMenu( hMenu ); GetDXUTState().SetMenu( hMenu );
+54
View File
@@ -26,6 +26,7 @@ TCHAR* DXUTVertexProcessingTypeToString(DWORD vpt);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
DXUTDeviceSettings g_DeviceSettings; DXUTDeviceSettings g_DeviceSettings;
// MATCH
CD3DSettingsDlg* DXUTGetSettingsDialog() CD3DSettingsDlg* DXUTGetSettingsDialog()
{ {
// Using an accessor function gives control of the construction order // Using an accessor function gives control of the construction order
@@ -35,6 +36,7 @@ CD3DSettingsDlg* DXUTGetSettingsDialog()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
CD3DSettingsDlg::CD3DSettingsDlg() CD3DSettingsDlg::CD3DSettingsDlg()
{ {
m_pStateBlock = NULL; m_pStateBlock = NULL;
@@ -43,6 +45,7 @@ CD3DSettingsDlg::CD3DSettingsDlg()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
CD3DSettingsDlg::~CD3DSettingsDlg() CD3DSettingsDlg::~CD3DSettingsDlg()
{ {
OnDestroyDevice(); OnDestroyDevice();
@@ -137,6 +140,7 @@ void CD3DSettingsDlg::CreateControls()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnCreateDevice( IDirect3DDevice9* pd3dDevice ) HRESULT CD3DSettingsDlg::OnCreateDevice( IDirect3DDevice9* pd3dDevice )
{ {
if( pd3dDevice == NULL ) if( pd3dDevice == NULL )
@@ -152,6 +156,7 @@ HRESULT CD3DSettingsDlg::OnCreateDevice( IDirect3DDevice9* pd3dDevice )
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Changes the UI defaults to the current device settings // Changes the UI defaults to the current device settings
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::Refresh() HRESULT CD3DSettingsDlg::Refresh()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -217,6 +222,7 @@ HRESULT CD3DSettingsDlg::Refresh()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnResetDevice() HRESULT CD3DSettingsDlg::OnResetDevice()
{ {
const D3DSURFACE_DESC* pDesc = DXUTGetBackBufferSurfaceDesc(); const D3DSURFACE_DESC* pDesc = DXUTGetBackBufferSurfaceDesc();
@@ -238,6 +244,7 @@ HRESULT CD3DSettingsDlg::OnResetDevice()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnRender( float fElapsedTime ) HRESULT CD3DSettingsDlg::OnRender( float fElapsedTime )
{ {
IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice(); IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
@@ -260,6 +267,7 @@ HRESULT CD3DSettingsDlg::OnRender( float fElapsedTime )
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
LRESULT CD3DSettingsDlg::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) LRESULT CD3DSettingsDlg::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{ {
m_Dialog.MsgProc( hWnd, uMsg, wParam, lParam ); m_Dialog.MsgProc( hWnd, uMsg, wParam, lParam );
@@ -270,6 +278,7 @@ LRESULT CD3DSettingsDlg::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnLostDevice() HRESULT CD3DSettingsDlg::OnLostDevice()
{ {
SAFE_RELEASE( m_pStateBlock ); SAFE_RELEASE( m_pStateBlock );
@@ -278,6 +287,7 @@ HRESULT CD3DSettingsDlg::OnLostDevice()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnDestroyDevice() HRESULT CD3DSettingsDlg::OnDestroyDevice()
{ {
m_Dialog.ClearFocus(); m_Dialog.ClearFocus();
@@ -286,6 +296,7 @@ HRESULT CD3DSettingsDlg::OnDestroyDevice()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
void WINAPI CD3DSettingsDlg::StaticOnEvent( UINT nEvent, int nControlID, void WINAPI CD3DSettingsDlg::StaticOnEvent( UINT nEvent, int nControlID,
CDXUTControl* pControl, void* pUserData ) CDXUTControl* pControl, void* pUserData )
{ {
@@ -296,6 +307,7 @@ void WINAPI CD3DSettingsDlg::StaticOnEvent( UINT nEvent, int nControlID,
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::OnEvent( UINT nEvent, int nControlID, void CD3DSettingsDlg::OnEvent( UINT nEvent, int nControlID,
CDXUTControl* pControl ) CDXUTControl* pControl )
{ {
@@ -356,6 +368,7 @@ void CD3DSettingsDlg::OnEvent( UINT nEvent, int nControlID,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::SetDeviceSettingsFromUI() HRESULT CD3DSettingsDlg::SetDeviceSettingsFromUI()
{ {
CDXUTComboBox* pComboBox; CDXUTComboBox* pComboBox;
@@ -405,6 +418,7 @@ HRESULT CD3DSettingsDlg::SetDeviceSettingsFromUI()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
CD3DEnumAdapterInfo* CD3DSettingsDlg::GetCurrentAdapterInfo() CD3DEnumAdapterInfo* CD3DSettingsDlg::GetCurrentAdapterInfo()
{ {
CD3DEnumeration* pD3DEnum = DXUTGetEnumeration(); CD3DEnumeration* pD3DEnum = DXUTGetEnumeration();
@@ -413,6 +427,7 @@ CD3DEnumAdapterInfo* CD3DSettingsDlg::GetCurrentAdapterInfo()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
CD3DEnumDeviceInfo* CD3DSettingsDlg::GetCurrentDeviceInfo() CD3DEnumDeviceInfo* CD3DSettingsDlg::GetCurrentDeviceInfo()
{ {
CD3DEnumeration* pD3DEnum = DXUTGetEnumeration(); CD3DEnumeration* pD3DEnum = DXUTGetEnumeration();
@@ -422,6 +437,7 @@ CD3DEnumDeviceInfo* CD3DSettingsDlg::GetCurrentDeviceInfo()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
CD3DEnumDeviceSettingsCombo* CD3DSettingsDlg::GetCurrentDeviceSettingsCombo() CD3DEnumDeviceSettingsCombo* CD3DSettingsDlg::GetCurrentDeviceSettingsCombo()
{ {
CD3DEnumeration* pD3DEnum = DXUTGetEnumeration(); CD3DEnumeration* pD3DEnum = DXUTGetEnumeration();
@@ -434,6 +450,7 @@ CD3DEnumDeviceSettingsCombo* CD3DSettingsDlg::GetCurrentDeviceSettingsCombo()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnAdapterChanged() HRESULT CD3DSettingsDlg::OnAdapterChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -467,6 +484,7 @@ HRESULT CD3DSettingsDlg::OnAdapterChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnDeviceTypeChanged() HRESULT CD3DSettingsDlg::OnDeviceTypeChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -507,6 +525,7 @@ HRESULT CD3DSettingsDlg::OnDeviceTypeChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnWindowedFullScreenChanged() HRESULT CD3DSettingsDlg::OnWindowedFullScreenChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -627,6 +646,7 @@ HRESULT CD3DSettingsDlg::OnWindowedFullScreenChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnAdapterFormatChanged() HRESULT CD3DSettingsDlg::OnAdapterFormatChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -707,6 +727,7 @@ HRESULT CD3DSettingsDlg::OnAdapterFormatChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnResolutionChanged() HRESULT CD3DSettingsDlg::OnResolutionChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -751,6 +772,7 @@ HRESULT CD3DSettingsDlg::OnResolutionChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnRefreshRateChanged() HRESULT CD3DSettingsDlg::OnRefreshRateChanged()
{ {
// Set refresh rate // Set refresh rate
@@ -761,6 +783,7 @@ HRESULT CD3DSettingsDlg::OnRefreshRateChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnBackBufferFormatChanged() HRESULT CD3DSettingsDlg::OnBackBufferFormatChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -863,6 +886,7 @@ HRESULT CD3DSettingsDlg::OnBackBufferFormatChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnDepthStencilBufferFormatChanged() HRESULT CD3DSettingsDlg::OnDepthStencilBufferFormatChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -911,6 +935,7 @@ HRESULT CD3DSettingsDlg::OnDepthStencilBufferFormatChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnMultisampleTypeChanged() HRESULT CD3DSettingsDlg::OnMultisampleTypeChanged()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@@ -953,6 +978,7 @@ HRESULT CD3DSettingsDlg::OnMultisampleTypeChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnMultisampleQualityChanged() HRESULT CD3DSettingsDlg::OnMultisampleQualityChanged()
{ {
g_DeviceSettings.pp.MultiSampleQuality = GetSelectedMultisampleQuality(); g_DeviceSettings.pp.MultiSampleQuality = GetSelectedMultisampleQuality();
@@ -962,6 +988,7 @@ HRESULT CD3DSettingsDlg::OnMultisampleQualityChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnVertexProcessingChanged() HRESULT CD3DSettingsDlg::OnVertexProcessingChanged()
{ {
DWORD dwBehavior = g_DeviceSettings.BehaviorFlags; DWORD dwBehavior = g_DeviceSettings.BehaviorFlags;
@@ -985,6 +1012,7 @@ HRESULT CD3DSettingsDlg::OnVertexProcessingChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnPresentIntervalChanged() HRESULT CD3DSettingsDlg::OnPresentIntervalChanged()
{ {
g_DeviceSettings.pp.PresentationInterval = GetSelectedPresentInterval(); g_DeviceSettings.pp.PresentationInterval = GetSelectedPresentInterval();
@@ -994,6 +1022,7 @@ HRESULT CD3DSettingsDlg::OnPresentIntervalChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
HRESULT CD3DSettingsDlg::OnDeviceClipChanged() HRESULT CD3DSettingsDlg::OnDeviceClipChanged()
{ {
if( IsDeviceClip() ) if( IsDeviceClip() )
@@ -1006,6 +1035,7 @@ HRESULT CD3DSettingsDlg::OnDeviceClipChanged()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddAdapter( const TCHAR* strDescription, UINT iAdapter ) void CD3DSettingsDlg::AddAdapter( const TCHAR* strDescription, UINT iAdapter )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER );
@@ -1016,6 +1046,7 @@ void CD3DSettingsDlg::AddAdapter( const TCHAR* strDescription, UINT iAdapter )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
UINT CD3DSettingsDlg::GetSelectedAdapter() UINT CD3DSettingsDlg::GetSelectedAdapter()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER );
@@ -1025,6 +1056,7 @@ UINT CD3DSettingsDlg::GetSelectedAdapter()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddDeviceType( D3DDEVTYPE devType ) void CD3DSettingsDlg::AddDeviceType( D3DDEVTYPE devType )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE );
@@ -1035,6 +1067,7 @@ void CD3DSettingsDlg::AddDeviceType( D3DDEVTYPE devType )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
D3DDEVTYPE CD3DSettingsDlg::GetSelectedDeviceType() D3DDEVTYPE CD3DSettingsDlg::GetSelectedDeviceType()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEVICE_TYPE );
@@ -1044,6 +1077,7 @@ D3DDEVTYPE CD3DSettingsDlg::GetSelectedDeviceType()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::SetWindowed( bool bWindowed ) void CD3DSettingsDlg::SetWindowed( bool bWindowed )
{ {
CDXUTRadioButton* pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); CDXUTRadioButton* pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED );
@@ -1055,6 +1089,7 @@ void CD3DSettingsDlg::SetWindowed( bool bWindowed )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
bool CD3DSettingsDlg::IsWindowed() bool CD3DSettingsDlg::IsWindowed()
{ {
CDXUTRadioButton* pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED ); CDXUTRadioButton* pRadioButton = m_Dialog.GetRadioButton( DXUTSETTINGSDLG_WINDOWED );
@@ -1063,6 +1098,7 @@ bool CD3DSettingsDlg::IsWindowed()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddAdapterFormat( D3DFORMAT format ) void CD3DSettingsDlg::AddAdapterFormat( D3DFORMAT format )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT );
@@ -1073,6 +1109,7 @@ void CD3DSettingsDlg::AddAdapterFormat( D3DFORMAT format )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
D3DFORMAT CD3DSettingsDlg::GetSelectedAdapterFormat() D3DFORMAT CD3DSettingsDlg::GetSelectedAdapterFormat()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_ADAPTER_FORMAT );
@@ -1082,6 +1119,7 @@ D3DFORMAT CD3DSettingsDlg::GetSelectedAdapterFormat()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddResolution( DWORD dwWidth, DWORD dwHeight ) void CD3DSettingsDlg::AddResolution( DWORD dwWidth, DWORD dwHeight )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION );
@@ -1097,6 +1135,7 @@ void CD3DSettingsDlg::AddResolution( DWORD dwWidth, DWORD dwHeight )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::GetSelectedResolution( DWORD* pdwWidth, DWORD* pdwHeight ) void CD3DSettingsDlg::GetSelectedResolution( DWORD* pdwWidth, DWORD* pdwHeight )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_RESOLUTION );
@@ -1109,6 +1148,7 @@ void CD3DSettingsDlg::GetSelectedResolution( DWORD* pdwWidth, DWORD* pdwHeight )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddRefreshRate( DWORD dwRate ) void CD3DSettingsDlg::AddRefreshRate( DWORD dwRate )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE );
@@ -1126,6 +1166,7 @@ void CD3DSettingsDlg::AddRefreshRate( DWORD dwRate )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
DWORD CD3DSettingsDlg::GetSelectedRefreshRate() DWORD CD3DSettingsDlg::GetSelectedRefreshRate()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_REFRESH_RATE );
@@ -1135,6 +1176,7 @@ DWORD CD3DSettingsDlg::GetSelectedRefreshRate()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddBackBufferFormat( D3DFORMAT format ) void CD3DSettingsDlg::AddBackBufferFormat( D3DFORMAT format )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT );
@@ -1145,6 +1187,7 @@ void CD3DSettingsDlg::AddBackBufferFormat( D3DFORMAT format )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
D3DFORMAT CD3DSettingsDlg::GetSelectedBackBufferFormat() D3DFORMAT CD3DSettingsDlg::GetSelectedBackBufferFormat()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_BACK_BUFFER_FORMAT );
@@ -1154,6 +1197,7 @@ D3DFORMAT CD3DSettingsDlg::GetSelectedBackBufferFormat()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddDepthStencilBufferFormat( D3DFORMAT format ) void CD3DSettingsDlg::AddDepthStencilBufferFormat( D3DFORMAT format )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL );
@@ -1164,6 +1208,7 @@ void CD3DSettingsDlg::AddDepthStencilBufferFormat( D3DFORMAT format )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
D3DFORMAT CD3DSettingsDlg::GetSelectedDepthStencilBufferFormat() D3DFORMAT CD3DSettingsDlg::GetSelectedDepthStencilBufferFormat()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_DEPTH_STENCIL );
@@ -1173,6 +1218,7 @@ D3DFORMAT CD3DSettingsDlg::GetSelectedDepthStencilBufferFormat()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddMultisampleType( D3DMULTISAMPLE_TYPE type ) void CD3DSettingsDlg::AddMultisampleType( D3DMULTISAMPLE_TYPE type )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE );
@@ -1183,6 +1229,7 @@ void CD3DSettingsDlg::AddMultisampleType( D3DMULTISAMPLE_TYPE type )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
D3DMULTISAMPLE_TYPE CD3DSettingsDlg::GetSelectedMultisampleType() D3DMULTISAMPLE_TYPE CD3DSettingsDlg::GetSelectedMultisampleType()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_TYPE );
@@ -1192,6 +1239,7 @@ D3DMULTISAMPLE_TYPE CD3DSettingsDlg::GetSelectedMultisampleType()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddMultisampleQuality( DWORD dwQuality ) void CD3DSettingsDlg::AddMultisampleQuality( DWORD dwQuality )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY );
@@ -1205,6 +1253,7 @@ void CD3DSettingsDlg::AddMultisampleQuality( DWORD dwQuality )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
DWORD CD3DSettingsDlg::GetSelectedMultisampleQuality() DWORD CD3DSettingsDlg::GetSelectedMultisampleQuality()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_MULTISAMPLE_QUALITY );
@@ -1214,6 +1263,7 @@ DWORD CD3DSettingsDlg::GetSelectedMultisampleQuality()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::AddVertexProcessingType( DWORD dwType ) void CD3DSettingsDlg::AddVertexProcessingType( DWORD dwType )
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING );
@@ -1224,6 +1274,7 @@ void CD3DSettingsDlg::AddVertexProcessingType( DWORD dwType )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
DWORD CD3DSettingsDlg::GetSelectedVertexProcessingType() DWORD CD3DSettingsDlg::GetSelectedVertexProcessingType()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_VERTEX_PROCESSING );
@@ -1244,6 +1295,7 @@ void CD3DSettingsDlg::AddPresentInterval( DWORD dwInterval )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
DWORD CD3DSettingsDlg::GetSelectedPresentInterval() DWORD CD3DSettingsDlg::GetSelectedPresentInterval()
{ {
CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL ); CDXUTComboBox* pComboBox = m_Dialog.GetComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL );
@@ -1253,6 +1305,7 @@ DWORD CD3DSettingsDlg::GetSelectedPresentInterval()
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
void CD3DSettingsDlg::SetDeviceClip( bool bDeviceClip ) void CD3DSettingsDlg::SetDeviceClip( bool bDeviceClip )
{ {
CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_DEVICECLIP ); CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_DEVICECLIP );
@@ -1261,6 +1314,7 @@ void CD3DSettingsDlg::SetDeviceClip( bool bDeviceClip )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// MATCH
bool CD3DSettingsDlg::IsDeviceClip() bool CD3DSettingsDlg::IsDeviceClip()
{ {
CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_DEVICECLIP ); CDXUTCheckBox* pCheckBox = m_Dialog.GetCheckBox( DXUTSETTINGSDLG_DEVICECLIP );
+550
View File
@@ -0,0 +1,550 @@
//--------------------------------------------------------------------------------------
// File: DXUTUniBuffer.cpp
//
// Desc: CUniBuffer, the Uniscribe-backed text buffer behind the edit controls
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "dxstdafx.h"
// <new.h> omits operator delete's throw(), which forces unwind frames into
// every dtor that deletes
#include <new>
#include "DXUTgui.h"
#define UNISCRIBE_DLLNAME "\\usp10.dll"
#define GETPROCADDRESS( Module, APIName, Temp ) \
Temp = GetProcAddress( Module, #APIName ); \
if( Temp ) \
*(FARPROC*)&_##APIName = Temp
#define PLACEHOLDERPROC( APIName ) \
_##APIName = Dummy_##APIName
// DXUT_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes,
// including the NULL terminator.
//
// Uniscribe does not support strings having bigger-than-16-bits length.
// This means that the string must be less than 65536 characters long,
// including the NULL terminator.
#define DXUT_MAX_EDITBOXLENGTH 0xFFFF
// stays in DXUTgui.cpp; retail reaches it across the tu boundary
LPCWSTR MaskText( LPCWSTR wszText );
// Static member initialization
HINSTANCE CUniBuffer::s_hDll = NULL;
HRESULT (WINAPI *CUniBuffer::_ScriptApplyDigitSubstitution)( const SCRIPT_DIGITSUBSTITUTE*, SCRIPT_CONTROL*, SCRIPT_STATE* ) = Dummy_ScriptApplyDigitSubstitution;
HRESULT (WINAPI *CUniBuffer::_ScriptStringAnalyse)( HDC, const void *, int, int, int, DWORD, int, SCRIPT_CONTROL*, SCRIPT_STATE*, const int*, SCRIPT_TABDEF*, const BYTE*, SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringAnalyse;
HRESULT (WINAPI *CUniBuffer::_ScriptStringCPtoX)( SCRIPT_STRING_ANALYSIS, int, BOOL, int* ) = Dummy_ScriptStringCPtoX;
HRESULT (WINAPI *CUniBuffer::_ScriptStringXtoCP)( SCRIPT_STRING_ANALYSIS, int, int*, int* ) = Dummy_ScriptStringXtoCP;
HRESULT (WINAPI *CUniBuffer::_ScriptStringFree)( SCRIPT_STRING_ANALYSIS* ) = Dummy_ScriptStringFree;
const SCRIPT_LOGATTR* (WINAPI *CUniBuffer::_ScriptString_pLogAttr)( SCRIPT_STRING_ANALYSIS ) = Dummy_ScriptString_pLogAttr;
const int* (WINAPI *CUniBuffer::_ScriptString_pcOutChars)( SCRIPT_STRING_ANALYSIS ) = Dummy_ScriptString_pcOutChars;
//--------------------------------------------------------------------------------------
void CUniBuffer::Initialize()
{
if( s_hDll ) // Only need to do once
return;
TCHAR wszPath[MAX_PATH+1];
if( !::GetSystemDirectory( wszPath, MAX_PATH+1 ) )
return;
// Verify whether it is safe to concatenate these strings
int len1 = lstrlen(wszPath);
int len2 = lstrlen(UNISCRIBE_DLLNAME);
if (len1 + len2 > MAX_PATH)
{
return;
}
// We have verified that the concatenated string will fit into wszPath,
// so it is safe to concatenate them.
StringCchCat( wszPath, MAX_PATH, UNISCRIBE_DLLNAME );
s_hDll = LoadLibrary( wszPath );
if( s_hDll )
{
FARPROC Temp;
GETPROCADDRESS( s_hDll, ScriptApplyDigitSubstitution, Temp );
GETPROCADDRESS( s_hDll, ScriptStringAnalyse, Temp );
GETPROCADDRESS( s_hDll, ScriptStringCPtoX, Temp );
GETPROCADDRESS( s_hDll, ScriptStringXtoCP, Temp );
GETPROCADDRESS( s_hDll, ScriptStringFree, Temp );
GETPROCADDRESS( s_hDll, ScriptString_pLogAttr, Temp );
GETPROCADDRESS( s_hDll, ScriptString_pcOutChars, Temp );
}
}
//--------------------------------------------------------------------------------------
void CUniBuffer::Uninitialize()
{
if( s_hDll )
{
PLACEHOLDERPROC( ScriptApplyDigitSubstitution );
PLACEHOLDERPROC( ScriptStringAnalyse );
PLACEHOLDERPROC( ScriptStringCPtoX );
PLACEHOLDERPROC( ScriptStringXtoCP );
PLACEHOLDERPROC( ScriptStringFree );
PLACEHOLDERPROC( ScriptString_pLogAttr );
PLACEHOLDERPROC( ScriptString_pcOutChars );
FreeLibrary( s_hDll );
s_hDll = NULL;
}
}
//--------------------------------------------------------------------------------------
bool CUniBuffer::SetBufferSize( int nNewSize )
{
// If the current size is already the maximum allowed,
// we can't possibly allocate more.
if( m_nBufferSize == DXUT_MAX_EDITBOXLENGTH )
return false;
int nAllocateSize = ( nNewSize == -1 || nNewSize < m_nBufferSize * 2 ) ? ( m_nBufferSize ? m_nBufferSize * 2 : 256 ) : nNewSize * 2;
// Cap the buffer size at the maximum allowed.
if( nAllocateSize > DXUT_MAX_EDITBOXLENGTH )
nAllocateSize = DXUT_MAX_EDITBOXLENGTH;
WCHAR *pTempBuffer = new WCHAR[nAllocateSize];
if( !pTempBuffer )
return false;
if( m_pwszBuffer )
{
CopyMemory( pTempBuffer, m_pwszBuffer, m_nBufferSize * sizeof(WCHAR) );
delete[] m_pwszBuffer;
}
else
{
ZeroMemory( pTempBuffer, sizeof(WCHAR) * nAllocateSize );
}
m_pwszBuffer = pTempBuffer;
m_nBufferSize = nAllocateSize;
return true;
}
//--------------------------------------------------------------------------------------
// Uniscribe -- Analyse() analyses the string in the buffer
//--------------------------------------------------------------------------------------
HRESULT CUniBuffer::Analyse()
{
if( m_Analysis )
_ScriptStringFree( &m_Analysis );
SCRIPT_CONTROL ScriptControl; // For uniscribe
SCRIPT_STATE ScriptState; // For uniscribe
ZeroMemory( &ScriptControl, sizeof(ScriptControl) );
ZeroMemory( &ScriptState, sizeof(ScriptState) );
_ScriptApplyDigitSubstitution ( NULL, &ScriptControl, &ScriptState );
if( !m_pFontNode )
return E_FAIL;
HRESULT hr;
if( !field_12 )
{
hr = _ScriptStringAnalyse( m_pFontNode->pFont ? m_pFontNode->pFont->GetDC() : NULL,
m_pwszBuffer,
lstrlenW( m_pwszBuffer ) + 1, // NULL is also analyzed.
lstrlenW( m_pwszBuffer ) * 3 / 2 + 16,
-1,
SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK,
0,
&ScriptControl,
&ScriptState,
NULL,
NULL,
NULL,
&m_Analysis );
}
else
{
hr = _ScriptStringAnalyse( m_pFontNode->pFont ? m_pFontNode->pFont->GetDC() : NULL,
MaskText( m_pwszBuffer ),
lstrlenW( MaskText( m_pwszBuffer ) ) + 1, // NULL is also analyzed.
lstrlenW( MaskText( m_pwszBuffer ) ) * 3 / 2 + 16,
-1,
SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK,
0,
&ScriptControl,
&ScriptState,
NULL,
NULL,
NULL,
&m_Analysis );
}
if( SUCCEEDED( hr ) )
m_bAnalyseRequired = false; // Analysis is up-to-date
return hr;
}
//--------------------------------------------------------------------------------------
CUniBuffer::CUniBuffer( int nInitialSize )
{
CUniBuffer::Initialize(); // ensure static vars are properly init'ed first
m_nBufferSize = 0;
m_pwszBuffer = NULL;
m_bAnalyseRequired = true;
m_Analysis = NULL;
m_pFontNode = NULL;
field_8 = 0;
field_12 = 0;
if( nInitialSize > 0 )
SetBufferSize( nInitialSize );
}
//--------------------------------------------------------------------------------------
CUniBuffer::~CUniBuffer()
{
delete[] m_pwszBuffer;
if( m_Analysis )
_ScriptStringFree( &m_Analysis );
}
//--------------------------------------------------------------------------------------
WCHAR& CUniBuffer::operator[]( int n ) // No param checking
{
// This version of operator[] is called only
// if we are asking for write access, so
// re-analysis is required.
m_bAnalyseRequired = true;
return m_pwszBuffer[n];
}
//--------------------------------------------------------------------------------------
void CUniBuffer::Clear()
{
*m_pwszBuffer = L'\0';
m_bAnalyseRequired = true;
}
//--------------------------------------------------------------------------------------
// Inserts the char at specified index.
// If nIndex == -1, insert to the end.
//--------------------------------------------------------------------------------------
bool CUniBuffer::InsertChar( int nIndex, WCHAR tchr )
{
assert( nIndex >= 0 );
if( nIndex < 0 || nIndex > lstrlenW( m_pwszBuffer ) )
return false; // invalid index
// Check for maximum length allowed
if( GetTextSize() + 1 >= DXUT_MAX_EDITBOXLENGTH )
return false;
if( lstrlenW( m_pwszBuffer ) + 1 >= m_nBufferSize )
{
if( !SetBufferSize( -1 ) )
return false; // out of memory
}
assert( m_nBufferSize >= 2 );
// Shift the characters after the index, start by copying the null terminator
WCHAR* dest = m_pwszBuffer + lstrlenW(m_pwszBuffer)+1;
WCHAR* stop = m_pwszBuffer + nIndex;
WCHAR* src = dest - 1;
while( dest > stop )
{
*dest-- = *src--;
}
// Set new character
m_pwszBuffer[ nIndex ] = tchr;
m_bAnalyseRequired = true;
return true;
}
bool CUniBuffer::InsertChar(int nIndex, CHAR tchr)
{
WCHAR WideCharStr[2];
ZeroMemory(&WideCharStr[0], sizeof(WideCharStr));
if(field_8)
{
CHAR MultiByteStr[3];
MultiByteStr[0] = field_8;
MultiByteStr[1] = tchr;
MultiByteStr[2] = 0;
MultiByteToWideChar(CP_ACP, 0, MultiByteStr, 2, WideCharStr, 1);
InsertChar(nIndex, WideCharStr[0]);
field_8 = 0;
return true;
}
else if(IsDBCSLeadByteEx(CP_ACP, tchr))
{
field_8 = tchr;
return false;
}
else
{
MultiByteToWideChar(CP_ACP, 0, &tchr, 1, WideCharStr, 1);
InsertChar(nIndex, WideCharStr[0]);
return true;
}
}
// overwrite variant of InsertChar; the buffer index assignment is samp's, not a typo of ours
bool CUniBuffer::SetChar(int nIndex, CHAR tchr)
{
WCHAR WideCharStr[2];
ZeroMemory(&WideCharStr[0], sizeof(WideCharStr));
if(field_8)
{
CHAR MultiByteStr[3];
MultiByteStr[0] = field_8;
MultiByteStr[1] = tchr;
MultiByteStr[2] = 0;
MultiByteToWideChar(CP_ACP, 0, MultiByteStr, 2, WideCharStr, 1);
InsertChar(nIndex, WideCharStr[0]);
field_8 = 0;
return true;
}
else if(IsDBCSLeadByteEx(CP_ACP, tchr))
{
field_8 = tchr;
return false;
}
else
{
MultiByteToWideChar(CP_ACP, 0, &tchr, 1, WideCharStr, 1);
this[nIndex] = WideCharStr[0];
return true;
}
}
//--------------------------------------------------------------------------------------
// Removes the char at specified index.
// If nIndex == -1, remove the last char.
//--------------------------------------------------------------------------------------
bool CUniBuffer::RemoveChar( int nIndex )
{
if( !lstrlenW( m_pwszBuffer ) || nIndex < 0 || nIndex >= lstrlenW( m_pwszBuffer ) )
return false; // Invalid index
MoveMemory( m_pwszBuffer + nIndex, m_pwszBuffer + nIndex + 1, sizeof(WCHAR) * ( lstrlenW( m_pwszBuffer ) - nIndex ) );
m_bAnalyseRequired = true;
return true;
}
//--------------------------------------------------------------------------------------
// Inserts the first nCount characters of the string pStr at specified index.
// If nCount == -1, the entire string is inserted.
// If nIndex == -1, insert to the end.
//--------------------------------------------------------------------------------------
bool CUniBuffer::InsertString( int nIndex, const WCHAR *pStr, int nCount )
{
assert( nIndex >= 0 );
if( nIndex > lstrlenW( m_pwszBuffer ) )
return false; // invalid index
if( -1 == nCount )
nCount = lstrlenW( pStr );
// Check for maximum length allowed
if( GetTextSize() + nCount >= DXUT_MAX_EDITBOXLENGTH )
return false;
if( lstrlenW( m_pwszBuffer ) + nCount >= m_nBufferSize )
{
if( !SetBufferSize( lstrlenW( m_pwszBuffer ) + nCount + 1 ) )
return false; // out of memory
}
MoveMemory( m_pwszBuffer + nIndex + nCount, m_pwszBuffer + nIndex, sizeof(WCHAR) * ( lstrlenW( m_pwszBuffer ) - nIndex + 1 ) );
CopyMemory( m_pwszBuffer + nIndex, pStr, nCount * sizeof(WCHAR) );
m_bAnalyseRequired = true;
return true;
}
//--------------------------------------------------------------------------------------
bool CUniBuffer::SetText( LPCWSTR wszText )
{
assert( wszText != NULL );
int nRequired = int(lstrlenW( wszText ) + 1);
// Check for maximum length allowed
if( nRequired >= DXUT_MAX_EDITBOXLENGTH )
return false;
while( GetBufferSize() < nRequired )
if( !SetBufferSize( -1 ) )
break;
// Check again in case out of memory occurred inside while loop.
if( GetBufferSize() >= nRequired )
{
StringCchCopyW( m_pwszBuffer, GetBufferSize(), wszText );
m_bAnalyseRequired = true;
return true;
}
else
return false;
}
//--------------------------------------------------------------------------------------
void ConvertAnsiToWide(LPCSTR wszSrc, LPWSTR wszDest, int nSize)
{
memset(wszDest, 0, sizeof(WCHAR) * nSize);
int nCount = MultiByteToWideChar(CP_ACP, 0, wszSrc, strlen(wszSrc), NULL, 0);
if(nCount < nSize)
MultiByteToWideChar(CP_ACP, 0, wszSrc, strlen(wszSrc), wszDest, nCount);
}
//--------------------------------------------------------------------------------------
bool CUniBuffer::SetText( LPCTSTR wszText )
{
if(lstrlenA(wszText) > 1024) return false;
WCHAR szBuffer[2049];
ConvertAnsiToWide(wszText, szBuffer, 2048);
SetText(szBuffer);
return true;
}
//--------------------------------------------------------------------------------------
HRESULT CUniBuffer::CPtoX( int nCP, BOOL bTrail, int *pX )
{
assert( pX );
*pX = 0; // Default
HRESULT hr = S_OK;
if( m_bAnalyseRequired )
hr = Analyse();
if( SUCCEEDED( hr ) )
hr = _ScriptStringCPtoX( m_Analysis, nCP, bTrail, pX );
return hr;
}
//--------------------------------------------------------------------------------------
HRESULT CUniBuffer::XtoCP( int nX, int *pCP, int *pnTrail )
{
assert( pCP && pnTrail );
*pCP = 0; *pnTrail = FALSE; // Default
HRESULT hr = S_OK;
if( m_bAnalyseRequired )
hr = Analyse();
if( SUCCEEDED( hr ) )
hr = _ScriptStringXtoCP( m_Analysis, nX, pCP, pnTrail );
// If the coordinate falls outside the text region, we
// can get character positions that don't exist. We must
// filter them here and convert them to those that do exist.
if( *pCP == -1 && *pnTrail == TRUE )
{
*pCP = 0; *pnTrail = FALSE;
} else
if( *pCP > lstrlenW( m_pwszBuffer ) && *pnTrail == FALSE )
{
*pCP = lstrlenW( m_pwszBuffer ); *pnTrail = TRUE;
}
return hr;
}
//--------------------------------------------------------------------------------------
void CUniBuffer::GetPriorItemPos( int nCP, int *pPrior )
{
*pPrior = nCP; // Default is the char itself
if( m_bAnalyseRequired )
if( FAILED( Analyse() ) )
return;
const SCRIPT_LOGATTR *pLogAttr = _ScriptString_pLogAttr( m_Analysis );
if( !pLogAttr )
return;
if( !_ScriptString_pcOutChars( m_Analysis ) )
return;
int nInitial = *_ScriptString_pcOutChars( m_Analysis );
if( nCP - 1 < nInitial )
nInitial = nCP - 1;
for( int i = nInitial; i > 0; --i )
if( pLogAttr[i].fWordStop || // Either the fWordStop flag is set
( !pLogAttr[i].fWhiteSpace && // Or the previous char is whitespace but this isn't.
pLogAttr[i-1].fWhiteSpace ) )
{
*pPrior = i;
return;
}
// We have reached index 0. 0 is always a break point, so simply return it.
*pPrior = 0;
}
//--------------------------------------------------------------------------------------
void CUniBuffer::GetNextItemPos( int nCP, int *pPrior )
{
*pPrior = nCP; // Default is the char itself
HRESULT hr = S_OK;
if( m_bAnalyseRequired )
hr = Analyse();
if( FAILED( hr ) )
return;
const SCRIPT_LOGATTR *pLogAttr = _ScriptString_pLogAttr( m_Analysis );
if( !pLogAttr )
return;
if( !_ScriptString_pcOutChars( m_Analysis ) )
return;
int nInitial = *_ScriptString_pcOutChars( m_Analysis );
if( nCP + 1 < nInitial )
nInitial = nCP + 1;
for( int i = nInitial; i < *_ScriptString_pcOutChars( m_Analysis ) - 1; ++i )
{
if( pLogAttr[i].fWordStop ) // Either the fWordStop flag is set
{
*pPrior = i;
return;
}
else
if( pLogAttr[i].fWhiteSpace && // Or this whitespace but the next char isn't.
!pLogAttr[i+1].fWhiteSpace )
{
*pPrior = i+1; // The next char is a word stop
return;
}
}
// We have reached the end. It's always a word stop, so simply return it.
*pPrior = *_ScriptString_pcOutChars( m_Analysis ) - 1;
}
File diff suppressed because it is too large Load Diff
+17 -9
View File
@@ -17,6 +17,7 @@
// Defines and macros // Defines and macros
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
#define EVENT_BUTTON_CLICKED 0x0101 #define EVENT_BUTTON_CLICKED 0x0101
#define EVENT_BUTTON_PRESSED 0x0102
#define EVENT_COMBOBOX_SELECTION_CHANGED 0x0201 #define EVENT_COMBOBOX_SELECTION_CHANGED 0x0201
#define EVENT_RADIOBUTTON_CHANGED 0x0301 #define EVENT_RADIOBUTTON_CHANGED 0x0301
#define EVENT_CHECKBOX_CHANGED 0x0401 #define EVENT_CHECKBOX_CHANGED 0x0401
@@ -328,6 +329,7 @@ public:
int AddFont( LPCTSTR strFaceName, LONG height, LONG weight ); int AddFont( LPCTSTR strFaceName, LONG height, LONG weight );
int AddTexture( LPCTSTR strFilename ); int AddTexture( LPCTSTR strFilename );
int SetFont( int iFont, LPCTSTR strFaceName, LONG height, LONG weight );
DXUTFontNode* GetFontNode( int iIndex ) { return m_FontCache.GetAt( iIndex ); }; DXUTFontNode* GetFontNode( int iIndex ) { return m_FontCache.GetAt( iIndex ); };
DXUTTextureNode* GetTextureNode( int iIndex ) { return m_TextureCache.GetAt( iIndex ); }; DXUTTextureNode* GetTextureNode( int iIndex ) { return m_TextureCache.GetAt( iIndex ); };
@@ -593,11 +595,15 @@ protected:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct DXUTListBoxItem struct DXUTListBoxItem
{ {
TCHAR strText[256]; TCHAR strText[257];
TCHAR strColumnText[3][129];
void* pData; void* pData;
RECT rcActive; RECT rcActive;
bool bSelected; bool bSelected;
D3DCOLOR TextColor;
bool field_29D;
}; };
class CDXUTListBox : public CDXUTControl class CDXUTListBox : public CDXUTControl
@@ -619,9 +625,10 @@ public:
void SetStyle( DWORD dwStyle ) { m_dwStyle = dwStyle; } void SetStyle( DWORD dwStyle ) { m_dwStyle = dwStyle; }
void SetScrollBarWidth( int nWidth ) { m_nSBWidth = nWidth; UpdateRects(); } void SetScrollBarWidth( int nWidth ) { m_nSBWidth = nWidth; UpdateRects(); }
void SetBorder( int nBorder, int nMargin ) { m_nBorder = nBorder; m_nMargin = nMargin; } void SetBorder( int nBorder, int nMargin ) { m_nBorder = nBorder; m_nMargin = nMargin; }
HRESULT AddItem( const TCHAR *wszText, void *pData ); HRESULT AddItem( const TCHAR *wszText, void *pData, D3DCOLOR TextColor );
HRESULT InsertItem( int nIndex, const TCHAR *wszText, void *pData ); HRESULT InsertItem( int nIndex, const TCHAR *wszText, void *pData, D3DCOLOR TextColor );
void RemoveItem( int nIndex ); void RemoveItem( int nIndex );
void SetItemColumnText( int nIndex, int nColumn, const TCHAR *wszText );
void RemoveItemByText( TCHAR *wszText ); void RemoveItemByText( TCHAR *wszText );
void RemoveItemByData( void *pData ); void RemoveItemByData( void *pData );
void RemoveAllItems(); void RemoveAllItems();
@@ -630,18 +637,17 @@ public:
int GetSelectedIndex( int nPreviousSelected = -1 ); int GetSelectedIndex( int nPreviousSelected = -1 );
DXUTListBoxItem *GetSelectedItem( int nPreviousSelected = -1 ) { return GetItem( GetSelectedIndex( nPreviousSelected ) ); } DXUTListBoxItem *GetSelectedItem( int nPreviousSelected = -1 ) { return GetItem( GetSelectedIndex( nPreviousSelected ) ); }
void SelectItem( int nNewIndex ); void SelectItem( int nNewIndex );
CDXUTScrollBar *GetScrollBar() { return &m_ScrollBar; }
enum STYLE { MULTISELECTION = 1 }; enum STYLE { MULTISELECTION = 1 };
int field_4D; int field_4D;
int field_51; int field_51[3];
int field_55;
int field_59;
protected: protected:
CDXUTScrollBar m_ScrollBar;
RECT m_rcText; // Text rendering bound RECT m_rcText; // Text rendering bound
RECT m_rcSelection; // Selection box bound RECT m_rcSelection; // Selection box bound
CDXUTScrollBar m_ScrollBar;
int m_nSBWidth; int m_nSBWidth;
int m_nBorder; int m_nBorder;
int m_nMargin; int m_nMargin;
@@ -798,6 +804,7 @@ public:
bool InsertChar( int nIndex, WCHAR tchr ); // Inserts the char at specified index. If nIndex == -1, insert to the end. bool InsertChar( int nIndex, WCHAR tchr ); // Inserts the char at specified index. If nIndex == -1, insert to the end.
bool InsertChar( int nIndex, CHAR tchr ); bool InsertChar( int nIndex, CHAR tchr );
bool SetChar( int nIndex, CHAR tchr );
bool RemoveChar( int nIndex ); // Removes the char at specified index. If nIndex == -1, remove the last char. bool RemoveChar( int nIndex ); // Removes the char at specified index. If nIndex == -1, remove the last char.
bool InsertString( int nIndex, const WCHAR *pStr, int nCount = -1 ); // Inserts the first nCount characters of the string pStr at specified index. If nCount == -1, the entire string is inserted. If nIndex == -1, insert to the end. bool InsertString( int nIndex, const WCHAR *pStr, int nCount = -1 ); // Inserts the first nCount characters of the string pStr at specified index. If nCount == -1, the entire string is inserted. If nIndex == -1, insert to the end.
bool SetText( LPCWSTR wszText ); bool SetText( LPCWSTR wszText );
@@ -1005,6 +1012,7 @@ public:
virtual void OnFocusOut(); virtual void OnFocusOut();
void PumpMessage(); void PumpMessage();
static bool IsImeActive();
virtual void RenderCandidateReadingWindow( IDirect3DDevice9* pd3dDevice, float fElapsedTime, bool bReading ); virtual void RenderCandidateReadingWindow( IDirect3DDevice9* pd3dDevice, float fElapsedTime, bool bReading );
virtual void RenderComposition( IDirect3DDevice9* pd3dDevice, float fElapsedTime ); virtual void RenderComposition( IDirect3DDevice9* pd3dDevice, float fElapsedTime );
@@ -1033,7 +1041,7 @@ protected:
struct CCandList struct CCandList
{ {
TCHAR awszCandidate[MAX_CANDLIST][256]; WCHAR awszCandidate[MAX_CANDLIST][256];
CUniBuffer HoriCand; // Candidate list string (for horizontal candidate window) CUniBuffer HoriCand; // Candidate list string (for horizontal candidate window)
int nFirstSelected; // First character position of the selected string in HoriCand int nFirstSelected; // First character position of the selected string in HoriCand
int nHoriSelectedLen; // Length of the selected string in HoriCand int nHoriSelectedLen; // Length of the selected string in HoriCand
@@ -1071,7 +1079,7 @@ protected:
static CUniBuffer s_CompString; // Buffer to hold the composition string (we fix its length) static CUniBuffer s_CompString; // Buffer to hold the composition string (we fix its length)
static BYTE s_abCompStringAttr[MAX_COMPSTRING_SIZE]; static BYTE s_abCompStringAttr[MAX_COMPSTRING_SIZE];
static DWORD s_adwCompStringClause[MAX_COMPSTRING_SIZE]; static DWORD s_adwCompStringClause[MAX_COMPSTRING_SIZE];
static TCHAR s_wszReadingString[32];// Used only with horizontal reading window (why?) static WCHAR s_wszReadingString[32];// Used only with horizontal reading window (why?)
static CCandList s_CandList; // Data relevant to the candidate list static CCandList s_CandList; // Data relevant to the candidate list
static bool s_bShowReadingWindow; // Indicates whether reading window is visible static bool s_bShowReadingWindow; // Indicates whether reading window is visible
static bool s_bHorizontalReading; // Indicates whether the reading window is vertical or horizontal static bool s_bHorizontalReading; // Indicates whether the reading window is vertical or horizontal
+28 -1
View File
@@ -2,9 +2,36 @@
#include "ID3DXFontHook.h" #include "ID3DXFontHook.h"
#include "../main.h" #include "../main.h"
int dword_10136EA0;
DWORD dword_10136E90;
int dword_10136EA4;
char *dword_10140AEC;
char *dword_10140AF0;
WCHAR WideCharStr[20000];
int off_10102BF0;
void sub_100739A0(char *lpMultiByteStr, WCHAR *lpWideCharStr, int cchWideChar);
void sub_100B60C0(char *lpString);
INT __stdcall ID3DXFontHook::DrawTextA(LPD3DXSPRITE pSprite, LPCSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) INT __stdcall ID3DXFontHook::DrawTextA(LPD3DXSPRITE pSprite, LPCSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color)
{ {
// TODO: ID3DXFontHook::DrawTextA if(pSprite)
{
dword_10136EA0 = (int)pSprite;
dword_10136E90 = Color;
dword_10136EA4 = 0;
if(strlen(pString) > 0x186A0)
return 0;
strcpy(dword_10140AEC, pString);
strcpy(dword_10140AF0, pString);
sub_100739A0(dword_10140AEC, WideCharStr, 20000);
sub_100B60C0(dword_10140AF0);
return m_pD3DFont->DrawTextA((LPD3DXSPRITE)&off_10102BF0, dword_10140AF0, strlen(dword_10140AF0), pRect, Format, Color);
}
return m_pD3DFont->DrawTextA(pSprite, pString, Count, pRect, Format, Color); return m_pD3DFont->DrawTextA(pSprite, pString, Count, pRect, Format, Color);
} }
+386 -9
View File
@@ -13,15 +13,360 @@
#include "../main.h" #include "../main.h"
extern IDirect3DDevice9 *pD3DDevice; extern IDirect3DDevice9 *pD3DDevice;
extern CNetGame *pNetGame;
D3DXMATRIX matView, matProj, matWorld; D3DXMATRIX matView, matProj, matWorld;
int dword_101A25F8;
int dword_101A25FC;
int dword_10140D60;
int dword_1026EBA0;
int dword_101516D8;
extern CGame *pGame;
extern CChatWindow *pChatWindow;
extern CNewPlayerTags *pNewPlayerTags;
extern GAME_SETTINGS tSettings;
int dword_1012DE64;
int dword_1026EB4C;
int dword_1026EB50;
int dword_1026EB54;
int dword_1026EB58;
int dword_1026EB5C;
int dword_1026EB60;
int dword_1026EB64;
int dword_1026EB68;
int dword_1026EB6C;
int dword_1026EB70;
int dword_1026EB74;
int dword_1026EB78;
int dword_1026EB84;
int dword_1026EB88;
int dword_1026EB8C;
int dword_1026EC24;
int dword_1026EC2C;
char byte_1026EBB8;
MATRIX4X4 stru_10140CF8;
MATRIX4X4 stru_10140AF8;
VECTOR vec_10140D3C;
VECTOR vec_10140D64;
char byte_10140C78[128];
void sub_1009D8B0(); // .text:1009D8B0
void sub_100C3F50(); // .text:100C3F50
void sub_100C41B0(); // .text:100C41B0
int sub_100A4470(); // .text:100A4470
int sub_100C3E20(int a1, int a2); // .text:100C3E20
int sub_10062270(std::string *pstrFileName); // .text:10062270
void sub_10074480(); // .text:10074480
void sub_10074210(); // .text:10074210
int sub_100B7E00(); // .text:100B7E00
void sub_1009E490(); // .text:1009E490
// samp keeps this gta helper in a data slot, so the call goes through a pointer
float (*dword_10102BF4)(float a1, float a2) = (float (*)(float, float))0x568FE0;
// dispatch helpers invoked on render-manager globals (thiscall)
class CD3DHookDispatch
{
public:
void FUNC_10066AB0(); // .text:10066AB0
void FUNC_1006BC70(); // .text:1006BC70
void FUNC_1006BC80(); // .text:1006BC80
void FUNC_1006BC90(void *a1, char *a2, int a3, int a4, int a5); // .text:1006BC90
void FUNC_1006F0B0(); // .text:1006F0B0
void FUNC_10060D70(); // .text:10060D70
void FUNC_10071260(); // .text:10071260
void FUNC_1006BB30(); // .text:1006BB30
void FUNC_10066ED0(); // .text:10066ED0
void FUNC_100696F0(); // .text:100696F0
void FUNC_1006A2E0(); // .text:1006A2E0
void FUNC_1006F890(); // .text:1006F890
void FUNC_10071AC0(); // .text:10071AC0
void FUNC_1006A910(); // .text:1006A910
void FUNC_100908E0(float a1); // .text:100908E0
void FUNC_10073780(); // .text:10073780
void FUNC_1006DC00(); // .text:1006DC00
void FUNC_10071410(); // .text:10071410
};
//-------------------------------------------
// per-frame nametag pass: walks the player pool and draws a tag over every visible remote ped
void sub_10075330()
{
if(!pNetGame)
return;
if(!pNetGame->GetSettings()->field_38)
return;
pNewPlayerTags->FUNC_1006CD80();
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
pGame->FindPlayerPed()->GetMatrix(&stru_10140CF8);
int iHighestId = pPlayerPool->field_2F3A;
for(int i = 0; i <= iHighestId; i++)
{
if(pPlayerPool->GetSlotState((PLAYERID)i) != 1)
continue;
CRemotePlayer *pRemotePlayer = pPlayerPool->GetAt((PLAYERID)i);
if(!pRemotePlayer)
continue;
CPlayerPed *pPlayerPed = pRemotePlayer->m_pPlayerPed;
if(!pPlayerPed)
continue;
if(!pRemotePlayer->field_10A)
continue;
if(!pRemotePlayer->field_4)
continue;
float fDistance = pPlayerPed->FUNC_1009F190();
if(fDistance <= pNetGame->GetSettings()->field_27)
{
if(pRemotePlayer->field_10A == 19 && pRemotePlayer->field_1E1 && sub_100B7E00())
{
((CEntity *)pRemotePlayer->field_1E1)->GetMatrix(&stru_10140AF8);
vec_10140D3C = stru_10140AF8.pos;
}
else
{
if(!pPlayerPed->IsAdded())
continue;
memset(&vec_10140D3C, 0, sizeof(VECTOR));
pPlayerPed->GetBonePosition(8, &vec_10140D3C);
}
vec_10140D64 = vec_10140D3C;
CAMERA_AIM *pAim = GameGetInternalAim();
int iLineOfSight = 0;
if(pNetGame->GetSettings()->field_2F)
iLineOfSight = ScriptCommand(&is_line_of_sight_clear,
vec_10140D64.X, vec_10140D64.Y, vec_10140D64.Z,
pAim->pos1x, pAim->pos1y, pAim->pos1z, 1, 0, 0, 1, 0);
if(!pNetGame->GetSettings()->field_2F || iLineOfSight)
{
sprintf(byte_10140C78, "%s (%d)", pPlayerPool->FUNC_100175C0(i), i);
if(!pRemotePlayer->field_10C)
{
pNewPlayerTags->Draw((D3DXVECTOR3 *)&vec_10140D64, byte_10140C78,
pRemotePlayer->GetPlayerColorAsARGB(), pPlayerPed->FUNC_1009F190(),
pNetGame->field_234, pRemotePlayer->FUNC_10016330());
}
}
}
}
pNewPlayerTags->FUNC_1006CD90();
}
//-------------------------------------------
// screenshot grab: reached from Present when the F8 handler raises dword_1012DE64
void sub_100755C0()
{
dword_1012DE64 = 0;
std::string strFileName;
int iIndex = sub_10062270(&strFileName);
IDirect3DSurface9 *pSurface;
pD3DDevice->CreateOffscreenPlainSurface(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL);
if(SUCCEEDED(pD3DDevice->GetFrontBufferData(0, pSurface)))
{
POINT pt;
pt.x = 0;
pt.y = 0;
ClientToScreen(*(HWND *)0xC97C1C, &pt);
RECT rc;
GetClientRect(*(HWND *)0xC97C1C, &rc);
rc.left += pt.x;
rc.right += pt.x;
rc.top += pt.y;
rc.bottom += pt.y;
D3DXSaveSurfaceToFileA(strFileName.c_str(), D3DXIFF_PNG, pSurface, NULL, &rc);
pChatWindow->AddInfoMessage("Screenshot Taken - sa-mp-%03i.png", iIndex);
}
else
{
pChatWindow->AddDebugMessage("Unable to save screenshot.");
}
}
//------------------------------------------- //-------------------------------------------
HRESULT __stdcall IDirect3DDevice9Hook::Present(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) HRESULT __stdcall IDirect3DDevice9Hook::Present(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
{ {
// TODO: IDirect3DDevice9Hook::Present if(dword_1012DE64)
sub_100755C0();
return pD3DDevice->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); sub_10074480();
if(!pGame->sub_100A0920())
{
if(pNetGame)
{
CVehiclePool *v3 = pNetGame->GetVehiclePool();
sub_10074210();
sub_10075330();
if(dword_1026EB8C)
((CD3DHookDispatch *)dword_1026EB8C)->FUNC_10066AB0();
if(byte_1026EBB8)
{
if(dword_1026EB5C)
((CD3DHookDispatch *)dword_1026EB5C)->FUNC_1006BC70();
float *v4 = (float *)((char *)v3 + 0x11AD8);
for(unsigned short i = 0; i < MAX_VEHICLES; i++, v4 += 3)
{
if(v3->GetSlotState(i) == 1)
{
CEntity *v7 = (CEntity *)v3->GetAt(i);
if(v7)
{
if(v7->FUNC_1009F0C0() <= 20.0f)
{
MATRIX4X4 a2;
v7->GetMatrix(&a2);
int v35[3];
v35[0] = *(int *)&a2.pos.X;
v35[1] = *(int *)&a2.pos.Y;
v35[2] = *(int *)&a2.pos.Z;
char string[264];
sprintf(string,
"[id: %d, type: %d subtype: %d Health: %.1f preloaded: %u]\n"
"Distance: %.2fm\n"
"PassengerSeats: %u\n"
"cPos: %.3f,%.3f,%.3f\n"
"sPos: %.3f,%.3f,%.3f",
i,
v7->GetModelIndex(),
v7->FUNC_100B7390(),
v7->FUNC_100B72A0(),
*((BYTE *)pGame + v7->GetModelIndex() - 0x122),
v7->FUNC_1009F0C0(),
v7->FUNC_100B8340(),
a2.pos.X, a2.pos.Y, a2.pos.Z, v4[-1], v4[0], v4[1]);
((CD3DHookDispatch *)dword_1026EB5C)->FUNC_1006BC90(v35, string, 0xFF358BD4, 1, 0);
}
}
}
}
if(dword_1026EB5C)
((CD3DHookDispatch *)dword_1026EB5C)->FUNC_1006BC80();
}
if(pNetGame)
{
if(*(int *)dword_1026EB4C)
{
pGame->sub_100A1DB0(0);
((CD3DHookDispatch *)dword_1026EB4C)->FUNC_1006F0B0();
goto LABEL_77;
}
if(GetAsyncKeyState(0x74) && pNetGame->GetGameState() == 5)
{
pGame->sub_100A1DB0(0);
if(dword_1026EB6C)
((CD3DHookDispatch *)dword_1026EB6C)->FUNC_10060D70();
goto LABEL_77;
}
if(pNetGame)
{
if(GetAsyncKeyState(0x79))
{
pGame->sub_100A1DB0(0);
if(dword_1026EB70)
((CD3DHookDispatch *)dword_1026EB70)->FUNC_10071260();
goto LABEL_77;
}
if(pNetGame && GetAsyncKeyState(0x70) && dword_1026EB74)
((CD3DHookDispatch *)dword_1026EB74)->FUNC_1006BB30();
}
}
}
if(pChatWindow->field_8)
pGame->sub_100A1DB0(1);
else
pGame->sub_100A1DB0(0);
if(pGame)
{
if(pGame->FindPlayerPed())
{
CPlayerPed *PlayerPed = pGame->FindPlayerPed();
if(PlayerPed->sub_100ADFA0() > 5000)
pGame->sub_100A1DB0(0);
}
}
if(dword_1026EB78)
((CD3DHookDispatch *)dword_1026EB78)->FUNC_10066ED0();
if(pNetGame && pNetGame->GetLabelPool())
pNetGame->GetLabelPool()->FUNC_10001350();
if(pChatWindow)
pChatWindow->FUNC_10067E00();
if(dword_1026EB84)
((CD3DHookDispatch *)dword_1026EB84)->FUNC_100696F0();
if(dword_1026EB88)
((CD3DHookDispatch *)dword_1026EB88)->FUNC_1006A2E0();
if(pNetGame)
{
if(dword_1026EB50)
((CD3DHookDispatch *)dword_1026EB50)->FUNC_1006F890();
if(pNetGame)
{
if(dword_1026EB54)
((CD3DHookDispatch *)dword_1026EB54)->FUNC_10071AC0();
if(pNetGame && dword_1026EB58)
((CD3DHookDispatch *)dword_1026EB58)->FUNC_1006A910();
}
}
if(dword_1026EC24)
((CD3DHookDispatch *)dword_1026EC24)->FUNC_100908E0(10.0f);
if(dword_1026EC2C)
((CD3DHookDispatch *)dword_1026EC2C)->FUNC_100908E0(10.0f);
if(dword_1026EB60)
((CD3DHookDispatch *)dword_1026EB60)->FUNC_10073780();
if(dword_1026EB64)
((CD3DHookDispatch *)dword_1026EB64)->FUNC_1006DC00();
if(dword_1026EB68)
((CD3DHookDispatch *)dword_1026EB68)->FUNC_10071410();
}
else
{
if(pGame->sub_100A0920() && pNetGame && *(int *)0xBA6774 && (GetAsyncKeyState(2) & 1) && !*(char *)0xBA8298)
{
float v32, v30;
char *p = (char *)0xBA873D;
int n = 175;
do
{
if(*(WORD *)p == 0x1203 && *(WORD *)p)
{
v32 = *(float *)(p - 29);
v30 = *(float *)(p - 25);
}
p += 40;
}
while(--n);
RakNet::BitStream bs;
bs.Write(v32);
bs.Write(v30);
bs.Write(dword_10102BF4(v32, v30) + 2.0f);
pNetGame->GetRakClient()->RPC("w", &bs, HIGH_PRIORITY, RELIABLE, 0, 0);
}
}
LABEL_77:
if(tSettings.bDebug)
sub_1009E490();
sub_1009D8B0();
HRESULT hr = pD3DDevice->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
sub_1009D8B0();
return hr;
} }
HRESULT __stdcall IDirect3DDevice9Hook::QueryInterface(REFIID riid, void** ppvObj) HRESULT __stdcall IDirect3DDevice9Hook::QueryInterface(REFIID riid, void** ppvObj)
@@ -106,9 +451,11 @@ UINT __stdcall IDirect3DDevice9Hook::GetNumberOfSwapChains()
HRESULT __stdcall IDirect3DDevice9Hook::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) HRESULT __stdcall IDirect3DDevice9Hook::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters)
{ {
// TODO: IDirect3DDevice9Hook::Reset sub_100C3F50();
HRESULT hr = pD3DDevice->Reset(pPresentationParameters);
return pD3DDevice->Reset(pPresentationParameters); if(hr >= 0)
sub_100C41B0();
return hr;
} }
HRESULT __stdcall IDirect3DDevice9Hook::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) HRESULT __stdcall IDirect3DDevice9Hook::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer)
@@ -233,9 +580,10 @@ HRESULT __stdcall IDirect3DDevice9Hook::BeginScene()
HRESULT __stdcall IDirect3DDevice9Hook::EndScene() HRESULT __stdcall IDirect3DDevice9Hook::EndScene()
{ {
// TODO: IDirect3DDevice9Hook::EndScene sub_1009D8B0();
HRESULT hr = pD3DDevice->EndScene();
return pD3DDevice->EndScene(); sub_1009D8B0();
return hr;
} }
HRESULT __stdcall IDirect3DDevice9Hook::Clear(DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) HRESULT __stdcall IDirect3DDevice9Hook::Clear(DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil)
@@ -363,7 +711,36 @@ HRESULT __stdcall IDirect3DDevice9Hook::GetTexture(DWORD Stage, IDirect3DBaseTex
HRESULT __stdcall IDirect3DDevice9Hook::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture) HRESULT __stdcall IDirect3DDevice9Hook::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture)
{ {
// TODO: IDirect3DDevice9Hook::SetTexture if(dword_101A25F8 && dword_101A25FC)
{
for(dword_10140D60 = 0; dword_10140D60 != 16; dword_10140D60++)
{
if(*(DWORD *)(dword_101A25FC + 4 * dword_10140D60 + 0x110B) == (DWORD)pTexture &&
*(DWORD *)(dword_101A25FC + 4 * dword_10140D60 + 0x114B))
{
return pD3DDevice->SetTexture(Stage,
(IDirect3DBaseTexture9 *)*(DWORD *)(dword_101A25FC + 4 * dword_10140D60 + 0x114B));
}
}
}
int v4 = sub_100A4470();
if(v4 && v4 == (int)pTexture && pNetGame && pNetGame->GetVehiclePool())
{
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
short v5 = pVehiclePool->FUNC_1001EB90(dword_101516D8);
int v7 = pVehiclePool->FUNC_10001120(v5);
if(v7 && *(DWORD *)(v7 + 0x8F))
{
sub_100C3E20(9, 2);
return pD3DDevice->SetTexture(Stage, (IDirect3DBaseTexture9 *)*(DWORD *)(v7 + 0x8F));
}
if(*(DWORD *)(dword_1026EBA0 + 0x20))
{
sub_100C3E20(9, 2);
return pD3DDevice->SetTexture(Stage, (IDirect3DBaseTexture9 *)*(DWORD *)(dword_1026EBA0 + 0x20));
}
}
return pD3DDevice->SetTexture(Stage, pTexture); return pD3DDevice->SetTexture(Stage, pTexture);
} }
+27 -2
View File
@@ -27,13 +27,38 @@ int dword_10125A58=0;
void DumpNetworkStateInformation(PCHAR sz) void DumpNetworkStateInformation(PCHAR sz)
{ {
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool(); CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
PLAYERID playerId=0; PLAYERID playerId;
char szBuffer[16384];
sz[0] = '\0'; sz[0] = '\0';
sprintf(sz,"\r\nState Information: Ped Context: %u\r\n",*pbyteCurrentPlayer); sprintf(sz,"\r\nState Information: Ped Context: %u\r\n",*pbyteCurrentPlayer);
// TODO: DumpNetworkStateInformation 10060160 playerId = 0;
do
{
if(playerId < MAX_PLAYERS && pPlayerPool->field_2A[playerId])
{
CNetPlayer *pNetPlayer = pPlayerPool->m_pPlayers[playerId];
CRemotePlayer *pRemotePlayer;
if(pNetPlayer)
pRemotePlayer = pNetPlayer->m_pRemotePlayer;
else
pRemotePlayer = NULL;
sprintf(szBuffer,"P%u (%u,%u) ",playerId,pRemotePlayer->field_10A,pRemotePlayer->field_1E7);
strcat(sz,szBuffer);
if(playerId > 0)
{
if(!((playerId + 1) % 4))
strcat(sz,"\r\n");
}
}
playerId++;
}
while(playerId != MAX_PLAYERS);
} }
//---------------------------------------------------- //----------------------------------------------------
+4
View File
@@ -31,6 +31,10 @@ public:
void ToggleImmunity(BYTE byteEnable); void ToggleImmunity(BYTE byteEnable);
void FUNC_1009C550(); // .text:1009C550
void FUNC_1009C570(float a1); // .text:1009C570
void FUNC_1009C5D0(int a1); // .text:1009C5D0
PED_TYPE *m_pPed; PED_TYPE *m_pPed;
DWORD m_dwMarkerID; DWORD m_dwMarkerID;
DWORD m_dwArrow; DWORD m_dwArrow;
+1 -1
View File
@@ -5,7 +5,7 @@
class CAudio class CAudio
{ {
private: public:
int field_0; int field_0;
bool field_4; bool field_4;
+1
View File
@@ -23,6 +23,7 @@ public:
void InterpolateLookAt(VECTOR *vecFrom, VECTOR *vecTo, int iTime, BYTE byteCut); void InterpolateLookAt(VECTOR *vecFrom, VECTOR *vecTo, int iTime, BYTE byteCut);
void FUNC_1009D660(CEntity *pEntity); void FUNC_1009D660(CEntity *pEntity);
void FUNC_1009D6B0(); void FUNC_1009D6B0();
void FUNC_1009D740(); // .text:1009D740
float GetDistanceFromPoint(VECTOR *vecPos); float GetDistanceFromPoint(VECTOR *vecPos);
CCamera() { CCamera() {
+2 -1
View File
@@ -65,7 +65,8 @@ typedef struct _WEAPON_SLOT_TYPE
{ {
DWORD dwType; DWORD dwType;
char _gap4[8]; DWORD field_4;
DWORD field_8;
DWORD dwAmmo; DWORD dwAmmo;
+13
View File
@@ -26,6 +26,7 @@ public:
void GetBoundCentre(PVECTOR Vector); void GetBoundCentre(PVECTOR Vector);
void GetBoundRect(PFRECT Rect); // unused void GetBoundRect(PFRECT Rect); // unused
UINT GetModelIndex(); UINT GetModelIndex();
int SetModelIndex(int iModel); // .text:1009EF50
void TeleportTo(float x, float y, float z); void TeleportTo(float x, float y, float z);
float GetDistanceFromLocalPlayerPed(); float GetDistanceFromLocalPlayerPed();
float GetDistanceFromCamera(); float GetDistanceFromCamera();
@@ -49,10 +50,22 @@ public:
DWORD GetWorldBoundRadius(); DWORD GetWorldBoundRadius();
void SetEulerAngles(float fX, float fY, float fZ); void SetEulerAngles(float fX, float fY, float fZ);
void FUNC_100A7E20(); // .text:100A7E20
virtual void Add(); virtual void Add();
virtual void Remove(); virtual void Remove();
BOOL IsAdded(); BOOL IsAdded();
float FUNC_1009F0C0(); // .text:1009F0C0
BOOL FUNC_1009F420(float a1, float a2, float a3, float a4); // .text:1009F420
float FUNC_1009F190(); // .text:1009F190
char FUNC_1009FC00(VECTOR *vecStart, VECTOR *vecEnd, char a3); // .text:1009FC00
char FUNC_1009FCE0(); // .text:1009FCE0
BYTE FUNC_100B8340(); // .text:100B8340
float FUNC_100B72A0(); // .text:100B72A0
int FUNC_100B7390(); // .text:100B7390
DWORD * FUNC_1009FA60(); // .text:1009FA60
VECTOR field_4[5]; VECTOR field_4[5];
ENTITY_TYPE *m_pEntity; ENTITY_TYPE *m_pEntity;
DWORD m_dwGTAId; DWORD m_dwGTAId;
+124 -49
View File
@@ -49,14 +49,18 @@ CGame::CGame()
memset(bUsedPlayerSlots, 0, sizeof(bUsedPlayerSlots)); memset(bUsedPlayerSlots, 0, sizeof(bUsedPlayerSlots));
memset(field_6E, 0, sizeof(field_6E)); memset(field_6E, 0, sizeof(field_6E));
field_55 = 0; field_55 = 0;
field_59 = 1; m_bHeadMove = 1;
field_5D = 90; field_5D = 90;
} }
void CGame::sub_100A0010() void CGame::sub_100A0010()
{ {
int time = (int)RakNet::GetTime(); int time = (int)RakNet::GetTime();
if(unnamed_1015068C) if(!unnamed_1015068C)
{
unnamed_1015068C = time;
}
else
{ {
if((time - unnamed_1015068C) > 30) if((time - unnamed_1015068C) > 30)
{ {
@@ -67,13 +71,9 @@ void CGame::sub_100A0010()
} }
*(BYTE*)0xB7356E = unnamed_10150688; *(BYTE*)0xB7356E = unnamed_10150688;
} }
else
{
unnamed_1015068C = time;
}
} }
void unnamed_100A0060(float a1) void __stdcall unnamed_100A0060(float a1)
{ {
*(float*)0xB7CB5C = a1; *(float*)0xB7CB5C = a1;
*(float*)0xB7CB58 = a1; *(float*)0xB7CB58 = a1;
@@ -243,9 +243,18 @@ void CGame::ProcessInputDisabling()
*(BYTE*)0x53F421 = 0x0F; *(BYTE*)0x53F421 = 0x0F;
*(BYTE*)0x53F422 = 0x8C; *(BYTE*)0x53F422 = 0x8C;
DIResetMouse(); *(DWORD*)0xB73424 = 0;
UpdatePads(); *(DWORD*)0xB73428 = 0;
DIResetMouse(); _asm mov edx, 0x541BD0
_asm call edx
_asm mov edx, 0x541DD0
_asm call edx
*(DWORD*)0xB73424 = 0;
*(DWORD*)0xB73428 = 0;
_asm mov edx, 0x541BD0
_asm call edx
UnFuck(0x6194A0,1); UnFuck(0x6194A0,1);
*(BYTE*)0x6194A0 = 0xE9; *(BYTE*)0x6194A0 = 0xE9;
@@ -253,9 +262,8 @@ void CGame::ProcessInputDisabling()
pD3DDevice->ShowCursor(FALSE); pD3DDevice->ShowCursor(FALSE);
field_65--; field_65--;
} else { } else {
if(field_65 <= 0) if(field_65 > 0)
return; field_65--;
field_65 -= 1;
} }
} }
@@ -269,8 +277,13 @@ void CGame::ToggleKeyInputsDisabled(int a2, BOOL a3)
memset((PVOID)0x541DF5,0x90,5); // disable call memset((PVOID)0x541DF5,0x90,5); // disable call
DisableMouseProcess(); DisableMouseProcess();
DIResetMouse(); *(DWORD*)0xB73424 = 0;
UpdatePads(); *(DWORD*)0xB73428 = 0;
_asm mov edx, 0x541BD0
_asm call edx
_asm mov edx, 0x541DD0
_asm call edx
UnFuck(0x6194A0u,1); UnFuck(0x6194A0u,1);
*(BYTE*)0x6194A0 = 0xC3; *(BYTE*)0x6194A0 = 0xC3;
@@ -293,8 +306,13 @@ void CGame::ToggleKeyInputsDisabled(int a2, BOOL a3)
if(field_61 != 3) if(field_61 != 3)
{ {
DisableMouseProcess(); DisableMouseProcess();
DIResetMouse(); *(DWORD*)0xB73424 = 0;
UpdatePads(); *(DWORD*)0xB73428 = 0;
_asm mov edx, 0x541BD0
_asm call edx
_asm mov edx, 0x541DD0
_asm call edx
UnFuck(0x6194A0,1); UnFuck(0x6194A0,1);
*(BYTE*)0x6194A0 = 0xC3; *(BYTE*)0x6194A0 = 0xC3;
@@ -308,8 +326,13 @@ void CGame::ToggleKeyInputsDisabled(int a2, BOOL a3)
if(field_61 != 4) if(field_61 != 4)
{ {
DisableMousePositionUpdate(); DisableMousePositionUpdate();
DIResetMouse(); *(DWORD*)0xB73424 = 0;
UpdatePads(); *(DWORD*)0xB73428 = 0;
_asm mov edx, 0x541BD0
_asm call edx
_asm mov edx, 0x541DD0
_asm call edx
UnFuck(0x6194A0,1); UnFuck(0x6194A0,1);
*(BYTE*)0x6194A0 = 0xC3; *(BYTE*)0x6194A0 = 0xC3;
@@ -380,29 +403,55 @@ void CGame::StartGame()
void CGame::sub_100A0110() CPlayerPed *CGame::sub_100A0110(int a1, float fX, float fY, float fZ, float fRotation, int a6, int a7)
{ {
// TODO: CGame::sub_100A0110() .text:100A0110 // TODO: CGame::sub_100A0110() .text:100A0110
return NULL;
} }
void CGame::sub_100A0210() int CGame::DeletePlayerPed(int pPlayerPed)
{ {
// TODO: CGame::sub_100A0210() .text:100A0210 if(pPlayerPed)
{
BYTE bytePlayerNumber = *(BYTE *)(pPlayerPed + 0x2B0);
((struc_vdelete *)pPlayerPed)->Delete(1);
bUsedPlayerSlots[bytePlayerNumber] = 0;
return 1;
}
return 0;
} }
void CGame::sub_100A0250() CVehicle *CGame::sub_100A0250(int a2, float a3, float a4, float a5, float a6, int a7)
{ {
// TODO: CGame::sub_100A0250() .text:100A0250 BOOL bKeepModelLoaded = 0;
if(*((char *)this + a2 - 290))
bKeepModelLoaded = 1;
CVehicle *pVehicle = new CVehicle(a2, a3, a4, a5, a6, bKeepModelLoaded, a7);
return pVehicle->m_pVehicle ? pVehicle : 0;
} }
void CGame::sub_100A02E0() char szUnk_10113968[8];
void sub_100A4170(const char *a1)
{ {
// TODO: CGame::sub_100A02E0() .text:100A02E0 (unused) memset(szUnk_10113968, 0, sizeof(szUnk_10113968));
strcpy(szUnk_10113968, a1);
} }
void CGame::sub_100A0310() void __stdcall sub_100A02E0(const char *a1)
{ {
// TODO: CGame::sub_100A0310() .text:100A0310 (unused) if(a1 && *a1 && strlen(a1) <= 8)
sub_100A4170(a1);
}
int __stdcall sub_100A0310(void *a1)
{
if(a1)
{
((struc_vdelete *)a1)->Delete(1);
return 1;
}
return 0;
} }
void CGame::sub_100A0330() void CGame::sub_100A0330()
@@ -438,6 +487,13 @@ void CGame::sub_100A1C10()
// TODO: CGame::sub_100A1C10() .text:100A1C10 // TODO: CGame::sub_100A1C10() .text:100A1C10
} }
//-----------------------------------------------------------
BOOL CGame::sub_100A0920()
{
return *(PDWORD)0xBA67A4 != 0;
}
@@ -479,8 +535,8 @@ BOOL CGame::SetModelDeletable(int iModelID)
{ {
BYTE * pStreamingModelInfo = (BYTE*)(iModelID * 20); BYTE * pStreamingModelInfo = (BYTE*)(iModelID * 20);
if(IsModelLoaded(iModelID)) if(iModelID > 20000 || iModelID < 0) return TRUE;
return TRUE; if(ScriptCommand(&is_model_available,iModelID)) return TRUE;
_asm push 2 _asm push 2
_asm push iModelID _asm push iModelID
@@ -573,10 +629,10 @@ void CGame::DisplayHud(BOOL bDisp)
{ {
if(bDisp) { if(bDisp) {
*(BYTE*)ADDR_ENABLE_HUD = 1; *(BYTE*)ADDR_ENABLE_HUD = 1;
ToggleRadar(1); *(PBYTE)0xBAA3FB = 0;
} else { } else {
*(BYTE*)ADDR_ENABLE_HUD = 0; *(BYTE*)ADDR_ENABLE_HUD = 0;
ToggleRadar(0); *(PBYTE)0xBAA3FB = 1;
} }
} }
@@ -668,7 +724,7 @@ int CGame::IsAnimationLoaded(char *szAnimFile)
void CGame::ReleaseAnimation(char *szAnimFile) void CGame::ReleaseAnimation(char *szAnimFile)
{ {
if (IsAnimationLoaded(szAnimFile)) if (ScriptCommand(&is_animation_loaded,szAnimFile))
ScriptCommand(&release_animation,szAnimFile); ScriptCommand(&release_animation,szAnimFile);
} }
@@ -713,7 +769,7 @@ void CGame::SetCheckpointInformation(VECTOR *pos, VECTOR *extent)
memcpy(&m_vecCheckpointPos,pos,sizeof(VECTOR)); memcpy(&m_vecCheckpointPos,pos,sizeof(VECTOR));
memcpy(&m_vecCheckpointExtent,extent,sizeof(VECTOR)); memcpy(&m_vecCheckpointExtent,extent,sizeof(VECTOR));
if(m_dwCheckpointMarker) { if(m_dwCheckpointMarker) {
DisableMarker(m_dwCheckpointMarker); ScriptCommand(&disable_marker, m_dwCheckpointMarker);
m_dwCheckpointMarker = NULL; m_dwCheckpointMarker = NULL;
DWORD dwMarkerID = 0; DWORD dwMarkerID = 0;
@@ -734,7 +790,7 @@ void CGame::SetRaceCheckpointInformation(BYTE byteType, VECTOR *pos, VECTOR *nex
m_byteRaceType = byteType; m_byteRaceType = byteType;
if(m_dwRaceCheckpointMarker) if(m_dwRaceCheckpointMarker)
{ {
DisableMarker(m_dwRaceCheckpointMarker); ScriptCommand(&disable_marker, m_dwRaceCheckpointMarker);
m_dwRaceCheckpointMarker = NULL; m_dwRaceCheckpointMarker = NULL;
DWORD dwMarkerID = 0; DWORD dwMarkerID = 0;
@@ -750,7 +806,12 @@ void CGame::SetRaceCheckpointInformation(BYTE byteType, VECTOR *pos, VECTOR *nex
void CGame::MakeRaceCheckpoint() void CGame::MakeRaceCheckpoint()
{ {
DisableRaceCheckpoint(); if (m_dwRaceCheckpointHandle)
{
ScriptCommand(&destroy_racing_checkpoint, m_dwRaceCheckpointHandle);
m_dwRaceCheckpointHandle = NULL;
}
m_bRaceCheckpointsEnabled = false;
ScriptCommand(&create_racing_checkpoint, (int)m_byteRaceType, ScriptCommand(&create_racing_checkpoint, (int)m_byteRaceType,
m_vecRaceCheckpointPos.X, m_vecRaceCheckpointPos.Y, m_vecRaceCheckpointPos.Z, m_vecRaceCheckpointPos.X, m_vecRaceCheckpointPos.Y, m_vecRaceCheckpointPos.Z,
@@ -796,7 +857,7 @@ void CGame::UpdateCheckpoints()
} }
} }
else if(m_dwCheckpointMarker) { else if(m_dwCheckpointMarker) {
DisableMarker(m_dwCheckpointMarker); ScriptCommand(&disable_marker, m_dwCheckpointMarker);
m_dwCheckpointMarker = NULL; m_dwCheckpointMarker = NULL;
} }
@@ -816,8 +877,13 @@ void CGame::UpdateCheckpoints()
} }
} }
else if(m_dwRaceCheckpointMarker) { else if(m_dwRaceCheckpointMarker) {
DisableMarker(m_dwRaceCheckpointMarker); ScriptCommand(&disable_marker, m_dwRaceCheckpointMarker);
DisableRaceCheckpoint(); if (m_dwRaceCheckpointHandle)
{
ScriptCommand(&destroy_racing_checkpoint, m_dwRaceCheckpointHandle);
m_dwRaceCheckpointHandle = NULL;
}
m_bRaceCheckpointsEnabled = false;
m_dwRaceCheckpointMarker = NULL; m_dwRaceCheckpointMarker = NULL;
} }
} }
@@ -878,7 +944,9 @@ void CGame::UpdateFarClippingPlane()
PED_TYPE *pPlayerPed = GamePool_FindPlayerPed(); PED_TYPE *pPlayerPed = GamePool_FindPlayerPed();
if(pPlayerPed) { if(pPlayerPed) {
if(GetActiveInterior() == 0) { DWORD dwInterior;
ScriptCommand(&get_active_interior,&dwInterior);
if(!(BYTE)dwInterior) {
fFarClip = 1250.0f - (pPlayerPed->entity.mat->pos.Z * 2.0f); fFarClip = 1250.0f - (pPlayerPed->entity.mat->pos.Z * 2.0f);
if(fFarClip < 700.0f) { if(fFarClip < 700.0f) {
fFarClip = 700.0f; fFarClip = 700.0f;
@@ -904,13 +972,13 @@ void CGame::AddToLocalMoney(int iAmount)
void CGame::ResetLocalMoney() void CGame::ResetLocalMoney()
{ {
int iMoney = GetLocalMoney(); int iMoney = *(int *)0xB7CE50;
if(!iMoney) return; if(!iMoney) return;
if(iMoney < 0) { if(iMoney < 0) {
AddToLocalMoney(abs(iMoney)); ScriptCommand(&add_to_player_money,0,abs(iMoney));
} else { } else {
AddToLocalMoney(-(iMoney)); ScriptCommand(&add_to_player_money,0,-(iMoney));
} }
} }
@@ -1025,10 +1093,13 @@ DWORD CGame::CreateWeaponPickup(int iModel, DWORD dwAmmo, float fX, float fY, fl
{ {
DWORD hnd; DWORD hnd;
if(!IsModelLoaded(iModel)) { // the model wait is spelled out, none of the model helpers are inline here
RequestModel(iModel); if(iModel <= 20000 && iModel >= 0 && !ScriptCommand(&is_model_available, iModel))
LoadRequestedModels(); {
while(!IsModelLoaded(iModel)) Sleep(5); ScriptCommand(&request_model, iModel);
ScriptCommand(&load_requested_models);
while(!ScriptCommand(&is_model_available, iModel)) Sleep(5);
} }
ScriptCommand(&create_pickup_with_ammo, iModel, 4, dwAmmo, fX, fY, fZ, &hnd); ScriptCommand(&create_pickup_with_ammo, iModel, 4, dwAmmo, fX, fY, fZ, &hnd);
@@ -1136,12 +1207,16 @@ void CGame::EnableClock(BYTE byteClock)
UnFuck(0x859A6C,10); UnFuck(0x859A6C,10);
if (byteClock) if (byteClock)
{ {
ToggleThePassingOfTime(1); UnFuck(0x52CF10,1);
*(PBYTE)0x52CF10 = 0x56; // push esi
field_69 = TRUE;
memcpy((PVOID)0x859A6C, byteClockData, 10); memcpy((PVOID)0x859A6C, byteClockData, 10);
} }
else else
{ {
ToggleThePassingOfTime(0); UnFuck(0x52CF10,1);
*(PBYTE)0x52CF10 = 0xC3; // ret
field_69 = FALSE;
memset((PVOID)0x859A6C,0,10); memset((PVOID)0x859A6C,0,10);
} }
} }
+31 -12
View File
@@ -17,7 +17,7 @@
class CGame // size: 322 class CGame // size: 322
{ {
private: public:
CAudio *m_pGameAudio; CAudio *m_pGameAudio;
CCamera *m_pGameCamera; CCamera *m_pGameCamera;
@@ -35,7 +35,7 @@ private:
BOOL m_bCheckpointsEnabled; BOOL m_bCheckpointsEnabled;
DWORD m_dwCheckpointMarker; DWORD m_dwCheckpointMarker;
int field_55; int field_55;
int field_59; int m_bHeadMove;
DWORD field_5D; DWORD field_5D;
int field_61; int field_61;
int field_65; int field_65;
@@ -56,22 +56,23 @@ public:
void InitGame(); void InitGame();
BOOL IsGameLoaded(); BOOL IsGameLoaded();
void RequestModel(int iModelID, int iLoadingStream = 2); void RequestModel(int iModelID, int iLoadingStream = 2);
void LoadRequestedModels(); void LoadRequestedModels();
BOOL IsModelLoaded(int iModelID); BOOL IsModelLoaded(int iModelID);
BOOL SetModelDeletable(int iModelID); BOOL SetModelDeletable(int iModelID);
void SetWorldTime(int iHour, int iMinute); void SetWorldTime(int iHour, int iMinute); // .text:100A0AB0
void GetWorldTime(BYTE* byteHour, BYTE* byteMinute); void GetWorldTime(BYTE* byteHour, BYTE* byteMinute);
void ToggleThePassingOfTime(BYTE byteOnOff); void ToggleThePassingOfTime(BYTE byteOnOff);
void SetWorldWeather(int iWeatherID); void SetWorldWeather(int iWeatherID); // .text:100A0B40
int GetWorldWeather(); int GetWorldWeather();
void DisplayHud(BOOL bDisp); void DisplayHud(BOOL bDisp);
BYTE IsHudEnabled(); BYTE IsHudEnabled();
void SetFrameLimiterOn(BOOL bLimiter); void SetFrameLimiterOn(BOOL bLimiter);
BOOL IsFrameLimiterEnabled(); BOOL IsFrameLimiterEnabled();
void EnableFrameLimiter(); void EnableFrameLimiter();
void SetFrameLimit(DWORD dwLimit); void SetFrameLimit(DWORD dwLimit); // .text:100A0BB0
void SetMaxStats(); void SetMaxStats();
void DisableTrainTraffic(); void DisableTrainTraffic();
void RefreshStreamingAt(float x, float y); void RefreshStreamingAt(float x, float y);
@@ -79,11 +80,12 @@ public:
int IsAnimationLoaded(char *szAnimFile); int IsAnimationLoaded(char *szAnimFile);
void ReleaseAnimation(char *szAnimFile); void ReleaseAnimation(char *szAnimFile);
void ToggleRadar(int iToggle); void ToggleRadar(int iToggle);
void DisplayGameText(char *szStr,int iTime,int iSize); void DisplayGameText(char *szStr,int iTime,int iSize); // .text:100A0CE0
DWORD FUNC_100A0D90(int a1, float fX, float fY, float fZ, int a5, int a6); // .text:100A0D90
void SetGravity(float fGravity); void SetGravity(float fGravity);
void EnableClock(BYTE byteClock); void EnableClock(BYTE byteClock);
void EnableZoneNames(BYTE byteEnable); void EnableZoneNames(BYTE byteEnable);
void SetWantedLevel(BYTE byteLevel); void SetWantedLevel(BYTE byteLevel); // .text:100A1420
void SetGameTextCount(WORD wCount); void SetGameTextCount(WORD wCount);
void DrawGangZone(float* fPos, DWORD dwColor); void DrawGangZone(float* fPos, DWORD dwColor);
void EnableStuntBonus(bool bEnable); void EnableStuntBonus(bool bEnable);
@@ -140,14 +142,23 @@ public:
void sub_100A0010(); void sub_100A0010();
void sub_100A0090(int a1, int a2); void sub_100A0090(int a1, int a2);
BYTE sub_100A00C0(); BYTE sub_100A00C0();
void sub_100A0110(); CPlayerPed *sub_100A0110(int a1, float fX, float fY, float fZ, float fRotation, int a6, int a7); // .text:100A0110
void sub_100A0210(); int DeletePlayerPed(int pPlayerPed); // .text:100A0210
void sub_100A0250(); CVehicle *sub_100A0250(int a2, float a3, float a4, float a5, float a6, int a7);
void sub_100A02E0();
void sub_100A0310();
void sub_100A0330(); void sub_100A0330();
BOOL sub_100A0920();
BOOL sub_100A0930();
void sub_100A0940(int a1, int a2);
void sub_100A0960();
BOOL sub_100A0970(int iModel); // .text:100A0970
void sub_100A09A0(int iModel, int a2); // .text:100A09A0
BOOL sub_100A1BC0();
void sub_100A1C10(); void sub_100A1C10();
void sub_100A1DB0(int a1);
BYTE FUNC_100A0EE0(); // .text:100A0EE0
int FUNC_100A0F90(); // .text:100A0F90
void LoadScene(char* szScene); void LoadScene(char* szScene);
int GetMemoryUsedForStreaming(); int GetMemoryUsedForStreaming();
@@ -161,6 +172,14 @@ public:
void LoadCullZone(char *szLine); void LoadCullZone(char *szLine);
BOOL IsUsingController(); BOOL IsUsingController();
void DisableWeaponLockOnTarget(); void DisableWeaponLockOnTarget();
void PlayCrimeReport(int a1, VECTOR *pPos, int a3, int a4, int a5); // .text:100A1790
}; };
//----------------------------------------------------------- //-----------------------------------------------------------
struct struc_vdelete { virtual int Delete(int a1); };
void sub_100A4170(const char *a1); // .text:100A4170
void __stdcall sub_100A02E0(const char *a1); // .text:100A02E0
int __stdcall sub_100A0310(void *a1); // .text:100A0310
int FUNC_1009D3D0(int iModel, float fX, float fY, float fZ, float fRadius); // .text:1009D3D0
+2888 -58
View File
File diff suppressed because it is too large Load Diff
+15 -4
View File
@@ -49,8 +49,17 @@ void SetIPLs(int iIPLs, int iGtaVersion)
patch(0x156495A,bIPLs); patch(0x156495A,bIPLs);
patch(0x156115C,bIPLs); patch(0x156115C,bIPLs);
} }
patch(0x40619B,bIPLs);
patch(0x405C3D,bIPLs); // the last two are _patch spelled out, not a call to it
DWORD dwProtect[2];
VirtualProtect((PVOID)0x40619B,sizeof(bIPLs),PAGE_EXECUTE_READWRITE,&dwProtect[0]);
memcpy((PVOID)0x40619B,bIPLs,sizeof(bIPLs));
VirtualProtect((PVOID)0x40619B,sizeof(bIPLs),dwProtect[0],&dwProtect[1]);
VirtualProtect((PVOID)0x405C3D,sizeof(bIPLs),PAGE_EXECUTE_READWRITE,&dwProtect[0]);
memcpy((PVOID)0x405C3D,bIPLs,sizeof(bIPLs));
VirtualProtect((PVOID)0x405C3D,sizeof(bIPLs),dwProtect[0],&dwProtect[1]);
} }
} }
@@ -130,7 +139,8 @@ void ApplyNewColStoreSizePatch(DWORD dwCount)
int x=0; int x=0;
while(x!=7) { while(x!=7) {
UnFuck(dwPatchAddrColStoreSize[x] + 2, 4); DWORD oldProt2;
VirtualProtect((PVOID)(dwPatchAddrColStoreSize[x] + 2),4,PAGE_EXECUTE_READWRITE,&oldProt2);
*(PDWORD)(dwPatchAddrColStoreSize[x] + 2) = 44 * dwCount; *(PDWORD)(dwPatchAddrColStoreSize[x] + 2) = 44 * dwCount;
x++; x++;
} }
@@ -473,6 +483,7 @@ PED_MODEL PedModelsMemory[319];
void RelocatePedsListHack() void RelocatePedsListHack()
{ {
DWORD oldProt;
BYTE *aPedsListMemory = (BYTE*)&PedModelsMemory[0]; BYTE *aPedsListMemory = (BYTE*)&PedModelsMemory[0];
// Init the mem // Init the mem
@@ -484,7 +495,7 @@ void RelocatePedsListHack()
} }
// Patch the GetPedsModelInfo to use us // Patch the GetPedsModelInfo to use us
// instead of the gta_sa.exe mem. // instead of the gta_sa.exe mem.
UnFuck(0x4C67AD,4); VirtualProtect((PVOID)0x4C67AD,4,PAGE_EXECUTE_READWRITE,&oldProt);
*(DWORD *)0x4C67AD = (DWORD)aPedsListMemory; *(DWORD *)0x4C67AD = (DWORD)aPedsListMemory;
} }
+955 -56
View File
File diff suppressed because it is too large Load Diff
+133 -3
View File
@@ -5,6 +5,21 @@
#include "aimstuff.h" #include "aimstuff.h"
#include "entity.h" #include "entity.h"
struct struc_13;
// where a synced shot came from, snapshotted by CPlayerPed::FUNC_100AFA70
struct SHOT_SYNC_DATA
{
DWORD field_0;
VECTOR vecOrigin;
VECTOR vecColPoint;
VECTOR vecOffset;
ENTITY_TYPE *pAttachedTo;
};
DWORD __stdcall GamePool_Vehicle_GetIndex(VEHICLE_TYPE *pVehicle);
void FUNC_100AE520(); // .text:100AE520
struct struc_97 struct struc_97
{ {
char _gap0[52]; char _gap0[52];
@@ -34,19 +49,41 @@ public:
return GameGetPlayerCameraMode(m_bytePlayerNumber); return GameGetPlayerCameraMode(m_bytePlayerNumber);
}; };
void SetCameraMode(BYTE byteMode) { // .text:10014340
GameSetPlayerCameraMode(byteMode, m_bytePlayerNumber);
};
void SetCameraExtZoom(float fZoom, float fRatio) { // .text:10014360
GameSetPlayerCameraExtZoom(m_bytePlayerNumber, fZoom, fRatio);
};
void SetInterior(BYTE byteInterior, BOOL bRefresh); // .text:100AD340
void ShowMarker(int iMarkerColorID); void ShowMarker(int iMarkerColorID);
void HideMarker(); void HideMarker();
BYTE GetCurrentWeapon(); BYTE GetCurrentWeapon();
int GetCurrentVehicleID(); int GetCurrentVehicleID() {
if(!m_pPed) return 0;
VEHICLE_TYPE *pVehicle = (VEHICLE_TYPE *)m_pPed->pVehicle;
return GamePool_Vehicle_GetIndex(pVehicle);
};
BOOL IsOnScreen(); BOOL IsOnScreen();
float GetHealth(); float GetHealth();
void SetHealth(float fHealth); void SetHealth(float fHealth);
float GetArmour(); float GetArmour();
void SetArmour(float fArmour); void SetArmour(float fArmour);
void SetSkin(int iSkin); // .text:100AFF50
void FUNC_100ABBD0(); // .text:100ABBD0
void FUNC_100ABD70(float a1); // .text:100ABD70
void FUNC_100AC010(); // .text:100AC010
void FUNC_100AC790(int a1); // .text:100AC790
BYTE FUNC_100AC850(WORD *pKiller); // .text:100AC850
DWORD GetStateFlags(); DWORD GetStateFlags();
void SetStateFlags(DWORD dwStateFlags); void SetStateFlags(DWORD dwStateFlags);
BOOL IsDead(); BOOL IsDead();
BOOL IsInVehicle(); BOOL IsInVehicle();
BOOL FUNC_100AC5D0(); // .text:100AC5D0
BOOL FUNC_100AC640(); // .text:100AC640
BYTE GetActionTrigger(); BYTE GetActionTrigger();
void SetActionTrigger(BYTE byteTrigger); void SetActionTrigger(BYTE byteTrigger);
@@ -61,6 +98,7 @@ public:
void GiveWeapon(int iWeaponID, int iAmmo); void GiveWeapon(int iWeaponID, int iAmmo);
void SetArmedWeapon(int iWeaponType, bool bUnk); void SetArmedWeapon(int iWeaponType, bool bUnk);
void FUNC_100AC290(int iGtaVehicleID, int iSeat); // .text:100AC290
void ClearAllWeapons(); void ClearAllWeapons();
void RemoveWeaponWhenEnteringVehicle(); void RemoveWeaponWhenEnteringVehicle();
WEAPON_SLOT_TYPE * GetCurrentWeaponSlot(); WEAPON_SLOT_TYPE * GetCurrentWeaponSlot();
@@ -101,6 +139,17 @@ public:
BOOL IsPerformingAnimation(char *szAnimName); BOOL IsPerformingAnimation(char *szAnimName);
CPlayerPed(); CPlayerPed();
~CPlayerPed();
int sub_100ADFA0(); // .text:100ADFA0
BOOL FUNC_100ABFC0(); // .text:100ABFC0
BYTE FUNC_100ABC50(); // .text:100ABC50
void FUNC_100AC410(DWORD dwGtaId, int a2); // .text:100AC410
void FUNC_100ADFB0(int iLevel); // .text:100ADFB0
int FUNC_100ADC90(); // .text:100ADC90
void FUNC_100ADFD0(char *szName, int a2, int a3, int a4, VECTOR *pvecPos, int a6, float a7, int a8, int a9, int a10); // .text:100ADFD0
void FUNC_100ABF10(float fAngle); // .text:100ABF10
void ProcessVehicleHorn(); void ProcessVehicleHorn();
@@ -134,10 +183,90 @@ public:
void SetShopName(char *szNewShopName); void SetShopName(char *szNewShopName);
void SetWeaponSkillLevel(int iSkill, WORD wLevel); void SetWeaponSkillLevel(int iSkill, WORD wLevel);
void SetWeaponAmmo(BYTE byteWeapon, WORD wAmmo); // .text:100B0080
VECTOR* GetBonePosition(int iBone, VECTOR *vecPos); VECTOR* GetBonePosition(int iBone, VECTOR *vecPos);
VECTOR* GetTransformedBonePosition(int iBone, VECTOR *vecOffset); VECTOR* GetTransformedBonePosition(int iBone, VECTOR *vecOffset);
BOOL FUNC_100AFA70(); // .text:100AFA70
void FUNC_100AFC70(VECTOR *vecIn, VECTOR *vecOut); // .text:100AFC70
BOOL FUNC_100ACEF0(); // .text:100ACEF0
void FUNC_100AF280(void *pShotSync); // .text:100AF280
void FUNC_100AEEE0(MATRIX4X4 *pMatrix); // .text:100AEEE0
BOOL HasObjectAttached(); // .text:100AEE30
void RemoveAttachedObject(int iIndex); // .text:100AEE50
void FUNC_100B0B10(int iIndex, char *pAttachData); // .text:100B0B10
BOOL GetAttachedObjectSlotState(int iIndex); // .text:100AEEB0
void RemoveAllAttachedObjects(); // .text:100B0AB0
void StopCarrying(); // .text:100ADC00
void Destroy(); // .text:100B0FA0
void ProcessDrunkCamera(); // .text:100ADDF0
void FUNC_100AD0F0(); // .text:100AD0F0
void FUNC_100AFFD0(); // .text:100AFFD0
int FUNC_100AE260(); // .text:100AE260
int FUNC_100ACDC0(); // .text:100ACDC0
int FUNC_100ACB60(); // .text:100ACB60
int FUNC_100ADB60(); // .text:100ADB60
int FUNC_100AE0A0(); // .text:100AE0A0
void FUNC_100AE100(); // .text:100AE100
void FUNC_100ADCA0(); // .text:100ADCA0
void FUNC_100B02D0(int a1); // .text:100B02D0
BOOL FUNC_100ACE40(); // .text:100ACE40
void FUNC_100ACF00(int a1); // .text:100ACF00
BOOL FUNC_100AD860(); // .text:100AD860
int FUNC_100ABDD0(); // .text:100ABDD0
void FUNC_100ABDF0(int a1); // .text:100ABDF0
void FUNC_100AD880(); // .text:100AD880
void FUNC_100AC720(); // .text:100AC720
void FUNC_100AEC90(); // .text:100AEC90
int FUNC_100AEF60(); // .text:100AEF60
int FUNC_100AC690(); // .text:100AC690
void FUNC_100ACE50(int a1); // .text:100ACE50
BOOL FUNC_100ADA00(); // .text:100ADA00
void FUNC_100AD3E0(); // .text:100AD3E0
BOOL FUNC_100AD030(); // .text:100AD030
void FUNC_100AD080(); // .text:100AD080
int FUNC_100AE960(int a1); // .text:100AE960
void FUNC_100AD8B0(int iWeapon); // .text:100AD8B0
struc_13 * FUNC_100AE5D0(); // .text:100AE5D0
DWORD FUNC_100AEBB0(int a1); // .text:100AEBB0
void FUNC_100AE560(int iType, int a2, int a3, int a4); // .text:100AE560
DWORD FUNC_100AE990(); // .text:100AE990
DWORD FUNC_100AE9E0(); // .text:100AE9E0
DWORD FUNC_100AEA30(); // .text:100AEA30
void FUNC_100AC6C0(); // .text:100AC6C0
void FUNC_100AE1E0(); // .text:100AE1E0
void FUNC_100AEA80(MATRIX4X4 *pMatrix, int iFrame); // .text:100AEA80
void FUNC_100AEB10(MATRIX4X4 *pMatrix, int iFrame); // .text:100AEB10
void FUNC_100ACE90(); // .text:100ACE90
void FUNC_100AEC10(MATRIX4X4 *pMatrix, int iBone); // .text:100AEC10
void FUNC_100AEC50(MATRIX4X4 *pMatrix, int iBone); // .text:100AEC50
int FUNC_100AD9C0(); // .text:100AD9C0
int FUNC_100AD9E0(); // .text:100AD9E0
void FUNC_100AF1F0(); // .text:100AF1F0
void FUNC_100AEF90(); // .text:100AEF90
void FUNC_100AE530(int a1, int a2); // .text:100AE530
float FUNC_100AF220(); // .text:100AF220
DWORD FUNC_100AE790(); // .text:100AE790
DWORD * FUNC_100AE6E0(); // .text:100AE6E0
DWORD FUNC_100AE5F0(DWORD *pTask); // .text:100AE5F0
DWORD FUNC_100AE6A0(); // .text:100AE6A0
void FUNC_100AD440(); // .text:100AD440
char * FUNC_100ADB70(int iIndex); // .text:100ADB70
int m_iCellPhoneEnabled; int m_iCellPhoneEnabled;
int field_4C[10]; int field_4C[10];
struc_97 field_74[10]; struc_97 field_74[10];
@@ -148,7 +277,7 @@ public:
BYTE m_bytePlayerNumber; BYTE m_bytePlayerNumber;
char _gap2B1[8]; char _gap2B1[8];
int field_2B9; int field_2B9;
char _gap2BD[4]; int field_2BD;
int field_2C1; int field_2C1;
int field_2C5; int field_2C5;
int field_2C9; int field_2C9;
@@ -166,7 +295,8 @@ public:
char field_2F7; char field_2F7;
char field_2F8; char field_2F8;
int field_2F9; int field_2F9;
char _gap2FD[48]; char field_2FD[44];
int field_329;
}; };
+19
View File
@@ -53,6 +53,8 @@ const SCRIPT_COMMAND set_marker_color = { 0x0165, "ii" }; // var_marker, co
const SCRIPT_COMMAND enable_zone_names = { 0x09BA, "i" }; 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 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 show_on_radar = { 0x0168, "ii" }; // var_marker, size
const SCRIPT_COMMAND create_arrow_above_actor = { 0x0187, "iv" }; // var_actor, var_marker
const SCRIPT_COMMAND show_on_radar2 = { 0x018B, "ii" }; // var_marker, size
const SCRIPT_COMMAND create_icon_marker_sphere = { 0x02A7, "fffiv" }; const SCRIPT_COMMAND create_icon_marker_sphere = { 0x02A7, "fffiv" };
@@ -94,9 +96,20 @@ const SCRIPT_COMMAND put_train_at = { 0x07c7, "ifff" };
const SCRIPT_COMMAND get_active_interior = { 0x077e, "v" }; const SCRIPT_COMMAND get_active_interior = { 0x077e, "v" };
const SCRIPT_COMMAND set_actor_z_angle = { 0x0173, "if" }; const SCRIPT_COMMAND set_actor_z_angle = { 0x0173, "if" };
const SCRIPT_COMMAND get_actor_z_angle = { 0x0172, "iv" };
const SCRIPT_COMMAND get_car_z_angle = { 0x0174, "iv" };
const SCRIPT_COMMAND lock_actor = { 0x04d7, "ii" }; const SCRIPT_COMMAND lock_actor = { 0x04d7, "ii" };
const SCRIPT_COMMAND refresh_streaming_at = { 0x04E4, "ff" }; const SCRIPT_COMMAND refresh_streaming_at = { 0x04E4, "ff" };
const SCRIPT_COMMAND select_interior = { 0x04BB, "i" }; // interior
const SCRIPT_COMMAND disassociate_object = { 0x0682, "ifffi" }; // var_object, x, y, z, ukn
const SCRIPT_COMMAND destroy_object_with_fade = { 0x09A2, "i" }; // var_object
// the two object commands samp.dll references that were missing here; the diff cannot
// see a wrong command id, the operand is a masked relocation
const SCRIPT_COMMAND destroy_object = { 0x0108, "i" }; // var_object
const SCRIPT_COMMAND script_0650 = { 0x0650, "i" }; // var_object, name not resolved
const SCRIPT_COMMAND task_pick_up_object = { 0x070A, "iifffiissi" };
const SCRIPT_COMMAND link_actor_to_interior = { 0x0860, "ii" }; // var_actor, interior
const SCRIPT_COMMAND put_actor_in_car2 = { 0x0430, "iii" }; const SCRIPT_COMMAND put_actor_in_car2 = { 0x0430, "iii" };
const SCRIPT_COMMAND kill_actor = { 0x0321, "i" }; const SCRIPT_COMMAND kill_actor = { 0x0321, "i" };
@@ -154,6 +167,12 @@ const SCRIPT_COMMAND is_wav_loaded = { 0x3D0, "i" };
const SCRIPT_COMMAND play_wav = { 0x3D1, "i" }; const SCRIPT_COMMAND play_wav = { 0x3D1, "i" };
const SCRIPT_COMMAND unload_wav = { 0x40D, "i" }; const SCRIPT_COMMAND unload_wav = { 0x40D, "i" };
const SCRIPT_COMMAND set_wav_at_location = { 0x3D7, "ifff" }; const SCRIPT_COMMAND set_wav_at_location = { 0x3D7, "ifff" };
const SCRIPT_COMMAND is_line_of_sight_clear = { 0x06BD, "ffffffiiiii" };
const SCRIPT_COMMAND set_widescreen = { 0x02A3, "i" };
// the fifth argument is declared "i" but samp passes a float
const SCRIPT_COMMAND script_command_0948 = { 0x0948, "fffii" };
const SCRIPT_COMMAND attach_object_to_player = { 0x069B, "iiffffff" }; // object, char, offset xyz, rot xyz
+1038 -2
View File
File diff suppressed because it is too large Load Diff
+93 -5
View File
@@ -9,7 +9,7 @@ struct struc_13
DWORD field_C; DWORD field_C;
}; };
void ProcessLineOfSight(VECTOR *vecOrigin, VECTOR *vecLine, VECTOR *colPoint, BOOL ProcessLineOfSight(VECTOR *vecOrigin, VECTOR *vecLine, VECTOR *colPoint,
DWORD *pHitEntity, int bCheckBuildings, int bCheckVehicles, int bCheckPeds, DWORD *pHitEntity, int bCheckBuildings, int bCheckVehicles, int bCheckPeds,
int bCheckObjects, int bCheckDummies, int bSeeThroughStuff, int bCheckObjects, int bCheckDummies, int bSeeThroughStuff,
int bIgnoreSomeObjectsForCamera, int bUnk1); int bIgnoreSomeObjectsForCamera, int bUnk1);
@@ -17,7 +17,7 @@ void ProcessLineOfSight(VECTOR *vecOrigin, VECTOR *vecLine, VECTOR *colPoint,
float GetNormalisation(VECTOR *vec); float GetNormalisation(VECTOR *vec);
float FloatDifference(float f1, float f2); float FloatDifference(float f1, float f2);
float FloatOffset(float f1, float f2); float FloatOffset(float f1, float f2); // .text:100B48B0
float NormalizeAngle(float fAngle); float NormalizeAngle(float fAngle);
void __stdcall WorldRemoveEntity(DWORD *dwEnt); void __stdcall WorldRemoveEntity(DWORD *dwEnt);
@@ -42,12 +42,12 @@ void __stdcall FUNC_100B4390(BYTE bytePlayer, DWORD a2, DWORD a3, DWORD a4, DWOR
struc_13 * __stdcall FUNC_100B43D0(BYTE bytePlayer); struc_13 * __stdcall FUNC_100B43D0(BYTE bytePlayer);
BYTE __stdcall FUNC_100B43F0(DWORD *pdwRenderWare); BYTE __stdcall FUNC_100B43F0(DWORD *pdwRenderWare);
float __stdcall SquaredDistanceBetweenHorizontalPoints(float x1, float y1, float x2, float y2); float __stdcall SquaredDistanceBetweenHorizontalPoints(float x1, float y1, float x2, float y2);
float DistanceBetweenHorizontalPoints(float x1, float y1, float x2, float y2); float __stdcall DistanceBetweenHorizontalPoints(float x1, float y1, float x2, float y2);
float DistanceBetweenPoints(float x1, float y1, float z1, float x2, float y2, float z2); float __stdcall DistanceBetweenPoints(float x1, float y1, float z1, float x2, float y2, float z2);
float __stdcall SquaredDistanceBetweenPoints(float x1, float y1, float z1, float x2, float y2, float z2); float __stdcall SquaredDistanceBetweenPoints(float x1, float y1, float z1, float x2, float y2, float z2);
float __stdcall SquaredDistanceBetweenPoints(VECTOR *vec1, VECTOR *vec2); float __stdcall SquaredDistanceBetweenPoints(VECTOR *vec1, VECTOR *vec2);
void __stdcall _VectorNormalise(VECTOR *vec); void _VectorNormalise(VECTOR *vec);
DWORD __stdcall CRC32FromUpcaseString(char *szString); DWORD __stdcall CRC32FromUpcaseString(char *szString);
float DegToRad(float fDegrees); float DegToRad(float fDegrees);
@@ -58,8 +58,13 @@ void SaveCameraRaster(char *filename);
BOOL IsFileOrDirectoryExists(char * szPath); BOOL IsFileOrDirectoryExists(char * szPath);
DWORD unnamed_100B6100(char *szString, int nMaxLen); DWORD unnamed_100B6100(char *szString, int nMaxLen);
int FUNC_100B61D0(int a1); // .text:100B61D0
bool FUNC_100B4B50(VECTOR *vecPos); bool FUNC_100B4B50(VECTOR *vecPos);
bool FUNC_100B4AE0(VECTOR *vec); // .text:100B4AE0
void FUNC_100B4D10(VECTOR *vecOut, MATRIX4X4 *pMatrix, VECTOR *vecOffset);
int FUNC_100B4BE0(int a1, int a2, int a3); // .text:100B4BE0
int FUNC_100B4C00(int a1, int a2, int a3); // .text:100B4C00
BUILDING_TYPE * GamePool_GetBuilding(); BUILDING_TYPE * GamePool_GetBuilding();
DUMMY_TYPE * GamePool_GetDummy(); DUMMY_TYPE * GamePool_GetDummy();
@@ -67,14 +72,27 @@ OBJECT_TYPE * GamePool_GetObject();
void ReplaceBuildingModel(ENTITY_TYPE *pEntity, int iModelID); void ReplaceBuildingModel(ENTITY_TYPE *pEntity, int iModelID);
int GetInvalidModelInfoCount(); int GetInvalidModelInfoCount();
int FUNC_100B3CD0(); // .text:100B3CD0
int FUNC_100B3D00(); // .text:100B3D00
DWORD * __stdcall GetModelInfo(int iModel); // .text:100A7A40
BOOL __stdcall IsValidModel(int iModel); // .text:100B3DB0
BOOL __stdcall IsValidPedModel(int iModel); // .text:100B3DD0
DWORD * __stdcall FUNC_100B46D0(int iModel); // .text:100B46D0
WORD __stdcall FUNC_100B4700(int iModel); // .text:100B4700
bool HasCollisionLoaded(VECTOR *vec); bool HasCollisionLoaded(VECTOR *vec);
BOOL __stdcall IsATrainPart(ENTITY_TYPE *pEntity); BOOL __stdcall IsATrainPart(ENTITY_TYPE *pEntity);
BOOL __stdcall FUNC_100B4860(VEHICLE_TYPE *pVehicle); // .text:100B4860
BOOL __stdcall FUNC_100B6950(VEHICLE_TYPE *pVehicle); // .text:100B6950
int __stdcall FUNC_100B64E0(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9); // .text:100B64E0
int __stdcall FUNC_100B6510(int a1, int a2); // .text:100B6510
BOOL IsHexChar(char c); BOOL IsHexChar(char c);
BOOL IsHexChar(wchar_t c); BOOL IsHexChar(wchar_t c);
DWORD GetColorFromEmbedCode(char *szString); DWORD GetColorFromEmbedCode(char *szString);
DWORD GetColorFromEmbedCode(wchar_t *szString); DWORD GetColorFromEmbedCode(wchar_t *szString);
void ReplaceUnprintableChars(char *szString); // .text:100B5DE0
void RemoveColorEmbedsFromString(char *szString); void RemoveColorEmbedsFromString(char *szString);
UINT GetVehicleSubtypeFromVehiclePtr(VEHICLE_TYPE *pVehicle); UINT GetVehicleSubtypeFromVehiclePtr(VEHICLE_TYPE *pVehicle);
@@ -83,3 +101,73 @@ DWORD * GetNextTaskFromTask(DWORD *task);
int GetTaskTypeFromTask(DWORD *task); int GetTaskTypeFromTask(DWORD *task);
const char* GetTaskNameFromTask(DWORD *task); const char* GetTaskNameFromTask(DWORD *task);
int FUNC_100B4BC0(int a1, int a2, int a3); // .text:100B4BC0
float FastSqrt(float x); // .text:100B5A60
void VectorCrossProduct(VECTOR *vecOut, VECTOR *vec1, VECTOR *vec2); // .text:100B4C20
void VectorNormaliseTo(VECTOR *vecOut, VECTOR *vecIn); // .text:100B4CC0
bool FUNC_100B4A70(VECTOR *vec); // .text:100B4A70
bool FUNC_100B3D30(int nModelIndex); // .text:100B3D30
int FUNC_100B41F0(void *pData); // .text:100B41F0
int __stdcall FUNC_100B4240(DWORD *pdwIn, DWORD dwParam); // .text:100B4240
void __stdcall FUNC_100B42B0(DWORD *pdwEntity); // .text:100B42B0
DWORD __stdcall FUNC_100B4430(int a1, int a2); // .text:100B4430
void FUNC_100B5D20(); // .text:100B5D20
void FUNC_100B52B0(MATRIX4X4 *pMatrix, float *pQuatOut); // .text:100B52B0
void FUNC_100B5480(float *pQuatOut, float *pQuatFrom, float *pQuatTo, float fT); // .text:100B5480
void FUNC_100B6A80(float *pQuat, MATRIX4X4 *pMatrix); // .text:100B6A80
void __stdcall FUNC_100B6900(VECTOR *pFront, VECTOR *pOut); // .text:100B6900
void FUNC_100B5470(float *pQuat, MATRIX4X4 *pMatrix); // .text:100B5470
void FUNC_100B5500(float *pQuat); // .text:100B5500
int FUNC_100B4100(int iModel); // .text:100B4100
int FUNC_100B4180(int iModel); // .text:100B4180
int FUNC_100B1DA0(DWORD *pRenderWare, int a2, int a3); // .text:100B1DA0
void FUNC_100B58A0(DWORD dwFrame, VECTOR *vecOut, int *a3); // .text:100B58A0
void __stdcall FUNC_100B44C0(BYTE bytePlayer, DWORD dwValue); // .text:100B44C0
DWORD __stdcall FUNC_100B4520(DWORD *pdw); // .text:100B4520
void __stdcall FUNC_100B4530(DWORD *pdwVtable); // .text:100B4530
void __stdcall FUNC_100B4550(DWORD *pdw, float fValue); // .text:100B4550
float __stdcall FUNC_100B4560(DWORD *pdw); // .text:100B4560
void __stdcall FUNC_100B4660(int iModel, int nTxdIndex); // .text:100B4660
void FUNC_100B46C0(DWORD dwValue); // .text:100B46C0
float FUNC_100B4FE0(float x, float y, float z); // .text:100B4FE0
int FUNC_100B56D0(int a1, int a2, int a3); // .text:100B56D0
void FUNC_100B5720(); // .text:100B5720
BOOL __stdcall FUNC_100B4570(int iModel); // .text:100B4570
DWORD __stdcall FUNC_100B45A0(int iModel); // .text:100B45A0
void __stdcall FUNC_100B45D0(int iModel, int a2); // .text:100B45D0
void __stdcall FUNC_100B4600(int iModel, int a2); // .text:100B4600
void __stdcall FUNC_100B4630(int iModel, int a2); // .text:100B4630
WORD __stdcall FUNC_100B4700(int iModel); // .text:100B4700
void __stdcall FUNC_100B4730(int iModel, WORD wValue); // .text:100B4730
BOOL __stdcall FUNC_100B44E0(DWORD *pModelInfo); // .text:100B44E0
WORD FUNC_100B6470(int a1, int a2, int a3, int a4, int a5); // .text:100B6470
void VectorScale(VECTOR *vecOut, VECTOR *vecIn, float fScale); // .text:100B51B0
void FUNC_100B51E0(int a1, int a2); // .text:100B51E0
float FUNC_100B5180(float *pQuat); // .text:100B5180
DWORD FUNC_100B1430(BYTE *pObject); // .text:100B1430, todo: implement
void FUNC_100B17D0(DWORD dwOther); // .text:100B17D0, todo: implement
void FUNC_100B1800(BYTE *pObject); // .text:100B1800, todo: implement
void FUNC_100B19D0(BYTE *pObject); // .text:100B19D0, todo: implement
void FUNC_100B1C80(BYTE *pObject); // .text:100B1C80, todo: implement
void FUNC_100B5910(int a1, int a2); // .text:100B5910
void FUNC_100B5940(int a1, int a2); // .text:100B5940
void FUNC_100B58D0(int a1, int a2, int a3); // .text:100B58D0
void FUNC_100B56F0(int a1, int a2, int a3); // .text:100B56F0
void FUNC_100B62B0(BYTE *pObject); // .text:100B62B0
BOOL __stdcall FUNC_100B62F0(BYTE *pObject); // .text:100B62F0
void __stdcall FUNC_100B6330(BYTE *pObject); // .text:100B6330
void FUNC_100B4D70(float m00, float m01, float m02, float m10, float m11, float m12,
float m20, float m21, float m22, float *pW, float *pX, float *pY, float *pZ); // .text:100B4D70, todo: implement
void FUNC_100B4F10(float w, float x, float y, float z, float *pM00, float *pM01,
float *pM02, float *pM10, float *pM11, float *pM12, float *pM20, float *pM21,
float *pM22); // .text:100B4F10, todo: implement
void FUNC_100B5260(MATRIX4X4 *pMatrix, float *pQuatOut); // .text:100B5260
void FUNC_100B5420(float *pQuat, MATRIX4X4 *pMatrix); // .text:100B5420
void FUNC_100B57E0(int a1, int nIndex, int a3, int a4); // .text:100B57E0
void FUNC_100B5790(int a1, int nIndex, int a3); // .text:100B5790
void FUNC_100B5740(int a1, int a2); // .text:100B5740
void FUNC_100B5830(int a1, int nIndex, float *pfOut); // .text:100B5830
void FUNC_100B5620(float *pQuat, float *pEuler); // .text:100B5620
void FUNC_100B5210(int a1, void *a2); // .text:100B5210, __cdecl: the caller's
// stack cleanup is folded into the next call's argument setup
+36 -2
View File
@@ -20,7 +20,12 @@ public:
VEHICLE_TYPE *m_pVehicle; VEHICLE_TYPE *m_pVehicle;
char _gap50[33]; char _gap50[20];
BYTE field_64;
int field_65;
char _gap69[8];
int field_71; int field_71;
@@ -30,7 +35,9 @@ public:
BYTE m_byteColor2; BYTE m_byteColor2;
BOOL m_bHasNewColor; BOOL m_bHasNewColor;
char _gap7F[57]; char _gap7F[4];
int field_83;
char _gap87[49];
CVehicle( int iType, float fPosX, float fPosY, float fPosZ, float fRotation = 0.0f, BOOL bKeepModelLoaded = FALSE, int a8 = 0); CVehicle( int iType, float fPosX, float fPosY, float fPosZ, float fRotation = 0.0f, BOOL bKeepModelLoaded = FALSE, int a8 = 0);
@@ -51,6 +58,12 @@ public:
BOOL HasTurret(); BOOL HasTurret();
BOOL HasADriver(); BOOL HasADriver();
void sub_100B7AC0(int iPanelDamage, int iDoorDamage, BYTE byteLightDamage); // .text:100B7AC0
void sub_100B7940(BYTE byteTyreDamage); // .text:100B7940
void FUNC_100B72C0(int a1); // .text:100B72C0
void FUNC_100B8170(float a1); // .text:100B8170
void FUNC_100B80B0(short a1); // .text:100B80B0
void SetHydraThrusters(DWORD dwDirection); void SetHydraThrusters(DWORD dwDirection);
DWORD GetHydraThrusters(); DWORD GetHydraThrusters();
@@ -71,6 +84,27 @@ public:
BOOL IsOccupied(); BOOL IsOccupied();
BOOL FUNC_100B8240(); // .text:100B8240
BOOL FUNC_100B8330(); // .text:100B8330
BOOL FUNC_100B7420(); // .text:100B7420
void FUNC_100B7090(int a1); // .text:100B7090
void FUNC_100B7840(int a1); // .text:100B7840
void FUNC_100B7900(float fT); // .text:100B7900
void FUNC_100B81A0(); // .text:100B81A0
void FUNC_100B81F0(); // .text:100B81F0
void FUNC_100B8150(char *szText); // .text:100B8150
void FUNC_100B7C10(); // .text:100B7C10
void FUNC_100B7C80(int a1); // .text:100B7C80
CVehicle *FUNC_100B7C90(); // .text:100B7C90
BOOL FUNC_100B7D70(); // .text:100B7D70
BOOL FUNC_100B7DD0(); // .text:100B7DD0
BOOL FUNC_100B70E0(); // .text:100B70E0
BOOL FUNC_100B7CF0(); // .text:100B7CF0
BOOL FUNC_100B7460(); // .text:100B7460
BOOL FUNC_100B7E00(); // .text:100B7E00
}; };
+2 -1
View File
@@ -20,7 +20,8 @@ CDeathWindow *pDeathWindow=0;
CAudioStream *pAudioStream=0; CAudioStream *pAudioStream=0;
CSpawnScreen *pSpawnScreen=0; CSpawnScreen *pSpawnScreen=0;
CNetGame *pNetGame=0; CNetGame *pNetGame=0;
//DWORD dword_1026EB98=0; class CDownloadListDispatch;
CDownloadListDispatch *dword_1026EB98=0;
CFontRender *pDefaultFont=0; CFontRender *pDefaultFont=0;
CUnkClass13 *pUnkClass13=0; CUnkClass13 *pUnkClass13=0;
CUnkClass14 *pUnkClass14=0; CUnkClass14 *pUnkClass14=0;
+1
View File
@@ -55,6 +55,7 @@ typedef struct _GAME_SETTINGS {
#include "net/menupool.h" #include "net/menupool.h"
#include "net/textdrawpool.h" #include "net/textdrawpool.h"
#include "net/labelpool.h" #include "net/labelpool.h"
#include "net/downloader.h"
#include "net/netgame.h" #include "net/netgame.h"
#include "net/scriptrpc.h" #include "net/scriptrpc.h"
+8
View File
@@ -14,3 +14,11 @@ CActorPool::CActorPool()
} }
//---------------------------------------------------- //----------------------------------------------------
CActorPool::~CActorPool()
{
for(ACTORID ActorID = 0; ActorID < MAX_ACTORS; ActorID++)
sub_100016F0(ActorID);
}
//----------------------------------------------------
+25 -1
View File
@@ -3,9 +3,22 @@
//---------------------------------------------------- //----------------------------------------------------
// 27 bytes, the block the create-actor RPC reads off the wire
typedef struct _ACTOR_INFO
{
ACTORID ActorID;
int iModel;
VECTOR vecPos;
float fRotation;
float fHealth;
BYTE byteInvulnerable;
} ACTOR_INFO;
//----------------------------------------------------
class CActorPool class CActorPool
{ {
private: public:
int field_0; int field_0;
int field_4[MAX_ACTORS]; int field_4[MAX_ACTORS];
int field_FA4[MAX_ACTORS]; int field_FA4[MAX_ACTORS];
@@ -16,6 +29,17 @@ private:
public: public:
CActorPool(); CActorPool();
~CActorPool(); // .text:100018E0
void sub_100016F0(ACTORID ActorID); // .text:100016F0
void sub_10001900(ACTOR_INFO *pActorInfo); // .text:10001900
int GetAt(ACTORID ActorID) {
if(ActorID >= MAX_ACTORS) return 0;
if(!field_FA4[ActorID]) return 0;
return field_4[ActorID];
}
ACTORID FUNC_100018B0(DWORD dwPtr); // .text:100018B0
}; };
//---------------------------------------------------- //----------------------------------------------------
+432
View File
@@ -0,0 +1,432 @@
#include "../main.h"
extern CChatWindow *pChatWindow;
extern CConfig *pConfig;
CDownloadManager *dword_10118A24;
int sub_100B5DC0(char *szPath); // .text:100B5DC0
int sub_100A7C30(DWORD a1, DWORD a2, char *a3, char *a4, char *a5); // .text:100A7C30
int sub_100A7BD0(DWORD a1, DWORD a2, char *a3, char *a4, char *a5); // .text:100A7BD0
int sub_100B2040(DWORD dwCrc); // .text:100B2040
//----------------------------------------------------
// layout locks: every offset below came out of the disassembly, so a wrong one
// fails to compile instead of quietly mismatching
typedef char AssertSlotSize[sizeof(DOWNLOAD_SLOT) == 0x230 ? 1 : -1];
typedef char AssertSlotPath[offsetof(DOWNLOAD_SLOT, szPath) == 0xC ? 1 : -1];
typedef char AssertSlotRequest[offsetof(DOWNLOAD_SLOT, Request) == 0x112 ? 1 : -1];
typedef char AssertRequestSize[sizeof(DOWNLOAD_REQUEST) == 0x11E ? 1 : -1];
typedef char AssertRequestCrc[offsetof(DOWNLOAD_REQUEST, dwCrc) == 0x11 ? 1 : -1];
typedef char AssertReadyFlag[offsetof(CDownloadManager, m_bSlotsReady) == 0x1344 ? 1 : -1];
typedef char AssertSlotArray[offsetof(CDownloadManager, m_Slots) == 0x1345 ? 1 : -1];
typedef char AssertEntryCount[offsetof(CDownloadList, m_dwCount) == 4 ? 1 : -1];
typedef char AssertEntryState[offsetof(DOWNLOAD_ENTRY, field_7) == 7 ? 1 : -1];
typedef char AssertEntryCrc[offsetof(DOWNLOAD_ENTRY, dwCrc) == 0x10 ? 1 : -1];
typedef char AssertEntry46[offsetof(DOWNLOAD_ENTRY, field_46) == 0x46 ? 1 : -1];
typedef char AssertEntry58[offsetof(DOWNLOAD_ENTRY, field_58) == 0x58 ? 1 : -1];
typedef char AssertEntry5A[offsetof(DOWNLOAD_ENTRY, field_5A) == 0x5A ? 1 : -1];
//----------------------------------------------------
// retail spawns the workers on an empty body
void __cdecl DownloadThreadProc(void *pParam)
{
}
//----------------------------------------------------
// spawns a worker for every idle slot and clears its request block
bool CDownloadManager::FUNC_1000C010()
{
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6)
continue;
m_Slots[i].dwThread = _beginthread(DownloadThreadProc, 0, &m_Slots[i]);
if(m_Slots[i].dwThread == -1)
{
m_Slots[i].field_6 = 0;
m_Slots[i].field_10D = 1;
m_Slots[i].field_10E = -1;
return false;
}
m_Slots[i].field_10E = -1;
m_Slots[i].dwSlotId = i + 1;
m_Slots[i].field_6 = 1;
m_Slots[i].field_7 = 0;
m_Slots[i].field_4 = 0;
m_Slots[i].field_10D = 0;
memset(m_Slots[i].szPath, 0, sizeof(m_Slots[i].szPath));
memset(&m_Slots[i].Request, 0, sizeof(m_Slots[i].Request));
}
m_bSlotsReady = 1;
return true;
}
//----------------------------------------------------
// the three removal helpers below only ever look in the first search dir
BOOL CDownloadList::FUNC_1000C590(DWORD dwId)
{
char szPath[261];
_snprintf(szPath, sizeof(szPath) - 1, "%s\\0x%X.dff", szDir1, dwId);
return DeleteFile(szPath);
}
//----------------------------------------------------
BOOL CDownloadList::FUNC_1000C5D0(DWORD dwId)
{
char szPath[261];
_snprintf(szPath, sizeof(szPath) - 1, "%s\\0x%X.txd", szDir1, dwId);
return DeleteFile(szPath);
}
//----------------------------------------------------
BOOL CDownloadList::FUNC_1000C610(char *szName)
{
char szPath[261];
_snprintf(szPath, sizeof(szPath) - 1, "%s\\%s", szDir1, szName);
return DeleteFile(szPath);
}
//----------------------------------------------------
bool CDownloadList::FUNC_1000D110(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry->dwCrc == dwCrc && pEntry->field_7 == 1)
return true;
}
return false;
}
//----------------------------------------------------
bool CDownloadList::FUNC_1000D150(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry->dwCrc == dwCrc && pEntry->field_7 == 2)
return true;
}
return false;
}
//----------------------------------------------------
char CDownloadList::FUNC_1000D190(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry->dwCrc == dwCrc)
return pEntry->field_58;
}
return 0;
}
//----------------------------------------------------
// ticks the retry countdown on every finished entry and retires it at zero
void CDownloadList::FUNC_1000D1E0()
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry->field_58 && pEntry->field_59)
{
if(!pEntry->field_5A)
{
sub_100B2040(pEntry->dwCrc);
pEntry->field_59 = 0;
pEntry->field_58 = 0;
}
else
{
pEntry->field_5A--;
}
}
}
}
//----------------------------------------------------
DWORD CDownloadList::FUNC_1000D240(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry && pEntry->dwCrc == dwCrc && pEntry->field_7 == 2)
return pEntry->field_46;
}
return 0;
}
//----------------------------------------------------
DWORD CDownloadList::FUNC_1000D280(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry && pEntry->dwCrc == dwCrc && pEntry->field_7 == 2)
return pEntry->field_4A;
}
return 0;
}
//----------------------------------------------------
// the FUNC_1000D320 twin for entries still in state 1
int CDownloadList::FUNC_1000D2C0(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(pEntry->dwCrc != dwCrc || pEntry->field_7 != 1)
continue;
if(!FUNC_1000C650(pEntry->field_C, pEntry->dwCrc, pEntry->field_46, pEntry->field_4A))
return 0;
pEntry->field_59 = 0;
pEntry->field_58 = 1;
return 1;
}
return 0;
}
//----------------------------------------------------
// same two-dir probe as FUNC_1000C770, only the handoff differs
int CDownloadList::FUNC_1000C650(DWORD a1, DWORD dwCrc, DWORD a3, DWORD a4)
{
char szCrc[28];
char szDff[261];
char szTxd[261];
sprintf(szCrc, "%X", a4);
sprintf(szDff, "%s\\0x%X.dff", szDir1, a3);
if(!sub_100B5DC0(szDff))
{
sprintf(szDff, "%s\\0x%X.dff", szDir2, a3);
if(!sub_100B5DC0(szDff))
return 0;
}
sprintf(szTxd, "%s\\0x%X.txd", szDir1, a4);
if(!sub_100B5DC0(szTxd))
{
sprintf(szTxd, "%s\\0x%X.txd", szDir2, a4);
if(!sub_100B5DC0(szTxd))
return 0;
}
return sub_100A7BD0(a1, dwCrc, szCrc, szDff, szTxd) != 0;
}
//----------------------------------------------------
// both model files have to be present in one of the two search dirs
int CDownloadList::FUNC_1000C770(DWORD a1, DWORD dwCrc, DWORD a3, DWORD a4)
{
char szCrc[28];
char szDff[261];
char szTxd[261];
sprintf(szCrc, "%X", a4);
sprintf(szDff, "%s\\0x%X.dff", szDir1, a3);
if(!sub_100B5DC0(szDff))
{
sprintf(szDff, "%s\\0x%X.dff", szDir2, a3);
if(!sub_100B5DC0(szDff))
return 0;
}
sprintf(szTxd, "%s\\0x%X.txd", szDir1, a4);
if(!sub_100B5DC0(szTxd))
{
sprintf(szTxd, "%s\\0x%X.txd", szDir2, a4);
if(!sub_100B5DC0(szTxd))
return 0;
}
return sub_100A7C30(a1, dwCrc, szCrc, szDff, szTxd) != 0;
}
//----------------------------------------------------
// promotes a staged entry once its file checks out; any failed check gives up
// on the whole lookup rather than scanning on
int CDownloadList::FUNC_1000D320(DWORD dwCrc)
{
for(DWORD i = 0; i != m_dwCount; i++)
{
DOWNLOAD_ENTRY *pEntry = GetAt(i);
if(!pEntry)
continue;
if(pEntry->dwCrc != dwCrc || pEntry->field_7 != 2)
continue;
if(!pEntry->field_0)
return 0;
if(!pEntry->field_1)
return 0;
if(!FUNC_1000C770(pEntry->field_C, pEntry->dwCrc, pEntry->field_46, pEntry->field_4A))
return 0;
pEntry->field_59 = 0;
pEntry->field_58 = 1;
return 1;
}
return 0;
}
//----------------------------------------------------
// parks a request in the first live idle slot; the workers pick it up from there
void CDownloadManager::AddURLRequest(DOWNLOAD_REQUEST *pRequest, char *szUrl)
{
if(pChatWindow && pConfig && pConfig->GetIntVariable("logurls"))
pChatWindow->AddInfoMessage("[url 0x%X]: %s", pRequest->dwCrc, szUrl);
dword_10118A24 = this;
if(!m_bSlotsReady)
FUNC_1000C010();
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6 && !m_Slots[i].field_4)
{
memcpy(&m_Slots[i].Request, pRequest, sizeof(DOWNLOAD_REQUEST));
strncpy(m_Slots[i].szPath, szUrl, sizeof(m_Slots[i].szPath) - 1);
m_Slots[i].field_4 = 1;
m_Slots[i].field_5 = 0;
return;
}
}
if(pChatWindow)
pChatWindow->AddDebugMessage("[error] AddURLRequest: No free slots!");
}
//----------------------------------------------------
// flags every slot for cancellation and drops the ready bit so the next
// request re-spawns the workers
void CDownloadManager::FUNC_1000C0C0()
{
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
m_Slots[i].field_7 = 1;
m_bSlotsReady = 0;
}
//----------------------------------------------------
// claims the first idle slot; field_5 is the hold flag FUNC_1000C140 releases
bool CDownloadManager::FUNC_1000C0F0()
{
if(!m_bSlotsReady)
return false;
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6 && !m_Slots[i].field_4 && !m_Slots[i].field_5)
{
m_Slots[i].field_5 = 1;
return true;
}
}
return false;
}
//----------------------------------------------------
void CDownloadManager::FUNC_1000C140()
{
if(!m_bSlotsReady)
return;
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6 && !m_Slots[i].field_4 && m_Slots[i].field_5)
{
m_Slots[i].field_5 = 0;
return;
}
}
}
//----------------------------------------------------
// the three counters below are 6-way unrolled by the compiler
int CDownloadManager::FUNC_1000C190()
{
int iCount = 0;
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6 && !m_Slots[i].field_4 && !m_Slots[i].field_5)
iCount++;
}
return iCount;
}
//----------------------------------------------------
int CDownloadManager::FUNC_1000C260()
{
int iCount = 0;
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6 && m_Slots[i].field_4)
iCount++;
}
return iCount;
}
//----------------------------------------------------
int CDownloadManager::FUNC_1000C2F0()
{
int iCount = 0;
for(int i = 0; i < MAX_DOWNLOAD_SLOTS; i++)
{
if(m_Slots[i].field_6 && m_Slots[i].field_5)
iCount++;
}
return iCount;
}
//----------------------------------------------------
// EOF
+120
View File
@@ -0,0 +1,120 @@
#pragma once
//----------------------------------------------------
#define MAX_DOWNLOAD_SLOTS 6
//----------------------------------------------------
// the block AddURLRequest copies into a slot, 0x11E bytes
struct DOWNLOAD_REQUEST
{
char _gap0[0x11];
DWORD dwCrc;
char _gap15[0x109];
};
//----------------------------------------------------
// one worker slot, 0x230 bytes; offsets pinned by 0x1000C010 and 0x1000C0C0
struct DOWNLOAD_SLOT
{
DWORD dwSlotId; // set to the 1-based slot index
char field_4;
char field_5;
char field_6; // slot live flag
char field_7; // cancel flag
DWORD dwThread; // _beginthread handle, -1 when the spawn failed
char szPath[257];
char field_10D;
DWORD field_10E; // initialised to -1
DOWNLOAD_REQUEST Request;
};
//----------------------------------------------------
// the record the lookups below match on; only the touched fields are known
struct DOWNLOAD_ENTRY
{
char field_0;
char field_1;
char _gap2[5];
char field_7;
char _gap8[4];
DWORD field_C;
DWORD dwCrc;
char _gap14[0x32];
DWORD field_46;
DWORD field_4A;
char _gap4E[0xA];
char field_58;
char field_59;
DWORD field_5A; // retry countdown
};
//----------------------------------------------------
// the list the game side queries; whether it is embedded in CDownloadManager
// at +0 is still open, the offsets are the same either way
class CDownloadList
{
public:
DOWNLOAD_ENTRY **m_pEntries;
DWORD m_dwCount;
char field_8;
char szDir1[0x105];
char szDir2[0x105];
char _gap213[4];
DWORD field_217;
char _gap21B[5];
BYTE field_220;
BYTE field_221;
void FUNC_10017D10(int a1) { // .text:10017D10
if(field_217 != a1) {
field_217 = a1;
field_221 = 0;
field_220 = 0;
}
};
DOWNLOAD_ENTRY *GetAt(DWORD dwIndex) { if(dwIndex >= m_dwCount) return NULL; return m_pEntries[dwIndex]; }
BOOL FUNC_1000C590(DWORD dwId); // .text:1000C590
BOOL FUNC_1000C5D0(DWORD dwId); // .text:1000C5D0
BOOL FUNC_1000C610(char *szName); // .text:1000C610
bool FUNC_1000D110(DWORD dwCrc); // .text:1000D110
bool FUNC_1000D150(DWORD dwCrc); // .text:1000D150
char FUNC_1000D190(DWORD dwCrc); // .text:1000D190
void FUNC_1000D1E0(); // .text:1000D1E0
DWORD FUNC_1000D240(DWORD dwCrc); // .text:1000D240
DWORD FUNC_1000D280(DWORD dwCrc); // .text:1000D280
int FUNC_1000D2C0(DWORD dwCrc); // .text:1000D2C0
int FUNC_1000C650(DWORD a1, DWORD dwCrc, DWORD a3, DWORD a4); // .text:1000C650
int FUNC_1000C770(DWORD a1, DWORD dwCrc, DWORD a3, DWORD a4); // .text:1000C770
int FUNC_1000D320(DWORD dwCrc); // .text:1000D320
};
//----------------------------------------------------
class CDownloadManager
{
public:
char _gap0[0x1344];
BYTE m_bSlotsReady;
DOWNLOAD_SLOT m_Slots[MAX_DOWNLOAD_SLOTS];
bool FUNC_1000C010(); // .text:1000C010
void AddURLRequest(DOWNLOAD_REQUEST *pRequest, char *szUrl); // .text:1000C380
void FUNC_1000C0C0(); // .text:1000C0C0
bool FUNC_1000C0F0(); // .text:1000C0F0
void FUNC_1000C140(); // .text:1000C140
int FUNC_1000C190(); // .text:1000C190
int FUNC_1000C260(); // .text:1000C260
int FUNC_1000C2F0(); // .text:1000C2F0
};
//----------------------------------------------------
// EOF
+7 -1
View File
@@ -9,7 +9,7 @@ typedef struct _LABEL
class CLabelPool class CLabelPool
{ {
private: public:
LABEL m_Labels[MAX_LABELS]; LABEL m_Labels[MAX_LABELS];
BOOL m_bLabelSlotState[MAX_LABELS]; BOOL m_bLabelSlotState[MAX_LABELS];
public: public:
@@ -18,4 +18,10 @@ public:
BOOL Delete(WORD wLabelID); BOOL Delete(WORD wLabelID);
void FUNC_10001350(); // .text:10001350
// .text:100011D0
void sub_100011D0(WORD wLabelID, PCHAR szText, DWORD dwColor, float fX, float fY, float fZ,
float fDrawDistance, BYTE byteShowBehindWalls, WORD wAttachedPlayer, WORD wAttachedVehicle);
}; };
+739 -1
View File
@@ -1,9 +1,29 @@
#include "../main.h" #include "../main.h"
#include "../game/util.h" #include "../game/util.h"
#include "../game/keystuff.h"
#include "../game/aimstuff.h"
extern CGame *pGame; extern CGame *pGame;
extern CNetGame *pNetGame; extern CNetGame *pNetGame;
extern CCmdWindow *pCmdWindow;
extern CUnkClass3 *pUnkClass3;
extern CUnkClass10 *pUnkClass10;
extern CDXUTDialog *pClassSelectDialog;
DWORD dword_100FE0A4 = -1;
DWORD dword_100FE0A8 = 30;
DWORD dword_100FE0AC = 30;
DWORD dword_101189A0;
DWORD dword_101189A4;
//----------------------------------------------------------
// layout locks for the fields split out of the pads
typedef char AssertLocalSize[sizeof(CLocalPlayer) == 0x324 ? 1 : -1];
typedef char AssertField14B[offsetof(CLocalPlayer, field_14B) == 0x14B ? 1 : -1];
typedef char AssertSpawnInfo[offsetof(CLocalPlayer, m_SpawnInfo) == 0x14F ? 1 : -1];
typedef char AssertField314[offsetof(CLocalPlayer, field_314) == 0x314 ? 1 : -1];
//---------------------------------------------------------- //----------------------------------------------------------
@@ -83,7 +103,12 @@ void CLocalPlayer::ResetAllSyncAttributes()
void CLocalPlayer::Say(PCHAR szText) void CLocalPlayer::Say(PCHAR szText)
{ {
// TODO: CLocalPlayer::Say .text:10005A10 BYTE byteTextLength = strlen(szText);
RakNet::BitStream bsSend;
bsSend.Write(byteTextLength);
bsSend.Write(szText, byteTextLength);
pNetGame->GetRakClient()->RPC(RPC_Chat, &bsSend, HIGH_PRIORITY, RELIABLE, 0, FALSE);
} }
//---------------------------------------------------------- //----------------------------------------------------------
@@ -109,3 +134,716 @@ DWORD CLocalPlayer::GetPlayerColorAsARGB()
//---------------------------------------------------- //----------------------------------------------------
//----------------------------------------------------
// the damage reports scale the amount down to a third before sending
void CLocalPlayer::FUNC_100068A0(WORD a1, float a2, int a3, int a4)
{
a2 *= 0.33f;
RakNet::BitStream bsSend;
bsSend.Write1();
bsSend.Write(a1);
bsSend.Write(a2);
bsSend.Write(a3);
bsSend.Write(a4);
pNetGame->GetRakClient()->RPC(RPC_PlayerDamage, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE);
}
//----------------------------------------------------
void CLocalPlayer::FUNC_100069B0(WORD a1, float a2, int a3, int a4)
{
a2 *= 0.33f;
RakNet::BitStream bsSend;
bsSend.Write0();
bsSend.Write(a1);
bsSend.Write(a2);
bsSend.Write(a3);
bsSend.Write(a4);
pNetGame->GetRakClient()->RPC(RPC_PlayerDamage, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE);
}
//----------------------------------------------------
void CLocalPlayer::FUNC_10006AC0(WORD a1, float a2, int a3, int a4)
{
RakNet::BitStream bsSend;
bsSend.Write0();
bsSend.Write(a1);
bsSend.Write(a2);
bsSend.Write(a3);
bsSend.Write(a4);
pNetGame->GetRakClient()->RPC(RPC_ActorDamage, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE);
}
//----------------------------------------------------
void CLocalPlayer::RequestClass(int iClass)
{
RakNet::BitStream bsSend;
bsSend.Write(iClass);
pNetGame->GetRakClient()->RPC(RPC_RequestClass, &bsSend, HIGH_PRIORITY, RELIABLE, 0, FALSE);
}
//----------------------------------------------------
void CLocalPlayer::SendStatsUpdate()
{
RakNet::BitStream bsSend;
int iMoney = pGame->FUNC_100A0F90();
int iDrunkLevel = m_pPlayerPed->sub_100ADFA0();
bsSend.Write((BYTE)ID_STATS_UPDATE);
bsSend.Write(iMoney);
bsSend.Write(iDrunkLevel);
pNetGame->GetRakClient()->Send(&bsSend, HIGH_PRIORITY, UNRELIABLE, 0);
}
//----------------------------------------------------
// class selection cycles field_2FE and re-requests on every step
void CLocalPlayer::SelectNextClass()
{
if(!field_306)
return;
MATRIX4X4 mat;
field_143 = 0;
m_pPlayerPed->GetMatrix(&mat);
if(field_2FE == pNetGame->GetSettings()->field_23 - 1)
field_2FE = 0;
else
field_2FE++;
pGame->m_pGameAudio->PlaySound(1052, mat.pos.X, mat.pos.Y, mat.pos.Z);
RequestClass(field_2FE);
}
//----------------------------------------------------
void CLocalPlayer::SelectPreviousClass()
{
if(!field_306)
return;
MATRIX4X4 mat;
field_143 = 0;
m_pPlayerPed->GetMatrix(&mat);
DWORD dwClass = field_2FE;
if(!dwClass)
dwClass = pNetGame->GetSettings()->field_23;
field_2FE = dwClass - 1;
pGame->m_pGameAudio->PlaySound(1053, mat.pos.X, mat.pos.Y, mat.pos.Z);
RequestClass(field_2FE);
}
//----------------------------------------------------
// leaving a vehicle; every guard shares one exit so the nesting has to stay
void CLocalPlayer::FUNC_10005BF0(WORD a1)
{
RakNet::BitStream bsSend;
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
if(a1 < MAX_VEHICLES && pVehiclePool->field_3074[a1])
{
int pVehicle = pVehiclePool->field_1134[a1];
if(pVehicle)
{
if(!m_pPlayerPed->FUNC_100ABFC0())
field_FA = a1;
if(((CVehicle *)pVehicle)->FUNC_100B7460())
pGame->m_pGameCamera->FUNC_1009D740();
if(!((CVehicle *)pVehicle)->FUNC_100B7E00())
{
bsSend.Write(a1);
pNetGame->GetRakClient()->RPC(RPC_ExitVehicle, &bsSend, HIGH_PRIORITY, RELIABLE_SEQUENCED, 0, FALSE);
}
}
}
}
//----------------------------------------------------
// entering a vehicle; the camera hand-off only runs for the vehicles that ask
void CLocalPlayer::FUNC_10005AD0(WORD a1, int a2)
{
RakNet::BitStream bsSend;
BYTE byteFlag = 0;
if(a2)
byteFlag = 1;
bsSend.Write(a1);
bsSend.Write(byteFlag);
pNetGame->GetRakClient()->RPC(RPC_EnterVehicle, &bsSend, HIGH_PRIORITY, RELIABLE_SEQUENCED, 0, FALSE);
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
if(a1 < MAX_VEHICLES && pVehiclePool->field_3074[a1])
{
CVehicle *pVehicle = (CVehicle *)pVehiclePool->field_1134[a1];
if(pVehicle && pVehicle->FUNC_100B7460())
{
DWORD dwGtaId = pVehicle->m_dwGTAId;
ScriptCommand(&camera_on_vehicle, dwGtaId, 3, 2);
dword_100FE0A4 = GetTickCount();
}
}
}
//----------------------------------------------------
// the enter-vehicle key handler; 46 is the parachute, which has to be put away
void CLocalPlayer::FUNC_10006FE0()
{
GTA_CONTROLSET *pKeys = GameGetInternalKeys();
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
if(pKeys->wKeys1[8] && !pKeys->wKeys2[8])
{
WORD wVehicleId = pVehiclePool->FUNC_1001EC00();
if(wVehicleId < MAX_VEHICLES && pVehiclePool->field_3074[wVehicleId])
{
CVehicle *pVehicle = (CVehicle *)pVehiclePool->FUNC_10001120(wVehicleId);
if(pVehicle->FUNC_1009F0C0() < 8.0f)
{
if(m_pPlayerPed->FUNC_100ABC50() == 46)
m_pPlayerPed->SetArmedWeapon(0, 0);
m_pPlayerPed->FUNC_100AC410(pVehicle->m_dwGTAId, 1);
FUNC_10005AD0(wVehicleId, 1);
}
}
}
}
//----------------------------------------------------
void CLocalPlayer::sub_10003710(int a1, int a2)
{
field_2DA = a1;
field_2DE = a2;
}
//----------------------------------------------------
void CLocalPlayer::sub_10004060()
{
if(field_306)
{
RequestSpawn();
field_302 = 1;
}
}
//----------------------------------------------------
// on foot and in a vehicle report their update rate separately
int CLocalPlayer::FUNC_10003B30()
{
if(m_pPlayerPed)
{
if(m_pPlayerPed->IsInVehicle())
return FUNC_10003AB0();
return FUNC_10003AF0();
}
return 1000;
}
//----------------------------------------------------
// the three words live inside field_0, so they are read through it
BOOL CLocalPlayer::FUNC_10004340(WORD a1, WORD a2, WORD a3)
{
if(a1 == *(WORD *)&field_0[6] && a2 == *(WORD *)&field_0[4] && a3 == *(WORD *)&field_0[2])
return FALSE;
return TRUE;
}
//----------------------------------------------------
// the sync interval, 15ms while the server asks for it and 30ms otherwise
int CLocalPlayer::FUNC_10003AB0()
{
if(m_pPlayerPed)
{
if(pNetGame->GetField239())
return 15;
return dword_100FE0AC + pGame->FUNC_100A00F0();
}
return 1000;
}
//----------------------------------------------------
int CLocalPlayer::FUNC_10003AF0()
{
if(m_pPlayerPed)
{
if(pNetGame->GetField239())
return 15;
return dword_100FE0A8 + pGame->FUNC_100A00F0();
}
return 1000;
}
//----------------------------------------------------
BOOL CLocalPlayer::FUNC_10004300(WORD a1, WORD a2, WORD a3)
{
if(a1 == *(WORD *)&field_94[4] && a2 == *(WORD *)&field_94[2] && a3 == *(WORD *)&field_94[0])
return FALSE;
return TRUE;
}
//----------------------------------------------------
PLAYERID CLocalPlayer::FUNC_10004B70()
{
if(!m_pPlayerPed)
return -1;
int iPed = m_pPlayerPed->FUNC_100AEF60();
if(!iPed)
return -1;
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
if(!pPlayerPool)
return -1;
return pPlayerPool->FUNC_100138C0(iPed);
}
//----------------------------------------------------
ACTORID CLocalPlayer::FUNC_10004BB0()
{
if(!m_pPlayerPed)
return -1;
int iPed = m_pPlayerPed->FUNC_100AEF60();
if(!iPed)
return -1;
CActorPool *pActorPool = pNetGame->GetActorPool();
if(!pActorPool)
return -1;
return pActorPool->FUNC_100018B0(iPed);
}
//----------------------------------------------------
// only accepts a spawn point the game says is inside the world
void CLocalPlayer::sub_10003BE0(SPAWN_INFO *pSpawnInfo)
{
if(FUNC_100B4B50(&pSpawnInfo->vecPos))
{
memcpy(&m_SpawnInfo, pSpawnInfo, sizeof(SPAWN_INFO));
field_17D = 1;
}
}
//----------------------------------------------------
void CLocalPlayer::sub_100040E0(BOOL bSpawn)
{
if(bSpawn)
{
if(m_pPlayerPed)
{
m_pPlayerPed->FUNC_100AC010();
m_pPlayerPed->SetSkin(m_SpawnInfo.iSkin);
}
field_143 = 1;
}
}
//----------------------------------------------------
void CLocalPlayer::FUNC_10004080()
{
field_143 = 0;
if(m_pPlayerPed)
{
m_pPlayerPed->FUNC_100ABBD0();
m_pPlayerPed->FUNC_100ABD70(100.0f);
m_pPlayerPed->FUNC_100AC790(0);
}
field_14B = GetTickCount();
field_147 = GetTickCount();
}
//----------------------------------------------------
// resends at most twice a second unless the block actually changed
BOOL CLocalPlayer::FUNC_10003A60(void *a2, void *a3, unsigned int a4)
{
if(GetTickCount() - field_13F > 500)
{
field_13F = GetTickCount();
return TRUE;
}
if(memcmp(a2, a3, a4))
{
field_13F = GetTickCount();
return TRUE;
}
return FALSE;
}
//----------------------------------------------------
void CLocalPlayer::FUNC_10004230(WORD a1)
{
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
if(pVehiclePool && a1 < MAX_VEHICLES && pVehiclePool->field_3074[a1])
{
field_30F = 2;
field_310 = a1;
field_314 = 0;
}
}
//----------------------------------------------------
void CLocalPlayer::RequestSpawn()
{
RakNet::BitStream bsSend;
pNetGame->GetRakClient()->RPC(RPC_RequestSpawn, &bsSend, HIGH_PRIORITY, RELIABLE, 0, FALSE);
}
//----------------------------------------------------
// straying outside the server boundary disarms and nags
void CLocalPlayer::FUNC_10003F50()
{
if(!pGame->FUNC_100A0EE0() && m_pPlayerPed->FUNC_1009F420(pNetGame->GetSettings()->fWorldBoundryPX,
pNetGame->GetSettings()->fWorldBoundryZX, pNetGame->GetSettings()->fWorldBoundryPY,
pNetGame->GetSettings()->fWorldBoundryNY))
{
m_pPlayerPed->SetArmedWeapon(0, 0);
pGame->DisplayGameText("Stay within the ~r~world boundries", 1000, 5);
}
}
//----------------------------------------------------
// leaving spectate only resets the spawn state when another class is pending
void CLocalPlayer::FUNC_100041C0(BOOL bSpectating)
{
if(m_bIsSpectating && !m_bWantsAnotherClass && !bSpectating)
sub_10003C20();
else if(m_bWantsAnotherClass && !bSpectating)
{
field_F0 = 0;
field_17D = 0;
}
m_bIsSpectating = bSpectating;
field_30F = 0;
field_314 = 0;
field_310 = -1;
}
//----------------------------------------------------
// picks a player to spectate; state 32 is not a spectatable one
void CLocalPlayer::FUNC_10004280(PLAYERID playerId)
{
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
if(pPlayerPool && pPlayerPool->GetSlotState(playerId) && pPlayerPool->GetAt(playerId)->field_10A
&& pPlayerPool->GetAt(playerId)->field_10A != 32)
{
field_30F = 1;
field_310 = playerId;
field_314 = 0;
}
}
//----------------------------------------------------
// the in-vehicle half of the boundary check, keyed off the driven vehicle
void CLocalPlayer::FUNC_10003FC0()
{
CVehiclePool *pVehiclePool = pNetGame->GetVehiclePool();
WORD wVehicleId = pVehiclePool->FUNC_1001EB90((int)m_pPlayerPed->GetGtaVehicle());
if(!pGame->FUNC_100A0EE0() && wVehicleId != INVALID_VEHICLE_ID && wVehicleId < MAX_VEHICLES
&& pVehiclePool->field_3074[wVehicleId])
{
CVehicle *pVehicle = (CVehicle *)pVehiclePool->field_1134[wVehicleId];
if(pVehicle && pVehicle->FUNC_1009F420(pNetGame->GetSettings()->fWorldBoundryPX,
pNetGame->GetSettings()->fWorldBoundryZX, pNetGame->GetSettings()->fWorldBoundryPY,
pNetGame->GetSettings()->fWorldBoundryNY))
pGame->DisplayGameText("Stay within the ~r~world boundries", 1000, 5);
}
}
//----------------------------------------------------
// counts the spawned players, recomputed once every 30 calls
int FUNC_10004120()
{
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
WORD i = 0;
if(dword_101189A4)
{
dword_101189A4--;
return dword_101189A0;
}
int iCount = 0;
dword_101189A4 = 30;
dword_101189A0 = 0;
if(pPlayerPool)
{
int iMax = pPlayerPool->field_2F3A;
for(; i <= iMax; i++)
{
if(pPlayerPool->GetSlotState(i))
{
CRemotePlayer *pRemotePlayer = pPlayerPool->GetAt(i);
if(pRemotePlayer->m_pPlayerPed && pRemotePlayer->field_10A)
dword_101189A0 = ++iCount;
}
}
}
return iCount;
}
//----------------------------------------------------
// reports the death reason and who did it
void CLocalPlayer::SendDeath()
{
RakNet::BitStream bsSend;
WORD wKiller;
BYTE byteReason = m_pPlayerPed->FUNC_100AC850(&wKiller);
bsSend.Write(byteReason);
bsSend.Write(wKiller);
pNetGame->GetRakClient()->RPC(RPC_Death, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE);
}
//----------------------------------------------------
void CLocalPlayer::SetInteriorId(BYTE byteInteriorId)
{
field_1CF = byteInteriorId;
RakNet::BitStream bsSend;
bsSend.Write(byteInteriorId);
pNetGame->GetRakClient()->RPC(RPC_SetInteriorId, &bsSend, HIGH_PRIORITY, RELIABLE, 0, FALSE);
}
//----------------------------------------------------
// drives class selection: centres the dialog on entry, then steps on the arrows
void CLocalPlayer::FUNC_10006100()
{
if(!pGame->sub_100A0920())
{
pGame->sub_100A1DB0(0);
pGame->ToggleKeyInputsDisabled(2, 0);
}
if(pUnkClass3 && pUnkClass3->GetField28())
return;
if(!field_306)
{
RECT rect;
pClassSelectDialog->SetVisible(true);
GetClientRect(pGame->GetMainWindowHwnd(), &rect);
pClassSelectDialog->SetLocation(rect.right / 2 - pClassSelectDialog->GetWidth() / 2,
rect.bottom - pClassSelectDialog->GetHeight() - 50);
field_306 = 1;
RequestClass(field_2FE);
return;
}
if(GetTickCount() - field_14B < 2000)
return;
if(!field_302)
{
if(!field_143)
return;
if((GetAsyncKeyState(VK_SHIFT) & 0x8000) && !pCmdWindow->GetField14E0())
{
sub_10004060();
return;
}
}
if(!field_143)
return;
DWORD dwElapsed = GetTickCount() - field_147;
if((GetAsyncKeyState(VK_LEFT) & 0x8000) && dwElapsed > 250)
{
field_147 = GetTickCount();
SelectPreviousClass();
return;
}
if((GetAsyncKeyState(VK_RIGHT) & 0x8000) && dwElapsed > 250)
{
field_147 = GetTickCount();
SelectNextClass();
}
}
//----------------------------------------------------
// keeps the FollowPedSA marker on the aim point, refreshed five times a second
void CLocalPlayer::FUNC_10002FA0()
{
if(m_pPlayerPed && (!pGame || pGame->m_bHeadMove) && !m_pPlayerPed->FUNC_100ADC90()
&& (!pUnkClass10 || !pUnkClass10->GetField80()))
{
MATRIX4X4 mat;
m_pPlayerPed->GetMatrix(&mat);
DWORD dwTick = GetTickCount();
if(dwTick - field_137 > 1000)
{
CAMERA_AIM *pAim = GameGetInternalAim();
float fX = pAim->f1x * 20.0f + mat.pos.X;
float fY = pAim->f1y * 20.0f + mat.pos.Y;
float fZ = pAim->f1z * 20.0f + mat.pos.Z;
field_137 = dwTick;
*(float *)&field_12B[0] = fX - mat.pos.X;
*(float *)&field_12B[4] = fY - mat.pos.Y;
*(float *)&field_12B[8] = fZ - mat.pos.Z;
}
if(dwTick - field_13B > 200)
{
VECTOR vecTarget;
vecTarget.X = mat.pos.X + *(float *)&field_12B[0];
vecTarget.Y = mat.pos.Y + *(float *)&field_12B[4];
vecTarget.Z = mat.pos.Z + *(float *)&field_12B[8];
m_pPlayerPed->FUNC_100ADFD0("FollowPedSA", 0, 2000, -1, &vecTarget, 0, 0.1f, 500, 3, 0);
field_13B = dwTick;
}
}
}
//----------------------------------------------------
// the special action code the sync packets carry; 5 to 8 are the dance styles
BYTE CLocalPlayer::GetSpecialAction()
{
if(m_pPlayerPed->FUNC_100ACDC0())
return 2;
if(m_pPlayerPed->FUNC_100ADB60())
{
switch(m_pPlayerPed->m_iDanceStyle)
{
case 0:
return 5;
case 1:
return 6;
case 2:
return 7;
case 3:
return 8;
}
}
if(m_pPlayerPed->FUNC_100ACB60())
return 10;
if(m_pPlayerPed->FUNC_100AE0A0())
return 11;
if(m_pPlayerPed->FUNC_100AE260())
return 68;
if(m_pPlayerPed->FUNC_100AC690())
return 1;
if(m_pPlayerPed->FUNC_100AC5D0())
return 3;
if(m_pPlayerPed->FUNC_100AC640())
return 4;
if(m_pPlayerPed->FUNC_100ADC90())
{
if(m_pPlayerPed->FUNC_100ADC90() == 1)
return 20;
if(m_pPlayerPed->FUNC_100ADC90() == 2)
return 22;
if(m_pPlayerPed->FUNC_100ADC90() == 3)
return 23;
if(m_pPlayerPed->FUNC_100ADC90() == 4)
return 21;
}
if(m_pPlayerPed->FUNC_100ACEF0())
return 24;
BYTE byteAction = m_pPlayerPed->FUNC_100ACE40() ? 25 : 0;
return byteAction;
}
+60 -5
View File
@@ -3,10 +3,21 @@
//---------------------------------------------------------- //----------------------------------------------------------
#pragma pack(1)
typedef struct _SPAWN_INFO {
BYTE byteTeam;
int iSkin;
BYTE byteUnk;
VECTOR vecPos;
float fRotation;
int iSpawnWeapons[3];
int iSpawnWeaponsAmmo[3];
} SPAWN_INFO, *PSPAWN_INFO;
#pragma pack(1) #pragma pack(1)
class CLocalPlayer class CLocalPlayer
{ {
private: public:
BYTE field_0[63]; BYTE field_0[63];
//BYTE field_3C[3]; //BYTE field_3C[3];
@@ -43,11 +54,12 @@ private:
DWORD field_13B; DWORD field_13B;
DWORD field_13F; DWORD field_13F;
BYTE _pad143[4]; DWORD field_143;
DWORD field_147; DWORD field_147;
BYTE _pad14B[50]; DWORD field_14B;
SPAWN_INFO m_SpawnInfo;
DWORD field_17D; DWORD field_17D;
DWORD field_181; DWORD field_181;
@@ -78,12 +90,12 @@ private:
DWORD field_306; DWORD field_306;
DWORD field_30A; DWORD field_30A;
BYTE _pad30E; BYTE field_30E;
BYTE field_30F; BYTE field_30F;
DWORD field_310; DWORD field_310;
BYTE _pad314[4]; DWORD field_314;
WORD field_318; WORD field_318;
@@ -102,10 +114,53 @@ public:
DWORD GetPlayerColorAsRGBA(); DWORD GetPlayerColorAsRGBA();
DWORD GetPlayerColorAsARGB(); DWORD GetPlayerColorAsARGB();
BOOL IsSpectating() { return m_bIsSpectating; }; BOOL IsSpectating() { return m_bIsSpectating; };
void SetTeam(BYTE byteTeam) { m_byteTeam = byteTeam; };
void ReturnToClassSelection() { m_bWantsAnotherClass = TRUE; }; void ReturnToClassSelection() { m_bWantsAnotherClass = TRUE; };
BOOL IsInRCMode() { return m_bInRCMode; }; BOOL IsInRCMode() { return m_bInRCMode; };
void SelectNextClass(); // .text:10005FF0
void SelectPreviousClass(); // .text:10006080
void RequestClass(int iClass); // .text:100058D0
void SendStatsUpdate(); // .text:10005D00
void FUNC_10005AD0(WORD a1, int a2); // .text:10005AD0
void FUNC_10006FE0(); // .text:10006FE0
void FUNC_10005BF0(WORD a1); // .text:10005BF0
void FUNC_10003570(); // .text:10003570
// the three ped-damage reports; all take `this` in ecx but never read it
void FUNC_100068A0(WORD a1, float a2, int a3, int a4); // .text:100068A0
void FUNC_100069B0(WORD a1, float a2, int a3, int a4); // .text:100069B0
void FUNC_10006AC0(WORD a1, float a2, int a3, int a4); // .text:10006AC0
void sub_10003C20(); // .text:10003C20
void sub_10003BE0(SPAWN_INFO *pSpawnInfo); // .text:10003BE0
void sub_100040E0(BOOL bSpawn); // .text:100040E0
void sub_100030F0(BYTE a1); // .text:100030F0
void sub_10003710(int a1, int a2); // .text:10003710
void sub_10004060(); // .text:10004060
int FUNC_10003AB0(); // .text:10003AB0
int FUNC_10003AF0(); // .text:10003AF0
int FUNC_10003B30(); // .text:10003B30
void RequestSpawn(); // .text:10003B60
BOOL FUNC_10004340(WORD a1, WORD a2, WORD a3); // .text:10004340
BOOL FUNC_10004300(WORD a1, WORD a2, WORD a3); // .text:10004300
PLAYERID FUNC_10004B70(); // .text:10004B70
ACTORID FUNC_10004BB0(); // .text:10004BB0
BOOL FUNC_10003A60(void *a2, void *a3, unsigned int a4); // .text:10003A60
void FUNC_10004080(); // .text:10004080
void FUNC_10004230(WORD a1); // .text:10004230
void FUNC_10004280(PLAYERID playerId); // .text:10004280
void FUNC_10002FA0(); // .text:10002FA0
BYTE GetSpecialAction(); // .text:10003410
void FUNC_10006100(); // .text:10006100
void SendDeath(); // .text:10005810
void SetInteriorId(BYTE byteInteriorId); // .text:10005970
void FUNC_10003F50(); // .text:10003F50
void FUNC_10003FC0(); // .text:10003FC0
void FUNC_100041C0(BOOL bSpectating); // .text:100041C0
DWORD GetField_F0() { return field_F0; };
}; };
//---------------------------------------------------------- //----------------------------------------------------------
+3 -1
View File
@@ -5,7 +5,7 @@
class CMenuPool class CMenuPool
{ {
private: public:
CMenu *m_pMenus[MAX_MENUS]; CMenu *m_pMenus[MAX_MENUS];
BOOL m_bMenuSlotState[MAX_MENUS]; BOOL m_bMenuSlotState[MAX_MENUS];
@@ -13,6 +13,8 @@ private:
BYTE m_byteExited; BYTE m_byteExited;
public: public:
int GetSlotState(BYTE byteMenuID) { if(byteMenuID > MAX_MENUS) return 0; return m_bMenuSlotState[byteMenuID]; }
CMenuPool(); CMenuPool();
~CMenuPool(); ~CMenuPool();
+310 -5
View File
@@ -4,9 +4,16 @@
extern CGame *pGame; extern CGame *pGame;
extern CChatWindow *pChatWindow; extern CChatWindow *pChatWindow;
extern CConfig *pConfig;
extern CAudioStream *pAudioStream;
void FUNC_100AABE0(); // .text:100AABE0
DWORD dword_10118A18;
//---------------------------------------------------- //----------------------------------------------------
// MATCH
BYTE __stdcall GetPacketID(Packet *p) BYTE __stdcall GetPacketID(Packet *p)
{ {
if (p==0) return 255; if (p==0) return 255;
@@ -22,6 +29,7 @@ BYTE __stdcall GetPacketID(Packet *p)
//---------------------------------------------------- //----------------------------------------------------
// MATCH
bool __stdcall HasTimestamps(Packet *p) bool __stdcall HasTimestamps(Packet *p)
{ {
if (p==0) return 0; if (p==0) return 0;
@@ -86,6 +94,7 @@ void CNetGame::UpdateNetwork()
// TODO: CNetGame::UpdateNetwork() // TODO: CNetGame::UpdateNetwork()
} }
// MATCH
void CNetGame::InitPools() void CNetGame::InitPools()
{ {
m_pPools = (NETGAME_POOLS *)calloc(1, sizeof(NETGAME_POOLS)); m_pPools = (NETGAME_POOLS *)calloc(1, sizeof(NETGAME_POOLS));
@@ -101,6 +110,7 @@ void CNetGame::InitPools()
m_pPools->pActorPool = new CActorPool(); m_pPools->pActorPool = new CActorPool();
} }
// MATCH
DWORD CNetGame::GetTime() DWORD CNetGame::GetTime()
{ {
return (DWORD)RakNet::GetTime(); return (DWORD)RakNet::GetTime();
@@ -109,10 +119,15 @@ DWORD CNetGame::GetTime()
//----------------------------------------------------------- //-----------------------------------------------------------
// Puts a personal marker using any of the radar icons on the map // Puts a personal marker using any of the radar icons on the map
// MATCH
void CNetGame::SetMapIcon(BYTE byteIndex, float fX, float fY, float fZ, BYTE byteIcon, DWORD dwColor, int iStyle) void CNetGame::SetMapIcon(BYTE byteIndex, float fX, float fY, float fZ, BYTE byteIcon, DWORD dwColor, int iStyle)
{ {
if (byteIndex >= 100) return; if (byteIndex >= 100) return;
if (m_dwMapIcon[byteIndex] != NULL) DisableMapIcon(byteIndex); if (m_dwMapIcon[byteIndex] != NULL) {
if (byteIndex >= 100) return;
ScriptCommand(&disable_marker, m_dwMapIcon[byteIndex]);
m_dwMapIcon[byteIndex] = NULL;
}
//ScriptCommand(&create_radar_marker_without_sphere, fX, fY, fZ, byteIcon, &m_dwMapIcon); //ScriptCommand(&create_radar_marker_without_sphere, fX, fY, fZ, byteIcon, &m_dwMapIcon);
m_dwMapIcon[byteIndex] = pGame->CreateRadarMarkerIcon(byteIcon, fX, fY, fZ, dwColor, iStyle); m_dwMapIcon[byteIndex] = pGame->CreateRadarMarkerIcon(byteIcon, fX, fY, fZ, dwColor, iStyle);
} }
@@ -120,6 +135,27 @@ void CNetGame::SetMapIcon(BYTE byteIndex, float fX, float fY, float fZ, BYTE byt
//----------------------------------------------------------- //-----------------------------------------------------------
// Removes the Map Icon // Removes the Map Icon
//----------------------------------------------------
// MATCH
// MATCH
void CNetGame::ResetMapIcons()
{
BYTE i;
for (i = 0; i < 100; i++)
{
if (m_dwMapIcon[i] != NULL) {
if (i >= 100) continue;
ScriptCommand(&disable_marker, m_dwMapIcon[i]);
m_dwMapIcon[i] = NULL;
}
}
}
//----------------------------------------------------
// MATCH
void CNetGame::DisableMapIcon(BYTE byteIndex) void CNetGame::DisableMapIcon(BYTE byteIndex)
{ {
if (byteIndex >= 100) return; if (byteIndex >= 100) return;
@@ -129,13 +165,282 @@ void CNetGame::DisableMapIcon(BYTE byteIndex)
//---------------------------------------------------- //----------------------------------------------------
void CNetGame::ResetMapIcons() //----------------------------------------------------
void CNetGame::Packet_RSAPublicKeyMismatch(Packet *p)
{ {
BYTE i; pChatWindow->AddDebugMessage("Failed to initialize encryption.");
for (i = 0; i < 100; i++) }
//----------------------------------------------------
void CNetGame::Packet_ConnectionBanned(Packet *p)
{
pChatWindow->AddDebugMessage("You are banned from this server.");
}
//----------------------------------------------------
void CNetGame::Packet_ConnectionSucceeded(Packet *p)
{
pChatWindow->AddDebugMessage("Server has accepted the connection.");
}
//----------------------------------------------------
// MATCH
void CNetGame::Packet_NoFreeIncomingConnections(Packet *p)
{
pChatWindow->AddDebugMessage("The server is full. Retrying...");
m_iGameState = GAMESTATE_WAIT_CONNECT;
}
//----------------------------------------------------
// MATCH
void CNetGame::Packet_InvalidPassword(Packet *p)
{
pChatWindow->AddDebugMessage("Wrong server password.");
GetRakClient()->Disconnect(0,0);
}
//----------------------------------------------------
// MATCH
void CNetGame::Packet_ConnectionAttemptFailed(Packet *p)
{
pChatWindow->AddDebugMessage("The server didn't respond. Retrying..");
m_iGameState = GAMESTATE_WAIT_CONNECT;
}
//----------------------------------------------------
// MATCH
void CNetGame::ToggleNameTagStatus()
{
if(!field_234)
{ {
if (m_dwMapIcon[i] != NULL) DisableMapIcon(i); pChatWindow->AddInfoMessage("NameTag Player Status: ON");
if(pConfig) pConfig->SetIntVariable("nonametagstatus",0);
field_234 = 1;
}
else
{
pChatWindow->AddInfoMessage("NameTag Player Status: OFF");
if(pConfig) pConfig->SetIntVariable("nonametagstatus",1);
field_234 = 0;
} }
} }
//---------------------------------------------------- //----------------------------------------------------
// MATCH
void CNetGame::AttemptConnect()
{
if(GetTickCount() - field_3D1 > 3000)
{
if(pChatWindow)
pChatWindow->AddDebugMessage("Connecting to %s:%d...",m_szHostOrIp,m_iPort);
m_pRakClient->Connect(m_szHostOrIp,m_iPort,0,0,2);
field_3D1 = GetTickCount();
m_iGameState = GAMESTATE_CONNECTING;
}
}
//----------------------------------------------------
void CNetGame::UpdateScoresPingsIPs()
{
if(GetTickCount() - dword_10118A18 > 3000)
{
dword_10118A18 = GetTickCount();
RakNet::BitStream bsSend;
if(GetRakClient())
GetRakClient()->RPC(RPC_UpdateScoresPingsIPs, &bsSend, HIGH_PRIORITY, RELIABLE, 0, FALSE);
}
}
//----------------------------------------------------
void CNetGame::ResetWorldBounds()
{
if(field_3D5->field_2B) FUNC_100AABE0();
field_3D5->fWorldBoundryPX = 20000.0f;
field_3D5->fWorldBoundryZX = -20000.0f;
field_3D5->fWorldBoundryPY = 20000.0f;
field_3D5->fWorldBoundryNY = -20000.0f;
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetPlayerPool()
{
delete m_pPools->pPlayerPool;
m_pPools->pPlayerPool = new CPlayerPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetGangZonePool()
{
delete m_pPools->pGangZonePool;
m_pPools->pGangZonePool = new CGangZonePool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetPickupPool()
{
delete m_pPools->pPickupPool;
m_pPools->pPickupPool = new CPickupPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetMenuPool()
{
delete m_pPools->pMenuPool;
m_pPools->pMenuPool = new CMenuPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetLabelPool()
{
delete m_pPools->pLabelPool;
m_pPools->pLabelPool = new CLabelPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetActorPool()
{
delete m_pPools->pActorPool;
m_pPools->pActorPool = new CActorPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetVehiclePool()
{
delete m_pPools->pVehiclePool;
m_pPools->pVehiclePool = new CVehiclePool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetTextDrawPool()
{
delete m_pPools->pTextDrawPool;
m_pPools->pTextDrawPool = new CTextDrawPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::ResetObjectPool()
{
delete m_pPools->pObjectPool;
m_pPools->pObjectPool = new CObjectPool();
}
//----------------------------------------------------
// MATCH
void CNetGame::Packet_DisconnectionNotification(Packet *p)
{
pChatWindow->AddDebugMessage("Server closed the connection.");
if(pAudioStream) pAudioStream->Stop(1);
GetRakClient()->Disconnect(2000,0);
}
//----------------------------------------------------
void CNetGame::Packet_AimSync(Packet *p)
{
RakNet::BitStream bsAimSync((char *)p->data, p->length, false);
char aimSync[31];
WORD wPlayerID;
BYTE bytePacketID = 0;
if(m_iGameState != GAMESTATE_CONNECTED) return;
bsAimSync.Read(bytePacketID);
bsAimSync.Read(wPlayerID);
bsAimSync.Read(aimSync, sizeof(aimSync));
CPlayerPool *pPlayerPool = GetPlayerPool();
if(wPlayerID <= MAX_PLAYERS)
{
CNetPlayer *pPlayer = pPlayerPool->m_pPlayers[wPlayerID];
if(pPlayer && pPlayer->m_pRemotePlayer)
pPlayer->m_pRemotePlayer->FUNC_10015760(aimSync);
}
}
//----------------------------------------------------
void CNetGame::Packet_PassengerSync(Packet *p)
{
RakNet::BitStream bsPassengerSync((char *)p->data, p->length, false);
char passengerSync[24];
WORD wPlayerID;
BYTE bytePacketID = 0;
if(m_iGameState != GAMESTATE_CONNECTED) return;
bsPassengerSync.Read(bytePacketID);
bsPassengerSync.Read(wPlayerID);
bsPassengerSync.Read(passengerSync, sizeof(passengerSync));
CPlayerPool *pPlayerPool = GetPlayerPool();
if(wPlayerID <= MAX_PLAYERS)
{
CNetPlayer *pPlayer = pPlayerPool->m_pPlayers[wPlayerID];
if(pPlayer && pPlayer->m_pRemotePlayer)
pPlayer->m_pRemotePlayer->FUNC_10017440(passengerSync);
}
}
//----------------------------------------------------
void CNetGame::Packet_TrailerSync(Packet *p)
{
RakNet::BitStream bsTrailerSync((char *)p->data, p->length, false);
char trailerSync[54];
WORD wPlayerID;
BYTE bytePacketID;
if(m_iGameState != GAMESTATE_CONNECTED) return;
bytePacketID = 0;
bsTrailerSync.Read(bytePacketID);
bsTrailerSync.Read(wPlayerID);
bsTrailerSync.Read(trailerSync, sizeof(trailerSync));
CPlayerPool *pPlayerPool = GetPlayerPool();
if(wPlayerID <= MAX_PLAYERS)
{
CNetPlayer *pPlayer = pPlayerPool->m_pPlayers[wPlayerID];
if(pPlayer && pPlayer->m_pRemotePlayer)
pPlayer->m_pRemotePlayer->FUNC_10015C90(trailerSync);
}
}
+65 -7
View File
@@ -5,11 +5,17 @@
#define GAMESTATE_WAIT_CONNECT 1 #define GAMESTATE_WAIT_CONNECT 1
#define GAMESTATE_CONNECTING 2
struct struc_41 struct struc_41
{ {
bool bUseCJWalk; bool bUseCJWalk;
int field_1; int field_1;
char _gap5[17]; float fWorldBoundryPX;
float fWorldBoundryZX;
float fWorldBoundryPY;
float fWorldBoundryNY;
char _gap15;
float field_16; float field_16;
char field_1A; char field_1A;
char _gap1B[4]; char _gap1B[4];
@@ -19,12 +25,15 @@ struct struc_41
char field_22; char field_22;
int field_23; int field_23;
float field_27; float field_27;
char _gap2B; char field_2B;
char field_2C; BYTE field_2C;
char field_2D; BYTE field_2D;
char field_2E; char field_2E;
char field_2F; char field_2F;
char _gap30[10]; int field_30;
char _gap34[4];
BYTE field_38;
char _gap39;
}; };
typedef struct _NETGAME_POOLS { typedef struct _NETGAME_POOLS {
@@ -51,8 +60,10 @@ private:
char m_szHostOrIp[257]; char m_szHostOrIp[257];
char m_szHostName[257]; char m_szHostName[257];
char field_232; char field_232;
public:
char field_233; char field_233;
char field_234; BYTE field_234;
private:
int m_iPort; int m_iPort;
int field_239; int field_239;
DWORD m_dwMapIcon[100]; DWORD m_dwMapIcon[100];
@@ -73,13 +84,60 @@ public:
DWORD GetTime(); DWORD GetTime();
int GetGameState() { return m_iGameState; }; int GetGameState() { return m_iGameState; };
char GetField232() { return field_232; };
int GetField239() { return field_239; };
void SetField232(char cValue) { field_232 = cValue; };
BOOL GetWalkStyle() { return field_3D5->bUseCJWalk; }; BOOL GetWalkStyle() { return field_3D5->bUseCJWalk; };
struc_41 * GetSettings() { return field_3D5; };
void SetWorldTime(BYTE byteHour) { field_3D5->field_2C = byteHour; };
void SetWorldMinute(BYTE byteMinute) { field_3D5->field_2D = byteMinute; };
void SetWeather(BYTE byteWeather) { field_3D5->field_2E = byteWeather; };
CVehiclePool * GetVehiclePool() { return m_pPools->pVehiclePool; };
CVehiclePool * FUNC_10001180(); // .text:10001180, out of line copy of GetVehiclePool
CPlayerPool * GetPlayerPool() { return m_pPools->pPlayerPool; }; CPlayerPool * GetPlayerPool() { return m_pPools->pPlayerPool; };
CPickupPool * GetPickupPool() { return m_pPools->pPickupPool; };
CActorPool * GetActorPool() { return m_pPools->pActorPool; };
CObjectPool * GetObjectPool() { return m_pPools->pObjectPool; };
CObjectPool * FUNC_10002E10() { return m_pPools->pObjectPool; }; // .text:10002E10, out of line copy of GetObjectPool
CGangZonePool * GetGangZonePool() { return m_pPools->pGangZonePool; }; CGangZonePool * GetGangZonePool() { return m_pPools->pGangZonePool; };
CLabelPool * GetLabelPool() { return m_pPools->pLabelPool; };
CTextDrawPool * GetTextDrawPool() { return m_pPools->pTextDrawPool; };
RakClientInterface * GetRakClient() { return m_pRakClient; }; RakClientInterface * GetRakClient() { return m_pRakClient; };
void ResetMapIcons(); void ResetMapIcons();
void SetMapIcon(BYTE byteIndex, float fX, float fY, float fZ, BYTE byteIcon, DWORD dwColor, int iStyle); void SetMapIcon(BYTE byteIndex, float fX, float fY, float fZ, BYTE byteIcon, DWORD dwColor, int iStyle);
void DisableMapIcon(BYTE byteIndex); // MATCH
void DisableMapIcon(BYTE byteIndex); // .text:10008FB0
CMenuPool * GetMenuPool() { return m_pPools->pMenuPool; }; // .text:100084F0
void ResetPlayerPool(); // .text:10008FE0
void ResetVehiclePool(); // .text:10009080
void ResetTextDrawPool(); // .text:10009110
void ResetObjectPool(); // .text:100091B0
void ResetGangZonePool(); // .text:10009250
void ResetPickupPool(); // .text:100092F0
void ResetMenuPool(); // .text:10009350
void ResetLabelPool(); // .text:100093F0
void ResetActorPool(); // .text:10009490
void AttemptConnect(); // .text:10008940
void ResetWorldBounds(); // .text:100088F0
void Packet_AimSync(Packet *p); // .text:10009C40
void Packet_PassengerSync(Packet *p); // .text:10009D30
void Packet_TrailerSync(Packet *p); // .text:10009E20
void Packet_RSAPublicKeyMismatch(Packet *p); // .text:10008D50
void Packet_ConnectionBanned(Packet *p); // .text:10008D70
void Packet_ConnectionSucceeded(Packet *p); // .text:10008D90
void Packet_NoFreeIncomingConnections(Packet *p); // .text:10008DB0
void Packet_DisconnectionNotification(Packet *p); // .text:10008DE0
void Packet_InvalidPassword(Packet *p); // .text:10008E20
void Packet_ConnectionAttemptFailed(Packet *p); // .text:10008E60
void UpdateScoresPingsIPs(); // .text:10008F10
void ToggleNameTagStatus(); // .text:10008E90
void sub_1000A540(); // .text:1000A540
}; };
+6
View File
@@ -16,6 +16,12 @@ public:
CRemotePlayer *m_pRemotePlayer; CRemotePlayer *m_pRemotePlayer;
std::string m_PlayerName; std::string m_PlayerName;
void SetPlayerName(PCHAR szName) { m_PlayerName = szName; };
int GetScore() { return field_4; };
int GetPing() { return field_C; };
PCHAR GetName() { return (PCHAR)m_PlayerName.c_str(); }; // .text:100175B0
CNetPlayer(PCHAR szPlayerName, BOOL bIsNPC); CNetPlayer(PCHAR szPlayerName, BOOL bIsNPC);
~CNetPlayer(); ~CNetPlayer();
}; };
+1216 -39
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -3,6 +3,8 @@
//---------------------------------------------------- //----------------------------------------------------
void sub_10001A60(PLAYERID playerId, int iEvent, int iVehicle, int iArg1, int iArg2); // .text:10001A60
void RegisterRPCs(RakClientInterface *); void RegisterRPCs(RakClientInterface *);
void UnRegisterRPCs(RakClientInterface *); void UnRegisterRPCs(RakClientInterface *);
+15
View File
@@ -10,3 +10,18 @@ CObjectPool::CObjectPool()
} }
field_0 = 0; field_0 = 0;
}; };
//----------------------------------------------------
CObjectPool::~CObjectPool()
{
for(int i = 0; i < MAX_OBJECTS; i++)
FUNC_10012850(i);
}
//----------------------------------------------------
void CObjectPool::FUNC_10012850(WORD wObject)
{
// TODO: CObjectPool::FUNC_10012850() .text:10012850
}
+38 -2
View File
@@ -1,13 +1,49 @@
#pragma once #pragma once
// samp object; holds the material/text data
class CObject
{
public:
char _gap0[68];
int field_44;
char _gap48[11];
BYTE field_53;
float field_54;
char _gap58[4403];
int field_118B;
char _gap118F[10];
BYTE field_1199;
public:
void FUNC_100A7E20();
void FUNC_100A9E30();
void FUNC_100A9E70();
void FUNC_100A80A0(VECTOR *pPos); // .text:100A80A0
void FUNC_100A8030(); // .text:100A8030
void FUNC_100A8530(int iModel, int iIndex, char *szTxd, char *szTexture, DWORD dwColour); // .text:100A8530
void FUNC_100A86B0(int iIndex, char *szText, BYTE byteSize, char *szFont, BYTE byteBold,
BYTE byteAlign, DWORD dwFontColour, DWORD dwBackColour, BYTE byteUnk); // .text:100A86B0
};
class CObjectPool class CObjectPool
{ {
private: public:
int field_0; int field_0;
int field_4[MAX_OBJECTS]; int field_4[MAX_OBJECTS];
int field_FA4[MAX_OBJECTS]; int field_FA4[MAX_OBJECTS];
public: public:
CObjectPool(); char FUNC_10012DE0(VECTOR *vecStart, VECTOR *vecEnd); // .text:10012DE0
CObjectPool();
~CObjectPool(); // .text:10013160
void FUNC_10012850(WORD wObject); // .text:10012850
void FUNC_10012A50(); // .text:10012A50
void FUNC_10012B10(); // .text:10012B10
void FUNC_10012B90(); // .text:10012B90
void FUNC_10012BD0(); // .text:10012BD0
CObject * FUNC_100129D0(ENTITY_TYPE *pEntity); // todo: implement
}; };
+15
View File
@@ -3,6 +3,15 @@
#define MAX_PICKUPS 4096 #define MAX_PICKUPS 4096
#pragma pack(1)
typedef struct _PICKUP {
int iModel;
int iType;
float fX;
float fY;
float fZ;
} PICKUP, *PPICKUP;
//---------------------------------------------------- //----------------------------------------------------
class CPickupPool class CPickupPool
@@ -20,6 +29,7 @@ private:
public: public:
// MATCH
CPickupPool() { CPickupPool() {
memset(field_F004, 0, sizeof(field_F004)); memset(field_F004, 0, sizeof(field_F004));
field_0 = 0; field_0 = 0;
@@ -33,6 +43,11 @@ public:
~CPickupPool(); ~CPickupPool();
void sub_10013440(int iPickup); // .text:10013440
void sub_10013320(int iPickup); // .text:10013320
void sub_10013270(PICKUP *pPickup, int iPickup); // .text:10013270
void sub_10013380(WORD wPickup); // .text:10013380
}; };
//---------------------------------------------------- //----------------------------------------------------
+11
View File
@@ -43,3 +43,14 @@ CPlayerPool::CPlayerPool()
} }
//---------------------------------------------------- //----------------------------------------------------
//----------------------------------------------------
CPlayerPool::~CPlayerPool()
{
delete m_pLocalPlayer;
m_pLocalPlayer = NULL;
for(PLAYERID playerId = 0; playerId < MAX_PLAYERS; playerId++)
sub_10014090(playerId,0);
}
+47 -2
View File
@@ -10,7 +10,7 @@
class CPlayerPool class CPlayerPool
{ {
private: public:
int field_0; int field_0;
PLAYERID m_LocalPlayerID; PLAYERID m_LocalPlayerID;
@@ -32,11 +32,26 @@ public:
if(playerId > MAX_PLAYERS) return; if(playerId > MAX_PLAYERS) return;
CNetPlayer* pPlayer = m_pPlayers[playerId]; CNetPlayer* pPlayer = m_pPlayers[playerId];
if(!pPlayer) return; if(!pPlayer) return;
pPlayer->m_PlayerName = szName; pPlayer->SetPlayerName(szName);
} }
PCHAR GetPlayerName(PLAYERID playerId) { // .text:100175C0
if(playerId == m_LocalPlayerID) return (PCHAR)field_6.c_str();
CNetPlayer *pPlayer = playerId > MAX_PLAYERS ? NULL : m_pPlayers[playerId];
if(!pPlayer) return NULL;
return pPlayer->GetName();
};
CLocalPlayer * GetLocalPlayer() { return m_pLocalPlayer; }; CLocalPlayer * GetLocalPlayer() { return m_pLocalPlayer; };
void FUNC_10013960(); // .text:10013960
BOOL sub_10014090(PLAYERID playerId, BYTE byteReason); // .text:10014090
BOOL sub_10014250(PLAYERID playerId, PCHAR szPlayerName, BOOL bIsNPC); // .text:10014250
PLAYERID FUNC_100138C0(DWORD dwPedPtr); // .text:100138C0
CRemotePlayer* GetAt(PLAYERID playerId) { CRemotePlayer* GetAt(PLAYERID playerId) {
if(playerId > MAX_PLAYERS) { return NULL; } if(playerId > MAX_PLAYERS) { return NULL; }
CNetPlayer *pNetPlayer = m_pPlayers[playerId]; CNetPlayer *pNetPlayer = m_pPlayers[playerId];
@@ -46,7 +61,37 @@ public:
PLAYERID GetLocalPlayerID() { return m_LocalPlayerID; }; PLAYERID GetLocalPlayerID() { return m_LocalPlayerID; };
int GetSlotState(PLAYERID playerId) { if(playerId >= MAX_PLAYERS) return 0; return field_2A[playerId]; }
PCHAR FUNC_100175C0(int iPlayerId); // .text:100175C0
BOOL IsPlayerNPC(PLAYERID playerId) {
if(playerId > MAX_PLAYERS) return FALSE;
CNetPlayer *pPlayer = m_pPlayers[playerId];
if(!pPlayer) return FALSE;
return pPlayer->m_bIsNPC;
}
int GetPlayerScore(PLAYERID playerId) {
if(playerId > MAX_PLAYERS) return 0;
CNetPlayer *pPlayer = m_pPlayers[playerId];
if(!pPlayer) return 0;
return pPlayer->GetScore();
}
int GetPlayerPing(PLAYERID playerId) {
if(playerId > MAX_PLAYERS) return 0;
CNetPlayer *pPlayer = m_pPlayers[playerId];
if(!pPlayer) return 0;
return pPlayer->GetPing();
}
int GetPlayerCount(BOOL bIncludeNPCs); // .text:100139F0, todo: implement
class CObject *FUNC_10013B70(ENTITY_TYPE *pEntity); // todo: implement
void sub_10013C90(); // todo: implement
void sub_10013D10(); // todo: implement
CPlayerPool(); CPlayerPool();
~CPlayerPool(); // .text:10014120
}; };
//---------------------------------------------------- //----------------------------------------------------
File diff suppressed because it is too large Load Diff
+105 -11
View File
@@ -3,10 +3,41 @@
//---------------------------------------------------- //----------------------------------------------------
struct UNOCCUPIED_SYNC_DATA
{
VEHICLEID VehicleID;
BYTE byteSeatID;
VECTOR vecRoll;
VECTOR vecDirection;
VECTOR vecPos;
VECTOR vecMoveSpeed;
VECTOR vecTurnSpeed;
};
struct TRAILER_SYNC_DATA
{
VEHICLEID TrailerID;
VECTOR vecPos;
float quat[4];
VECTOR vecMoveSpeed;
VECTOR vecTurnSpeed;
};
// the bullet sync payload, 0x28 bytes on the wire
struct BULLET_SYNC_DATA
{
BYTE byteHitType;
WORD wHitID;
VECTOR vecHitOrigin;
VECTOR vecHitTarget;
VECTOR vecCenterOfHit;
BYTE byteWeaponID;
};
#pragma pack(1) #pragma pack(1)
class CRemotePlayer class CRemotePlayer
{ {
private: public:
//char _gap0[509]; //char _gap0[509];
int field_0; int field_0;
int field_4; int field_4;
@@ -21,30 +52,46 @@ private:
char field_8E[31]; char field_8E[31];
char field_AD[24]; char field_AD[24];
char field_C5[68]; // one 68-byte block: ResetAllSyncAttributes memsets it whole
struct {
char _pad0[18];
float quat[4]; // 0xD7
char _padE7[16];
VECTOR vecOffset; // 0xF7
WORD wVehicleID; // 0x103
int iAnimation; // 0x105
} field_C5;
char field_109; char field_109;
char field_10A; BYTE field_10A;
char field_10B; BYTE field_10B;
int field_10C; int field_10C;
int field_110; int field_110;
char _gap114[152]; char _gap114[76];
float field_160;
float field_164;
float field_168;
float quat16C[4];
VECTOR field_17C;
VECTOR field_188;
VECTOR field_194;
VECTOR field_1A0;
int field_1AC; float field_1AC;
int field_1B0; float field_1B0;
int field_1B4; int field_1B4;
char field_1B8; char field_1B8;
DWORD field_1B9; DWORD field_1B9;
DWORD field_1BD; int field_1BD;
int field_1C1; int field_1C1;
int field_1C5; int field_1C5;
char field_1C9[12]; VECTOR field_1C9;
DWORD field_1D5; DWORD field_1D5;
DWORD field_1D9; DWORD field_1D9;
CPlayerPed *m_pPlayerPed; CPlayerPed *m_pPlayerPed;
int field_1E1; CVehicle *field_1E1;
PLAYERID m_PlayerID; PLAYERID m_PlayerID;
short field_1E7; WORD field_1E7;
int field_1E9; int field_1E9;
int field_1ED; int field_1ED;
int field_1F1; int field_1F1;
@@ -61,8 +108,55 @@ public:
DWORD GetPlayerColorAsRGBA(); DWORD GetPlayerColorAsRGBA();
DWORD GetPlayerColorAsARGB(); DWORD GetPlayerColorAsARGB();
void FUNC_10017C80(BYTE byteValue) { field_4 = (byteValue != 0); }; // .text:10017C80
BOOL FUNC_10001080() { return m_pPlayerPed && field_10A; }; // .text:10001080
char FUNC_10014380() { return field_C; }; // .text:10014380
int FUNC_10014390() { return field_10C; }; // .text:10014390
void EnterVehicle(VEHICLEID VehicleID, BOOL bPassenger); void EnterVehicle(VEHICLEID VehicleID, BOOL bPassenger);
void ExitVehicle(); void ExitVehicle();
void FUNC_100143A0(); // .text:100143A0
void FUNC_10014500(int a1); // .text:10014500
void FUNC_10014540(short a1, short a2, short a3); // .text:10014540
void FUNC_10014650(); // .text:10014650
void FUNC_100148F0(); // .text:100148F0
void FUNC_10014FF0(); // .text:10014FF0
void FUNC_10017260(BYTE *pSync, int iTime); // .text:10017260
void FUNC_10014C40(); // .text:10014C40
void FUNC_10016370(BULLET_SYNC_DATA *pSync); // .text:10016370
void FUNC_10014950(); // .text:10014950
void FUNC_10015140(); // .text:10015140
void FUNC_100158D0(UNOCCUPIED_SYNC_DATA *pSync); // .text:100158D0
void FUNC_10015C90(TRAILER_SYNC_DATA *pTrailer); // .text:10015C90
void FUNC_10014E60(); // .text:10014E60
void FUNC_10015460(); // .text:10015460
void FUNC_10015760(BYTE *pAim); // .text:10015760
BOOL FUNC_10017130(int a1, int iSkin, int a3, VECTOR *pPos, float fRotation,
DWORD dwColor, BYTE byteStyle); // .text:10017130
void FUNC_10015650(MATRIX4X4 *pMat, VECTOR *pMoveSpeed, float fT); // .text:10015650
void FUNC_10017340(BYTE *pSync, int iTime); // .text:10017340
void FUNC_10017440(BYTE *pSync); // .text:10017440
void FUNC_10014800(); // .text:10014800
void FUNC_10017610(char *szText); // .text:10017610
void FUNC_100150D0(VECTOR *pPos, VECTOR *pMoveSpeed); // .text:100150D0
void FUNC_100155E0(int a1, VECTOR *pPos, VECTOR *pMoveSpeed); // .text:100155E0
void FUNC_10015760(char *pAimSync); // .text:10015760
void FUNC_10015C90(char *pTrailerSync); // .text:10015C90
void FUNC_10017440(char *pPassengerSync); // .text:10017440
BOOL FUNC_100145F0(); // .text:100145F0
void FUNC_10016270(BYTE byteNewState, BYTE byteOldState); // .text:10016270
void FUNC_100165B0(BYTE byteNewState); // .text:100165B0
BOOL FUNC_10014620(); // .text:10014620
void FUNC_10016660(); // .text:10016660
float FUNC_100160A0(CRemotePlayer *pOther); // .text:100160A0
float FUNC_10016120(); // .text:10016120
void sub_10017610(PCHAR szText); // .text:10017610
void FUNC_10017530(); // .text:10017530
void FUNC_10017570(); // .text:10017570
int FUNC_10016330(); // .text:10016330
}; };
//---------------------------------------------------- //----------------------------------------------------
+1751 -75
View File
File diff suppressed because it is too large Load Diff
+59
View File
@@ -2,6 +2,7 @@
#include "../main.h" #include "../main.h"
BOOL unnamed_100B2AF0(); BOOL unnamed_100B2AF0();
extern int dword_1026EB4C;
//---------------------------------------------------- //----------------------------------------------------
@@ -17,3 +18,61 @@ CTextDrawPool::CTextDrawPool()
} }
//---------------------------------------------------- //----------------------------------------------------
void CTextDrawPool::FUNC_1001E7F0(unsigned short TextDrawID)
{
CTextDraw *pTextDraw = (CTextDraw *)field_2400[TextDrawID];
if(pTextDraw) {
delete pTextDraw;
field_2400[TextDrawID] = 0;
field_0[TextDrawID] = 0;
}
}
//----------------------------------------------------
// MATCH
CTextDrawPool::~CTextDrawPool()
{
for(int i = 0; i < MAX_TEXT_DRAWS; i++) {
CTextDraw *pTextDraw = (CTextDraw *)field_2400[i];
if(pTextDraw) {
delete pTextDraw;
field_2400[i] = 0;
field_0[i] = 0;
}
}
}
//----------------------------------------------------
void CTextDrawPool::FUNC_1001E870()
{
for(int i = 0; i != MAX_TEXT_DRAWS; i++) {
if(field_0[i]) ((CTextDraw *)field_2400[i])->FUNC_100B34A0();
}
}
//----------------------------------------------------
void CTextDrawPool::FUNC_1001E8A0()
{
for(int i = 0; i != MAX_TEXT_DRAWS; i++) {
if(field_0[i]) ((CTextDraw *)field_2400[i])->FUNC_100B36B0();
}
}
//----------------------------------------------------
void CTextDrawPool::FUNC_1001E830()
{
int i = 0;
if(!dword_1026EB4C || !*(int *)dword_1026EB4C) {
while(i != MAX_TEXT_DRAWS) {
if(field_0[i]) ((CTextDraw *)field_2400[i])->FUNC_100B3480();
i++;
}
}
}
//----------------------------------------------------
+33
View File
@@ -3,13 +3,46 @@
//---------------------------------------------------- //----------------------------------------------------
class CTextDraw
{
public:
~CTextDraw(); // .text:100B2F50
void FUNC_100B3480(); // .text:100B3480
void FUNC_100B34A0(); // .text:100B34A0
void FUNC_100B36B0(); // .text:100B36B0
void FUNC_100B2F60(char *szText); // .text:100B2F60
};
//----------------------------------------------------
class CTextDrawPool class CTextDrawPool
{ {
private: private:
int field_0[MAX_TEXT_DRAWS]; int field_0[MAX_TEXT_DRAWS];
int field_2400[MAX_TEXT_DRAWS]; int field_2400[MAX_TEXT_DRAWS];
public: public:
int GetAt(unsigned short TextDrawID)
{
if(TextDrawID >= MAX_TEXT_DRAWS) return 0;
if(!field_0[TextDrawID]) return 0;
return field_2400[TextDrawID];
}
CTextDrawPool(); CTextDrawPool();
void FUNC_1001E7F0(unsigned short TextDrawID); // .text:1001E7F0
void FUNC_1001E830(); // .text:1001E830
void FUNC_1001E870(); // .text:1001E870
~CTextDrawPool(); // .text:1001E8D0
void FUNC_1001E8A0(); // .text:1001E8A0
// creates the slot's CTextDraw, replacing any existing one; returns it or 0
int FUNC_1001E910(unsigned short TextDrawID, char *pTransmit, char *szText); // .text:1001E910
}; };
//---------------------------------------------------- //----------------------------------------------------
+276
View File
@@ -1,5 +1,45 @@
#include "../main.h" #include "../main.h"
#include "../game/util.h"
extern CChatWindow *pChatWindow;
extern int dword_1026EBA0;
// same layout as the camera collision points that game/hooks.cpp passes around
typedef struct
{
VECTOR vecPos;
float field_C;
float field_10;
} CAMCOL_POINT;
char __stdcall FUNC_100B65D0(CAMCOL_POINT *pStart, CAMCOL_POINT *pEnd, ENTITY_TYPE *pEntity,
VECTOR *vecBoundCentre, float fScale, int a6); // .text:100B65D0
// the number plate renderer lives on a global, only its texture builder is needed here
class CPlateRenderer
{
public:
int FUNC_1006D880(char *szPlate); // .text:1006D880
};
// layout locks: these fail to compile if a field offset or the size moves
typedef char chk_CVehiclePool_size[sizeof(CVehiclePool) == 0x17898 ? 1 : -1];
typedef char chk_VEHICLE_WAITING_size[sizeof(VEHICLE_WAITING) == 40 ? 1 : -1];
typedef char chk_field_4[offsetof(CVehiclePool, field_4) == 4 ? 1 : -1];
typedef char chk_field_FA4[offsetof(CVehiclePool, field_FA4) == 0xFA4 ? 1 : -1];
typedef char chk_field_1134[offsetof(CVehiclePool, field_1134) == 0x1134 ? 1 : -1];
typedef char chk_field_3074[offsetof(CVehiclePool, field_3074) == 0x3074 ? 1 : -1];
typedef char chk_field_4FB4[offsetof(CVehiclePool, field_4FB4) == 0x4FB4 ? 1 : -1];
typedef char chk_field_9DD4[offsetof(CVehiclePool, field_9DD4) == 0x9DD4 ? 1 : -1];
typedef char chk_field_BD14[offsetof(CVehiclePool, field_BD14) == 0xBD14 ? 1 : -1];
typedef char chk_field_DC54[offsetof(CVehiclePool, field_DC54) == 0xDC54 ? 1 : -1];
typedef char chk_field_FB94[offsetof(CVehiclePool, field_FB94) == 0xFB94 ? 1 : -1];
typedef char chk_field_11AD4[offsetof(CVehiclePool, field_11AD4) == 0x11AD4 ? 1 : -1];
typedef char chk_field_17894[offsetof(CVehiclePool, field_17894) == 0x17894 ? 1 : -1];
typedef char chk_CVehicle_field_64[offsetof(CVehicle, field_64) == 0x64 ? 1 : -1];
typedef char chk_CVehicle_field_65[offsetof(CVehicle, field_65) == 0x65 ? 1 : -1];
typedef char chk_CVehicle_field_71[offsetof(CVehicle, field_71) == 0x71 ? 1 : -1];
//---------------------------------------------------- //----------------------------------------------------
@@ -18,3 +58,239 @@ CVehiclePool::CVehiclePool()
} }
//---------------------------------------------------- //----------------------------------------------------
int CVehiclePool::FindGtaIDFromID(int VehicleID)
{
if(field_4FB4[VehicleID]) return GamePool_Vehicle_GetIndex((VEHICLE_TYPE *)field_4FB4[VehicleID]);
return INVALID_VEHICLE_ID;
}
//----------------------------------------------------
void CVehiclePool::FUNC_1001E9B0()
{
int iHighest = 0;
for(int i = 0; i < MAX_VEHICLES; i++) {
if(field_3074[i]) iHighest = i;
}
field_0 = iHighest;
}
//----------------------------------------------------
int __stdcall FUNC_1001EBE0(VEHICLE_TYPE *pVehicle)
{
if(pVehicle) return GamePool_Vehicle_GetIndex(pVehicle);
return INVALID_VEHICLE_ID;
}
//----------------------------------------------------
short CVehiclePool::FUNC_1001EB90(int a1)
{
for(int i = 1; i <= field_0; i++) {
if(a1 == field_4FB4[i]) return i;
}
return -1;
}
//----------------------------------------------------
// MATCH
CVehiclePool::~CVehiclePool()
{
for(VEHICLEID VehicleID = 0; VehicleID < MAX_VEHICLES; VehicleID++) {
FUNC_1001EA80(VehicleID);
}
}
//----------------------------------------------------
void CVehiclePool::FUNC_1001EDE0()
{
for(VEHICLEID VehicleID = 0; VehicleID <= field_0; VehicleID++) {
if(field_3074[VehicleID]) ((CVehicle *)field_1134[VehicleID])->FUNC_100B81F0();
}
}
//----------------------------------------------------
void CVehiclePool::FUNC_1001EB00(unsigned short VehicleID, int a2)
{
if(field_3074[VehicleID]) ((CVehicle *)field_1134[VehicleID])->FUNC_100B7090(a2);
}
//----------------------------------------------------
int CVehiclePool::FUNC_1001EA80(unsigned short VehicleID)
{
if(VehicleID < MAX_VEHICLES && field_3074[VehicleID] && field_1134[VehicleID]) {
((CVehicle *)field_1134[VehicleID])->FUNC_100B81F0();
field_3074[VehicleID] = 0;
delete (CVehicle *)field_1134[VehicleID];
field_1134[VehicleID] = 0;
field_4FB4[VehicleID] = 0;
FUNC_1001E9B0();
return 1;
}
return 0;
}
//----------------------------------------------------
void CVehiclePool::FUNC_1001EB30(unsigned short VehicleID, char a2, BYTE a3)
{
if(VehicleID < MAX_VEHICLES && field_3074[VehicleID] && field_1134[VehicleID] && field_BD14[VehicleID]) {
CVehicle *pVehicle = (CVehicle *)field_1134[VehicleID];
if(a2) {
pVehicle->field_64 = 1;
pVehicle->field_65 = 0;
}
pVehicle->FUNC_100B7840(a3);
}
}
//----------------------------------------------------
int CVehiclePool::FUNC_1001EC00()
{
float fClosestDistance = 10000.0f;
VEHICLEID ClosestVehicleID = INVALID_VEHICLE_ID;
for(VEHICLEID VehicleID = 0; VehicleID <= field_0; VehicleID++) {
if(VehicleID < MAX_VEHICLES && field_3074[VehicleID] && field_BD14[VehicleID]) {
float fDistance = ((CVehicle *)field_1134[VehicleID])->FUNC_1009F0C0();
if(fDistance < fClosestDistance) {
fClosestDistance = fDistance;
ClosestVehicleID = VehicleID;
}
}
}
return ClosestVehicleID;
}
//----------------------------------------------------
void CVehiclePool::FUNC_1001ED70()
{
if(!field_17894) return;
if(dword_1026EBA0 && !*(DWORD *)(dword_1026EBA0 + 0x20))
*(DWORD *)(dword_1026EBA0 + 0x20) = ((CPlateRenderer *)dword_1026EBA0)->FUNC_1006D880("XYZSR998");
for(VEHICLEID VehicleID = 0; VehicleID <= field_0; VehicleID++) {
if(field_3074[VehicleID]) ((CVehicle *)field_1134[VehicleID])->FUNC_100B81A0();
}
}
//----------------------------------------------------
short CVehiclePool::FUNC_1001EEB0(int a1, VECTOR *vecOrigin, VECTOR *vecLine)
{
char colPoint[52];
DWORD dwHitEntity = 0;
ProcessLineOfSight(vecOrigin, vecLine, (VECTOR *)colPoint, &dwHitEntity, 0, 1, 0, 0, 0, 0, 0, 0);
if(!dwHitEntity) return -1;
// the sentinel has to stay on the loop exit path, folding it into the return narrows it to 16 bits
int iVehicleID;
for(int i = 1; ; i++) {
if(i > field_0) { iVehicleID = INVALID_VEHICLE_ID; break; }
if(dwHitEntity == field_4FB4[i]) { iVehicleID = i; break; }
}
return iVehicleID;
}
//----------------------------------------------------
char CVehiclePool::FUNC_1001EE20(VECTOR *vecStart, VECTOR *vecEnd)
{
for(int i = 0; i <= field_0; i++) {
if(field_3074[i] && field_1134[i]) {
CVehicle *pVehicle = (CVehicle *)field_1134[i];
if(pVehicle->IsAdded() && pVehicle->FUNC_1009F190() < 300.0f
&& !pVehicle->FUNC_1009FCE0()
&& pVehicle->FUNC_1009FC00(vecStart, vecEnd, 1)) return 1;
}
}
return 0;
}
//----------------------------------------------------
int CVehiclePool::FUNC_1001EC70(float fX, float fY, float fZ)
{
float fClosestDistance = 20000.0f;
VEHICLEID ClosestVehicleID = INVALID_VEHICLE_ID;
for(VEHICLEID VehicleID = 0; VehicleID <= field_0; VehicleID++) {
if(field_3074[VehicleID] && field_BD14[VehicleID]) {
float fDistance = ((CVehicle *)field_1134[VehicleID])->GetDistanceFromPoint(fX, fY, fZ);
if(fDistance < fClosestDistance) {
fClosestDistance = fDistance;
ClosestVehicleID = VehicleID;
}
}
}
return ClosestVehicleID;
}
//----------------------------------------------------
short CVehiclePool::FUNC_1001EF30(float fMaxDistance, VECTOR *vecStart, VECTOR *vecEnd, float fRadius)
{
CAMCOL_POINT colStart;
CAMCOL_POINT colEnd;
VECTOR vecBoundCentre;
// copying the points field by field is what keeps `vecStart` in a register over the walk
colStart.vecPos.X = vecStart->X;
colStart.vecPos.Y = vecStart->Y;
colStart.vecPos.Z = vecStart->Z;
colStart.field_C = fRadius;
colEnd.vecPos.X = vecEnd->X;
colEnd.vecPos.Y = vecEnd->Y;
colEnd.vecPos.Z = vecEnd->Z;
colEnd.field_C = fRadius;
float fClosestDistance = 100000.0f;
VEHICLEID ClosestVehicleID = INVALID_VEHICLE_ID;
for(int i = 0; i <= field_0; i++) {
if(field_3074[i] && field_1134[i]) {
CVehicle *pVehicle = (CVehicle *)field_1134[i];
if(pVehicle->IsAdded() && pVehicle->FUNC_1009F190() < fMaxDistance && !pVehicle->FUNC_100B7420()) {
pVehicle->GetBoundCentre(&vecBoundCentre);
if(FUNC_100B65D0(&colStart, &colEnd, pVehicle->m_pEntity, &vecBoundCentre, 1.0f, 1)) {
float fDistance = pVehicle->GetDistanceFromPoint(vecStart->X, vecStart->Y, vecStart->Z);
if(fDistance < fClosestDistance) {
fClosestDistance = fDistance;
ClosestVehicleID = i;
}
}
}
}
}
return ClosestVehicleID;
}
//----------------------------------------------------
int CVehiclePool::FUNC_1001ED10(VEHICLE_WAITING *pWaiting)
{
// do/while with a `!=` bound, a for or while here gets unrolled or rotated
int i = 0;
do {
if(!field_FA4[i]) break;
i++;
} while(i != MAX_WAITING_VEHICLES);
if(i == MAX_WAITING_VEHICLES)
return pChatWindow->AddDebugMessage("All vehicle waiting slots are consumed!");
field_FA4[i] = 1;
field_4[i] = *pWaiting;
return i;
}
//----------------------------------------------------
+58 -4
View File
@@ -1,6 +1,17 @@
#pragma once #pragma once
#define INVALID_VEHICLE_ID 0xFFFF
#define MAX_WAITING_VEHICLES 100
//----------------------------------------------------
// a vehicle the pool cannot create yet is parked in one of these; the payload layout is unresolved
struct VEHICLE_WAITING
{
char field_0[40];
};
//---------------------------------------------------- //----------------------------------------------------
class CVehiclePool class CVehiclePool
@@ -8,21 +19,64 @@ class CVehiclePool
public: public:
int field_0; int field_0;
char _gap4[4000]; VEHICLE_WAITING field_4[MAX_WAITING_VEHICLES];
char field_FA4[400]; int field_FA4[MAX_WAITING_VEHICLES];
int field_1134[MAX_VEHICLES]; int field_1134[MAX_VEHICLES];
int field_3074[MAX_VEHICLES]; int field_3074[MAX_VEHICLES];
int field_4FB4[MAX_VEHICLES]; int field_4FB4[MAX_VEHICLES];
char _gap6EF4[12000]; char _gap6EF4[8000];
WORD field_8E34[MAX_VEHICLES];
DWORD field_9DD4[MAX_VEHICLES]; DWORD field_9DD4[MAX_VEHICLES];
char _gapBD14[48000]; int field_BD14[MAX_VEHICLES];
int field_DC54[MAX_VEHICLES];
int field_FB94[MAX_VEHICLES];
VECTOR field_11AD4[MAX_VEHICLES];
int field_17894; int field_17894;
int GetSlotState(unsigned short VehicleID) { if(VehicleID >= MAX_VEHICLES) return 0; return field_3074[VehicleID]; }
int GetAt(unsigned short VehicleID)
{
if(VehicleID < MAX_VEHICLES && field_3074[VehicleID]) return field_1134[VehicleID];
return 0;
}
void FUNC_1001E9B0(); // .text:1001E9B0
int FUNC_1001EA80(unsigned short VehicleID); // .text:1001EA80
~CVehiclePool(); // .text:1001F060
void FUNC_1001EB00(unsigned short VehicleID, int a2); // .text:1001EB00
void FUNC_1001EB30(unsigned short VehicleID, char a2, BYTE a3); // .text:1001EB30
void FUNC_1001EDE0(); // .text:1001EDE0
short FUNC_1001EB90(int a1); // .text:1001EB90
int FindGtaIDFromID(int VehicleID); // .text:1001EBC0
int FUNC_10001120(unsigned short a1); // .text:10001120
int FUNC_1001EC00(); // .text:1001EC00
int FUNC_1001ED10(VEHICLE_WAITING *pWaiting); // .text:1001ED10
int FUNC_1001EC70(float fX, float fY, float fZ); // .text:1001EC70
short FUNC_1001EF30(float fMaxDistance, VECTOR *vecStart, VECTOR *vecEnd, float fRadius); // .text:1001EF30
short FUNC_1001EEB0(int a1, VECTOR *vecOrigin, VECTOR *vecLine); // .text:1001EEB0
void FUNC_1001ED70(); // .text:1001ED70
char FUNC_1001EE20(VECTOR *vecStart, VECTOR *vecEnd); // .text:1001EE20
CVehiclePool(); CVehiclePool();
}; };
+84
View File
@@ -26,6 +26,8 @@ HealthBarVertices1_s HealthBarVertices1[4] =
}; };
extern D3DXMATRIX matView, matProj; extern D3DXMATRIX matView, matProj;
extern CFontRender *pDefaultFont;
extern CDeathWindow *pDeathWindow;
CNewPlayerTags::CNewPlayerTags(IDirect3DDevice9* pDevice) CNewPlayerTags::CNewPlayerTags(IDirect3DDevice9* pDevice)
{ {
@@ -76,6 +78,88 @@ void CNewPlayerTags::End()
m_pStates->Apply(); m_pStates->Apply();
} }
// the nametag pass brackets its batch with these two instead of Begin/End
void CNewPlayerTags::FUNC_1006CD80()
{
if(m_pSprite)
m_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
}
void CNewPlayerTags::FUNC_1006CD90()
{
if(m_pSprite)
m_pSprite->End();
}
void CNewPlayerTags::Draw(D3DXVECTOR3* pPlayerPos, PCHAR szName, DWORD dwColor, float fDistanceFromLocalPlayer,
BYTE bNameTagStatus, int nStatusStyle)
{
D3DXVECTOR3 TagPos = *pPlayerPos;
TagPos.z += 0.2f + (fDistanceFromLocalPlayer * 0.0475f);
D3DVIEWPORT9 Viewport;
m_pDevice->GetViewport(&Viewport);
D3DXVECTOR3 Out;
D3DXMATRIX matIdent;
D3DXMatrixIdentity(&matIdent);
D3DXVec3Project(&Out, &TagPos, &Viewport, &matProj, &matView, &matIdent);
if(Out.z > 1.0f)
return;
RECT rectStatus;
rectStatus.left = (int)Out.x;
rectStatus.top = (int)Out.y;
rectStatus.right = (int)Out.x;
rectStatus.bottom = (int)Out.y;
RECT rectText = rectStatus;
SIZE size = pDefaultFont->MeasureText2(szName, 0);
rectText.left -= size.cx / 2;
rectText.right += size.cx / 2;
rectText.top += 17 - size.cy;
pDefaultFont->RenderText(m_pSprite, szName, rectText, 256, dwColor, 1);
if(bNameTagStatus)
{
if(pDeathWindow)
{
if(!pDeathWindow->field_14B)
pDeathWindow->CreateAuxFonts();
ID3DXFont *pFont1 = pDeathWindow->field_14F;
ID3DXFont *pFont2 = pDeathWindow->field_153;
if(pFont1 && pFont2)
{
RECT rectCalc;
rectCalc.left = 0;
rectCalc.top = 0;
rectCalc.right = 0;
rectCalc.bottom = 0;
pFont2->DrawText(NULL, "C", 1, &rectCalc, DT_CALCRECT|DT_NOCLIP|DT_VCENTER|DT_CENTER, 0);
rectStatus.top += (rectCalc.bottom - rectCalc.top) / 2 + 17;
rectStatus.bottom = rectStatus.top + 2;
rectStatus.left += -22 - (rectCalc.right - rectCalc.left) / 2;
rectStatus.right = rectStatus.left + 1;
if(nStatusStyle == 2)
{
pFont2->DrawText(NULL, "C", 1, &rectStatus, DT_NOCLIP|DT_VCENTER|DT_CENTER, 0xFF000000);
rectStatus.top -= 2;
rectStatus.left--;
pFont1->DrawText(NULL, "E", 1, &rectStatus, DT_NOCLIP|DT_VCENTER|DT_CENTER, 0xFFE3E1E3);
}
}
}
}
}
void CNewPlayerTags::DeleteDeviceObjects() void CNewPlayerTags::DeleteDeviceObjects()
{ {
SAFE_RELEASE(m_pStates); SAFE_RELEASE(m_pStates);
+5
View File
@@ -25,7 +25,12 @@ public:
void Begin(); void Begin();
void End(); void End();
void FUNC_1006CD80();
void FUNC_1006CD90();
void Draw(D3DXVECTOR3* pPlayerPos, float fHealth, float fArmor, float fDistanceFromLocalPlayer); void Draw(D3DXVECTOR3* pPlayerPos, float fHealth, float fArmor, float fDistanceFromLocalPlayer);
// the nametag label pass, 0x1006CDA0
void Draw(D3DXVECTOR3* pPlayerPos, PCHAR szName, DWORD dwColor, float fDistanceFromLocalPlayer,
BYTE bNameTagStatus, int nStatusStyle);
void DeleteDeviceObjects(); void DeleteDeviceObjects();
void RestoreDeviceObjects(); void RestoreDeviceObjects();
+16
View File
@@ -79,6 +79,7 @@
OmitFramePointers="TRUE" OmitFramePointers="TRUE"
AdditionalIncludeDirectories="d3d9\include\" AdditionalIncludeDirectories="d3d9\include\"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SACO_EXPORTS;SAMPCLI" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SACO_EXPORTS;SAMPCLI"
StringPooling="TRUE"
ExceptionHandling="TRUE" ExceptionHandling="TRUE"
RuntimeLibrary="0" RuntimeLibrary="0"
StructMemberAlignment="1" StructMemberAlignment="1"
@@ -329,6 +330,12 @@
<File <File
RelativePath=".\net\actorpool.h"> RelativePath=".\net\actorpool.h">
</File> </File>
<File
RelativePath=".\net\downloader.cpp">
</File>
<File
RelativePath=".\net\downloader.h">
</File>
<File <File
RelativePath=".\net\gangzonepool.cpp"> RelativePath=".\net\gangzonepool.cpp">
</File> </File>
@@ -1003,6 +1010,12 @@
</File> </File>
<File <File
RelativePath=".\d3d9\dxutil.cpp"> RelativePath=".\d3d9\dxutil.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="2"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\d3d9\include\dxutil.h"> RelativePath=".\d3d9\include\dxutil.h">
@@ -1054,6 +1067,9 @@
<File <File
RelativePath=".\d3d9\common\DXUTSettingsDlg.h"> RelativePath=".\d3d9\common\DXUTSettingsDlg.h">
</File> </File>
<File
RelativePath=".\d3d9\common\DXUTUniBuffer.cpp">
</File>
</Filter> </Filter>
<Filter <Filter
Name="temp" Name="temp"
+166 -3
View File
@@ -2,6 +2,14 @@
#include "main.h" #include "main.h"
extern CGame* pGame; extern CGame* pGame;
extern CNetGame *pNetGame;
// retail walks these rows with calloc(n, 45); lock the layout so a field edit cannot drift it
typedef char SCOREBOARD_ROW_size_probe[sizeof(SCOREBOARD_ROW) == 45 ? 1 : -1];
typedef char SCOREBOARD_ROW_name_probe[offsetof(SCOREBOARD_ROW, szName) == 4 ? 1 : -1];
typedef char SCOREBOARD_ROW_id_probe[offsetof(SCOREBOARD_ROW, iPlayerId) == 0x21 ? 1 : -1];
typedef char SCOREBOARD_ROW_score_probe[offsetof(SCOREBOARD_ROW, iScore) == 0x25 ? 1 : -1];
typedef char SCOREBOARD_ROW_ping_probe[offsetof(SCOREBOARD_ROW, iPing) == 0x29 ? 1 : -1];
CScoreBoard::CScoreBoard(IDirect3DDevice9 *pD3DDevice) CScoreBoard::CScoreBoard(IDirect3DDevice9 *pD3DDevice)
{ {
@@ -58,12 +66,167 @@ void CScoreBoard::ResetDialogControls(CDXUTDialog *pDialog)
m_pListBox->OnInit(); m_pListBox->OnInit();
m_pListBox->GetElement(0)->TextureColor.Init(D3DCOLOR_ARGB( 200, 255, 255, 255 )); m_pListBox->GetElement(0)->TextureColor.Init(D3DCOLOR_ARGB( 200, 255, 255, 255 ));
m_pListBox->field_4D = 3; m_pListBox->field_4D = 3;
m_pListBox->field_51 = field_24 * field_14; m_pListBox->field_51[0] = field_24 * field_14;
m_pListBox->field_59 = field_28 * field_14; m_pListBox->field_51[2] = field_28 * field_14;
m_pListBox->field_55 = field_2C * field_14; m_pListBox->field_51[1] = field_2C * field_14;
m_pListBox->SetEnabled(false); m_pListBox->SetEnabled(false);
m_pListBox->SetVisible(false); m_pListBox->SetVisible(false);
FUNC_1006E930(); FUNC_1006E930();
} }
} }
void CScoreBoard::GetRect(RECT *pRect)
{
pRect->left = (int)field_8;
pRect->right = pRect->left + (int)field_14;
pRect->top = (int)field_C;
pRect->bottom = pRect->top + (int)field_18;
}
void CScoreBoard::Hide(bool bResetInput)
{
if(!field_0) return;
if(!m_pDialog) return;
m_pDialog->SetVisible(false);
m_pListBox->SetEnabled(false);
m_pListBox->SetVisible(false);
if(bResetInput)
pGame->ToggleKeyInputsDisabled(0, FALSE);
field_0 = 0;
}
// swapping rows through a temp is what retail inlines at both sort sites
inline void SwapScoreboardRows(SCOREBOARD_ROW *pA, SCOREBOARD_ROW *pB)
{
SCOREBOARD_ROW tmp = *pA;
*pA = *pB;
*pB = tmp;
}
void CScoreBoard::FUNC_1006ED30()
{
if(!pNetGame) return;
if(!pNetGame->GetPlayerPool()) return;
if(!field_0) return;
if(!m_pDialog) return;
int nSelected = m_pListBox->GetSelectedIndex();
CDXUTScrollBar *pScrollBar = m_pListBox->GetScrollBar();
int nTrackPos = pScrollBar->GetTrackPos();
m_pListBox->RemoveAllItems();
CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool();
int nRows = pPlayerPool->GetPlayerCount(0) + 1;
int localPlayerId = pPlayerPool->GetLocalPlayerID();
SCOREBOARD_ROW *pRows = (SCOREBOARD_ROW *)calloc(nRows, sizeof(SCOREBOARD_ROW));
strcpy(pRows->szName, pPlayerPool->GetLocalPlayerName());
pRows->Color = pPlayerPool->GetLocalPlayer()->GetPlayerColorAsARGB();
pRows->iScore = pPlayerPool->field_0;
pRows->iPing = pPlayerPool->field_22;
pRows->iPlayerId = pPlayerPool->GetLocalPlayerID();
SCOREBOARD_ROW *pRow = pRows + 1;
for(int playerId = 0; playerId < MAX_PLAYERS; playerId++)
{
if(pPlayerPool->GetSlotState((PLAYERID)playerId) != 1) continue;
if(playerId == localPlayerId) continue;
if(pPlayerPool->IsPlayerNPC((PLAYERID)playerId)) continue;
pRow->iPing = pPlayerPool->GetPlayerPing((PLAYERID)playerId);
strcpy(pRow->szName, pPlayerPool->FUNC_100175C0(playerId));
pRow->iScore = pPlayerPool->GetPlayerScore((PLAYERID)playerId);
pRow->Color = pPlayerPool->GetAt((PLAYERID)playerId)->GetPlayerColorAsARGB();
pRow->iPlayerId = playerId;
pRow++;
}
if(field_40 == 1)
{
for(int i = nRows - 1; i > 0; i--)
for(int j = 0; j < i; j++)
if(strcmp(pRows[j + 1].szName, pRows[j].szName) < 0)
SwapScoreboardRows(&pRows[j], &pRows[j + 1]);
}
else if(field_40 == 2)
{
for(int i = nRows - 1; i > 0; i--)
for(int j = 0; j < i; j++)
if(pRows[j + 1].iScore > pRows[j].iScore)
SwapScoreboardRows(&pRows[j], &pRows[j + 1]);
}
char szText[256];
SCOREBOARD_ROW *pFill = pRows;
for(int i = 0; i < nRows; i++)
{
sprintf(szText, "%u", pFill->iPlayerId);
m_pListBox->AddItem(szText, (void *)pFill->iPlayerId, pFill->Color);
if(m_pListBox->GetItem(i) && pFill->szName[0])
{
m_pListBox->SetItemColumnText(i, 0, pFill->szName);
sprintf(szText, "%d", pFill->iScore);
m_pListBox->SetItemColumnText(i, 1, szText);
sprintf(szText, "%u", pFill->iPing);
m_pListBox->SetItemColumnText(i, 2, szText);
}
pFill++;
}
if(nSelected < 0)
m_pListBox->SelectItem(-1);
else
m_pListBox->SelectItem(nSelected);
free(pRows);
pScrollBar->SetTrackPos(nTrackPos);
}
void CScoreBoard::Show()
{
if(field_0) return;
if(!m_pDialog) return;
m_pDialog->SetVisible(true);
m_pListBox->SetEnabled(true);
m_pListBox->UpdateRects();
m_pListBox->SetVisible(true);
FUNC_1006ED30();
pGame->ToggleKeyInputsDisabled(3, FALSE);
field_0 = 1;
}
void CScoreBoard::ClickPlayer()
{
if(!field_0) return;
if(!m_pDialog) return;
DXUTListBoxItem *pItem = m_pListBox->GetSelectedItem();
if(pItem)
{
PLAYERID playerId = (PLAYERID)atoi(pItem->strText);
RakNet::BitStream bsSend;
bsSend.Write(playerId);
bsSend.Write((BYTE)0);
pNetGame->GetRakClient()->RPC(RPC_ClickPlayer, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE);
}
if(!field_0) return;
if(!m_pDialog) return;
m_pDialog->SetVisible(false);
m_pListBox->SetEnabled(false);
m_pListBox->SetVisible(false);
pGame->ToggleKeyInputsDisabled(0, FALSE);
field_0 = 0;
}
+14
View File
@@ -1,6 +1,15 @@
#pragma once #pragma once
struct SCOREBOARD_ROW
{
D3DCOLOR Color;
char szName[29];
int iPlayerId;
int iScore;
int iPing;
};
class CScoreBoard class CScoreBoard
{ {
private: private:
@@ -27,4 +36,9 @@ public:
void FUNC_1006E930(); void FUNC_1006E930();
void ResetDialogControls(CDXUTDialog *pDialog); void ResetDialogControls(CDXUTDialog *pDialog);
void GetRect(RECT *pRect);
void FUNC_1006ED30();
void Show();
void ClickPlayer();
void Hide(bool bResetInput);
}; };
+101 -2
View File
@@ -1,6 +1,9 @@
#include "main.h" #include "main.h"
extern CGame *pGame;
extern D3DXMATRIX matView, matProj;
CUnkClass10::CUnkClass10(IDirect3DDevice9 *pD3DDevice) CUnkClass10::CUnkClass10(IDirect3DDevice9 *pD3DDevice)
{ {
m_pD3DDevice = pD3DDevice; m_pD3DDevice = pD3DDevice;
@@ -19,8 +22,104 @@ CUnkClass10::CUnkClass10(IDirect3DDevice9 *pD3DDevice)
D3DXCreateLine(pD3DDevice, &m_pD3DLine); D3DXCreateLine(pD3DDevice, &m_pD3DLine);
D3DXCreateFont(m_pD3DDevice, 22, 0, FW_NORMAL, 1, FALSE, D3DXCreateFont(pD3DDevice, 22, 0, FW_NORMAL, 1, FALSE,
SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "SAMPAUX3", &m_pD3DFont1); SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "SAMPAUX3", &m_pD3DFont1);
D3DXCreateFont(m_pD3DDevice, 28, 0, FW_NORMAL, 1, FALSE, D3DXCreateFont(pD3DDevice, 28, 0, FW_NORMAL, 1, FALSE,
SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "SAMPAUX3", &m_pD3DFont2); SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "SAMPAUX3", &m_pD3DFont2);
} }
float CUnkClass10::FUNC_10071C20(D3DXVECTOR3 *pPos, D3DXVECTOR2 *pOut)
{
D3DXVECTOR3 In = *pPos;
D3DVIEWPORT9 Viewport;
D3DXVECTOR3 Out;
D3DXMATRIX matIdent;
m_pD3DDevice->GetViewport(&Viewport);
D3DXMatrixIdentity(&matIdent);
D3DXVec3Project(&Out, &In, &Viewport, &matProj, &matView, &matIdent);
pOut->x = Out.x;
pOut->y = Out.y;
return Out.z;
}
PCHAR CUnkClass10::FUNC_10071F90()
{
return "C";
}
// SAMPAUX3 glyph for the marker style in field_7C
PCHAR CUnkClass10::FUNC_10071FA0(int nIndex)
{
if(nIndex == 0)
{
if(field_7C == 0) return "6";
if(field_7C == 1) return "3";
if(field_7C == 2) return "9";
}
else if(nIndex == 1)
{
if(field_7C == 0) return "7";
if(field_7C == 1) return "4";
if(field_7C == 2) return "A";
}
else if(nIndex == 2)
{
if(field_7C == 0) return "8";
if(field_7C == 1) return "5";
if(field_7C == 2) return "B";
}
return "0";
}
void CUnkClass10::FUNC_10072040(RECT *pRect, POINT *pPoint)
{
pRect->left = pPoint->x - field_0 / 2;
pRect->right = pRect->left + field_0;
pRect->top = pPoint->y - field_4 / 2;
pRect->bottom = pRect->top + field_4;
}
// picks the hovered cell out of the seven hit rects
void CUnkClass10::FUNC_100720A0()
{
POINT point;
GetCursorPos(&point);
ScreenToClient(pGame->GetMainWindowHwnd(), &point);
if(!field_84) field_113 = -1;
else if(!pGame->field_61) field_113 = -1;
else if(PtInRect(&field_8[0], point)) field_113 = 0;
else if(PtInRect(&field_8[1], point)) field_113 = 1;
else if(PtInRect(&field_8[2], point)) field_113 = 2;
else if(PtInRect(&field_8[3], point)) field_113 = 3;
else if(PtInRect(&field_8[4], point)) field_113 = 4;
else if(PtInRect(&field_8[5], point)) field_113 = 5;
else field_113 = PtInRect(&field_8[6], point) ? 10 : -1;
}
void CUnkClass10::FUNC_100721F0(int nStyle)
{
if(field_78 == 1 && nStyle == 2)
nStyle = 0;
field_7C = nStyle;
}
BOOL CUnkClass10::FUNC_100723C0()
{
RECT rect;
GetClientRect(pGame->GetMainWindowHwnd(), &rect);
field_A7 = (rect.right - rect.left) / 2;
field_AB = (rect.bottom - rect.top) / 2;
return SetCursorPos(field_A7, field_AB);
}
+17 -2
View File
@@ -4,7 +4,9 @@
class CUnkClass10 class CUnkClass10
{ {
private: private:
char _gap0[120]; int field_0;
int field_4;
RECT field_8[7];
int field_78; int field_78;
int field_7C; int field_7C;
int field_80; int field_80;
@@ -17,7 +19,9 @@ private:
char field_A4; char field_A4;
char field_A5; char field_A5;
char field_A6; char field_A6;
char _gapA7[92]; int field_A7;
int field_AB;
char _gapAF[84];
IDirect3DDevice9 *m_pD3DDevice; IDirect3DDevice9 *m_pD3DDevice;
ID3DXLine *m_pD3DLine; ID3DXLine *m_pD3DLine;
ID3DXFont *m_pD3DFont1; ID3DXFont *m_pD3DFont1;
@@ -25,6 +29,17 @@ private:
int field_113; int field_113;
public: public:
int GetField80() { return field_80; }; // .text:10002E70, out of line copy
CUnkClass10(IDirect3DDevice9 *pD3DDevice); CUnkClass10(IDirect3DDevice9 *pD3DDevice);
float FUNC_10071C20(D3DXVECTOR3 *pPos, D3DXVECTOR2 *pOut);
PCHAR FUNC_10071F90();
PCHAR FUNC_10071FA0(int nIndex);
void FUNC_10072040(RECT *pRect, POINT *pPoint);
void FUNC_100720A0();
void FUNC_100721F0(int nStyle);
BOOL FUNC_100723C0();
}; };
+2 -1
View File
@@ -15,7 +15,8 @@ CUnkClass3::CUnkClass3(IDirect3DDevice9 *pD3DDevice)
field_10 = 300; field_10 = 300;
field_14 = 100; field_14 = 100;
field_18 = 30; field_18 = 30;
memset(field_89, 0, sizeof(field_89)); // retail zeroes this with a loop, not memset: the inline rep stosd sets edi up first
for(int i = 0; i < 516; i++) field_89[i] = 0;
} }
void CUnkClass3::ResetDialogControls(CDXUTDialog *pDialog) void CUnkClass3::ResetDialogControls(CDXUTDialog *pDialog)
+2
View File
@@ -25,4 +25,6 @@ public:
CUnkClass3(IDirect3DDevice9 *pD3DDevice); CUnkClass3(IDirect3DDevice9 *pD3DDevice);
void ResetDialogControls(CDXUTDialog *pDialog); void ResetDialogControls(CDXUTDialog *pDialog);
int GetField28() { return field_28; }; // .text:10002E60, out of line copy
}; };
+32 -5
View File
@@ -1,10 +1,37 @@
#include "main.h" #include "main.h"
CIntArray::~CIntArray()
{
SetSize(0);
}
bool CIntArray::SetSize(unsigned int nSize)
{
if(!nSize) {
if(m_pData) {
free(m_pData);
m_pData = NULL;
}
m_nSize = 0;
return true;
}
int *pNew = (int *)realloc(m_pData, nSize * sizeof(int));
if(!pNew) return false;
m_pData = pNew;
if(m_nSize < nSize) {
for(unsigned int i = m_nSize; i != nSize; i++)
m_pData[i] = 0;
}
m_nSize = nSize;
return true;
}
CUnkClass5::CUnkClass5(IDirect3DDevice9 *pD3DDevice) CUnkClass5::CUnkClass5(IDirect3DDevice9 *pD3DDevice)
{ {
field_0 = 0;
field_4 = 0;
m_pD3DDevice = pD3DDevice; m_pD3DDevice = pD3DDevice;
m_pDialog = NULL; m_pDialog = NULL;
field_30 = 0; field_30 = 0;
@@ -22,9 +49,9 @@ CUnkClass5::CUnkClass5(IDirect3DDevice9 *pD3DDevice)
field_240 = 220; field_240 = 220;
field_24C = 0; field_24C = 0;
field_250 = -1; field_250 = -1;
field_254 = RakNet::GetTime();
field_25C = 0; field_25C = 0;
field_258 = 0; field_258 = 0;
field_254 = RakNet::GetTime();
} }
void CUnkClass5::ResetDialogControls(CDXUTDialog *pDialog) void CUnkClass5::ResetDialogControls(CDXUTDialog *pDialog)
@@ -41,7 +68,7 @@ void CUnkClass5::ResetDialogControls(CDXUTDialog *pDialog)
m_pListBox->SetEnabled(false); m_pListBox->SetEnabled(false);
m_pListBox->SetVisible(false); m_pListBox->SetVisible(false);
m_pListBox->field_4D = 2; m_pListBox->field_4D = 2;
m_pListBox->field_51 = field_23C; m_pListBox->field_51[0] = field_23C;
m_pListBox->field_55 = field_240; m_pListBox->field_51[1] = field_240;
} }
} }
+13 -2
View File
@@ -1,11 +1,22 @@
#pragma once #pragma once
class CIntArray
{
public:
CIntArray() { m_pData = NULL; m_nSize = 0; }
~CIntArray();
bool SetSize(unsigned int nSize);
int *m_pData;
unsigned int m_nSize;
};
class CUnkClass5 class CUnkClass5
{ {
private: private:
int field_0; CIntArray m_Array;
int field_4;
IDirect3DDevice9* m_pD3DDevice; IDirect3DDevice9* m_pD3DDevice;
char _gapC[8]; char _gapC[8];
int field_14; int field_14;