marcel303 / keen

Keen Dreams port using SDL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Some notes

fragmental opened this issue · comments

These are some notes and observations I've made while using the executables for windows and linux. I've used both a windows executable you provided in a zip file, and a windows executable I built using visual studio and have made a note where they differed. The linux version I built.

Windows
-High cpu usage about 30 cpu%
-Menu runs at high fps ~300-500. Makes using the controller to move the cursor difficult. Mouse works fine
-In-game (levels, overworld) will drop back down to 70fps. CPU usage stays the same
-/tickfps causes game to also run at ~300-500 fps
-My build has this weird thing where the actual cursor location can shift around as you move in and out of the window. Your build doesn't seem to have that problem, but it also doesn't allow the cursor to exit the window.
-No matter which button is hit on the controller, the game will automatically choose "Try again" when "Exit to Tuberia" is selected. Works fine with keyboard.
-When I use x360ce to make my controller emulate an xbox360 controller, jump is A, and shoot is B.
-Also x360ce tells me that the xinput dll you provided is for 64 bit, and automatically replaces it with a 32 bit dll of the same name.
-One of my save files seems to have corrupted?

Linux
-cpu usage seems relatively low
-/tickfps causes the game to feel a little slow. Or maybe it runs fast without it? I haven't played the dos version so I can't really tell.
-I don't know how to monitor fps on linux.
-Gamepad Buttons work as expected when selecting "Try again"
-Keyboard buttons seem to be remapped or something? Escape works fine. And maybe Enter, but space doesn't do what it's supposed to, and when typing in the name after dying, or the save name, the buttons are different. 1 is 9. backspace is U. etc.

Both
-Jump is X, shoot is A. No button for menu or stats. Any way to change that? I would prefer jump to be A, and shoot to be X. I would also like to be able to bring up stats from the controller as well as exiting to to menu, and navigating the menu as much as possible.
-I'm using a directx controller. A Logitech Rumblepad 2.

I don't know if this is original functionality or not, but...
-When I press any button standing directly above a flag, I will automatically go to a level on a separate part of the over world. And I can do this indefinitely, even if I've already completed that level. Sometimes that level will automatically restart when I die without giving me any option dialog.
-If I am falling from a great height and pressing toward an opening in a cliff, I am unable to make it into the that opening. I may be able to grab what is inside if it is close enough to the edge.

Hi, I will try to go through these issues one by one and address them!
Windows:

  • High CPU and high frame rate: this is due to vsync being disabled. I added a change which explicitly tells SDL to use vsync (06b746a)
  • Menu high FPS: Same issue. Game drops to 70, but that's only artificial. It still draws the game at 300-500 most probably. It just updates the game logic at 70 fps. Should also be fixed with the above fix. Unless SDL is broken or your display driver forces vsync to be off.
  • /TICKFPS causes the game logic to run in lock step with the actual frame rate. This only works correctly if vsync is working, and your display is set to somewhere around 70Hz. If your display is synced at 60Hz, the game will feel a bit slow. The reason for having /TICKFPS is to have super smooth scrolling, with one logic/scrolling update per frame being drawn.
  • Cursor shift: This is due to building a Debug version of the game I suspect. Debugging doesn't work very pleasantly when SDL is grabbing the cursor. It makes it hard to go to the debugger and set breakpoints etc. Try compiling a Release version instead! I also added a warning about this when building a Debug version (5f43771).

Linux:

  • Low CPU: This means vsync is doing its thing.
  • Slow: Probably because your display is synced to 60Hz. Try increasing it to 70Hz (this is what the DOS game used). Otherwise, do not use /TICKFPS :-)
  • Keyboard buttons: Ouch! There was an issue where the keyboard mapping from SDL to Keen's key codes was only done on Windows. This is fixed now. Also I extended the translation table to translate all keys used by Keen instead of just a small selection (I got a bit lazy here before :-). See 06b746a and 20cdc56.

Both:

  • Menu and stats: Should be fixed with above changes.

To-do:

  • Game save corruption.
  • Gamepad issues.
  • Stats from the controller.
  • Flag issue. I will look into this..
  • Falling issue: This is how I remember it from the DOS days!

Ok, I have tested a new Windows build.

  • I can confirm that cursor shift was the debug version. In visual studio, changing the build target is controlled through a little drop-down menu. It's very easy to change, but the default is debug.

  • Selection seems to work correctly from the controller in the "Try again/Exit to Tuberia" menu.

  • vsync didn't seem to work, so I checked graphics settings and made sure it was set to "Application Settings" so the application had control over vsync. Still didn't seem to work. However, if I force vsync to "On" in the graphics settings, vsync does work in the game. Though it would be forced on globally, as well. This laptop has integrated Intel graphics and I'm using "Intel Graphics and Media Control Panel" to change the settings. Vsync being on does fix the noticeable screen tearing I was seeing before, that I never mentioned. CPU usage also drops significantly, as expected. I might copy the files to a different windows computer and make sure that the issue isn't specific to this system.

  • I have been able to consistently reproduce the save file issue. I think that, for some weird reason, the save files are incompatible between builds, even if the source hasn't changed. If I save the game, rebuild the exe, and then replace the exe, the save file no longer works.

And I've test a new Linux build

  • Most of the keyboard buttons are right, but not the top number row. 1 is still 9 etc.

Ok, thanks! I will look into SDL if there's any other option to try to get vsync enabled. Perhaps a OpenGL driver extension is needed on Windows.

I suspect I know what's happening with the save games. And I'm a little surprised this didn't affect me on Macos. The game saves are implemented in a very simple way, where all of the objects (the player, the enemies, and everything else) get written to disk by just writing out their memory contents. Each object is the exact same struct, with some information about location, active sprite etc, and a pointer to a 'statetype' object. The statetype object defines the actual behavior of an object and can change depending on the state of the object (player walks, jumps, etc). It has pointers to tick (think), collision response (react) and other functions. Now.. each game object points to a state type and these pointers get written to disk. Upon loading the game, these pointers will point to the same memory, inside the executable, at the time of saving. Normally on DOS this worked perfectly. But modern OS'ses have a security feature where the memory contents of an application (where the data, functions, etc are stored) gets randomized at startup of the application. This to make it more hard for hackers to know where certain data lives, and poke/change values into it to cause security risks or to prevent them from executing certain code by making the execution pointer point to something else. Anyway, long story.. but these changing memory locations for the state types are (I suspect) what's causing these crashes. I know a solution to this, which will make saving games a tad slower, but first I'd have to make a table for all of the known state types. This is a lot of work. I put the list of all state types up here: https://pastebin.com/2R6NqZW6. Maybe interesting to look at since it reveals some things about how the game is coded and works internally. :-) I will work on this later, when I'm back on Windows myself.

Oh wait, the issue does happen when I switch between debug and release builds, so I'm able to debug the issue after all! :-) I've made a list of all state types, and convert state type pointers into indices into this list when saving. When loading it gets the state type pointer again given the index that was saved. See: 14c56ff

This does mean your old save game(s) will no longer work, but they will work from now on, with different builds of the game etc.

I tested and have confirmed that the save games do work across builds now.

Ok thanks great to hear that's fixed! I'm making separate issues for the remaining bugs and closing this one.

Remaining issues:

Fix vsync not (force) enabled on Windows.
This issue is causing high CPU load and difficulties navigating the UI.

Better document the various command line options.
/TICKFPS unclear for instance.

Source incorrectly ships with 32-bit version of XInput dll.
Provide 32-bits x86 version of the XInput dll.

Weird issue with flag at the start of the game.
When I press any button standing directly above a flag, I will automatically go to a level on a separate part of the over world. And I can do this indefinitely, even if I've already completed that level. Sometimes that level will automatically restart when I die without giving me any option dialog.

Fix keyboard mapping 0..9 keys.
Most of the keyboard buttons are right, but not the top number row. 1 is still 9 etc.