June Development Report

Being one of our most popular games, quite a bit of effort was put into improving our World of Warcraft support for the Cedega 6.1 beta. There were some instances of broken character or foliage models which we tracked down to a combination of our "Fragment Offset" option and GLSL. With Fragment Offset disabled and when running in mixed mode, all of the models look correct now using 2.0 shaders. We also had reports that distant objects such as mountain ranges were appearing as all-white instead of being properly fogged. This turned out to be a bug with our fixed function over vertex shader code (labeled "Fixed Program" in the GUI) and has been resolved. However, distant objects may not be correctly hidden by fog.

Another issue that has plagued WoW users since 6.0.2 is the inability to run WoW in OpenGL mode (by appending "-opengl" to the command line of the application's shortcut). There was a regression that snuck into 6.0.2 involving how we report video card details to games. This has also been resolved in the 6.1 beta, but you must also disable Framebuffer Objects in the GUI for this mode to work in WoW. We also tracked down a bug where certain objects such as characters or the ground would be rendered with incorrect textures. This typically occurred after moving to a new zone, and it has been fixed in 6.1. Finally, we tracked down the intermittent crashing since the last major WoW update to a thread-safety issue in a particular case of our filesystem APIs which WoW started to use; that was also fixed.

When using the mouse in relative mode in DirectInput, there needs to be a way to make sure the mouse always gives reliable data. The big problem here is that when the mouse cursor reaches an edge of the screen it stops reporting movement toward that edge. To get around this we are repeatedly (behind the scenes) moving the cursor back to the center of the screen when it is hidden and in relative input mode. This ensures that the mouse cursor will never get too close to the edge of the screen and will always report reliable movement data. Under Windows, this same functionality occurs; however, unlike our implementation, the return value of GetCursorPos() still tracks a sort of 'virtual cursor position' and will return an appropriate value. A title on which we are currently working makes use of this function while getting mouse information through DirectInput. This resulted in the menu mouse cursor always jumping back to the same location on screen, making it pretty much useless.

The solution to this problem required two changes, one of which had been on our to-do list for a while. The first change involved altering how often and the way the mouse cursor was being moved back to the center of the screen. Prior to now, it was warping the cursor back once every few milliseconds. Now we warp it after a certain number of move events. We also changed it to warp to the center of the screen instead of the center of the window - we were previously using the wrong coordinate space. We also checked to see if the mouse warping mode should be disabled if the GetDeviceState() or GetDeviceData() stopped being called for a while. The second change involved tracking a 'virtual cursor position' and making sure it was passed back with the WM_MOUSEMOVE messages that we were modifying. This allowed the GetCursorPos() function to return a correctly tracked position instead of just the location of the point we were warping the cursor to. With these changes, the mouse now behaves as expected in the menus of this title, and will do so with other games that use the same approach.

With Windows XP, Microsoft introduced side-by-side assemblies (SxS) as part of their attempts to manage application and DLL versioning issues. This provides a method by which multiple versions of a DLL can be available on the system at the same time. An application is then compiled to include an XML manifest, which describes (among other things) the specific versions that it expects for different DLLs. There is more to this setup than just a simple lookup of a DLL name and its version - there are policies which allow certain versions of a DLL to be replaced by another. We have implemented the first level of support for SxS assemblies which allows applications that are linked in this manner to correctly locate and load their libraries at run-time. There is more work to be done here and this mechanism is likely to be used by more and more Windows titles in the future. In particular, this work allows a fresh Command & Conquer 3 install to locate its C libraries and start up.

Finally, an issue we dealt with to get LAN play working with Command & Conquer 3 provides an interesting example of a place where Windows and UNIX APIs can be very similar but subtly different. In particular, much of the Winsock API is based upon the BSD sockets API which is found in most Unix-like systems including Linux. While this eases the implementation of these APIs, there are subtle differences in the implementations that need to be addressed. For example, the common gethostbyname() function exists in both the BSD sockets and Winsock APIs but has a number of Windows-specific behaviours that need to be emulated. This function is passed a host name as a string and returns a pointer to a host information structure, including its network addresses if available.

In Winsock, it is valid to specify the host name as NULL, in which case, the Winsock library should treat it as though the function was called with the local host's name. The behaviour of passing NULL is not specified in the BSD sockets API and on many platforms will cause a program to crash. Another difference is that passing the local host's name to gethostbyname() will return all of the non-loopback addresses on the local host. On Linux, passing the local host's name will return the information that is configured in the name resolver (e.g. DNS, /etc/hosts). By more closely replicating the Windows behaviour, we are improving the compatibility of titles with network play.

Mark Adams
Development Manager
TransGaming Technologies
Broadening the Playing Field