aliens

Author Topic: OpenXcom performance for dummies  (Read 12788 times)

Offline bramcor

  • Captain
  • ***
  • Posts: 76
    • View Profile
OpenXcom performance for dummies
« on: August 24, 2010, 04:03:52 pm »
Cut & paste from another thread:

So by default the globe view is only updated 10 times per second? That seem kinda low compared to my refresh rate of 60 Hz...

Makes me wonder how the guys at Mythos ever got UFO to run smoothly on my 486, when OpenXcom on a much more powerful modern system crawls to a halt.

Is compiled C++ that inefficient? Is the code immature? Should we all quit our day jobs and go back to hacking assembler code?

Reason I'm asking is not to be an ass, but that my system ought to be able to generate a gazillion fps of this relatively simple low poly representation of Earth .. but somehow it doesn't :P

Please help me understand why the world of OpenXcom code does not work the way my mind expects it to! ;)

Offline Daiky

  • Battlescape Programmer
  • Administrator
  • Commander
  • *****
  • Posts: 904
    • View Profile
Re: OpenXcom performance for dummies
« Reply #1 on: August 24, 2010, 07:12:07 pm »
Hi bramcor,
I think you are mixing up game timers and performance (or FPS) here. Let me try to explain:

A game timer is something that calls a function at fixed intervals to do some recalculations and update the state of objects in the game. In this case, it is used to update the in-game time for the day-night cycle(which updates the globe), monthly calculation of base costs, ... later maybe movement of ships(which will update the globe), AI, etc...

It is very important that on every system this is at exactly 10 times per second, increasing that frequency will just make the gametime go faster, and certainly has nothing to do with performance like you say in your title.

If you would check the real FPS openXCOM gets, I bet it is a lot higher than you get in Call of Duty 4 :)
« Last Edit: August 24, 2010, 07:26:58 pm by Daiky »

Offline SupSuper

  • Lazy Developer
  • Administrator
  • Commander
  • *****
  • Posts: 2162
    • View Profile
Re: OpenXcom performance for dummies
« Reply #2 on: August 24, 2010, 07:35:36 pm »
1. The game screen refreshes itself as fast as it can. But the *ingame timer* (the clock you see on the Geoscape) only updates 10 times per second. If the ingame timer advanced as fast as it could on a modern computer, you could barely react to any ingame events as the time would just whizz on by as an ingame month passed in a second (this'll happen if you run the original without any emulation or slowdown utilities). Updating every 0.1s is fast enough for any player to react to (eg. In 5 Secs speed, 50 ingame seconds will pass every real second. In 1 Day speed, 10 ingame days will pass every real second).

The globe itself only redraws itself when the ingame timer updates, because stuff on the globe only changes when the ingame time changes. It'd be a waste of time to redraw when nothing at all has changed.

2. Technically speaking, OpenXcom is not a pinnacle of speed. I am not a pinnacle of programming. SDL rendering is slow. Globe rendering is slow. You'll never notice this on modern systems, but OpenXcom would probably not run well on low-end systems, specially not a 486 like the original. The original X-Com was written in C/ASM by much more experienced programmers, and there's no reasonable way to figure out how they did it, so best we can do is guess.

The current globe is not a "real 3D-accelerated globe" like you'd find on a modern game, but a 2D representation like the original. It has to take the flat world data from the original X-Com data, convert all the coordinates to radians for modern trigonometric functions, generate the ocean polygons, figure out which polygons are currently facing the player, map it all to a ortographic projection for a 3D look on-screen, shade it according to daylight, etc. It's not a simple problem. But the current solution is accurate and fast enough for the purposes of the project. If someone can come up with a better method, well, this is open-source, they are free to post their approach.

Offline bramcor

  • Captain
  • ***
  • Posts: 76
    • View Profile
Re: OpenXcom performance for dummies
« Reply #3 on: August 24, 2010, 08:41:29 pm »
Thank you guys for preventing my head from exploding :)

After posting I realized that half my question was based on a misinterpretation of the thread, where I first asked the question. I usually know game timers are different from refresh rates, but somehow I managed to excrete a brain fart in public... actually I was more interested in the part about how coding OpenXcom in c++ is different from how UFO was made and what impact it has on the systems that execute the code.

One of the things that fooled me was my observation of day/night cycles in OpenXcom, where I saw the boundary move in relatively huge steps out of sync with the timer. I simply assumed this was an expression of the overall game timer, mixed it up with refresh rate, forgot to look at how fast the time updated and never did the math on how many times per second that corresponded to. Then I decided that the movement of the day/night boundary would be my new measure of performance and fps. I could be doing stand-up with this stuff!

Come to think of it, I have a feeling that the timer updated less than 10 times per second in UFO - but as you pointed out that is dependent on the hardware you run it on...
« Last Edit: August 24, 2010, 08:44:15 pm by bramcor »

Offline Daiky

  • Battlescape Programmer
  • Administrator
  • Commander
  • *****
  • Posts: 904
    • View Profile
Re: OpenXcom performance for dummies
« Reply #4 on: August 25, 2010, 01:53:46 am »
actually I was more interested in the part about how coding OpenXcom in c++ is different from how UFO was made and what impact it has on the systems that execute the code.
Big parts of the code of XCOM UFO must have been copy-paste from Laser Squad (Julian Gollop's creation), which was the game XCOM UFO was based on. That game was written for systems like ZX spectrum, C64,... Proof of that is for example in a lot of the variables that had a maximum of 255, that is 8 bit. Also one of the reasons why initially the game was split up between 2 executables, to save memory. Data that needed to be loaded are very compact binary blocks, byte by byte read from disk directly into memory. Such things were a typical way of working in assembly written software. The reason why XCOM UFO was so easely ported to Amiga was also because of that, the Amiga could nicely run ZX spectrum, C64, etc games.
Anyway, when the game was released, hardware was already far beyond the minimum requirements of XCOM UFO. Later on, it was ported into one EXE and compiled to run on windows.

Offline pmprog

  • Commander
  • *****
  • Posts: 647
  • Contributor
    • View Profile
    • Polymath Programming
Re: OpenXcom performance for dummies
« Reply #5 on: August 25, 2010, 09:37:53 am »
2. Technically speaking, OpenXcom is not a pinnacle of speed. I am not a pinnacle of programming. SDL rendering is slow. Globe rendering is slow. You'll never notice this on modern systems, but OpenXcom would probably not run well on low-end systems, specially not a 486 like the original. The original X-Com was written in C/ASM by much more experienced programmers, and there's no reasonable way to figure out how they did it, so best we can do is guess.
There are two main points in DOS over Windows
  • In DOS you have direct access to the video memory, you have no APIs to interact with. Meaning, drawing pixels on the screen is as simple as setting a byte in memory. In Windows, You have a Window, which has a handle and a DC (Device Context). With all the memory protection etc. that happens, you have to "lock" the DC (The act of GetDC locks it, ReleaseDC frees it) in order to draw on it, then you have to use the provided API to draw, which will have layers of security and memory protection to make sure you only draw where you're supposed to.
  • With the exception of TSRs, DOS is a single process system. Once XCOM is running, nothing else runs. Windows has to manage CPU timeslices for passing to other running processes (Email client, Web browser, Windows Indexing, MSN Messenger, etc. etc. etc.)


But the current solution is accurate and fast enough for the purposes of the project. If someone can come up with a better method, well, this is open-source, they are free to post their approach.
I too would love to see it. There must be a better way than how I did it, but I'll be damned if I can think of it.