Well hello.
I don't think anyone else has showed how this can be done. Anyways, I've looked in ETSDK where it draws the loading screen. This function took my attention: 'CG_DrawConnectScreen'. So I loaded up the ETPro module in IDA, since it contains a few text strings, it wasn't very hard to find it.
The function where it is called is then (in pseudocode)
Looking a little further, I found the function where it processes the 'loading bar': 'void CG_LoadPanel_RenderLoadingBar'.
The only line that caught my attention there was the trap function: 'trap_GetHunkData( &hunkUsed, &hunkExpected );'.
Now lets hook the call and block it, so we can overwrite it with our own loadingscreen.
When we draw where snap ain't set yet, we will draw in the loadingscreen.
And finally, where we draw the loading bar and some text:
This is very close to copy/pasting. But credit whenever you use
Shout: sp00f, King Horny and ETSDK
Uploading a screenshot in the attachment. The red bar on the top shows the loading progress.
Regards,
mOwl
I don't think anyone else has showed how this can be done. Anyways, I've looked in ETSDK where it draws the loading screen. This function took my attention: 'CG_DrawConnectScreen'. So I loaded up the ETPro module in IDA, since it contains a few text strings, it wasn't very hard to find it.
Code:
CG_Text_Paint_Centred_Ext( 540, y, 0.2f, 0.2f, colorWhite, str && *str ? str : [b]"ETHost"[/b], 0, 26, 0, &bg_loadscreenfont2 );
Code:
.text:30066835 loc_30066835: ; CODE XREF: sub_30066080+437j
.text:30066835 ; sub_30066080+440j
.text:30066835 mov eax, offset aEthost ; "ETHost"
.text:3006683A jmp loc_300664C6
The function where it is called is then (in pseudocode)
Code:
void __cdecl sub_30066080(int a1, int a2)
Looking a little further, I found the function where it processes the 'loading bar': 'void CG_LoadPanel_RenderLoadingBar'.
The only line that caught my attention there was the trap function: 'trap_GetHunkData( &hunkUsed, &hunkExpected );'.
Now lets hook the call and block it, so we can overwrite it with our own loadingscreen.
Code:
[b]CHooks class:[/b]
typedef void (WINAPIV *cg_loadingScreen_t)(qboolean a1, qboolean a2);
static void h_CG_LoadingScreen(qboolean a1, qboolean a2);
cg_loadingScreen_t o_CG_LoadingScreen;
[b]Hooking:[/b]
hooks.o_CG_LoadingScreen = (cg_loadingScreen_t) Detour((BYTE *)main.hCgame + 0x066080, h_CG_LoadingScreen);
[b]Hooked function:[/b]
void CHooks::h_CG_LoadingScreen(qboolean valid, qboolean refresh)
{
//engine.h_LoadingScreen(refresh, 1);
if (!valid)
return;
hooks.o_CG_LoadingScreen(valid, refresh);
}
When we draw where snap ain't set yet, we will draw in the loadingscreen.
Code:
void CEngine::h_DrawActiveFrame_Pre(int serverTime, int stereoView, int demoPlayback)
{
if (!loading)
this->drawAtLoading();
if (!engine.cg_snap)
return;
loading = true;
}
And finally, where we draw the loading bar and some text:
Code:
void CEngine::drawAtLoading()
{
char print[1024];
// Background
draw.drawFillRect(0, 0, 640, 480, colorBlack);
// Loading bar
float loadPercent;
int hunkUsed, hunkNeeded;
hooks.o_syscall(CG_GETHUNKDATA, &hunkUsed, &hunkNeeded);
if ( hunkNeeded <= 0 )
return;
loadPercent = hunkUsed / (float)hunkNeeded;
if ( loadPercent < 0.f ) loadPercent = 0.f;
if ( loadPercent > 1.f ) loadPercent = 1.f;
vec4_t loadclr = {1, 0, 0, 0.5};
draw.drawFillRect(0, 0, 640*loadPercent, 5, loadclr);
draw.drawFillRect(0, 480-5, 640*loadPercent, 5, loadclr);
// Draw title and loading percentage
draw.drawTextCenterScreen(50, 0.17, "^7ET^1:^7ProtoType", false, colorWhite);
float percent = (float)(loadPercent * 100);
sprintf_s(print, sizeof(print), "^7Loading: %1.1f percent", percent);
draw.drawTextCenterScreen(60, 0.15, print, false, colorWhite);
}
This is very close to copy/pasting. But credit whenever you use
Shout: sp00f, King Horny and ETSDK
Uploading a screenshot in the attachment. The red bar on the top shows the loading progress.
Regards,
mOwl