.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   Half-Life 1 SDK (http://forums.bots-united.com/forumdisplay.php?f=33)
-   -   Lightmap performance drop (http://forums.bots-united.com/showthread.php?t=3485)

Lazy 26-01-2005 20:47

Lightmap performance drop
 
This has been bugging the hell out of me, for some reason the Half-Life engine chokes when there are no lightmaps to be drawn.
I had an idea for nightvision that wouldn't have to rely on dynamic lights but disable the lightmaps which would make the world fullbright and then I could draw over the screen for the nv effect.
I'm able to disable the lightmaps fine but the engine takes a very noticable performance hit of anywhere between 10-30fps, I thought the engine would have LESS to do...
And after the world has been made fullbright it won't go back, even after the surfaces have been restored the world stays the same.

Any ideas why this is happening?

Note: Thrown together code
Code:

#include <windows.h>
#include "hud.h"
#include "cl_util.h"

#include <vector>

#define HARDWARE_MODE
#include "com_model.h"

typedef struct {
  int cached_light[ MAXLIGHTMAPS ];
  int msurface_index;
}
lightdatasave_t;

std::vector< lightdatasave_t >g_vSavedlights;
void* g_pLightdata = NULL;

void DisableLightmaps( void ) {
  cl_entity_t*  pWorldspawn        = NULL;
  model_t*          pWorld                = NULL;
  DWORD                  dwOldprotect  = 0;
  register int  i                          = 0;
  register int  lm                        = 0;
  lightdatasave_t lSaved;

  // Clear out the saved lights vector
  g_vSavedlights.clear( );

  // Get a pointer to the worldspawn entity
  pWorldspawn = gEngfuncs.GetEntityByIndex( 0 );

  // Return on failure
  if ( ! pWorldspawn )
          return;

  // Get the world model
  pWorld = pWorldspawn->model;

  // Return if we don't have a valid pointer for the model, marksurfaces or
  // lightmap data.
  if ( ! pWorld || ! pWorld->marksurfaces || ! pWorld->lightdata )
          return;

  // Allow writes to the lightdata pointer
  VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), PAGE_READWRITE, &dwOldprotect );

  // Save the lightdata pointer, then disable it.
  g_pLightdata = ( void* ) pWorld->lightdata;
  pWorld->lightdata = NULL;

  // Restore the protection on the lightmap data
  VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), dwOldprotect, &dwOldprotect );

  // Allow writes to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), PAGE_READWRITE, &dwOldprotect );

  // Loop through all of the marksurfaces and kill their lightmap
  // data
  for ( ; i < pWorld->nummarksurfaces; i++ ) {
          // Copy the cached_light member from the surface and the surface index into
          // our temporary structure.
        memcpy( lSaved.cached_light, pWorld->marksurfaces[ i ]->cached_light, sizeof( int ) * MAXLIGHTMAPS );
          lSaved.msurface_index = i;

          // Add it to the vector
          g_vSavedlights.push_back( lSaved );

          // TODO:
          // Unroll this loop...
          for ( lm = 0; lm < MAXLIGHTMAPS; lm++ ) {
                // Fullbright!
                pWorld->marksurfaces[ i ]->cached_light[ lm ] = 255;
          }
  }

  // Restore protection to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), dwOldprotect, &dwOldprotect );
}

void RestoreLightmaps( void ) {
  cl_entity_t*  pWorldspawn        = NULL;
  model_t*          pWorld                = NULL;
  DWORD                  dwOldprotect  = 0;
  register int  i                          = 0;
  register int  lm                        = 0;
  lightdatasave_t* ptr                  = NULL;
  std::vector< lightdatasave_t >::iterator iBegin;
  std::vector< lightdatasave_t >::iterator iEnd;

  iBegin = g_vSavedlights.begin( );
  iEnd = g_vSavedlights.end( );

  // Get a pointer to the worldspawn entity
  pWorldspawn = gEngfuncs.GetEntityByIndex( 0 );

  // Return on failure
  if ( ! pWorldspawn )
          return;

  // Get the world model
  pWorld = pWorldspawn->model;

  // Return if we don't have a valid pointer for the model, marksurfaces or
  // lightmap data.
  if ( ! pWorld || ! pWorld->marksurfaces || ! pWorld->lightdata )
          return;

  // Allow writes to the lightdata pointer
  VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), PAGE_READWRITE, &dwOldprotect );

  // Restore the model's lightmap data pointer
  pWorld->lightdata = ( color24* ) g_pLightdata;
  g_pLightdata = NULL;

  // Restore the protection on the lightmap data
  VirtualProtect( ( ( void* ) &pWorld->lightdata ), sizeof( void* ), dwOldprotect, &dwOldprotect );

  // Allow writes to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), PAGE_READWRITE, &dwOldprotect );

  while ( iBegin != iEnd ) {
          ptr = ( lightdatasave_t* ) &( *iBegin );

          if ( ptr )
                memcpy( pWorld->marksurfaces[ ptr->msurface_index ]->cached_light, ptr->cached_light, sizeof( int ) * MAXLIGHTMAPS );

          iBegin++;
  }

  // Restore protection to the marksurfaces
 VirtualProtect( ( void* ) pWorld->marksurfaces, pWorld->nummarksurfaces * sizeof( msurface_t ), dwOldprotect, &dwOldprotect );

  // Clear out the saved data vector
  g_vSavedlights.clear( );
}


Pierre-Marie Baty 26-01-2005 22:06

Re: Lightmap performance drop
 
ouch... client code.
I know nothing about client-side code :(

anyway, that code itself shouldn't make the client slow down... I suppose these are one-time call functions ? Make sure you're not calling DisableLightmaps() each frame, that would rather sound like it to me...

Lazy 26-01-2005 22:10

Re: Lightmap performance drop
 
Nah, DisableLightmaps is being called once only.
I'm trying to get this on the HL2SDK but I can't find the model_t definition!
Its driving me up the wall!

Thats the good thing about the hl1 sdk, soo much more organized lol. I guess I just have to get used to it :/

I'm still bothered by the slowdown though, it does the same thing when r_fullbright is set to 1 so my code ( should ) be fine.

@$3.1415rin 27-01-2005 17:17

Re: Lightmap performance drop
 
I guess that's really because you already know that old code for years.

really strange, since that would save one texture stage. maybe there's just something strange inside the HL engine, which hasnt been touched for years, since nobody used it and thus it's unoptimized.

and btw : // TODO:
// Unroll this loop...


i'd suggest you don't care about that and let the compiler decide :)

Lazy 27-01-2005 17:44

Re: Lightmap performance drop
 
Hehe, if only I had an optimizing compiler :)
I still think its a better idea to hand optimize things since you can see things the compiler can't.

[Quick rant]
BAH! There is no model_t definition, its just used as a pointer so the engine can give you various bits of information from a model.
That really sucks since this lightmap method of illuminating the world cannot work now.

sfx1999 27-01-2005 17:59

Re: Lightmap performance drop
 
Maybe it has to do with disabling and reenabling multitexturing.

Lazy 27-01-2005 18:02

Re: Lightmap performance drop
 
I was thinking that might have something to do with it but I do not know enough about OpenGL to re-enable it ( If it's even possible without the engine code ).

sfx1999 27-01-2005 18:12

Re: Lightmap performance drop
 
Even so, it would still be disabling and renabling.

Anyway, that probably isn't it, because the HUD doesn't cause a slowdown like that.

Lazy 29-01-2005 20:56

Re: Lightmap performance drop
 
Slightly off topic:
===============

I'm trying some things to prevent certain commands from being used, the only problem is that some are handled completely by the engine and cannot be blocked or changed.

I found this in the QuakeWorld client source...
Code:

typedef struct cmd_function_s
{
        struct cmd_function_s        *next;
        char                                        *name;
        xcommand_t                                function;
} cmd_function_t;

...
...
...
...

static        cmd_function_t    *cmd_functions;                // possible commands to execute

Since both engines are similar I hope that structure hasn't changed so that the functions can be hooked after they are received by the network socket.

The question is how do I find it in memory?
If I were to get some memory reading tool I could look for "rate" or something and find the start of the command list by working backwards.

Can you reccommend any memory searching tools?
I looked for memory dumping programs but only found pages relating to the windows blue screen physical memory dump.

Pierre-Marie Baty 30-01-2005 02:02

Re: Lightmap performance drop
 
The only memory search tool I can recommand is TSearch, because it's the only one I know (and I wouldn't be surprised if it was the only one existing). It was originally a tool to search for cheats for console games running in emulators (like in UltraHLE, I believe the Zelda cheats were discovered with that tool).

More on topic, I know nothing like the code you posted in the HL engine... I was thinking that all client commands were going either through client commands or impulses, or through usercmd_t's.

sfx1999 30-01-2005 02:47

Re: Lightmap performance drop
 
What commands are you trying to block? Rate can be controlled using sv_maxrate and fov can be blocked somehow. I don't remember exactly how to do that. Also, some commands send impulse values to the server.

Lazy 30-01-2005 04:02

Re: Lightmap performance drop
 
Here's the total so far...
I was reading on some forums about the admin "slowhack" plugin and all of the things it does. Theres some things I can tolerate but no one has the right to change my personal settings.
With protection in mind I set out to build a client-side utility to protect myself from potentially abusive admins ( also to test out a theory I had ).
A few hours later I had something that successfully hooked the client without needing a launcher application.
I developed a quick function which hooked the engine's pfnClientCmd function which would compare the passed string to those on a list.
If the command is blocked I'd have the client say something like "Potential client hijack attempt, command (blah) is protected".
And it worked, partially at least.
If I were to type the command into my console it was blocked fine, but if done through say amx_execclient the command gets executed anyway and my code isn't notified.

So, my great protection plan only works on one side and unfortunately its the wrong one.
I quickly opened up the quakeworld source and did a quick lookup on how those incoming functions were handled which brought me to that one linked-list and structure.

If I can get a pointer to that then hooking the commands directly should be no problem.
Just note that this is not a cheat in any way, shape or form.
If you want to see the source it is available to certain people on request.

dub 30-01-2005 13:07

Re: Lightmap performance drop
 
just thinking about this needs to be done for hl2 too against malicious admins. I read an article on www.steampowered.com forums, how admin`s have the rights to access disk root dir using ..\..\..\..\..\ in the console to overwrite important system files if they wanted.

Pierre-Marie Baty 30-01-2005 15:26

Re: Lightmap performance drop
 
Well, who would ever want to compromise his own server ?

A multiplayer game service is insecure by nature. No good admin would run a game server on a tactically important machine. Who can attest there's no backdoor in one or several of your plugins ?

I think we should not make all that fuss about security for personal machines. Designing, coding, testing and validating hacker-proof code is a VERY boring and time-consuming task ; meanwhile all that time could be used to develop a lot of other cool things, such as improving code stability, implementing new features, etc.

If the game authors start to become paranoid about security, well it's a sad thing, because they will waste a lot of resources in it that will not be spent elsewhere.


All times are GMT +2. The time now is 10:29.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.