| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
Put all the cvars together contiguously; then we don't need to generate
lots of individual calls to extfree() and can instead simply iterate a
fixed-sized array.
|
| |
|
|
|
|
| |
This isn't really making a difference right now but maybe it will in
future builds with different section padding or LTO optimiser
interactions or whatever.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Now everything is either explicitly a rep thing, or explicitly some
other small run of reasonably efficient instructions. No library calls
or function call overhead of any kind. Code size remains nice and small.
Ban a few other bad libc functions while we're at it. More can be added
later if we decide that's a useful idea.
This will require some discipline and workarounds to cope with Clang's
tendency to shove mem* calls in places you don't want them even when you
tell it not to. Well, c'est la vie.
I'm a little nervous that the __builtin_memmove() usage in shuntvars()
could still one day emit actual library calls. It appears we're not
importing memmove() from anywhere at the moment, though. So I guess it's
good enough for now.
Also I had to get rid of alloca() in con_.c but that was kind of bad
anyway, so that's fine.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For some reason the DLL got a tiny little bit bigger again but that's
fine. This will make orig_ calls more efficient in the inline case, and
also make it harder to screw up and hook the wrong thing by mistake.
Self-explanatory-ish, apart from the fact it's a fairly large API change
of course. And it relies on some more bonkers assembler directive
hackery.
But it works!
The only complaint one might have is that the featsetup functions no
longer take an explicit string which occasionally yields slightly less
perfect error messages, but I've decided this isn't really a problem and
makes the API nicer to use. It's a tradeoff, innit.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Does away with the need to mark a region as executable on load.
Also allows the self-modified stuff and hook trampolines to fit in the
same page, so we take up ever-so-slightly less memory.
Unfortunately I had issues getting the test binary to build correctly
and eventually decided to give up as it wasn't testing much of value
anyway.
Also note that the build now allows for .c and .S files with the same
basename, which required renaming the .o files, so you might want to
clean out your .build/ directory before building this one.
|
| | |
|
| | |
|
| |
|
|
|
| |
Kind of unpleasant and probably something to revisit at some point to
see if there's a more straightforward approach we can come up with.
|
| | |
|
| |
|
|
|
|
|
|
| |
I screwed up merging Evan's changes, and also didn't have that one
REQUIRE_GAMEDATA for some reason, and also didn't test actually turning
on the sst_inputhud cvar once everything had loaded fine in testing.
Unlucky, I guess. Better testing might still have caught it.
|
| | |
|
| | |
|
| |
|
|
| |
Quick unused header cleanup pass while we're at it.
|
| |
|
|
|
| |
Pretty hacky for now, but not the worst thing in the world. Can always
be tidied up later.
|
| |
|
|
|
| |
Not really sure what was going on here. This is just a workaround,
really, but it works well enough for the time being.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
While we're at it, come up with a way for certain gamedata matches to be
Windows-only. Somewhat reduces ifdef usage, although does not entirely
remove it of course.
Tested in HL2 2707. Haven't tested other HL2 builds, or Episode 1.
Doesn't seem to work in DMoMM yet either; not sure why.
A big list of stuff still to fix follows.
Hidden cvars are currently an issue. We still need to figure out what to
do with the flag bits because FCVAR_HIDDEN just doesn't exist in OE and
there's some other flag with the same value instead.
We also need to do something about the flag setting in fixes.c since
HIDDEN is again not a thing, and also DEVONLY is not a thing either.
When the plugin is autoloaded, all the initial log text gets eaten,
because there's some stupid crap we have to do to trick the engine into
displaying coloured text otherwise it just won't. Not even stuff from
Warning(). Very stupid, but Hayden already figured out a solution, so
that'll be done in another upcoming commit.
Apparently raw mouse input breaks the menu. We might need to bump up the
priority on making that hook only be active when there's no UI open -
something I wanted to do anyway due to the demo drive issues.
Big thanks to Hayden for doing a lot of the initial groundwork on this,
particularly the cvar registration stuff. He gets a copyright notice in
con_.c even though I ended up doing a lot of stuff differently because
quite a bit of his work is still in there.
Don't blame him for the self-modifying code though, that was my crazy
idea. Sorry, but, in my defence... Well, it works.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since this codebase is already extremely nonportable, I've decided to
relax the obsessive ifdef-else-error usage around all the extensions.
From now on, if there's no alternative to using an extension, we can
just use that extension. If it's possible to do something in a
relatively portable way, we can still try to do that in order to make
the code somewhat reusable, in contexts where that makes sense.
I also decided to use langext.h for naked functions and tail calls. If
that's used in another codebase build with a different compiler, those
just won't work, but that's fine. The benefit is really just that
there's less ceremony in places where those are used, because it's
likely there'll be a few more such places in the future, and it gets
annoying reading all the double-underscore stuff all over the place.
I still kind of want to do something about all the _WIN32 ifdefs too,
but I've realised that doing so will lead to almost nothing actually
being built on Linux. Then again, none of it currently runs on Linux so
I guess that's a moot point. Will worry about it later, anyway.
|
| |
|
|
|
|
|
| |
Turns out, there's no need for the trailing underscores. Plus, glibc
does some stupid stuff with __attribute__ for non-GCC compilers. Not
that that matters here, but it seems like a good practice just to use
the forms that never have such problems. And it's shorter too.
|
| |
|
|
|
|
|
|
|
|
|
| |
This is a step towards making command hooks work in OE, once OE is
supported.
Not the most ideal or efficient thing in the world, but it works okay
until we come up with something better, I suppose. Not a fan of the argv
copying but avoiding that would make the API a lot less ergonomic.
Not the easiest problem to solve, really...
|
| |
|
|
|
| |
Don't worry about the fact I typed l4 instead 14 for the last release
btw. No idea how that happened but I guess it doesn't matter anyway.
|
| | |
|
| |
|
|
|
|
| |
This improves the ergonomics of a few different things, and sets us up
somewhat for the fact OE had a different interface for commands too
(it was v1 only and had a separate API call for getting the args).
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
Most notably, don't just silently return when no parameter is provided;
allow the default handler to print the usual error message.
Also, don't raise the PluginLoaded/PluginUnloaded events when nothing
has actually happened. And rearrange the v1/v2 union so we don't need to
spell out `v2.common`.
Error message issue pointed out by Evan Lin - thanks!
|
| | |
|
| |
|
|
| |
On the plus side, SST's release cadence has never been so lively!
|
| |
|
|
|
| |
Every. Single. Time. And having screwed up the zip dates was just a
bonus I suppose.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Specifically when building in debug mode, we now:
* Display all features on load, including skipped and internal ones,
sorted by internal name instead of display name.
* Print the names of all matched gametype tags after the feature list.
* Add an sst_dbg_getcmdcb command to get the address of a command
callback for quick breakpoint insertion or Ghidra lookup.
* Add an sst_dbg_sendtables command to dump out the full ServerClass
tree to help get names for entprops.txt. Note: this output is very
long so you'll likely need to log console output to a file to be able
to read it all.
There's a bunch of developer experience and debug help stuff I want to
get done eventually. This is just a very small piece, but it's a start.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
This probably should have been the design from the start.
It's still possible to use void pointers, and this is done in a couple
of places for simplicity, but wherever possible, we have actual structs
for things now.
Additionally, in places where vtables are fiddled with, e.g. vtable
hooks, we have actual struct definitions with vtable pointers so there's
need for pointer-casting horror.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This both simplifies and complicates things, but probably hopefully
maybe simplifies things overall. Certainly in cases like the L4D1 demo
thing where there's 3 inline hooks at once, it seems simpler to be able
to batch the fallible stuff to avoid rollbacks. In cases where you only
need one hook, it's a bit more verbose, but what can you do.
Thanks bill for discussing this with me pretty exhaustively and giving a
lot of good input.
I think both of us still kind of hate it actually.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Turns out this was fixed in version 2112 (October 2012), so it was
fairly easy to isolate in Ghidra (I had previously thought this was
fixed by TLS). The CDirector::FinaleEscapeState member is used in
CDirector::IsFinaleWon (and maybe another function, I don't remember).
Prior to Valve's fix, the value was never reset to 0 after finishing a
campaign, so when the Swamp (or Crash Course) "minifinale" events ran,
the game would behave as though the player was entering the
end-of-finale cutscene and block votes, make players invincible etc.
2112 fixed this bug by setting the member back to 0 in CDirector::Reset,
so here we just set it to 0 when quickreset is used, since that is
essentially the recommended way to start a run at this point.
Now co-op hosts won't need to restart their game after finishing
a campaign anymore!
|
| |
|
|
|
|
|
|
| |
They're legally unnecessary as far as I know, and kind of annoying to
maintain on a long-term basis.
This was done with the consent of all 3 other contributors, in case
anyone was wondering.
|
| |
|
|
|
|
| |
Confusingly, the old matchmaking interface refers to No Mercy as
apartments (plural), but refers to the first level as apartment
(singular). Good meme.
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
In the future we can also consider moving to {} instead of {0} for
initialisers, but my old Clang (16) doesn't support this, so it might be
wise to wait longer on that one so people don't need too bleeding-edge
of a compiler just to build this thing.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Also switch to somewhat proper C23 flags while we're at it.
This is a huge change. It took me forever, in between being really busy.
Sorry about that. But the good news is I'm now free to start integrating
the various patches that have accumulated since last release. Well, at
least in between still being really busy. Gotta manage expectations.
The main benefit of introducing GAMESPECIFIC() is that features
that don't apply to a particular game no longer show up *at all*, and
less time is wasted on init. It also enables a cool optimisation wherein
unnecessary REQUIRE_GAMEDATA() checks can elided at compile time
whenever the gamedata is known up-front to always exist in supported
games.
The DEF_FEAT_CVAR macro family meanwhile makes it easier to manage the
lifecycle of cvars/ccmds, with less manual registering, unhiding and
such.
Originally I was going to try and just hack these features into the
existing codegen abomination, but it just got too terrible. This rewrite
should make it easier to continue tweaking codegen behaviour in future.
It also has slightly better error messages.
|
| | |
|
| |
|
|
|
|
|
|
| |
This isn't totally ideal - it'd be nice to have a way to get colours
working, at least for errors/warnings. But it might not really be
possible to do that without custom networking stuff, so this will do for
the forseeable future. The main goal is just to be able to have
CON_SERVERSIDE commands actually give output to the relevant player.
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
| |
My new programming style is branch hints. All non-confusing branches
must be hinted when I can be bothered. It's faster, sometimes, maybe.
Also, start trying to use more signed sizes in at least some of the
places where it makes sense. Unsigned sizes are surprisingly
error-prone!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- As much as possible avoid dragging system headers into translation
units. This should avoid namespace pollution and, hopefully, speed up
builds a little bit.
- Avoid leaning on the UCRT so much on Windows - prefer native win32
calls and native file handles except where doing so is inconvenient
(in particular, for stat(), which we might try and replace later).
- Also, switch from SystemFunction036 to ProcessPrng on Windows. This
requires us to generate a stub for bcryptprimitives.dll because
Microsoft haven't bothered to provide a link library, but the function
is better-documented and seems to be a more direct under-the-hood call
as well. Apparently it's what's used by the major web browsers these
days, which seems like a good indication it's stable and trusted.
- Lastly, remove a bunch of functions and macros and stuff that weren't
actually being used. It seems good to try and keep the scope of
OS-dependent stuff relatively contained and only add to it when
actually required.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
I've resisted doing this for a long time but it's getting to the point
where blocking a release indefinitely is a real problem, and this
satisfies the original request from some leaderboard people to just make
SST identifiable in some way or another. It means the demo stuff can
happen at whatever pace it happens at and other stuff can happen
independently. Less stress and sadness.
Of course, it'll only be kept in as long as required, but there'll be
no rush to get rid of it for any particular release either.
|
| |
|
|
|
| |
Thanks bill for spotting this issue. It was causing crashes on unload,
which is obviously no good.
|