PopCap Developer Program Forums

PopCap Developer Program

Home of the open source PopCap Games Framework


Go Back   PopCap Developer Program Forums
Register Blogs Search Today's Posts Mark Forums Read

PopCap Games Framework Version 1.3 Changes



General


  • Removed support for Visual Studio / Visual C++ 6. If you use these versions, you will need to update your project files manually.
    • Note: you can download Visual Studio 2005 Express edition for free from Microsoft (http://msdn.microsoft.com/vstudio/express/)
  • PAKfile support - See docs/Pak Resource File Support.doc
  • Added support for wide displays and for windowed emulation of wide displays.
  • Some wide string/localization related changes to strings/chars: Use the WideString.vcproj projects for widestring support
  • Added support to draw anti-aliased lines/polygons.
  • Cached WAV files are "encrypted" (weakly) to prevent the easy copying of sound resources.
  • All demos were made to be widestring compatible and we added corresponding widestring projects. std::string has been replaced with SexyString, char with SexyChar, and a few std::string to SexyString conversion functions are now scattered about the demos, where needed.
  • Irrelevant build configurations were removed from the projects.
  • Fixed problem with project files where the framework wouldn't be built unless you manually built it. This caused the error with not finding sexyappframework.lib and preventing the demos from linking if you just did a rebuild all.
  • Made all projects default to not use edit/continue in debug mode.

Vista Support


  • Added GetAppDataFolder() to get the top-level directory where you can save files to. On Vista, this returns the appropriate storage location. On non-Vista, this returns the empty string.
    • mFullCompanyName member of SexyAppBase is used to create this directory in the SexyAppBase::Init function.
    • This directory looks like this: \mFullCompanyName\mProdName\
  • Added CheckForVista() function that returns true if running on Vista.
  • Added CheckFor98Mill() function that returns true if running on Win95, Win98, or WinME.
  • Changed registry functions to use HKEY_CURRENT_USER on all systems.
  • Cached sound files save to GetAppDataFolder() location now (this is the same location on Pre-Vista machines; see above).
  • Added AllowAllAccess() function to Common to allow developers to set the permissions to directories/files to Everyone -> Full Control.

ImageLib


  • JPEG2000 support added using j2k-codec (see http://www.j2k-codec.com for licensing information).
  • Fix to GetImage function not casting std::string::size_type to an int before passing it to min/max.
  • Added gAutoLoadAlpha global variable. When true, GetImage will look for alpha masks (same filename with _ at the end or beginning of file). When false, alpha masks will not be automatically loaded.
  • Added gIgnoreJPEG2000Alpha global variable. When true, the alpha channel in a jp2 file will be set to entirely opaque. When false, the alpha channel will be preserved.

SWTri_Pixel888.cpp


  • Fix for alpha values that might end up getting messed up when writing to memory images.

DDI_FastStretch_Additive.inc


  • Fix for drawing stretched images in software being off a pixel.

HTTPTransfer


  • Added member variable /mContentLength/ to hold the "Content-Length: " parameter.

MI_NormalBlt/BltRotatedHelper.inc


  • 16-bit rotation optimizations.

BASS related


  • Upgraded BASS files to work with 2.3 (2.2.0.1 is still shipped by default w/ framework though).
  • Exposed a lot more bass.dll methods.
  • Added variable, BassMusicInterface::mMusicLoadFlags, so that you can override the BASS music loading flags with whatever flags you want.

MTRand


  • Added methods for retrieving random integers and floats within a specified range.

SoundManager/DSoundManager


  • Added GetFreeSoundId to SoundManager to return the first available sound id.
  • Has resource manager call soundmanager->releasesound when a sound is unloaded.
  • Sound ids are based on GetFreeSoundID instead of mCurSoundId, and mCurSoundId no longer exists.

Slider


  • Added the ability to have vertical sliders instead of only horizontal: Just specify mHorizontal = false. Defaults to true for backwards compatibility.
  • Fixed bug in SetValue():
    Setting a value less than 0 or greater than 1 could cause problems/crashes. Now clamps value to 0->1 range.
  • Added functionality so that if you click on the scroll bar (but not on the thumb) then the thumb and value get set to the position you clicked on. Previously, the widget didn't respond if you clicked anywhere outside of the thumb.

Font/ImageFont


  • Fixed small inefficiency in CharWidth.
  • Allow colors specified in the decriptor to be simple integers such as 0xffffff instead of (1,1,1,1).
  • Fix crash with legacy font loading.
  • Make SysFonts return the correct Descent so that WriteWordWrapped works correctly.
  • Support drawing on MemoryImage objects with SysFont objects.

SexyAppBase


  • Added mPhysMinimized and defer alt-enter processing to ProcessDeferredMessages.
  • Added mEnableMaximizeButton option to enable/disable the maximize button.
  • Added KillDialog method which lets you specify whether you want to remove and delete the dialog or not (useful for scrolling the dialog off the screen after it's ended).
  • Added tablet support.
  • Broke up the GameAlreadyRunning/NotifyGame message logic into virtual functions that can be overridden. This is so apps can do other things if the game is already running.
  • Add mFullCompanyName -- used for setting AppDataFolder.
  • mChangeDirTo for -changedir command line parameter.
  • Add WM_QUERYOPEN hook which calls SexyAppBase::AppCanRestore. If this method returns true, Windows will be allowed to restore the window. Otherwise, it will not.
  • Add mIsDisabled to track disabled state of main window.
  • Change RegistryRead to use helper function RegistryReadKey while passing in HKEY_CURRENT_USER as the key to read.

FlashWidget


  • SysColorChanged notification for Widgets. Now FlashWidget can detect when it needs to MarkDirty entirely.
  • Fixed a crash caused by referencing invalid memory.
  • Windows SDK v6.0 does not include comsuppw.lib by default with comdef.h. Manually added it.

SexyMatrix


  • Allow DrawImageTransform to have scalex = -1 for mirroring an image.

ModVal


  • Made it so you can have multiple M()'s on a line instead of having to have unique M1(), M2(), etc.

D3DInterface


  • Added mPhysMinimized and defer alt-enter processing to ProcessDeferredMessages.
  • Fixed multithreaded issue with mImageSet.
  • Fixed problem in BltTransformed when center parameter was true.
  • Copy right and bottom pixels to fill the borders of textures which don't go to the border. This emulates the texture having clamping turned on and going right up to the edge.
  • Recover bits shouldn't recover old bits (make sure bitschangedcount is up to date).

Graphics and related .inc files


  • Added the ability to return a wordwrapped string to writing its original color by using the ^oldclr^ tag.
  • Added SetScale:
    Scales all calls that route through DrawImage(Image* theImage, int theX, int theY, const Rect& theSrcRect) by a value. This is part of the graphics state, so you can use Push/PopState with it.
  • Added Is3D to see if this graphics is drawing using the 3d card.
  • New draw string wordwrapped.
  • Added DrawStringColor.
  • Support for antialiased line/polygon drawing/filling.
  • Made WriteWordWrapped be able to continue from an indented point.
  • Changed DrawStringColor to take an old color.
  • Fixed problem with DrawLineClipHelper needing to tell calling function that line is completely clipped.
  • Commented back in theOldColor in WriteWordWrappedHelper.
  • Fixed for loop scoped variable problem.
  • Optimizations to common drawing paths. Huge increases in FPS in some situations. If things look weird, #undef OPTIMIZE_SOFTWARE_DRAWING in MemoryImage.h
  • Fixes bug with drawing stretched images to another image and having the resulting image appear partially transparent.
  • Divide by zero fix when DestRect width/height = 1 and also stretching out (Bilinear blend version of stretching)
  • Just return from DrawImageBox if srcWidth or srcHeight <= 0.
  • Fixed write string problem where ^^ wouldn't work if it was near the end of the string.
  • Added theMaxChars parameter to WriteWordWrapped so you can gradually reveal all of the characters in a bunch of lines of text (just using substr doesn't work because the word wrapping changes as characters appear).
  • Made DrawImageRotatedF use the exact subpixel center of the image as the pivot point (as opposed to the integer center).

WidgetContainer


  • Added WidgetContainer::WidgetRemovedHelper for calling RemovedFromManager on all child widgets and for calling DisableWidget on all child widgets.
  • Fixed: If you have a widget that is at the end of mWidgets, and then that widget adds another widget and calls UpdateApp (like the blocking dialog box wait function), if you do not remove the added widget (i.e. set autokill for a blocking dialog wait function), and if the addING widget is not at the END of the mWidgets list, then the app will crash with an invalid iterator, as there is only 1 mUpdateIterator and it is being overwritten while UpdateApp is called. Also, if mUpdateThisRemoved is ever set while calling UpdateApp, its value will overwrite any previous value before the call to UpdateApp.
  • Added WidgetContainer::mZOrder which is used to keep a widget at a certain relative position in the widget list.
  • Fixes a re-entrency bug that can cause the app to crash if mUpdateIterator is already at the end of the widget list inside of UpdateAll and mUpdateThisRemoved is false: previously the iterator got incremented again, causing it to be invalid.
  • Fix to GetWidgetAtHelper related to Base Modal dialogs.
  • Made all functions virtual.

Widget related


  • Fixed default values for fast stretch and linear blend in FlushDeferredOverlayWidgets.
  • Added ability to have draw overlay pass in the priority at which it's calling the function.
  • Made Widget::ShowFinger check if mWidgetManager == NULL: previously it did this:
    if (on)
        mWidgetManager->mApp->SetCursor(CURSOR_HAND);
    else
        mWidgetManager->mApp->SetCursor(CURSOR_POINTER);


    ...which will crash if the widget manager is NULL.

ResourceManager


  • Added LoadFont and DeleteFont.
  • Added support to use sys fonts in resources.xml, via path="!sys:font_face" size="point_size" Bold, underline, italics, and shadow can all be specified as attributes in the tag itself.

Checkbox


  • Added default draw method to checkbox for if no checked/unchecked image is specified.

XMLParser


  • Fixed a potential bug with reusing the same XMLParser object on multiple files.
  • Added more supported encoding types: UTF-8, UTF-16, UTF-16LE, UTF-16BE.
  • Encoding types can be automatically detected by byte-order-markers, or they can be explicitly set with SetEncodingType method.

D3DTester


  • Always retest 3d if it fails... This way, the user isn't permanently locked out of 3d for any reason.

Common.h/.cpp


  • Fixed MkDir so it can handle backwards and forward slashes.
  • Added functions: CheckForVista, GetAppDataFolder, SetAppDataFolder, AllowAllAccess. See "Vista" section for more Vista details.
  • Many helper functions introduced to support wide string, and the new framework string type: SexyString.
  • Added macro _S() which can be used to encapsulate string or character constants. This will ensure that strings are wide string if _USE_WIDE_STRING is defined, or narrow strings if it is undefined.


PopCap Games Framework Version 1.22 Changes



Support for Visual Studio 2005

Fixed some C++ language conformance issues

Fixed some bugs with the flash widget and rendering issues

Got tired of casting warnings, properly casting stuff now

Fixed some demo bugs and bad programming practices

IMPORTANT NEW CHANGE:

In order to cut filesize bloat, caused by the addition of the software triangle rasterizer code in 1.21, you now need to do the following IF you use DrawImageMatrix or DrawImageTransform (with a complex transformation) or if you get errors compiling or at run time you get the assert "You need to call SWTri_AddDrawTriFunc or SWTri_AddAllDrawTriFuncs"
  1. Include "SexyAppFramework/SWTri.h"
  2. Call the function SWTri_AddAllDrawTriFuncs()
  3. Alternatively to #2, if you know which triangle draw functions you need, you can add them specifically via SWTri_AddDrawTriFunc(...) and specifying which draw function you need (check SWTri.h for a list).
Removed the ImageLib project files as they aren't needed, to avoid confusion

PopCap Games Framework Version 1.21 Changes



Widgets are no longer removed from their container in WidgeContainer::RemovedFromManager. It's your responsibility to remove all widgets from a container before deleting the container. Widgets will assert if they have a parent or if they have haven children in their destructor. To assist you, there's a helper method WidgetContainer::RemoveAllWidgets().

Added LinearBlending for DrawImageMatrix/DrawImageTransform. Call Graphics::SetLinearBlend to enable/disable linear blending.

Added good default faststretch and linear blend settings to WidgetManager drawing:
aClipG.SetFastStretch(!is3D);
aClipG.SetLinearBlend(is3D);

Changed 3d test to not require "nvidia", "ati", or "radeon" in the name of the driver for recommending the video card if the video card driver's year is >= 2002.

Changed Dialog::mYesButton and Dialog::mNoButton to Dialog::ID_YES and Dialog::ID_NO (1000 and 1001) to avoid conflict with user defined buttons.

Various bug fixes

Debug key (ctrl-alt-d) changes:
F2 - Start/Stop Perf Timing

F3 - toggle framerate display
Shift F3 - toggle framerate/mouse coord display

F8 - Show current Video Stats (mostly used to see if 3d is currently on)
Shift F8 - Toggle 3d mode

F10 - Single Step Program (show one frame at a time)
Shift F10 - Stop single steping
Ctrl F10 - Toggle Slow Motion

F11 - Take Screenshot (goes into the _screenshots) directory
Shift F11 - Dump all program images in memory to the _dump directory

PopCap Games Framework Version 1.2 Changes



Overview


There have been a number of changes to the framework since version 1.0, much of which has been in the area of widgets and graphics. The big change in widgets is the formalization of widget hierarchies, which allows any number of child widgets to be parented by any widget. This makes it easier to create widget-based user interfaces than before. The big changes in graphics include a non-hardware-accelerated textured triangle rasterizer and an overall decrease in the memory that images consume.

There have been a number of changes in just about all of the major framework sections, most of which are small, but hopefully add up to the framework being even friendlier than before.

Backwards Compatibility


Version 1.2 is backward-compatible, except DDImage::OnlyKeepDDSurface has been replaced by a more generalized MemoryImage::PurgeBits. Example:

Version 1.0:

if (mApp->Is3DAccelerated())
    mNextBackdrop->mOnlyKeepDDSurface = true;
else
    mNextBackdrop->OnlyKeepDDSurface();


Version 1.2:

mNextBackdrop->mWantDDSurface = true;

mNextBackdrop->PurgeBits();


App Changes


Many of the image-based SexyAppBase methods that construct images (such as SexyAppBase::GetImage) have been modified to directly return DDImages rather than Images. This should avoid some confusion and allow you to avoid feeling uncomfortable making “dangerous” upcasts.

Initialization and shutdown has changed slightly, in that there is now a ShutdownHook and an InitHook. Overriding ShutdownHook takes the place of overriding Shutdown, except you don't have to check mShutdown and call the base implementation, and InitHook gets called by SexyAppBase::Init at the end. In addition, it is now safe to call Shutdown during the loading thread; doing so will only cause mLoadingFailed to be set to true, which is the standard way to cause program termination from that thread.

Blocking operations are now formally and generally supported by the framework. The only blocking operation allowed before was Dialog::WaitForResult, which returned the dialog result once the dialog was closed. Blocking operation support has been generalized to simplify some types of time-based tasks by allowing state to be maintained within local variables (and by nature of code execution location) rather than forcing widgets to explicitly store that state information across calls to Update. The obvious use is for dialogs, but it can also be used for transitions or other animations (for example, calling a RollDice() method that creates a dice object, animates the rolling, and returns the result). One thing to be careful of is that the program can be shut down at any time, so you must be able to exit gracefully from your blocking calls. SexyApp::UpdateApp returns false if the application is shutting down, and you can detect that the blocking call was terminated prematurely by checking SexyAppBase::mExitToTop. The core of a blocking call should be formatted as such:

while ((gSexyAppBase->UpdateApp()) && (mStillPerformingTask))
{
    // This code gets executed once per update
}
return mTaskResult;


Or, if you need the termination condition to be evaluated with more granularity because you want to avoid processing update or any other input events if the termination condition is met by a previous input event (such as clicking a button), you can use the following:

bool updated;
while ((gSexyAppBase->UpdateApp(&updated)) && (mStillPerformingTask))
{
    // This code gets executed after every input event and after
    // every update


    if (updated)
    {
        // This code gets executed once per update
    }
}
return mTaskResult;


Widget Changes


Full widget hierarchies are now support, which allows any widget to be a parent to any number of child widgets. The child widgets inherit flags from the parent widget, draw relative to the parent widget, and are added and removed from the widget manager along with the parent widget. This means that in a widget's constructor you can allocate a child widget, immediately position it and add it as your child by calling the parent widget's AddWidget method instead of the WidgetManager's AddWidget, and then delete it in the destructor without having to remove it first – no other child management is required. To facilitate this generalized parenting, both Widget and WidgetManager now share a base class: WidgetContainer. Despite the enhanced functionality, widgets are still fairly light-weight and no changes are required for old widgets to work as they always have.

A “flag system” has been added to Widgets to help simplify some common-usage cases such as always marking widgets dirty (avoiding explicit calls to MarkDirty) and pausing the game when it loses focus. Widget behavior is described by the following flags:

WIDGETFLAGS_UPDATE - Set to receive Update calls
WIDGETFLAGS_MARK_DIRTY - Set to automatically mark the widget dirty
WIDGETFLAGS_DRAW - Set to allow drawing
WIDGETFLAGS_CLIP - Set to clip Graphics passed into Draw
WIDGETFLAGS_ALLOW_MOUSE - Set to allow mouse interaction
WIDGETFLAGS_ALLOW_FOCUS - Set to allow focus to be maintained


The only flag not set by default is WIDGETFLAGS_MARK_DIRTY. A top-level widget's flags are based on the initial WidgetManager::mWidgetFlags value, but modified by that widget's parent WidgetContainer::mWidgetFlagsMod value. mWidgetFlagsMod allows you to override flags by specifying which ones to turn off and which ones to turn on. The default setting of mWidgetFlagsMod neither adds or removes flags, so adding WIDGETFLAGS_MARK_DIRTY to WidgetManager::mWidgetFlags will cause every widget to automatically mark itself dirty, or you could set one particular Widget's mWidgetFlagsMod.mAddFlags to WIDGETFLAGS_MARK_DIRTY to enable it just for that one Widget. To use more than one flag, use the bitwise OR operator to combine them together.

The flags system now extends to modal dialogs, which are more flexible and well-behaved now. In order for modal dialogs to be modal, focus must be taken away from any widgets under the modal dialog and mouse interaction must not be allowed. This behavior is defined by mDefaultBelowModalFlagsMod.mRemoveFlags, which is initially set to WIDGETFLAGS_ALLOW_MOUSE | WIDGETFLAGS_ALLOW_FOCUS. Any widget can act as a modal widget, however, with WidgetManager::SetBaseModal, and the modal behavior can be extended to not updating or even not drawing widgets beneath the base modal widget by passing in the appropriate FlagsMod to the function. The modal system has been further extended by allowing modal widgets to stack, so a dialog can open another dialog but have its previous modal settings remembered when the second dialog closes. Focus is automatically returned to the formerly-focused widget when a modal widget closes, as well.

Overlay drawing has now been incorporated as a basic widget feature. Most applications have a need for some type of overlay drawing, generally where the game board needs to draw some graphic effects over some other widgets such as button widgets, but it cannot due so because the board is, in fact, beneath the other widgets. Previously, developers would generally create an OverlayWidget that was positioned at the top level which was responsible for drawing the special effects, often by just a simple dispatch to mBoard->DrawOverlay. These overlays can be a pain, however, since they have to be managed separately from the widget that actually wants to draw the overlaid graphics, and the developer typically has to do extra work to make sure that the OverlayWidget stays properly placed at the top of the widget list (but under dialogs and sometimes transitions, etc).

The new integrated solution is exposed as Widget::DeferOverlay. DeferOverlay schedules a call to Widget::DrawOverlay later on, after other widgets have had a chance to draw. The overlay scheme is based on priorities, where you pass in an overlay priority to DeferOverlay, and every Widget has an mPriority that determines its Draw() priority. When a widget is reached in the drawing cycle that has a higher priority than a deferred overlay, the overlay is drawn before that widget's Draw is called. In the simple normal case, every Widget has a priority of zero except Dialogs, which have a priority of one (these are default). The board will call DeferOverlay() (with the default priority of zero), where the overlay will not get drawn until either a dialog (with the priority of one) is encountered or all widgets have been drawn. Multiple overlays can be scheduled for a single Widget. DeferOverlay should be called in the widget's normal Draw method and not in Update.

Another change is that lazy programmers that don't want to pass around Graphics to things like sprites can get the current graphics context from WidgetManager::mCurG, although it's only valid during widget drawing.

Dialog Changes


Previously, dialog results had to be decoded through button ids passed into SexyAppBase::ButtonDepress, but now Dialogs work with a generic DialogListener. The dialog's DialogListener is specified in Dialog::mDialogListener which defaults to gSexyAppBase. DialogListener includes DialogButtonPress and DialogButtonDepress, both of which receive the dialog id and the applicable dialog's button id. Button ids are 1 for yes/ok, and 0 for no/cancel (or for one-button dialogs). In contrast, by using ButtonPress/Depress to catch the clicks, the ids passed in were the id of the dialog box plus 2000 for yes/ok and plus 3000 for no/cancel..

Dialogs also now include default drawing implementation so you can include dialogs in quick mockups without requiring extra graphics or overriding SexyAppBase::NewDialog.

Graphics Changes


There are several new methods in the graphics class that are made possible by the inclusion of a software triangle rasterizer in the framework. The calls are:

DrawImageMatrix
DrawImageTransform
DrawTriangleTex

DrawImageMatrix draws an image with an arbitrary matrix transformation (for instance a scale and a rotation concatenated together).

DrawImageTransform is similar to DrawImageMatrix but it uses the Transform class which keeps track of whether or not the transformation is a simple one which can be accomplished with other graphics calls. So, for instance, if you simply do a rotation transformation, DrawImageTransform will delegate the call to DrawImageRotated. If the transformation can't be accomplished with a more specific graphics call then DrawImageMatrix is used to accomplish the drawing.

Both DrawImageMatrix and DrawImageTransform draw the image relative to its center rather than its upper-left corner.

DrawTriangleTex will draw a textured triangle using the image passed to it as the texture.

Please note that the software triangle rasterizer doesn't have support for additive drawing or linear blending right now, but we plan to add these in the future.

Other graphics changes include a reduction in memory consumption by allowing for some redundant data to be removed from images. In 2d mode, images typically end up containing both the raw 32-bit pixel data plus “native data”, which has been converted to the format of the display for faster drawing. In 3d mode, images contain the 32-bit pixel data plus the memory occupied by the textures comprising the image in the Direct3D texture manager. In both cases, the 32-bit raw pixel data can be often considered extraneous. To help reduce overall memory usage, MemoryImage::PurgeBits has been added. This call indicates to the image that you do not need the raw bits around, only the native data. PurgeBits can be accessed through the resource manager by adding “nobits”, “nobits2d”, and “nobits3d” tags to images in your resource XML file. “nobits3d” means that you want to get rid of the bits only in 3d mode, “nobits2d” means you only want to get rid of them in 2d mode, and “nobits” means to get rid of them regardless of mode. Note that, while purging the raw image bits does reduce overall memory usage, it's unlikely to actually produce any frame rate improvement on low-memory machines, as those unused bits would be paged out by the Windows virtual memory manager anyway. An important thing to note is that you shouldn't purge an image if you are going to be calling GetBits on it, or doing any other operation that as a side effect calls GetBits. Since the bits would have been deleted, the resulting call to GetBits will have to rebuild the data, causing a performance hit. Functions that implicitly call GetBits are as follows:
  • Rotational drawing functions (such as BltRotated)
  • Stretch blit functions
  • Palletize
  • And any other function that makes a call to GetBits().
Thus for images that are stretched and rotated in real-time, you should not purge their bits.

In other news, maintaining the graphics state such as the current clipping area, color, drawing mode, scaling mode, and translation is now easier through the inclusion of Graphics::PushState and Graphics::PopState. This can be automated by the GraphicsAutoState object, whereby a GraphicsAutoState can be constructed on the stack of a graphics-related method where the state is pushed in the GraphicsAutoState constructor and popped in the destructor. This allows you to do the following:

void Board::DrawObject(Graphics* g, Object* theObject)
{
    GraphicsAutoState anAutoState;

    // Do whatever you want to the state of graphics here, because it
    // will be restored by anAutoState's destructor when we exit

}


Another new graphics method is Graphics::SetClipRect and Graphics::ClearClipRect, which give you more control over the graphics clipping region.

Sound Changes


A few small sound changes have occurred, as well. First of all, oggs and wavs are no longer cached out as wavs in the same directory as the original sounds, but rather are created in a “cached” directory off of the main game directory. This should make some things less annoying such as making it easier to not include the cached sounds when packaging builds.

Another sound change is allowing for dynamically allocated sounds. Dynamic allocation is accomplished through the addition of DSoundManager::LoadSound(theFileName). This will allocate the next available channel, counting down from MAX_SOURCE_SOUNDS. By allocating sounds from the highest channel down, we avoid conflicting with sound channels that may be allocated by the resource manager. Any allocated sound can be freed with DSoundManager::ReleaseSound.

Other Small Fixes / Changes


  • Fixed mVSyncUpdates problem with monitors running at over 100HZ
  • Fixed crash bug in EditWidget for small text fields (< 10 characters visible)
  • During crash in debug mode added “Debug” button to crash dialog so the crash can be tranferred to a debugger (if not already running in a debugger)
  • Cursor widgets and transient widgets removed
  • The update backlog is limited to 200ms instead of 1 second

All times are GMT -7. The time now is 11:32 AM.


2000-2007 PopCap Games, Inc. All names are trademarks or registered trademarks of PopCap Games.