Category Archives: GTA IV

Adding ALT+Enter (windowed <--> fullscreen) switch to IV

I haven’t posted much the past months due to my work commitment and the fact that the stuff I’m working on currently requires a lot of explanation and thus time to create the posts. I hope I can get some posts out during my winter vacation though!

Anyway, last weekend when I was recording some IV footage I found it unbelievable inconvenient I had to remove the “-windowed” switch and restart the game when I wanted to go fullscreen. Also I couldn’t simply go back to windowed mode then, which was annoying as well, since the fullscreen mode of IV is not known to be very ALT-TAB friendly…

So I thought it would be nice to have a simple fullscreen <–> windowed mode switch. Judging from my recent DX 11 experience I was sure it would be really simple, as it doesn’t involve more than a single call to SetFullscreenState. It turned out it’s more difficult on DX 9 though. Here’s how I finally realized it (research based on EFLC 1.1.2.0 as always):

Finding the windowed code

Okay so we know there is code to make the game windowed at startup due ot the “-windowed” commandline switch. So that’s a good way to start. A simple string search for “windowed” yielded good results: [GRAPHICS] Force windowed mode

Following that led us to the commandline switch we were seeking. Doing an xref in IDA eventually led to this piece of code (without the names usually of course):


.text:007D77DE 048                 mov     g_cmdarg_fullscreenMode.m_pszValue, offset aFullscreen ; "fullscreen"
.text:007D77E8 048                 mov     g_cmdarg_windowedMode.m_pszValue, esi
.text:007D77EE 048                 mov     g_bSettingsIsFullscreenMode, eax

Followed by API calls to SetWindowLongA and SetWindowPos this seemed like the right place. Especially the call below is very interesting:

.text:007D77FF 058                 call    GetScreenSettings

After some analysis it turns out it writes width, height and whether the game should run in fullscreen mode to the variables pushed. We also find bSettingsIsFullscreenMode
being used in that function again. At that time I went in-game to the graphics menu, changed the value of bSettingsIsFullscreenMode in memory and hit Space to apply changes. And it worked: So simple, yet effective!

Manually resetting the d3d device

However it still required us to go in the menu and choose to save changes, which is not as convenient as a simple ALT+Enter anytime during gameplay. Now we had to manually call the code resetting our d3d device and applying the changes. I decided to set a breakpoint on GetScreenSettings and went into the graphics menu again (and saved) just to find it being called from

 .text:00480B4D 034                 call    GetScreenSettings 

A more in-depth analysis of this function turned out it is responsible for the graphics menu and only called when you select the Graphics tab in the game menu. Furthermore, once you hit Space, the code at 00480AB3 is called. So by utilizing this code part I was able to reset the d3d device and reflect the change I made to bSettingsIsFullscreenMode. Simple as that!

The next LCPDFR  release will contain this function, I hope you find it as useful as I do.

 

 

Exploring IV’s vehicle liveries

Hi,

I had a look at the vehicle livery system of IV earlier today. Yard1 – once again – asked me whether I could take a look at this, since he said IV would limit the amount of liveries to four per vehicle even if more than four textures were added to the WTD file.

Edit: Video: Click here.

So I launched IDA and took a look at the native function SET_CAR_LIVERY to find out how changing a livery works at all. The second argument for the native is the livery texture index, ranging from 0-3 normally. A quick back trace led to the following code:

mov ecx, [ebx+eax*4+CVehicleModelInfo.m_adwLiveryTextureHashes]
movsx edx, [ebx+CVehicleModelInfo.__parent.m_wTxdId]

 

The register EAX holds the index of the texture and since it’s multiplied by 4 we know each entry has the size of 4 bytes, a DWORD. When passing a value from 0-3 to the native, the name of the texture as a hash is returned. However when passing 4, we get CDCDCDCD, so unallocated memory. This leads to the conclusion that the game either didn’t load our 5th texture or that we’re dealing with an array of size 4. The latter is the case. We only have a dwHashes[3] here, so anything past 4 textures will simply not be stored and thus can’t be retrieved later. Note that higher values might lead to unexpected behavior, since no range check is done and the code will just grab the value from memory exceeding the array bounds.

How to allow more liveries then? Simply hook into the function and change the specific location to return the hash for modelName_sign_n to bypass the array limitation. This way it wil look up the texture later by hash (it’s loaded by the game already) and assign it to the vehicle. Using such a simpe hook, you can extend the allowed range to any number you like. I might post an example later which does this for you.

On another note, I’m currently doing a research project on the texture/model loading of the rage engine and how it is stored/used in EFLC with cp702 which is getting along pretty good so far. I hope to be able to tell you more about this soon!

Lennart

ELS 8 behind the scenes

Hello,

today I’d like to share the story behind the version 8 release of ELS and the techniques used. The other day, Yard1 sent me a message about the same old topic: ELS and its biggest problem, namely repairing the vehicle all the time. This topic has been discussed by me and Lt.Caine hundreds of times and we spent many days looking for possible solutions. I think it was back in 2011 when I first took a look at the issue, but I never really came up with a solution. My attempt back then was to kill the “repair” part of the repair function. Sounds great, right? It worked partly, the extras got enabled and disabled just fine and I was able to prevent windows from repairing and also managed to keep bulletholes. The car body was still repaired though and I gave up after a few weeks.

But this time it was different. I had done a lot of research since 2011 and I thought I might be able to get it to work this time. However, I knew my old approach of changing the repair code didn’t work, so I thought of something new. You have to understand that I have no experience at all with modelling, so I didn’t really know how adding custom extras for models worked. But I had a new idea, since Yard1 told me that the extra lights would act exactly the same as the indicator lights. So I thought, maybe I could clone them in memory. Put simply, that didn’t work out. While I was able to do all weird things possible with the indicators and other parts (change color, size, brightness, location) via memory hacking, I didn’t manage to make IV recognize the extras as indicators. That was my main idea, since I could toggle indicators. I had hoped making extras indicators would allow me to toggle them without repairing as well. But that didn’t work.

I was already starting to get annoyed again, when I had a small chat with NicolaiB. He explained to me in detail how the whole modelling thing works and what these extras are and encouraged me to get things going again. This time I had another idea: Why not enable all extras and then find a way to kill their render code? This way they would be hidden to the user, but the vehicle would not repair. After some research I was able to do exactly that: Disabling the rendering of an turned-on extra. So technically all extras would stay enabled, you just can not see that. I ported my quick and dirty assembler hacks to C++ and added some timer functions to make it look like a siren. And guess what? It worked perfectly! Below I’ve attached two screenshots of showing this work in progress (you might recognize them as being posted earlier on LCPDFR.com):

Lights by LMS #1

Lights by LMS #1

And the same situation a second later:

Lights by LMS #2

Lights by LMS #2

Some time after I got it working, I spoke to Lt.Caine about a possible ELS integration and I’m happy to announce that we’re working together on ELS 8!

Thanks to Yard1 and NicolaiB for their assistance with modelling knowledge and Lt.Caine for his ELS partnership. Also thanks Sam for his input.

Thanks for reading and stay tuned,

Lennart/LMS