The bin partitioning in ActorMap worked by dividing the map up into a few chunks of cells, each of which would contain some actors. Unfortunately, the bins were accessed directly in world coordinates which are on a scale 1024x greater than cell coordinates. This lead to all actors being placed into the bottom right bin. When checking for actors in a box, only this bottom right bin would be iterated for actors. Thanks to the fact this bin indeed contained all the actors, some clamps on the input ranges and filtering required per bin anyway, this actually returned correct results. Effectively, it was as if there was no spatial partitioning at all.
Not surprisingly however, this is fairly inefficient. By correcting the spatial partitioning to actually partition we see a 7x speedup in ActorsInBox on the RA shellmap.
Additionally exposed an InitializeSettings method on game to initialize the global settings so that other classes can set up all the secret dependencies on the global settings required.
Textures, FrameBuffers and VertexBuffers allocated by the Sdl2 Renderer were only being released via finalizers. This could lead to OpenGL out of memory errors since resources may not be cleaned up in a timely manner. To avoid this, IDisposable has been implemented and transitively applied to classes that use these resources.
As a side-effect some static state is no longer static, particularly in Renderer, in order to facilitate this change and just for nicer design in general.
Also dispose some bitmaps.
This enables the map importer to map the .ini video definitions to ours.
The mapping generally is as follows:
Intro => BackgroundInfo
Brief => Briefing
Action => GameStart
Win => GameWon
Lose => GameLost
An issue in some Red Alert maps means that this mapping is not always
quite correct. In those maps that do not have a 'Brief' video defined
(scg03a is an example), Westwood has assigned the video that should
probaby have been the 'Action' video to the 'Intro' slot instead. I can
only assume that that was done due to some limitation in the original
game code. Mappers will have to correct that assignment manually in
those cases.
Values for the report are generated by calling ToString on members, we avoid calling this on value types for performance. By instead just copying the value we can delay calling ToString until later and avoid spending time and memory creating strings that usually go unused.
Reinitializing the initial cell info layer for the path search took a fair bit of time. We cache this initial setup so it only has to be done each time the map size changes. A CopyValuesFrom method in CellLayer is provided which copies values between layers by just copying the internal arrays for super speed.
This speeds up InitCellInfo 10x.