End of GSoC and Future Plans

First of all, some comments regarding what I have been coding since my last blog post. Mostly I have been hunting bugs, and testing games to if all was working well.

There were some compilation/linking problems with some ports and with some help I have hopefully fixed them all, still there are some ports that have not been tested yet. Some problems arised also when switching between SDL and OpenGL graphics modes, but those bugs are fixed now. Also, there was some discussion regarding the aspect ratio modes in devel list. I was taking as base for the aspect ratio correction system the one that the SDL graphics manager had, but that wasn’t really necessery for the OpenGL rendering, as it does allow scaling to any size. After some talk, I removed some unnecessay options, and now there are 3 aspect ratio modes: “None”, “Conserve” and “Original” (this last one added after its suggestion in the discussion).

And, the big news are that Google Summer of Code (Winter of Code for me here, hehe) has ended, at least the coding part has ended last monday. Now it is time for the final evaluations, and I hope that finish well 🙂 It was a really nice time, and a great experience 😀

I finished well the SDL backend refactoring (including most of its ports), into a modularized design, and the OpenGL graphics manager for the SDL backend is working good. However, I could not finish all what I planned to do, I could not finish the WinCE port refactoring in time. It is a really complicated port to modularize, there is a lot of common code between the events and graphics parts, and without being able to test it nor even compile it, it is a really hard task. I will have to discuss a bit about this with my mentors later.

And for the future, I plan to continue working on ScummVM. There are some pending feature for implementing in the OpenGL graphics manager, like shaders, that because the short available GSoC time I couldn’t do. And I thought before starting GSoC that I would be able to implement them in time, but reality showed to be more complicated. Still, before I hope that my branch be merged with trunk, and in case there is some problem for that, I plan to continue my work and fix those issues.

Status Report

This last week, I have been working mainly on fixing bugs, and testing the SDL refactoring changes and the new OpenGL graphics manager. So far, it is going well. Here is a list of the changes:

  • Merged from trunk (Not upto actual HEAD, but was a big update)
  • Fixed a crash when a texture was only partialy updated, crashing Broken Sword 2.
  • Fixed a hack for reseting the wndow scale to x1 when starting a game. I added a resetGraphicsScale() function to OSystem.
  • Added options in Graphics Mode list for switching between SDL graphics modes and OpenGL graphics modes.
  • Added OpenGL libs to configure script for MingW, it was not compiling before.
  • Added support for BGR pixel formats.
  • After some discussions and changes, improved the way that the default fullscreen mode was selected. Now it will prioritize the desktop resolution, and in case that it is not available select one that has the same aspect ratio the desktop has, and as last resource use the one with the best metric.
  • Implement coordinates adjustments for warpMouse, the cannon sequence of COMI was failing when using aspect ratio correction and resizing the window.
  • Disabled 16/9 and 16/10 aspect ratio corrections, they are not really needed.
  • Implement some basic OpenGL auto detection for the configure script.
  • Other minor fixes, and some commenting.

Also, it is needed some help testing the modified Ports, and testing the new OpenGL graphics manager, you can follow the discussion on the mailing list.

At this point I am behind my shedule, I should have finished the OpenGL graphics manager quite ago, and start working on refactoring some ports. So, the next plans are to continue debugging the changes I made, try to finsih the WinCE port refactoring and the next week work on merging with trunk and doing the last tweaks.

OpenGL Graphics manager almost there

 

The OpenGL Graphics Manager is now usable 😀 It displays games well, and has all the features that the SDL Graphics Manager has (but all the scalers filters), and includes some new features like windows resizing to any size.

It is now able to use GL_NEAREST and GL_LINEAR as filters for scaling the textures. You can switch filter modes with Ctrl-Alt-F hotkey. That is not a great variety of filters, compared to the scalers that uses the SDL Graphics Manager, but they should be hardware accelerated rather than software processed.

It is now able to use GL_NEAREST and GL_LINEAR as filters for scaling the textures. You can switch filter modes with Ctrl-Alt-F hotkey. That is not a great variety of filters, compared to the scalers that uses the SDL Graphics Manager, but they should be hardware accelerated rather than software processed.

I also changed the overlay pixel format to RGBA5551 insteand of a RGBA4444, allowing a better color display. I had some problems working with the alpha channel of the overlay, because OpenGL doesn’t include any function for blitting into a texture when updating it. Also, the SDL Graphics Manger uses a RGB565 format for the overlay, but thanks to its dirty rect system it doesn’t need to use and alpha channel, as it only draws the modified overlay areas. However, I don’t make use of a extensive dirty rect system on OpenGL, so I need to use an alpha channel.

So after some work I finaly decided to nulify the alpha bit from the pixels buffer when updating the texture, and it is working now almost exactly as the SDL Graphics Manager does. The only difference is that it has a bit less for green colors in favor for a bit for alpha.

One of the major changes was redesigning the blitting system. Previously I had a copy of the texture data on each GLTexture, and when updating the texture I also updated the extra data. Then I could use this data for recreating the textures after an OpenGL context change or a filter change. However, functions like lockScreen() and grabOverlay() have to return the original pixel data from that texture, but the copy I had wasn’t the original data, as in most cases it was already converted from a palette format to a RGB/RGBA format. So I decided to remove this extra data from GLTexture, and add inteand some new variables on the graphics manager that would save the original pixel data. Now, when updating the screen or the overlay, the pixel data is saved on those variables, and the a dirty rect is extended with the modified area. When updating the screen the pixel data in its original format is converted to the OpenGL texture format in case they have paletted/clut8 format and the OpenGL texture is updated. For RGBA8888, RGBA5551 and other common RGB/A formats there is no conversion needed, OpenGL will do it already for us.

The other major change is the aspect ratio feature. Its mode can be switched with Ctrl-Alt-A, and it will loop through all aspect ratio modes. The default, aka “Normal”, mode will not conserve the aspect ratio when resizing the screen, it will just stretch the contents to the screen size. The “Conserve” mode, will mantain the current aspect ratio in use. And the “4/3″, “16/9″, and “16/10″ modes will stretch the contents to that size. When resizing the window, or using a fullscreen mode that doesn’t have the current aspect ratio in use, only one dimension of the screen contents will be stretched to the window size, and the other will not fill all the window size. So black stripes will wrap the contents and the aspect ratio will be mantained.

Another addition is Ctrl-Alt-Enter. While Alt-Enter will enter fullscreen with the best available mode (and exit it if already in fullscreen), Ctrl-Alt-Enter will loop through all available fullscreen modes. This enables the user to select what fullscreen mode to use.

Other minor implementations:

  • OSD messages, pretty much like the SDL Graphics Manager style
  • Ctrl-S will save now a bmp screenshot of the current screen
  • Screen shake effect is working

Still, I need to complete some more things before finishing with the OpenGL Graphics Manager:

  • Add options for switching between OpenGL manager and SDL manager
  • Porting to OpenGL ES and testing, most OpenGL code should work for GLES, still I need some testing
  • Code cleanup and documentation

 

OpenGL Advances

SDL/OpenGL Graphics Manager in action

I have advanced in many things this week. And the OpenGL Graphics Manager can now display the ScummVM start menu (There are still some little issues to fix).

I started the week merging from trunk, so I can make sure that my changes are fully compatible with the actual development. But, I had to merge manually some files, and also to revise all merged code (There were some merging errors, and ton of conflicts).

I also fixed lots of errors on the GL manager, there were lots of segfaults thanks to bad memory allocation, I was reserving less than I should, and some problems with non power of two textures.

x2 Scale Factor

Now, the Overlay and Cursor are working. The overlay was simpler to implement, as it uses a 16 bit rgba pixel format, but the cursor was complicated because it is needed to convert the cursor from a paletted surface to a rgba one, because OpenGL does not support nicely paletted textures.

I have worked too on scaling and resizing the ScummVM window. With OpenGL a texture scaling is pretty easy, though it can complicate because resizing the window causes problems with the OpenGL context, and I also had some hard time for adjusting the mouse coordinates to the current scaling.

Resized x1 Window

After many tries, and fixes, now the graphics manager supports x1, x2, and x3 scale factors (Hotkeys: Ctrl+Alt+(Plus/Minus)), which will resize the overlay size, and it also supports the window to be resized from the borders to any size. Resizing from the borders won’t modify the overlay or game screen size, so it they will be stretched to fit into the window.

However, I still need to implement a feature for maintaining the aspect ratio while resizing the window, so black borders will be added around the screen instead of breaking the aspect ratio.

Finally, I implemented fullscreen support. Had some bad time debugging it, because thanks to some segfaults raising when ScummVM was in fullscreen, not allowing me to change to Visual Studio. Still, I could find the problem revising the code, and now fullscreen works well. But, I need to do a better testing of fullscreen and also scaling on linux, I have made most tests on a virtual machine and the virtual machine does not handle OpenGL and fullscreen well.

My plan for this week is to implement aspect ratio support and game screen drawing. This 2 things are the last biggest things I need to work on, and only some small functions, documentation and some code cleanup will be left.

Status Report

I have created a new class “OpenGLSDLGraphicsManager”, which is a subclass from the OpenGLGraphicsManager. This way, I will not mix SDL code, and so allow other backends to make use from the OpenGLGraphicsManager.

I had some problems with how the OpenGLSDLGraphicsManager and the SDLGraphicsManager worked with the SDL backend. I need that both managers be able to work with the SDL backend and that implies that they need to be able to work along with the other SDL managers.

The problem is that the SDL event manager needs to get access to some intern data and call some functions from the graphics manager. So, I need to have some extra public functions declared in the SDL graphics managers that are not the ones called from OSystem.

For allowing the SDL event manager to call these functions, my first approach was to create an abstract “BaseSdlGraphicsManager”, which would be parent from SdlGraphicsManager and OpenGLGraphicsManager. However, this would lead to class ambiguity and a inheritance diamond problem. Not something really nice.

Finaly, I decided to move those functions to the virtual GraphicsManager class. This will polute a bit the GraphicsManager, as some other backends may not need to use those functions. However, any other way for resolving this would be much more complex and would not be really worth the problem.

Another solution, could have been to move those functions to OSystem_SDL, and include in each one a condition like:

1 if (_graphicsManagerType == kOpenGL) {
2  ((OpenGLSDLGraphicsManager  *)_graphicsManager)->callFunction(arg1, arg2, ...);
3 else if (_graphicsManagerType == kSDL) {
4  ((SDLGraphicsManager  *)_graphicsManager)->callFunction(arg1, arg2, ...);
5
6 }

But that is not very elegant…

Also, I implemented the PixelFormat related functions, and changed how the GLTexture class manages the pixel format. Now GLTexture setups its pixel format from the constructor insteand of having multiple classes for each format.

And, after implementing the GFX functions, at last I could make a blank opengl screen to pop up in my screen. Still nothing is blitted into the screen, but that will be the next step 🙂

So, for this week, I plan to implement the drawing to the screen. That will be the main task, but I plan to do some cleanup and improve the actual code as well (It is a bit messy in some parts)

Unexpected Problems

Last Wednesday, I had some problems with partitions from my hard drive 🙁

The system partition would not be recognized, so I could not boot the pc, and it seems that when I tried to fix it I damaged it harder…

But now I am back with a reformatted disk. I lost some data, but at least I could backup some of my files before reformatting. Well, now I shall continue with the project.

Second Milestone Completed

I have finished the second milestone coding on my schedule, and would be good to explain what the refactoring changes are. Still some testing is needed for the refactored backends that I am not able to compile, but the main coding is complete.

For this milestone I have been working on refactoring the SDL backend, and also its sub backends, including the ports for GP2X and GP2XWIZ, LINUXMOTO, Samsung TV, Symbian, and of course the Windows, Mac OS X and POSIX based OS.

My first step for refactoring the SDL backend was to organize the SDL code and functions into specialized Managers classes, which are namely: SdlTimerManager, SdlMutexManager, SdlMixerManager, SdlGraphicsManager, SdlEventManager, SdlAudioCDManager.

The OSystem functions are already divided into categories which make the job easier, and there were already some modular classes before I started working (Like DefaultTimerManager, AudioCDManager, FilesystemFactory, SaveFileManager and others). However, some SDL specific code and functions were a bit ambiguous and took a bit more to decide how to deal with the code, as they were used by the graphics code and the events code. In most cases I just opted to create some extra public functions on the SDL Managers, so the other managers can call that code or get some data.

I will explain now a bit about each new manager in particular

SdlTimerManager

The SdlTimerManager was a simply class to implement. It subclass from DefaultTimerManager, and what I only needed to do was to setup the SDL timer callback and invoke the callback handle from the parent class.

There was a bit of discussion when I added to the manager the getMillis, delayMillis and getTimeAndDate functions. I added them to the timer manager thinking on the manager as a “Time” related manager, but after some feedback from Fingolfin, I realized that the purpose of the Timer Manager was indeed only related to “Timers” and no “Time” in general. After that, I just moved them back to OSystem_SDL.

SdlAudioCDManager

This class inhereits from DefaultAudioCDManager, which was initialy called AudioCDManager and was declared as a singleton class. I removed its singleton status, having to subclass a singleton class is painful and bad for health. And so, I renamed the AudioCDManager to DefaultAudioCDManager, and created a pure abstract class “AudioCDManager” (Not to confuss :P) as base for the DefaultAudioCDManager.

The functionality of the DefaultAudioCDManager is practically the same as before, it emulates the cd playback trying to read the sound files from the local folder, and if it fails makes a try, and call the real cd playback functions. Those real cd functions were previously on OSystem, but I moved them to the AudioCDManager insteand.

This last move, allows that a subclass from DefaultAudioCDManager be able to easily implement the real cd functions when overriding.

One other major change, appart from moving some OSystem functions, was to redirect all calls to the singleton instance of the manager to g_system->getAudioCDManager()->function(). Not really tough, a CTRL+SHIFT+H did most of the work 🙂

SdlMixerManager

The mixer manager was a bit more complicated. There was already an Audio::MixerImpl class being used, but there was many SDL mixer related functions on the OSystem_SDL class. My first thought, was to use the same approach I have been using with other managers, like the SdlTimerManager or the SdlEventManager, and I subclassed the Audio::MixerImpl with the SdlMixerImpl class (Named this way for consistency with MixerImpl).

But having things this way created a big incovenient. The Audio::MixerImpl has the audio sample rate saved in a constant variable that is initialized taking the value from an argument from its constructor. Having things this way, leaved 2 ways open, or making the sample rate variable not constant (something not really good), or making a kinda hackish way for getting and passing the sample rate at the contructor list.

Seeing both options weren’t really good, Fingolfin suggested me to have the SdlMixerManager wrap the Audio::MixerImpl insteand of inhereiting from it. So, I moved this way, and all went well.

I also created a new class, DoubleBufferSDLMixerManager, for the double buffering playback, needed for Mac OS X and GP2X platforms. This class inhereits from the SdlMixerManager, and changes a bit how the audio callback is handled.

And finaly, there is also a SymbianSdlMixerManager subclassing the SdlMixerManager. Symbian port needs to downmix the sound buffer if there is no stereo support.

SdlGraphicsManager

The biggest manager and the most complex one. There are many graphics related functions, and took some time to revise all code. I created a new abstract class as base for it, called GraphicsManager and a NullGraphicsManager for the null backend.

There did not arise many problems, some thought was needed for deciding what to do with variables shared by both events code and graphics code, for which I ended creating and making public some functions.

This class has also many subclasses for different ports, Symbian, GP2X, GP2XWIZ and Linuxmoto. Most changes needed because low resolutions and being unable to support scalers or some other features.

SdlEventManager

The events manager subclass from the DefaultEventManager, which handles the engine related events. The SdlEventManager insteand handles the backend related events, but it also implements the real code to poll the events that the platform sends.

The way this works now is a bit “tricky”. Engines can get the event manager from OSystem, g_system->getEventManager() and update the events queue calling the pollEvent() function. However, when constructing, the SdlEventManager passes the OSystem class to the DefaultEventManager as a EventSource. This makes the DefaultEventManager to call pollEvents() from OSystem, but OSystem_SDL calls to pollSdlEvents from its sdl event manager.  Before, the actual pollSdlEvents() was directly on OSystem_SDL, just that now is on the sdl events manager. The call stack is kind of recursive, but it isn’t that bad.

The SdlEventManager has some backend specific subclass also, for GP2X (And GP2XWiz also), Linuxmoto and Samsung TV. Most of the functions overrides are for remapping some joystick or buttons from the handheld devices.

SdlMutexManager

The mutex manager is the tyniest manager, only 4 functions. It inhereits from the abstract class MutexManager I created for it, and the SDL code was practically copy pasted from the OSystem_SDL.

OSystem_SDL

On the other hand, the OSystem_SDL class, aka the SDL backend inhereits from the ModularBackend class, designed for the first milestone. Most of the calls to the Managers functions are made in the ModularBackend, so now OSystem_SDL needs to implement only some few functions, that include general functions (like initBackend()) and other misc functions that can’t be in a manager.

And, I have also created 3 subclasses for the SDL backend. OSystem_Win32, for Windows. OSystem_POSIX, for unix systems. And OSystem_MacOSX, which inhereits from the posix class. This way things are a bit more organized, and there are some less #ifdefs definitions in middle of the code that make it harder to read.

Well, that is all for now, I will start working on the OpenGL implementation from now on. My bad I am 6 days late, I should have started last moday…

However, the week I had reserved for the OpenGL ES implementation can be fused with the other OpenGL weeks in the schedule, as it is more like OpenGL ES testing rather than implementing new features.

Alejandro

Some ports modularized, some left

I have done some progress modularizing the SDL based ports. Posix and Mac OS X ports have been refactored and are working well, and I have also committed modularized versions of Symbian and Samsung TV ports. However, these last 2 ports still need some testing (I have send a message to mail list asking for help).

Now, I am working with the WinCE port, a task I have started some time ago. I plan having finished the WinCE port by today (or in worst case tomorrow), as well as the Linuxmoto port. And for monday, I should have modularized the Gp2xwiz port, the last one in my list (By now, I will work on porting other ports after finishing with OpenGL).

On monday or tuesday, I plan working on documentation after finishing with all SDL based ports, and also doing some general cleanup of code. This will leave me with 2 days of delay for starting my next task, creating an OpenGL Graphics Manager. However, 2 days are not a great deal.

Now, ports

I have to apologize, as I have not been really productive last week. I hope to be more active this week and make a  good progress on the project.

Last week I have made some fixes and tweaks to the ModularBackend code, and I have fixed all the problems with some code in the new SDL Managers that was having problems after modularization, principally because it was needed to access some protected variables or methods that were now in other manager class.

I have also created a new port for Windows, in backends/platfrom/win32. It is a subclass from the SDL backend, but it contains some code specific to Windows. I will be doing next the same for Posix and Mac OSX systems.

I have also been working on applying the new ModularBackend design to other ports, like WinCE and Symbian. However, I can’t compile those ports and test them and working “blind” is not really nice. I am still double checking the modifications and working on the new WinCE and Symbian Managers, so these commits will need to wait a bit.

This week, I plan first to complete the Posix and Mac OSX ports, which will be similar to the Win32 one. Then, I will continue with the WinCE and Symbian ports as well as all other SDL based ports.

I would like to work on modularizing non-SDL ports, but for next week I should be starting with the OpenGL Graphics Manager. So, non-SDL ports will need to wait until all other milestones are finished, and if I have left time I will be working on them.

Refactoring of SDL Backend

I think I have finished the first milestone, the design of the new backend system. This is reflected in the ModularBackend class, the new abstract classes (AudioCDManager, MutexManager, GraphicsManager), and the default and null classes (DefaultAudioCDManager,  NullGraphicsManager, NullMutexManager). I may still need to tweak some things, but the design is pretty clear now.

I’ll now continue with the SDL refactoring, which is going good. All SDL Managers have been implemented by now, but I still have lots of work to do.

Now, I have to fix some code that is commented out since modularization, and I’ve to revise sdl code in general but specially the events and graphics managers.

Then, I’ll implement new OSystem_SDL subclasses for Windows, Posix/Unix systems and Mac OSX.

Finally, I’ll start creating the documentation for the changes I’ve made.