Home > Releases > Simple2D 1.11 now available

Simple2D 1.11 now available

A new major release of Simple2D is now available (the download link can be found at the bottom of the page).

Version 1.11 introduces 49 improvements and bug fixes with an emphasis on user interface coding. Improvements have been made to scene objects, user interface objects and object groups, experimental support for skinning has been added, as well as support for XInput-compatible gamepads.

System requirements

  • Windows 7 Service Pack 1 with Platform Update for Windows 7
  • Windows Server 2008 R2 Service Pack 1 with Platform Update for Windows 7
  • Windows 8

The installer will download and install Platform Update for Windows 7 for you if you don’t have it already.

Migrating your libraries from Simple2D 1.06 or later

Simply run the new installer. Your Simple2D installation will be upgraded automatically to the latest version.

Migrating your libraries from Simple2D 1.05 or earlier

  1. Uninstall Simple2D from Add/Remove Programs in Control Panel
  2. Run the new installer

Migrating your applications from Simple2D 1.10

Applications must now link to xinput9_1_0.lib as well as the previously used DirectX libraries.

There is one breaking change in this version: Simple2D::GetFocusObject() now returns a pointer instead of a reference.

Migration your applications from Simple2D 1.07 or earlier

Please see the section entitled Code Migration from Simple2D 1.07 and earlier in the Simple2D 1.10 Release Notes.

Improvements and bug fixes

Program structure:

  • When creating a standard Windows or full-screen application using a class derived from Simple2D, include Simple2D.h as normal. New feature: If you want to define your own main() or WinMain(), eg. for a console application or custom Windows application, include Simple2DLib.h instead (the new example GamepadTextDemo shows this)


  • Bug fix: Calling Simple2D::Line() without a brush argument (to use the current brush) failed to call Prepare() on the brush (to set gradient properties etc.)
  • Bug fix: Calling SetPoints(), SetPointsWH(), SetPointsUsingAlignmentType() or SetPointsUsingAlignmentTypeWH() on a brush before the brush resource is created caused an application crash (the brush resource is now created if needed when these functions are called)

Scene objects:

  • You can now unbind an animation from an object with SceneObject::Unbind(bindingName) (this allows the previously bound variable to be set freely once again)
  • The BindAlpha2 binding type was added

User interface objects:

  • Breaking change: Simple2D::GetFocusObject() now returns a pointer instead of a reference (in case there is no focus object, nullptr is returned)
  • ButtonTemplate can now be initialized with the parameterized constructor ButtonTemplate(std::string text, boost::function<void (Button &)> onClick = NULL)
  • The UserInterfaceItemGroup template class functions AddItemRow() and AddItemColumn() can now accept a vector of InterfaceItems as well as an array (the size argument can be omitted when using a vector)
  • The TextBoxTemplate and TextBoxGroupTemplate structs have been added for use with UserInterfaceItemGroup (both can be initialized with parameterized constructors)
  • A group of text boxes can be referred to as a TextBoxGroup (a concrete specialization of UserInterfaceItemGroup)
  • TextBox now has an IsPassword public property which you can set to control whether the display of the text is replaced with asterisks (“*”)
  • TextBoxes can now have captions. Configure the caption with TextBox::SetCaption(string text, TextFormat format, GenericBrush *brush, TextBoxCaptionPosition position, int gap). The position parameter should be TBCP_Above or TBCP_Left depending on where the caption should be displayed, and gap is the number of pixels gap between the text box and the caption text.
  • Typedefs ButtonList and TextBoxList have been added to represent storing ButtonTemplates and TextBoxTemplates in vectors
  • Tabbable items are now supported. InterfaceObjects in an ObjectGroup with focus can be tabbed through with Tab and Shift+Tab. To implement a tabbable object group, implement ITabbedObjectGroup. To implement a tabbable item, implement ITabbedItem. Currently, only TextBox is tabbable of the built-in interface element types. To find the next item in a tabbed object group, call ITabbedItem *ITabbedObjectGroup::FindTabbedItem(). To find the previous item, specify the optional bool parameter as false. The built-in group ObjectGroup now implements ITabbedObjectGroup by default, so no changes are needed to your code to support tabbable text boxes. Non-tabbable items in a group (objects which do not implement ITabbedItem) will be ignored and can be freely mixed in a group with tabbable items.
  • Skinned dialog boxes are now available via the new Dialog class. A title bar, information/error label, arbitrary number of text boxes and buttons can be added to the dialog, and the visual layout configured via a separate class. See the SkinnedDialogDemo example for usage information.

Object groups:

  • Objects can now remove themselves from their owner scene or group by calling SceneObject::SetDone() (this can also be used by application code as an alternative to Scene::Remove())
  • The new functions ObjectManager::AddBehind(&|*), ObjectManager::AddBehindRef(&|*) and ObjectManager::AddDrawingBehind(func) allow you to add objects to the back of a Scene or ObjectGroup (rendered behind all the existing objects)
  • The parent owner of each object is now stored; set and cleared automatically via SceneObject::SetOwner(ObjectManager &|*) when an object is added to or removed from a scene or group and can be fetched with ObjectManager *SceneObject::GetOwner(). NOTE: SetOwner() should not be called directly by your own applications.
  • Adding a UserInterfaceItemGroup to a Scene or ObjectGroup now returns a vector of unmanaged raw pointers to the objects created so that you can reference them in your application (the pointers are still managed by the Scene or ObjectGroup so you can just discard them when they are no longer needed)
  • You can now get the objects in a Scene or ObjectGroup with boost::ptr_list<SceneObject> *ObjectManager::GetObjects().
  • Bug fix: potential memory leak when removing objects added to a Scene or ObjectGroup via a UserInterfaceItemGroup (SetDeleteBehaviour() was not called on the child objects)
  • Bug fix: Mouse events were not dispatched to user interface objects in an ObjectGroup (or derived class thereof)
  • Bug fix: The mouse co-ordinate checking against objects in an ObjectGroup was not mapped relative to the position of the ObjectGroup on the screen
  • Bug fix: Mouse events were dispatched to user interface objects in an ObjectGroup even if the ObjectGroup was switched off (not visible)
  • Bug fix: Potential crash if the object with focus is removed from the scene or the scene or group owning the object is deleted (object was not de-focussed first)

Gamepad support:

  • The new Gamepad class (Gamepad.h, included by Simple2DLib.h) provides access to Xbox 360 controllers connected via USB from your applications using XInput
  • The Gamepad constructor allows you to specify X and Y deadzones for both sticks, in percent (0-1). The default is 5% in X and 2% in Y, based on controller testing.
  • bool CheckConnection() re-tests all controller connections returns true if a controller is connected, false otherwise
  • bool GetPort() returns the port (1-4) of the connected controller (0 if not connected) (uses data from previous call to CheckConnection())
  • bool Refresh() calls CheckConnection() and if a controller is connected, retrieves its state and makes it available in via a number of methods and public fields. Call Gamepad::Refresh() every frame in your UpdateObjects() function, it will automatically deal with controller connects and disconnects. If Refresh() returns true, a controller is connected and its state is now available; if Refresh() returns false, don’t do any gamepad input processing this frame
  • XINPUT_GAMEPAD *GetState() fetches the XINPUT_GAMEPAD object from when the controller state was last retrieved by Refresh(). Only use this if you need a feature which isn’t supported by the Gamepad class.
  • bool IsPressed(WORD) returns true if the specified button is currently pressed down (using the data from the last call to Refresh()), eg. IsPressed(XINPUT_GAMEPAD_A) or IsPressed(XINPUT_GAMEPAD_LEFT_SHOULDER)
  • void SetDeadzone(float, float) allows you to set the X and Y thumb stick deadzones in percent
  • Public fields: leftStickX, leftStickY, rightStickX and rightStickY give the off-center movement of each stick from -1 to 1 (-1 is fully left or up, 1 is fully right or down). A value of 0 indicates the stick is in the specified deadzone; all possible positions outside the deadzone are scaled from 0-1. leftTrigger and rightTrigger return the percentage depressed each trigger is, from 0-1. No deadzone is configurable.
  • Public fields: the Buttons field is a std::map of XInput button codes and official button name strings for use in your own applications
  • You can configure gamepad support to send keyboard events to your application’s Windows message pump (which will forward them to your OnKeyDown and OnKeyUp functions, the active scene etc.) to minimize the number of changes you need to make to allow existing applications to use the gamepad. Use EnableKeyEvents() and DisableKeyEvents() to toggle this on and off (it is off by default; turning it on will cause key events to be sent to the application’s main window). Use SetWindow(HWND) to send keyboard event messages to the specified window. See the new GamepadWinMsgDemo demo for examples.
  • You can map gamepad buttons to keyboard keys to make integration with existing applications easier. Use AddKeyMapping(WORD, int) with an XINPUT_GAMEPAD_* enum value and a virtual key code to add a mapping, and RemoveKeyMapping(int) or RemoveKeyMappingByButton(WORD) to remove it. Mapped buttons will have the corresponding virtual key code sent in Windows key event messages, unmapped buttons will have their XINPUT_GAMEPAD_* enum value sent. See the new GamepadMappingDemo demo for examples.
  • You can map the analog sticks and triggers to keyboard keys if their movement amount exceeds a specified threshold. Use AddAnalogKeyMapping(AnalogButtons, float, int) with an analog item enum value, threshold from 0-1 (but must be greater than 0), and a virtual key code to add a mapping, and RemoveAnalogKeyMapping(AnalogButtons) to remove it. Mapped items will have the corresponding virtual key code sent in Windows key event messages; movement of unmapped items will not generate any messages. The values for the AnalogButtons enum are LeftStickLeft, LeftStickRight, LeftStickUp, LeftStickDown, RightStickLeft, RightStickRight, RightStickUp, RightStickDown, LeftTrigger and RightTrigger. See the new GamepadMappingDemo demo for examples.
  • If you try to map a button or analog item that has already been mapped, the new mapping will replace the old one. To remove all mappings for digital and analog items, call ClearMappings().
  • You can set the repeat interval for buttons or analog movements on the controller in milliseconds. Use SetRepeatIntervalMsAll(int) to set all buttons and analog movements to a fixed repeat interval. Use SetRepeatIntervalMs(WORD, int) (with an XInput enum value) and SetAnalogRepeatIntervalMs(AnalogButtons) to set repeat rates for individual buttons and analog actions. Use a value of 0 to indicate that the button push or movement should not send repeated messages.


  • EXPERIMENTAL: The ability to create and consume skins and objects which use them has been added (ISkin<>, specializations, Skin, SkinnedObjectGroup, Dialog). See the SkinnedDialogDemo example for information on how to implement and use skins.

Compiler issues:

  • The _SCL_SECURE_NO_WARNINGS flag is now set in the Simple2D library header
  • Bug fix: Simple2DLib.h in Simple2D 1.10 would not compile on Visual Studio 2010 (syntax error due to use of C++11 for (each) construct)
  • Bug fix: Simple2D could not be re-compiled by end users because the release libraries were compiled with /GL (Whole Program Optimization). This has been removed

Changes to example applications:

  • AsyncHTTPDemo – now attempts to get the Content-Length of the file to download and show how many bytes there are in total
  • AsyncHTTPDemo – the notification bar now includes a progress bar when the Content-Length header is present
  • AsyncHTTPDemo – now allocates its download buffer memory on the heap instead of the stack; the buffer size is increased from 256K to 64MB and a chunk size has been introduced as the maximum amount to download per iteration of the while loop (64K)

New example applications:

  • GamepadTextDemo – shows how to retrieve movement and button information from a connected Xbox 360 controller
  • GamepadWinMsgDemo – shows how to configure the gamepad library to send button presses/releases to your OnKeyDown and OnKeyUp functions
  • GamepadMappingDemo – shows how to configure the gamepad library to map buttons and analog movements on the game controller to keyboard keys
  • SkinnedDialogDemo – shows how to used a skinned dialog box and define custom skins

Known issues in Simple2D 1.11

  • Simple2D::TextWidth() returns an incorrect result if the text contains a newline.
  • ResolutionX and ResolutionY are not correctly set in the main application constructor
  • Gamepad support does not currently support vibration


Download link (always download the latest version)

Please be aware that Simple2D is very much a work in progress, and that changes from version to version can break older code, although I try to maintain backwards compatibility as much as possible. The code is currently undergoing significant re-factoring with each new version.

I hope you find Simple2D useful!

For setup and installation instructions, follow the Simple2D Installation Tutorial.

Previous version release notes (1.10)

  1. captcpsc
    August 30, 2013 at 04:09

    Hi Katy, I recently found your site through Google researching parallax scrolling and have decided to walk through the whole tutorial! I’ve carefully tried to follow your instructions on setting up in Microsoft Visual Studio 2012, but seem to have run into some problems using Boost 1.54. It seems in that version there was a big restructuring? I am now downloading the Boost 1.53 in an attempt to get that to work. I was hoping you might be able to write something up on using Boost 1.54; or quite possibly one of your followers have figured it out! Any tips on setting up projects to work in visual studio 2012/windows 7 64 Bit would also be awesome.

    These are the errors I am receiving.
    1>—— Build started: Project: CollisionDemo, Configuration: Debug Win32 ——
    1>Gamepad.obj : error LNK2019: unresolved external symbol _XInputGetState@8 referenced in function “public: bool __thiscall S2D::Gamepad::CheckConnection(void)” (?CheckConnection@Gamepad@S2D@@QAE_NXZ)
    1>Simple2D.obj : error LNK2019: unresolved external symbol _D2D1CreateFactory@16 referenced in function “private: long __thiscall S2D::Simple2D::CreateDeviceIndependentResources(void)” (?CreateDeviceIndependentResources@Simple2D@S2D@@AAEJXZ)
    1>Simple2D.obj : error LNK2019: unresolved external symbol _D2D1MakeRotateMatrix@16 referenced in function “public: static class D2D1::Matrix3x2F __cdecl D2D1::Matrix3x2F::Rotation(float,struct D2D_POINT_2F)” (?Rotation@Matrix3x2F@D2D1@@SA?AV12@MUD2D_POINT_2F@@@Z)
    1>Simple2D.obj : error LNK2019: unresolved external symbol _D2D1MakeSkewMatrix@20 referenced in function “public: static class D2D1::Matrix3x2F __cdecl D2D1::Matrix3x2F::Skew(float,float,struct D2D_POINT_2F)” (?Skew@Matrix3x2F@D2D1@@SA?AV12@MMUD2D_POINT_2F@@@Z)
    1>Simple2D.obj : error LNK2019: unresolved external symbol __imp__DWriteCreateFactory@12 referenced in function “private: long __thiscall S2D::Simple2D::CreateDeviceIndependentResources(void)” (?CreateDeviceIndependentResources@Simple2D@S2D@@AAEJXZ)
    1>Simple2D.obj : error LNK2019: unresolved external symbol _D3D11CreateDevice@40 referenced in function “private: long __thiscall S2D::Simple2D::CreateDeviceResources(void)” (?CreateDeviceResources@Simple2D@S2D@@AAEJXZ)
    1>Simple2D.obj : error LNK2019: unresolved external symbol “public: __thiscall S2D::Animation::Animation(class boost::function,int,double,double,enum S2D::Animation::CycleType,bool)” (??0Animation@S2D@@QAE@V?$function@$$A6ANN@Z@boost@@HNNW4CycleType@01@_N@Z) referenced in function “public: static class S2D::Animation __cdecl S2D::Animation::FromPlus(double,double,int,class boost::function)” (?FromPlus@Animation@S2D@@SA?AV12@NNHV?$function@$$A6AXXZ@boost@@@Z)
    1>Simple2D.obj : error LNK2019: unresolved external symbol “public: __thiscall S2D::GradientObject::GradientObject(struct D3DCOLORVALUE &,struct D3DCOLORVALUE &,enum S2D::AlignmentType,enum D2D1_EXTEND_MODE)” (??0GradientObject@S2D@@QAE@AAUD3DCOLORVALUE@@0W4AlignmentType@1@W4D2D1_EXTEND_MODE@@@Z) referenced in function “public: class S2D::GradientObject * __thiscall S2D::Simple2D::MakeBrush(struct D3DCOLORVALUE &,struct D3DCOLORVALUE &,enum S2D::AlignmentType,enum D2D1_EXTEND_MODE,bool)” (?MakeBrush@Simple2D@S2D@@QAEPAVGradientObject@2@AAUD3DCOLORVALUE@@0W4AlignmentType@2@W4D2D1_EXTEND_MODE@@_N@Z)
    1>Simple2D.obj : error LNK2019: unresolved external symbol “public: __thiscall S2D::S2DScene::InterfaceObject::InterfaceObject(int,int,int,int)” (??0InterfaceObject@S2DScene@S2D@@QAE@HHHH@Z) referenced in function “public: __thiscall S2D::S2DScene::Button::Button(int,int,int,int,int,int,class std::basic_string<char,struct std::char_traits,class std::allocator >,class S2D::GenericBrush *,class S2D::GenericBrush *,class boost::intrusive_ptr,class S2D::GenericBrush *,class boost::function,bool)” (??0Button@S2DScene@S2D@@QAE@HHHHHHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVGenericBrush@2@1V?$intrusive_ptr@UIDWriteTextFormat@@@boost@@1V?$function@$$A6AXAAVButton@S2DScene@S2D@@@Z@7@_N@Z)
    1>*********\Debug\CollisionDemo.exe : fatal error LNK1120: 9 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    • August 30, 2013 at 04:21

      Just looked into this for you. That doesn’t look like a Boost problem to me, it seems like you have forgotten to link to the various DirectX libraries (and I forgot to mention that you now need to link to XInput as well – I’ve fixed that in the installation tutorial and release notes above, thanks!). Open your project properties and navigate to Linker -> Input, make sure you add these libraries as well as Simple2D.lib (or Simple2Dd.lib for debug builds): d2d1.lib, d3d11.lib, dxguid.lib, dwrite.lib and xinput9_1_0.lib. Then it should compile and link nicely. Let me know if you have any other problems and best of luck with the tutorials! (there are more parts planned)

      • captcpsc
        August 30, 2013 at 10:49

        I’ll try not to bother you too much! I don’t know if you need to include this with your install.

        1>—— Rebuild All started: Project: Simple2D-Test, Configuration: Debug Win32 ——
        1> Main.cpp
        1>Simple2Dd.lib(Simple2D.obj) : warning LNK4099: PDB ‘vc110.pdb’ was not found with ‘Simple2Dd.lib(Simple2D.obj)’ or at ‘C:\Program Files (x86)\DJKaty.com\Simple2D\Simple2D-Test\Debug\vc110.pdb’; linking object as if no debug info
        1> Simple2D-Test.vcxproj -> C:\Program Files (x86)\DJKaty.com\Simple2D\Simple2D-Test\Debug\Simple2D-Test.exe
        ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

        • August 30, 2013 at 12:29

          Argh, yes, the .pdb file contains the debug symbols for the library. What I should have done is compile it with /Z7 instead of /Zi so that the debug symbols are embedded into Simple2Dd.lib. I’ve made this change now for the next version to be released. In the meantime, you can disable warning LNK4099 although you won’t get debug symbols from Simple2D while debugging. If you desperately need a copy of Simple2Dd.lib with the symbols included, shoot me an email on the contact page and I’ll send you a re-compiled copy.

  1. August 30, 2013 at 05:13
  2. August 30, 2013 at 16:46
  3. August 30, 2013 at 16:49
  4. November 9, 2013 at 10:44
  5. March 28, 2014 at 13:11

Share your thoughts! Note: to post source code, enclose it in [code lang=...] [/code] tags. Valid values for 'lang' are cpp, csharp, xml, javascript, php etc. To post compiler errors or other text that is best read monospaced, use 'text' as the value for lang.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: