Quantcast

Jump to content

» «
Photo

SCM Hook for San Andreas

82 replies to this topic
op9080
  • op9080

    Player Hater

  • Members
  • Joined: 19 Sep 2005

#1

Posted 08 November 2005 - 03:10 PM Edited by Suction Testicle Man, 06 March 2006 - 10:33 AM.

I originally posted this in the misc forum, but I think this forum is more appropriate. I uploaded source code for a SA script injector.

Q: What is it?
A: A GTA San Andreas loader & script injector with source code.

Where can I get it?
here
or here -STM

Features:
========
  • Supports GTA SA v1.0 US & EU executables. Automatically detects the version and uses the correct addresses.
  • Either starts a new instance of the game or connects to an existing instance if there's one running.
  • Can run the game in either fullscreen or window mode. You can switch between fullscreen and window mode while running by pressing the Alt-Enter hotkey.
    Limitation: Window mode is only possible if your game resolution is strictly smaller than your desktop resolution (so that it can fit the entire window with its frame in). Otherwise it will run in fullscreen.
  • Injects a custom script into the script engine. The custom script can be paused/continued by pressing Alt-S. The default script it comes with lets you explore Liberty City. Press Alt-L to go to Liberty City. Press Alt-G to return to the mainland. You can take a vehicle if you want. If you don't, a Banshee will be spawned for you. You'll also get a jetpack, and unlimited height on the jetpack so you can explore all of Saint Mark's.
    Warning: very little of LC is solid in SA, so you'll quickly fall off on ground. If you do, press Alt-G for rescue. If you're in your own car, you'll get an insane stunt of around 10000 feet as a bonus smile.gif
  • Will disable some of the splash screens on startup (thanks to kyeman).
  • Press Alt-F10 to reduce gravity by a factor of 50. Press Alt-F10 again to return to normal (thanks to Stretchnutter).
  • Press Alt-F9 to remove the game's 270 KPH speed limit on the Hydra. Press Alt-F9 again to reinstate the limit.
  • Press Alt-F8 to set unlimited height on aircraft. Press Alt-F8 again to reinstate the limit.
Command line options:
====================
-window : run in window mode
-fullscreen : run fullscreen (the default)
-script : inject the script (the default)
-noscript : don't inject the script
-splash : enable splash screens
-nosplash : disable splash screens (the default)


For developers who want to use the source code:
==============================================
  • Doesn't use a DLL. Instead it loads itself into the GTA SA process.
  • Was built using MSVC 7.1. I've tried to remove all incompatibilities with MSVC 6.0, so hopefully it will compile with 6.0 as well. You must link with the /FIXED:NO linker option. It's also recommended that you set a high base address with /BASE (My project file uses /BASE:0x48320000).
  • You can add your own hotkeys in customKeyHook().
  • You can add special script processing code in customScriptHook(). define the symbol DO_CUSTOM_SCRIPT_HOOK to enable this.
  • There's a skeleton hook for IDirect3DDevice9::Present() if you want to do some custom drawing. Add the code in customPresent() and define the symbol DO_CUSTOM_PRESENT.
  • It has a set of iostream-style classes to support script building. They support insertion of opcodes, GTA parameter types 1 - 9, jump labels and If-Then-Else blocks. You can look at the sample scripts in custom.cpp to get the idea. Full documentation can be found in Readme.txt.
  • If you don't want to use the supplied classes, you can use your favorite script builder/compiler and stuff raw script bytes with Script::add().
  • For a GXT hook, define DO_GXT_HOOK and use customStrings().
  • For full thread control, define DO_FULL_THREAD_CONTROL and use customThreadFilter(). This lets you decide which threads of main.scm get executed and which don't.
Changelog:
=========
Nov 15 2005
  • added unlimited height on aircraft.
Nov 13 2005
  • added unlimited height jetpack to Liberty City explorer.
  • added speed limit remover for the Hydra.
Nov 10 2005
  • updates timers @32 @33 in injected script
  • GXT hook
  • full thread control
  • does not unhook if have custom jobs
Nov 09 2005
  • fixed some MSVC 6.0 compilation issues
Nov 08 2005
  • original version

Y_Less
  • Y_Less

    629

  • Members
  • Joined: 14 Mar 2004

#2

Posted 08 November 2005 - 04:29 PM Edited by Y_Less, 08 November 2005 - 04:53 PM.

I'm downloading this now, not seen it yet, but I'm sure it will be huge (ceedj will love you).

Edit: I like the way it runs WITH the SCM, rather than replacing it.

op9080
  • op9080

    Player Hater

  • Members
  • Joined: 19 Sep 2005

#3

Posted 08 November 2005 - 06:16 PM

In addresses 0x46A1F0 - 0x46A22C there's a script-tick loop that iterates over the linked list of threads and calls ProcessOneCommand on each. I hook right after the loop so the injected script gets executed as if it were one additional thread. However, it won't get saved to or otherwise disrupt the savefile because it's not actually in the linked list so the game doesn't know about it.

There is one unresolved issue with this method which is that if the player goes to the main menu and starts or loads a new game, the injected script doesn't know anything about it. This may or may not affect it, depending on what the injected script does. For instance, in my Liberty City script, if you load a new game when you're in LC, the script still thinks you're in LC, so you need to press Alt-G to "go back" before your can use Alt-L to go to LC again. I may find a solution to this some day.

If you start yet another thread from the injected script with create_thread, the new thread will get chained to the linked list of threads and therefore go to the savefile. If the new thread is executing code in main.scm, that's ok. If the new thread is executing your own code outside main.scm, it will bomb once the savefile is reloaded on the count of trying to execute non-existent code.

I put in an option to mark the injected script as a mission thread. I don't know what the risks of doing so may be. Normally the game only runs one mission thread, so if you mark your injected script as a mission while a mission is already running.... who knows what might happen. But if you first check there's no mission running, I think it should be ok.

FalconGT
  • FalconGT

    Snitch

  • Members
  • Joined: 04 Jul 2004

#4

Posted 08 November 2005 - 09:05 PM

Great work will download when i get home.

Flip1299
  • Flip1299

    Insane and lovin it

  • Members
  • Joined: 02 Aug 2005

#5

Posted 08 November 2005 - 10:10 PM

EDIT: ignore this post

Spooky
  • Spooky

    Prince of the Yolkfolk

  • Members
  • Joined: 13 Jan 2002

#6

Posted 09 November 2005 - 12:38 AM

op9080: The code looks really good man, thanks for sharing it with the community.

I'll be having a good mess about with some scripts in the morrow smile.gif

cBonky
  • cBonky

    Square Civilian

  • Members
  • Joined: 10 Oct 2005

#7

Posted 09 November 2005 - 12:54 AM

Excellent work!!!

I was playing around with a similar idea for a customizable racing mod, although only just learning the scripting myself, the whole concept of using replacement main.scm's that frequently break the game was abhorrent to me.

If only I had the time to read every single post on these forums, I bet half the ideas I have have already been partially implemented.

op9080
  • op9080

    Player Hater

  • Members
  • Joined: 19 Sep 2005

#8

Posted 09 November 2005 - 01:03 PM

MSVC 6.0 users, please note I uploaded a new version that fixes some more compilation problems with the 6.0 compiler.

Y_Less
  • Y_Less

    629

  • Members
  • Joined: 14 Mar 2004

#9

Posted 09 November 2005 - 06:16 PM

QUOTE (cBonky @ Nov 9 2005, 00:54)
Excellent work!!!

I was playing around with a similar idea for a customizable racing mod, although only just learning the scripting myself, the whole concept of using replacement main.scm's that frequently break the game was abhorrent to me.

If only I had the time to read every single post on these forums, I bet half the ideas I have have already been partially implemented.

I wish all new people were like you! I like you already tounge.gif .

op9080, can you set it so (like the VC SCM hook) it replaces the SCM (as an option)?

op9080
  • op9080

    Player Hater

  • Members
  • Joined: 19 Sep 2005

#10

Posted 10 November 2005 - 11:31 AM Edited by op9080, 10 November 2005 - 05:20 PM.

QUOTE (Y_Less @ Nov 9 2005, 20:16)
op9080, can you set it so (like the VC SCM hook) it replaces the SCM (as an option)?

No. I didn't even realize spookie's hook does that!

[Note: never mind, done]

Y_Less
  • Y_Less

    629

  • Members
  • Joined: 14 Mar 2004

#11

Posted 10 November 2005 - 04:34 PM

Spookies, if you run with an SCM, replaces the SCM entirely so you need all the MAIN code in it, if yours could have an option for that, it would be very useful, but this way is useful too.

op9080
  • op9080

    Player Hater

  • Members
  • Joined: 19 Sep 2005

#12

Posted 10 November 2005 - 05:13 PM Edited by op9080, 10 November 2005 - 05:18 PM.

Y_Less, your wish is granted.

I posted a new version:
  • Added a GXT hook, see customStrings(). Define the symbol DO_GXT_HOOK.
  • Added full control of the game's own threads. If you define the symbol DO_FULL_THREAD_CONTROL, it will call your filter function customThreadFilter() with a pointer to each thread's GST before executing it. You can return false to prevent execution of the thread. If you want to disable main.scm completely,use
    CODE
    bool customThreadFilter(PGTASA_SCRIPT_THREAD pGst)
    {
     return false;
    }

    You can also twiddle each thread's GST to your heart's desire before having it executed.
  • The local timers @32 @33 now get updated on the injected thread's GST, so the injected thread can use them. Before, they were just standing still at 0.

Y_Less
  • Y_Less

    629

  • Members
  • Joined: 14 Mar 2004

#13

Posted 10 November 2005 - 05:25 PM

Cool, I'll probably play about a bit after tea.

FalconGT
  • FalconGT

    Snitch

  • Members
  • Joined: 04 Jul 2004

#14

Posted 11 November 2005 - 01:58 AM

QUOTE (Spooky @ Nov 9 2005, 00:38)
op9080: The code looks really good man, thanks for sharing it with the community.

I'll be having a good mess about with some scripts in the morrow smile.gif

Spookie any chance you gonna release the source for the SA speedo mod ??

op9080
  • op9080

    Player Hater

  • Members
  • Joined: 19 Sep 2005

#15

Posted 13 November 2005 - 02:53 PM

When you go to Liberty City you now get a jet pack and it sets unlimited height on the jetpack, so you can explore the entire city.

Also lets you remove the speed limit on the Hydra.

Smellton
  • Smellton

    Can't get off my chair

  • Members
  • Joined: 22 Mar 2005

#16

Posted 16 November 2005 - 12:58 AM

So can you get around the SCM size limits with this?

ceedj
  • ceedj

    PEDS Creator

  • Feroci
  • Joined: 21 May 2005
  • None

#17

Posted 22 November 2005 - 04:06 PM

As I woke up this morning, I was just thinking how cool it would be if someone did a SCM Hook for SA...

...and here it is! I guess I should start on SA Studios, no?

Will download and check out. Many, MANY thanks for this...

Y_Less
  • Y_Less

    629

  • Members
  • Joined: 14 Mar 2004

#18

Posted 22 November 2005 - 04:11 PM

QUOTE (ceedj @ Nov 22 2005, 16:06)
As I woke up this morning, I was just thinking how cool it would be if someone did a SCM Hook for SA...

...and here it is! I guess I should start on SA Studios, no?

Will download and check out. Many, MANY thanks for this...

Cuh, it's about time you found this! tounge.gif I knew you'd like it and even tried linking you to it in FBI, but you're even less active there than me!

ceedj
  • ceedj

    PEDS Creator

  • Feroci
  • Joined: 21 May 2005
  • None

#19

Posted 22 November 2005 - 05:17 PM Edited by ceedj, 23 November 2005 - 12:46 AM.

I know, I've been without online access for a while. So this is a touch of "good" irony, seeing how as my DSL JUST got turned on, and it seems I need the DX9 SDK to make this work.

I guess timing is everything. blink.gif

EDIT: Wow. I mean. like, WOW. Very nice work sir. smile.gif

A couple of questions though (you had know that was coming):

1) I like the fact that you included a windows keyhook, but I don't quite understand it's usage. Could you shed some light on this? Or would it be easier for me to use the keyhook I use for Vice/Liberty/Myriad Studios? For example, I use this now:

CODE

#include <iostream.h>
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)  ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

and then I do this:

if (KEYDOWN(VK_DELETE) && KEYDOWN(0x54)) //DELETE + T
<code here>


2) Can I use traditional C/C++ if/else statements? These are WAY faster in Vice, rather than using the game "if" commands. Another example:

CODE

AGrp1Ped1State3:
if (KEYDOWN(0x52)) //r
{ pGrp1Ped1->SetActorWaitState(3, 2000); //lean back, look l & r
goto FreezeClock;
} else {
 goto AGrp1Ped1State4; }

Obviously, my stuctures will be different, but the idea is the same. What do you think?

3) Multi-Threading. I'm guessing since we can use the Lable lab1, lab2, etc, that it's refering to in-game threads as opposed to the single monster thread I have to use with Vice. As I understand it, I can use goubs now too? This will save a TON of extra coding.

4) Globals and Locals. Everytrhing here is defined with numbers; I assume this is because this is how it gets compiled to use in San An. I'll need about 20-30 globals; does the script automatically allocate extra globals beyond what is originally used? I don't want it to overwrite anything already in the game.

I'm sure I'll think of more, but for now, this is an AWESOME piece of work. Many thanks again!

ceedj
  • ceedj

    PEDS Creator

  • Feroci
  • Joined: 21 May 2005
  • None

#20

Posted 27 November 2005 - 08:19 PM Edited by ceedj, 30 November 2005 - 10:01 PM.

Been using this for a few days now. I just have a few minor quibbles...

1) There are a few "sussed" Opcodes in Opcode.h, but it's only a few swapped paramaters. I noticed two of them in the math opcode section, but all seems to be well now. You might want to check over that again just to make sure.

EDIT: 1a) You should also note somewhere that users should define G PLAYER_CHAR(2); if they want to use any opcodes that use PLAYER_CHAR instead of PLAYER_ACTOR (freeze player, set wanted level, etc).

2) The keyhook isn't really much of a keyhook, limiting use to just the ALT key and whatever else. It'd be nice if we had someway of using SHIFT, CRTL, etc. Well, "I" do, but I had to write a new hook inside it, and it's one I'm not really pleased with because of...

3) The way you call parms with theScript.setLocalVar(blah, blah). It's good and it's bad. Good, because it affords an insane amount of control over parameters. Bad because getting the simplest thing to work takes an insane amount of setting up. Very ying-yang. smile.gif

EDIT: 3a) Speaking of set:LocalVar, is there any reason why we can do the same for Globals? Aside from it not being defined of course. Just curious about this...

4) The whole process reminds me of a new girlfriend: at first, you love all the cute things it does. Then you bang your head on a concrete wall trying to figure it out. Finally, you're just resigned to the fact that it's better than nothing.

My point here is that it'd be nice if we all would just pick ONE language to use for mission coding. I don't mind spending a lot of time on a project; but I do hate spending said time on trying to learn yet ANOTHER interpritation of mission coding. I think I understand now what Barton was trying to say when Spookie's SCM mod came out early this year.

Please, please PLEASE don't take this as me being harsh or unappreciative. I do like what you've managed to do - getting this builder to hook right inside of an orginal scm is brilliant. One of the things I was NOT looking forward to was having to recreate a bunch of external threads inside a stripped SCM. This hook of yours eliminates that, so I can concentrate on good ped animaition control and making all the mission specific interiors accessable (Jizzy's club, the Sindacco Meat Factory, Caligulas upstairs, etc).

Anyway, I'm rambling now, but I have a couple of requests:

1) Is there anyway to make this so that if it's already loaded and you load another game, that this will re-load with it, rather than having to shut the game down and start it up again? Not terribly neccessary, but it would be nice.

2) You should probably indicate in the READ ME somewhere that you need to uncomment certain things in Common.h to get them to work. Or maybe that's what you meant by "define symbol". Either way, it took me forever just to figure THAT out. You might want to make it a bit clearer to those without a huge C/C++ background. Like me. smile.gif

Anywho, thanks again for the work you've put into this. rah.gif

ceedj
  • ceedj

    PEDS Creator

  • Feroci
  • Joined: 21 May 2005
  • None

#21

Posted 30 November 2005 - 06:26 PM

Houston, we have a problem. blink.gif

Animation Sequences work fine ONLY if the amount of characters in the file name(s) is 8 or less. Which is why this works:

CODE

DEFINE_OPCODE(action_seq, 0x0605, "vssfiiiii");

theScript << action_seq << WhichPed << "TAP_HAND" << "PED" << 4.0 << 1 << 0 << 0 << 0 << 2000;


But this will not:

CODE

theScript << action_seq << WhichPed << "IDLE_CHAT" << "PED" << 4.0 << 1 << 0 << 0 << 0 << 2000;


Anyone have any ideas on how to overcome this? I think the charcters need to be set around 13-16...

Un3462
  • Un3462

    Mack Pimp

  • Members
  • Joined: 27 Jun 2002

#22

Posted 30 November 2005 - 06:53 PM

i don't know much c(++), but try changing the following in scripting.cpp:
CODE
Script& Script::operator<<(const char* str)
{
  BYTE b[9];
  if (!str)
    return *this;
  memset(b, 0, 9);
  b[0] = 9;
  strncpy((char*) b + 1, str, 8);
  add(b, 9);
  return *this;
}

to
CODE
Script& Script::operator<<(const char* str)
{
  BYTE b[34];
  if (!str)
    return *this;
  b[0] = 14;
  b[1] = strlen(str);
  strncpy((char*) b + 2, str, b[1]);
  add(b, b[1] + 2);
  return *this;
}

ceedj
  • ceedj

    PEDS Creator

  • Feroci
  • Joined: 21 May 2005
  • None

#23

Posted 30 November 2005 - 07:15 PM Edited by ceedj, 30 November 2005 - 07:35 PM.

Wow. Just like, WOW.

THANK YOU CYQ!!! inlove.gif inlove.gif inlove.gif inlove.gif

I had suspected that this was the section that needed to be altered.

Just out of curiousity, how did you arrive at those values? In case I need to bump it up again? (I gather the "b[0] = 14;" is where it is set)

Also note that if you want to use animations in files OTHER than "PED" you will have to load it first using the load_animation opcode. You should probably release_animation after you're done as well.

Many HUGE thanks again! rah.gif

EDIT: Ok the longest string I was able to find thus far is "BMX_TALKRIGHT_LOOP", and I didn't need to change any values for it to work, so unless I find one bigger that causes a problem, I don't think anything needs to be changed. Awesome. smile.gif

Un3462
  • Un3462

    Mack Pimp

  • Members
  • Joined: 27 Jun 2002

#24

Posted 30 November 2005 - 07:41 PM

14 is the parameter type for a variable length string. the byte after that is the string length, and the rest is the string (not null-terminated). the hook might not handle variable length string variables correctly either, but i don't think you really need those.

to bump it up again you only need to increase the buffer size, which is now 34 (partype byte + length byte + 32 byte string, which is more than enough, and i don't even know if such long strings are supported by sa's interpreter). or, depending on how "add" is implemented, you could try simply sending it the two special bytes first, and then another "add" call for the string directly from the function argument.

WarMachine245
  • WarMachine245

    Player Hater

  • Members
  • Joined: 15 Aug 2005

#25

Posted 08 January 2006 - 03:52 AM

will i have to start a whole new game to use this thing?

random_download
  • random_download

    :o

  • Members
  • Joined: 07 Mar 2004

#26

Posted 08 January 2006 - 10:11 AM

QUOTE (WarMachine245 @ Jan 8 2006, 03:52)
will i have to start a whole new game to use this thing?

No.

NFO_bakasan
  • NFO_bakasan

    VC:MP Developer

  • Members
  • Joined: 13 May 2004

#27

Posted 09 January 2006 - 06:52 AM

very nice work icon14.gif icon14.gif

Sobeit
  • Sobeit

    mta ninja

  • BUSTED!
  • Joined: 11 May 2004

#28

Posted 26 January 2006 - 05:17 PM

ill gladly mirror this file, but the link here is broken.

anyone who could send it to me it would be great.

AlienX
  • AlienX

    Player Hater

  • Members
  • Joined: 04 Jul 2005

#29

Posted 18 February 2006 - 04:11 PM

link works good for me but otherwise

Download Here

BenMillard
  • BenMillard

    aka Cerbera

  • Members
  • Joined: 22 Jun 2002
  • United-Kingdom

#30

Posted 19 February 2006 - 06:45 PM Edited by Cerbera, 06 March 2006 - 02:26 PM.

Removing the height and speed limits for planes is awesome, I can't believe I havn't found this mod before!

By the way, OP, you really need a better host. There was a queue of half an hour for me to download this, which I only realised after looking through every piece of randomly positioned text on the automated download page. I used AlienX's mirror in the end.

Is there a way to specify which install of GTASA the loader starts up in? I've got two installs and it always loads up my backup one, without letting me choose whether that's the one I want or not. It's a pain having to run my modded install, tab out of it, start the loader, than tab back in every time I want to test a change to an airplane setup.

It's a great mod, I really like being able to fly at high speeds and altitudes, it's just a bit inconveniant having to switch between GTASA and the desktop. smile.gif

(EDIT) Using the limit removal for planes, I've come up with a Hydra setup which accelerates a bit more realistically and have released it in my GTASA Handling Overhaul topic. Top speed when flying level is about 600mph. However, thanks to the height limit remover, you can do massive dives to get over 800km/h! colgate.gif

(EDIT2) I've worked around the GTASA install selection. I created a shortcut to the EXE on my desktop, opened its Properties and then set the Shortcut key. I can now just press Ctrl+Alt+L when at the main menu in GTASA to start the loader. I can then use the loader's built in shortcuts for turning off the speed limit (Alt+F9) and altitude limits (Alt+F8) in-game.




2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users