FunkyFr3sh / cnc-ddraw

GDI, OpenGL and Direct3D 9 re-implementation of the DirectDraw API for classic 2D games for better compatibility with Windows ME, 2000, XP, Vista, 7, 8, 10, 11, Wine (Linux/macOS/Android) and Virtual Machines
https://discord.gg/afWXJNDDF5
MIT License
2.27k stars 145 forks source link

Twisted Metal 2 #40

Closed LuKeSt0rm closed 4 years ago

LuKeSt0rm commented 4 years ago

Hello, first thank you very much for your effort and work. I tried to use "cnc-ddraw" on Twisted Metal 2, but the following error occurs when starting the game: "DirectDraw Error A DirectDraw object could not be created (code: 1). You may need to restart your computer and/or reinstall DirectX." cnc-ddraw.log

FunkyFr3sh commented 4 years ago

The only unusual thing I can see in the logs is that the game is trying to run in windowed mode, that isn't supported by cnc-ddraw. Is there any way you can enable fullscreen mode in the game and then retry?

LuKeSt0rm commented 4 years ago

No, unfortunately there is no possibility to set fullscreen mode

elishacloud commented 4 years ago

I just downloaded the game from here: https://www.myabandonware.com/game/twisted-metal-2-bf3#download

It looks like this game uses DirectX 8. Try using this project instead: https://github.com/crosire/d3d8to9

Edit: you may need to configure these compatibility options:

image

LuKeSt0rm commented 4 years ago

This game doesn't use DirectX 8 (Should be DirectX 5) and I know the compatibility settings.

elishacloud commented 4 years ago

You are right. It is using an older version of DirectX. However, it seems like the game fails before calling any "real" function.

"The only unusual thing I can see in the logs is that the game is trying to run in windowed mode"

This game does run in fullscreen not windowed mode! However, by the time the game requests windowed mode it has already failed. As an exit routine, it calls SetCooperativeLevel() to set the display back to normal and then it calls RestoreDisplayMode() and exits.

I suspect that it is looking at the display settings and checking if it is set for 16 bit color. If not it fails.

elishacloud commented 4 years ago

I suspect that it is looking at the display settings and checking if it is set for 16 bit color. If not it fails.

Ok, I was wrong. It seems to be tracking each DirectDraw interface separately.

It calls the following functions:

DirectDrawCreate(NULL, pDD1, NULL);
pDD1->QueryInterface(IID_IDirectDraw2, pDD2);
pDD1->Release();

It expects to get a 0 from the last call, but instead it gets a 1. If you hard code this line to always return a 0 it can at least load the game. That will likely cause other issues, but at least it gets past the first error.

elishacloud commented 4 years ago

Here is an ugly hack. I am just using dxwrapper for this hack. I hard coded the return value to 0. I don't know if that will cause any other issues for this particular game, but you can try it out yourself.

Here are the test files: ddraw.zip

LuKeSt0rm commented 4 years ago

Thanks, it seems to work. I have tried dxwnd too and it seems to work best. With dxwnd even the music works when you want it to.

I want to use a wrapper, because I think it gives the highest and most stable compatibility between the different Windows versions. Also I think it will be more and more difficult to play an older game native without a wrapper in the future. (Because e.g. compatibility settings etc. are removed)

Last question that concerns me: (Sorry for off topic) If you use a wrapper, how big is the impact on the performance in terms of multiplayer? (Or is it even different from wrapper to wrapper)

elishacloud commented 4 years ago

I have tried dxwnd too and it seems to work best.

Yeah, dxwnd is one of the older wrappers. It has some of the most broad compatibility working with DirectX 1 through 11, but it is also somewhat more difficult to use. It does not a lot more than just wrap DirectX and can hook registry and a bunch of other stuff. However, it does not convert DirectX to another other version. The game will remain in DirectX 5 with this wrapper.

I want to use a wrapper, because I think it gives the highest and most stable compatibility between the different Windows versions.

I understand. That is the purpose of many of these wrappers. For this game dxwrapper can convert DirectX 5 to DirectX 9 and it can convert DirectInput to DirectInput8. This allows you to use other tools with the game that support newer versions of DirectX.

If you use a wrapper, how big is the impact on the performance in terms of multiplayer?

It does depend on the wrapper. For example in both cnc-ddraw and in dxwrapper the processing for blts are moved from the GPU to the CPU. However, in most cases that is fine because it is still faster than native ddraw, for various reasons.

As long as it runs well on single player then it should be fine for multiplayer.

Note: there is probably a way that we could hack cnc-ddraw to work with this game also, but to put in a real fix for this would be somewhat hard with cnc-ddraw, I think.

LuKeSt0rm commented 4 years ago

Thank you very much for your infos and help.

For this game dxwrapper can convert DirectX 5 to DirectX 9 and it can convert DirectInput to DirectInput8. This allows you to use other tools with the game that support newer versions of DirectX.

If you have a special config for this game or I can adjust some settings, I would like to test it with dxwrapper. Is it possible to write somewhere else that we don't go too off topic here?

elishacloud commented 4 years ago

If you have a special config for this game or I can adjust some settings, I would like to test it with dxwrapper.

The test build I gave you converted the game to DirectX9 and DirectInput8. The two settings I enabled for this are:

Dd7to9    = 1
Dinputto8 = 1

Is it possible to write somewhere else that we don't go too off topic here?

My dxwrapper GitHub account is here.

FunkyFr3sh commented 4 years ago

Looks like it's working with cnc-ddraw too, I attach it here in case you want to play around with it:

cnc-ddraw_TM2.zip

Edit: Applied elishas hack + had to set maxgameticks to 60 because it was running too fast

Note to myself: When pressing Alt+Enter to switch to windowed mode the game reacts to the Enter key (Probably a directinput bug...)

LuKeSt0rm commented 4 years ago

Wow, it's working very well, only the input menu in options and multiplayer menu nothing is displayed with "direct3d9". With "opengl" the menu is displayed, but texts/boxes are moved. Is there any way to fix this ? Have the feeling that with "opengl" the game works even better.

Thank you, appreciate that very much.

FunkyFr3sh commented 4 years ago

Wow, it's working very well, only the input menu in options and multiplayer menu nothing is displayed with "direct3d9". With "opengl" the menu is displayed, but texts/boxes are moved. Is there any way to fix this ? Have the feeling that with "opengl" the game works even better.

Thank you, appreciate that very much.

Ah, didn't test that screen. Are you using the settings file I included in the .zip I linked in my last post? If not, the then make sure you set "handlemouse=false".

You may have to use OpenGL or GDI for this game for normal fullscreen, I guess windowed and windowed-fullscreen should work fine with direct3d9 on all versions of windows though. Upscaling that input menu is currently not possible because it's not pure DirectDraw so it will show up in the top left of the screen in case you got upscaling enabled.

LuKeSt0rm commented 4 years ago

Good to know, I have used your settings file with "handlemouse=false" and I had not activated upscaling. The menus use images or similar at certain positions, right ?

FunkyFr3sh commented 4 years ago

Good to know, I have used your settings file with "handlemouse=false" and I had not activated upscaling. The menus use images or similar at certain positions, right ?

The game is drawing the background and everything with DirectDraw and then it puts some "Physical" buttons/textboxes/etc.. on top of the window from the looks of it. There is probably a second window that will show up once you go into the input menu and on that window it will put the buttons. Direct3d9 will force the main window into fullscreen-exclusive mode, that means all other windows that are layered on top will become invisible.

It was looking alright for me, but I'm not sure. If you noticed that something is off then maybe you could upload a screenshot and I'll check

FunkyFr3sh commented 4 years ago

Just found another issue that might explain the problem you were reporting. I'm not sure if normal fullscreen with OpenGL is still working for you with it so I set it to GDI now by default.

You could still use OpenGL or Direct3d with windowed or windowed-fullscreen (windowed=true+fullscreen=true) mode if you want though.

cnc-ddraw_TM2_test2.zip

LuKeSt0rm commented 4 years ago

With GDI, OpenGL and Direct3D9 the gameplay is working fine (test2)

With GDI and OpenGL the text/graphic "Keyboard" is not displayed in the upper left corner of the input menu. But if you press the down arrow key, the graphic "Keyboard" is displayed. https://i.imgur.com/HoFGcrF.png

With Direct3D9 the multiplayer menu and input menu looks like this (test1 and test2) https://i.imgur.com/K5AKoPI.png | https://i.imgur.com/LMK8348.png

FunkyFr3sh commented 4 years ago

Not too bad :+1: Was the other problem you did mention fixed with test2 or did you mean the missing Keyboard graphic with it?

And yeah, that's how Direct3D9 will look like in normal fullscreen.

LuKeSt0rm commented 4 years ago

The problem I mean is that with direct3d9 in the multiplayer menu and input menu only the background is displayed without any content. (as you can see on the two screenshots at direct3d9 in the previous post. It occurs only with direct3d9, at least at my end.)

FIXED: The following issue with the missing images of the maps was caused by the wrongly named *.pcx files in the shelldb3 folder. In the multiplayer menu, when you start a game you can select the map in the middle. But the image of the map is not displayed, no matter which renderer you use.

FunkyFr3sh commented 4 years ago

Oh I see... Yeah forget about Direct3d for this game, same happens for me too (Not worth the effort fixing it)

Map selection works fine for me, TM2.exe version 97.10.31.100

LuKeSt0rm commented 4 years ago

Map selection in multiplayer (TCP/IP) via DirectPlay?

FunkyFr3sh commented 4 years ago

yes

LuKeSt0rm commented 4 years ago

Strange... can you send me your game exe?

FunkyFr3sh commented 4 years ago

I use the one from elisha's link above

elishacloud commented 4 years ago

Applied elishas hack + had to set maxgameticks to 60 because it was running too fast

Note: By default dxwrapper should run at the correct speed by reading the correct Flip() and Blt() flags, this works with many games such as Dune 2000, Dark Reign, etc. However, if the game runs too fast with dxwrapper you can enable vsync to slow it down a bit.

EnableVSync   = 1
LuKeSt0rm commented 4 years ago

Thanks for info, elishacloud

FunkyFr3sh

I use the one from elisha's link above

It's not the game exe, thanks for the hint, that's how I got on the track. The issue was caused by wrongly named *.pcx files in the shelldb3 folder.

My Goal: I want to make a "Ready2Play" package with Launcher for comfortable playing on modern systems. Where also the online modification (tmchu) is included, which allows multiplayer Online/LAN. Because I don't have the knowledge to patch the exe file to fix/change rendering or to program a wrapper, I try to find the best possible wrapper. Of course I give credits, thanks for all the help!

elishacloud commented 4 years ago

@Canno, dxwrapper is already being used this way for some games. For example GOG is shipping some games with dxwrapper to get them working on Windows 10. If you find any issues with dxwrapper just let me know and I will do my best to resolve them.

LuKeSt0rm commented 4 years ago

@elishacloud I will test dxwrapper again and report back to you at your project on github.

@FunkyFr3sh I have compiled cnc-ddraw myself with Visual Studio and have to find out that the file size is different to your test1 and test2 builds, is there code included that is not included in the master branch?

FunkyFr3sh commented 4 years ago

Yeah, you have to add the hack from elisha to make it working

It expects to get a 0 from the last call, but instead it gets a 1. If you hard code this line to always return a 0 it can at least load the game. That will likely cause other issues, but at least it gets past the first error.

LuKeSt0rm commented 4 years ago

I have also done it and it works too. But your ddraw.dll is 258kb(test1)/261kb(test2) where mine is only 255kb. (Just wonder about the file size of the dll)

FunkyFr3sh commented 4 years ago

Oh, maybe different version of visual studio will produce a slightly different size?

LuKeSt0rm commented 4 years ago

Yes, that was also my thought, I don't have so much experience in this area yet. I also made a small patch for the change, so I can easily apply it. I'm still learning programming/assembler and everything that goes with it. (I learn fast)

I have already made the following changes to tm2.exe

LuKeSt0rm commented 4 years ago

Is it possible that with OpenGL renderer with fullscreen mode the textboxes and texts are displayed correctly in the upper left corner of the menus like multiplayer or input options, as it works with GDI renderer ? That would be perfect :)

FunkyFr3sh commented 4 years ago

Yeah you can use a trick to workaround the problem easily with opengl, insert the following code:

if (!ddraw->windowed && ddraw->renderer == render_main) This->render.height++;

here:

https://github.com/CnCNet/cnc-ddraw/blob/e10cfa3e1a504440fd01b900338a9e11583367fd/src/main.c#L838

LuKeSt0rm commented 4 years ago

Thanks, I have tested "windowed-fullscreen" without the change and the menus are working fine with OpenGL and Direct3D9.

Edit: Have tested your suggested code, it works fine with OpenGL. I also adapted it for Direct3D9, but with Direct3D9 and the change I get a warning about "Using slow software rendering" in the upper middle of the game.

Code if (!ddraw->windowed && ddraw->renderer == render_main || render_d3d9_main) This->render.height++;

FunkyFr3sh commented 4 years ago

Yeah, this trick definitely doesn't work with Direct3D9... It's a lot more complicated to get it working with Direct3D9, but it's not really worth it. GDI is faster than OpenGL and Direct3D9 at lower resolutions anyways, if you want the best possible performance then stick to GDI. OpenGL and Direct3D9 will be faster at high resolutions (1280x720 and above). Having OpenGL working is cool though, maybe someone wants to use a screen recording software or display a overlay, that will be working fine with OpenGL. Keep GDI the default setting and add a checkbox to your launcher so they can switch quickly to OpenGL if needed.

LuKeSt0rm commented 4 years ago

I did some research about GDI/OpenGL and came to this solution. I will do it with the launcher exactly as you say. Thanks again for your help and effort :)

elishacloud commented 4 years ago

@FunkyFr3sh,

Yeah, this trick definitely doesn't work with Direct3D9... It's a lot more complicated to get it working with Direct3D9, but it's not really worth it.

Can you explain a bit more on the issues with getting this working on Direct3D9?

FunkyFr3sh commented 4 years ago

@FunkyFr3sh,

Yeah, this trick definitely doesn't work with Direct3D9... It's a lot more complicated to get it working with Direct3D9, but it's not really worth it.

Can you explain a bit more on the issues with getting this working on Direct3D9?

set Windowed = TRUE in D3DPRESENT_PARAMETERS Create a borderless window and move it to the top left of the screen Call ChangeDisplaySettings with a resolution matching the size of the window ... Add code to handle Alt+Tab on your own

elishacloud commented 4 years ago

I see. Thanks @FunkyFr3sh!

LuKeSt0rm commented 4 years ago

The mod for the online multiplayer is started by a separate exe and injects the change like the new hud when starting the game in the texture loading screen. But this will not be loaded, don't know if cnc-ddraw prevents this or if the loading screen simply loads too fast. Without cnc-ddraw native a texture loading screen appears where the changes are loaded like new hud, which works.

How can I fix this ? Btw: The whole thing works similar to cncnet and C&CRA2 with the spawner. ( I think)

To reproduce: 1.Download and copy the files into the tm2 folder 2.Start TMC exe 3.Create -> GO The standard TM2 hud is present instead of the new one, which is not loaded. Otherwise everything seems to work. TM2OnlineMod_test.zip

Thanks for taking over TM2 in cnc-ddraw, so I don't need my patch anymore.

FunkyFr3sh commented 4 years ago

First I tried it on windows XP and It said TMC wasn't a valid win32 executable. Then I tried it on windows 7 and it didn't start there either so I had to manually install .NET 4.0.

On the first start it crash and on the second start it worked. I click on create and it says "Wrong Tcp port [2]". If I click on READY or GO it crashes

LuKeSt0rm commented 4 years ago

Strange. I have re-uploaded the files in my post above, try again. Make sure that the ID exe is not deleted by the virus program. Unfortunately this is often recognized as false positive.

FunkyFr3sh commented 4 years ago

Still the same, ld.exe is still there

LuKeSt0rm commented 4 years ago

1.TM2 exe replaced ? 2.Go to settings and choose the folder at Id.exe 3.Try to make a local game -> View -> Enable "Show modul Local Connection" -> Click on "Create" in the toolbar

FunkyFr3sh commented 4 years ago

Same result with or without. My game is working fine, I can start tm2.exe and play. Just TMC.exe is causing problems

Edit: I get a System.MissingMethodException, so maybe a dll file is missing or maybe I installed the wrong .NET version?

LuKeSt0rm commented 4 years ago

Did you try to run the TMC exe as administrator ? Wrong .NET version -> "TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5"

FunkyFr3sh commented 4 years ago

Now it works (with .NET 4.5)! But it looks exactly the same for me with and without cnc-ddraw, so I'm not sure what you mean. But maybe it's just loading too fast. I don't see any loading screen, I'm right in the gameplay.

LuKeSt0rm commented 4 years ago

The new hud is activated in the game settings, but is not loaded. If you start without wrapper native and with DirectDraw enabled in the game settings you will see the new hud. You can also see a preview of the hud in the game settings at the bottom at "View".

Edit: I deactivated the option "Enable DirectDraw" in game settings, because if you set the resolution different than "640x480" it will not work with wrapper.