Andrew Reed / Mbed OS CITY1082-i2c_master_wifi_mqtt
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Bounce.c Source File

Bounce.c

00001 /*********************************************************************
00002 *                SEGGER Microcontroller GmbH                         *
00003 *        Solutions for real time microcontroller applications        *
00004 **********************************************************************
00005 *                                                                    *
00006 *        (c) 1996 - 2018  SEGGER Microcontroller GmbH                *
00007 *                                                                    *
00008 *        Internet: www.segger.com    Support:  support@segger.com    *
00009 *                                                                    *
00010 **********************************************************************
00011 
00012 ** emWin V5.48 - Graphical user interface for embedded applications **
00013 All  Intellectual Property rights  in the Software belongs to  SEGGER.
00014 emWin is protected by  international copyright laws.  Knowledge of the
00015 source code may not be used to write a similar product.  This file may
00016 only be used in accordance with the following terms:
00017 
00018 The software  has been licensed to  Cypress Semiconductor Corporation,
00019 whose registered  office is situated  at 198 Champion Ct. San Jose, CA 
00020 95134 USA  solely for the  purposes of creating  libraries for Cypress
00021 PSoC3 and  PSoC5 processor-based devices,  sublicensed and distributed
00022 under  the  terms  and  conditions  of  the  Cypress  End User License
00023 Agreement.
00024 Full source code is available at: www.segger.com
00025 
00026 We appreciate your understanding and fairness.
00027 ----------------------------------------------------------------------
00028 Licensing information
00029 Licensor:                 SEGGER Microcontroller Systems LLC
00030 Licensed to:              Cypress Semiconductor Corp, 198 Champion Ct., San Jose, CA 95134, USA
00031 Licensed SEGGER software: emWin
00032 License number:           GUI-00319
00033 License model:            Services and License Agreement, signed June 10th, 2009
00034 Licensed platform:        Any Cypress platform (Initial targets are: PSoC3, PSoC5)
00035 ----------------------------------------------------------------------
00036 Support and Update Agreement (SUA)
00037 SUA period:               2009-06-12 - 2022-07-27
00038 Contact to extend SUA:    sales@segger.com
00039 ----------------------------------------------------------------------
00040 File        : Bounce.c
00041 Purpose     : Bouncing balls demo
00042 ---------------------------END-OF-HEADER------------------------------
00043 */
00044 
00045 #include <stddef.h>
00046 #include <stdlib.h>
00047 #include <malloc.h>
00048 #include <math.h>
00049 
00050 #include "DIALOG.h"
00051 
00052 /*********************************************************************
00053 *
00054 *       Define
00055 *
00056 **********************************************************************
00057 */
00058 #define ID_WINDOW_0   (GUI_ID_USER + 0x00)
00059 #define ID_BUTTON_0   (GUI_ID_USER + 0x01)
00060 #define ID_BUTTON_1   (GUI_ID_USER + 0x02)
00061 #define ID_BUTTON_2   (GUI_ID_USER + 0x03)
00062 #define ID_CHECKBOX_0 (GUI_ID_USER + 0x04)
00063 #define ID_CHECKBOX_1 (GUI_ID_USER + 0x05)
00064 #define ID_TEXT_0     (GUI_ID_USER + 0x06)
00065 #define ID_SLIDER_0   (GUI_ID_USER + 0x07)
00066 
00067 #define MIN_RANDOM_V  0           // Minimum velocity (x or y) to be used in generating random balls
00068 #define MAX_RANDOM_V  80          // Maximum velocity (x or y) to be used in generating random balls
00069 #define MIN_RANDOM_R  5           // Minimum radius to be used in generating random balls
00070 #define MAX_RANDOM_R  40          // Maximum radius to be used in generating random balls
00071 #define M_PI          3.1415926f
00072 #define M_TO_A_RATIO  0.1f        // Ratio of mass to area used in generating random balls
00073 
00074 #define TIME_SLICE    20
00075 #define NUM_BALLS     10
00076 #define GRAVITY       100
00077 
00078 #define XSIZE_SPLASH  220
00079 #define YSIZE_SPLASH  120
00080 #define PERIOD_SPLASH 3000
00081 
00082 #if GUI_VERSION < 54400
00083   #define WM_USER_DATA (WM_USER + 0)
00084 #endif
00085 
00086 /*********************************************************************
00087 *
00088 *       Types
00089 *
00090 **********************************************************************
00091 */
00092 enum Wall { WALL_NONE, WALL_X1, WALL_Y1, WALL_X2, WALL_Y2 };
00093 enum Type { TYPE_NONE, TYPE_WALL, TYPE_BALL };
00094 
00095 typedef struct {
00096   float x, y;
00097 } VECTOR;
00098 
00099 typedef struct {
00100   float x1, y1, x2, y2;
00101 } WALLS;
00102 
00103 typedef struct BALL BALL;
00104 
00105 struct BALL {
00106   VECTOR p;      // Position
00107   VECTOR v;      // Velocity
00108   float  m;      // Mass
00109   float  r;      // Radius
00110   U32    Index;  // Normally used as color
00111   int    Id;     // ID
00112   BALL * pNext;
00113 };
00114 
00115 typedef struct {
00116   int   CollisionType;
00117   int   WhichWall;
00118   float TimeToCollision;
00119 } COLLISION;
00120 
00121 typedef struct {
00122   int        xPos, yPos;
00123   int        xSize, ySize;
00124   void    (* pfDrawBk)  (WM_HWIN hWin, void * pConfig);
00125   void    (* pfDrawBall)(WM_HWIN hWin, void * pConfig, U32 Index, float x, float y, float r);
00126   unsigned   Range;
00127   unsigned * pRadius;
00128   unsigned   NumBalls;
00129   float      vMin, vMax;
00130   float      rMin, rMax;
00131   unsigned   TimeSlice;
00132   float      Gravity;
00133   int        HasBallGravity;
00134   int        HasGroundGravity;
00135   int        HasInitialVelocity;
00136   GUI_COLOR  ColorBk;  // Used if pfDrawBk() not set
00137 } BALLSIM_CONFIG;
00138 
00139 typedef struct {
00140   BALL           * pFirstBall;            // Stores all the balls
00141   int              HasWalls;              // Have wall boundaries been set?
00142   WALLS            Walls;
00143   int              NextId;                // Next ID to assign to an added ball
00144   unsigned         MaxCollisions;         // Max number of collisions per frame in advanceSim
00145   unsigned         MaxCollisionsPerBall;  // Max number of collisions per frame based on the number of balls
00146   float            MinArea;               // Minimum area within walls
00147   float            MaxDiameter;           // Maximum diameter out of all the balls
00148   unsigned         NumBalls;
00149   BALLSIM_CONFIG * pConfig;
00150 } BALLSIM;
00151 
00152 /*********************************************************************
00153 *
00154 *       Static (const) data
00155 *
00156 **********************************************************************
00157 */
00158 static GUI_CONST_STORAGE GUI_COLOR _ColorsSeggerLogo_80x40[] = {
00159 #if (GUI_USE_ARGB == 0)
00160   0x000000, 0xFFFFFF, 0x292929, 0x5F5F5F,
00161   0x96433D, 0xB0726E, 0xCACACA, 0xF8F3F3,
00162   0xD7D7D7, 0xEBDCDB, 0x363636, 0x9D4F49,
00163   0xAA6661, 0x949494, 0xA1A1A1, 0xB77E7A,
00164   0x444444, 0xBD8A86, 0xD1ADAA, 0xE4E4E4,
00165   0xF2F2F2, 0x6C6C6C, 0x797979, 0xA35B55,
00166   0xD8B9B6, 0xAFAFAF, 0xBCBCBC, 0xF2E8E7,
00167   0x515151, 0xCBA19E, 0xE5D0CF, 0x878787,
00168   0xC49592, 0xDEC4C2
00169 #else
00170   0xFF000000, 0xFFFFFFFF, 0xFF292929, 0xFF5F5F5F,
00171   0xFF3D4396, 0xFF6E72B0, 0xFFCACACA, 0xFFF3F3F8,
00172   0xFFD7D7D7, 0xFFDBDCEB, 0xFF363636, 0xFF494F9D,
00173   0xFF6166AA, 0xFF949494, 0xFFA1A1A1, 0xFF7A7EB7,
00174   0xFF444444, 0xFF868ABD, 0xFFAAADD1, 0xFFE4E4E4,
00175   0xFFF2F2F2, 0xFF6C6C6C, 0xFF797979, 0xFF555BA3,
00176   0xFFB6B9D8, 0xFFAFAFAF, 0xFFBCBCBC, 0xFFE7E8F2,
00177   0xFF515151, 0xFF9EA1CB, 0xFFCFD0E5, 0xFF878787,
00178   0xFF9295C4, 0xFFC2C4DE
00179 #endif
00180 
00181 };
00182 
00183 static GUI_CONST_STORAGE GUI_LOGPALETTE _PalSeggerLogo_80x40 = {
00184   34,  // Number of entries
00185   1,   // Has transparency
00186   &_ColorsSeggerLogo_80x40[0]
00187 };
00188 
00189 static GUI_CONST_STORAGE unsigned char _acSeggerLogo_80x40[] = {
00190   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
00191         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
00192   0x02, 0x02, 0x0A, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
00193         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0A, 0x02, 0x02,
00194   0x02, 0x02, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00195         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x02, 0x02,
00196   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00197         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00198   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00199         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00200   0x02, 0x03, 0x01, 0x01, 0x21, 0x0F, 0x09, 0x01, 0x01, 0x01, 0x01, 0x09, 0x11, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00201         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00202   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x01, 0x05, 0x04, 0x0B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00203         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00204   0x02, 0x03, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x20, 0x04, 0x04, 0x0C, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00205         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00206   0x02, 0x03, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x0C, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00207         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00208   0x02, 0x03, 0x01, 0x01, 0x01, 0x09, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x07, 0x0B, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00209         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00210   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x1E, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00211         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00212   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00213         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00214   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00215         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00216   0x02, 0x03, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x09, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x12, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00217         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00218   0x02, 0x03, 0x01, 0x01, 0x04, 0x1E, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x09, 0x0B, 0x04, 0x04, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00219         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00220   0x02, 0x03, 0x01, 0x01, 0x04, 0x0B, 0x07, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x18, 0x04, 0x04, 0x0B, 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00221         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00222   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x05, 0x01, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x11, 0x04, 0x04, 0x17, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 
00223         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1B, 0x01, 0x01, 0x03, 0x02,
00224   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x04, 0x1D, 0x01, 0x01, 0x01, 0x09, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x07, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
00225         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1D, 0x01, 0x01, 0x03, 0x02,
00226   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x04, 0x04, 0x1E, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x1B, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 
00227         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1B, 0x01, 0x01, 0x03, 0x02,
00228   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x04, 0x04, 0x0B, 0x07, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x1D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00229         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00230   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x04, 0x04, 0x0B, 0x07, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x1D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00231         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00232   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x04, 0x04, 0x1E, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x1B, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 
00233         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1B, 0x01, 0x01, 0x03, 0x02,
00234   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x04, 0x1D, 0x01, 0x01, 0x01, 0x09, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x07, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 
00235         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1D, 0x01, 0x01, 0x03, 0x02,
00236   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x05, 0x01, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x11, 0x04, 0x04, 0x17, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 
00237         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1B, 0x01, 0x01, 0x03, 0x02,
00238   0x02, 0x03, 0x01, 0x01, 0x04, 0x0B, 0x07, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x18, 0x04, 0x04, 0x0B, 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00239         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00240   0x02, 0x03, 0x01, 0x01, 0x04, 0x1E, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x09, 0x0B, 0x04, 0x04, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00241         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00242   0x02, 0x03, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x09, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x12, 0x01, 0x01, 0x14, 0x1A, 0x0D, 0x0D, 0x1A, 0x01, 0x01, 0x01, 0x13, 0x06, 0x06, 0x06, 0x06, 0x06, 0x08, 0x01, 0x01, 0x01, 0x13, 0x19, 
00243         0x0D, 0x0E, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x13, 0x0E, 0x0D, 0x0E, 0x08, 0x01, 0x01, 0x01, 0x14, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00244   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x0F, 0x01, 0x01, 0x08, 0x0A, 0x02, 0x02, 0x02, 0x02, 0x10, 0x13, 0x01, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x08, 0x01, 0x1F, 0x02, 0x02, 
00245         0x02, 0x02, 0x02, 0x03, 0x14, 0x01, 0x01, 0x1F, 0x02, 0x02, 0x02, 0x02, 0x02, 0x15, 0x01, 0x01, 0x16, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06, 0x06, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00246   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x1F, 0x02, 0x15, 0x13, 0x08, 0x1C, 0x02, 0x0D, 0x01, 0x03, 0x02, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x01, 0x19, 0x02, 0x02, 0x0D, 
00247         0x06, 0x19, 0x0A, 0x02, 0x19, 0x01, 0x0D, 0x02, 0x02, 0x0E, 0x06, 0x0E, 0x0A, 0x02, 0x06, 0x01, 0x03, 0x02, 0x16, 0x06, 0x06, 0x06, 0x06, 0x14, 0x06, 0x02, 0x1C, 0x06, 0x06, 0x0D, 0x02, 0x02, 0x06, 0x01, 0x01, 0x01, 0x03, 0x02,
00248   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x12, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x1E, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x01, 0x1F, 0x02, 0x10, 0x0E, 0x08, 0x14, 0x06, 0x14, 0x01, 0x03, 0x02, 0x0E, 0x06, 0x06, 0x06, 0x13, 0x01, 0x03, 0x02, 0x16, 0x01, 
00249         0x01, 0x01, 0x08, 0x0D, 0x14, 0x01, 0x10, 0x02, 0x0D, 0x01, 0x01, 0x01, 0x08, 0x0E, 0x14, 0x01, 0x03, 0x02, 0x16, 0x06, 0x06, 0x06, 0x13, 0x01, 0x06, 0x02, 0x03, 0x01, 0x01, 0x14, 0x10, 0x02, 0x06, 0x01, 0x01, 0x01, 0x03, 0x02,
00250   0x02, 0x03, 0x01, 0x01, 0x01, 0x09, 0x04, 0x04, 0x0B, 0x09, 0x01, 0x01, 0x07, 0x0B, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x01, 0x08, 0x10, 0x02, 0x02, 0x02, 0x02, 0x15, 0x08, 0x01, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x1A, 0x01, 
00251         0x13, 0x03, 0x03, 0x03, 0x0E, 0x01, 0x02, 0x02, 0x06, 0x01, 0x08, 0x03, 0x03, 0x03, 0x0E, 0x01, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0A, 0x01, 0x06, 0x02, 0x0A, 0x03, 0x03, 0x0A, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00252   0x02, 0x03, 0x01, 0x01, 0x07, 0x17, 0x04, 0x04, 0x18, 0x01, 0x01, 0x01, 0x0C, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x0D, 0x03, 0x02, 0x02, 0x1C, 0x01, 0x03, 0x02, 0x0E, 0x06, 0x06, 0x06, 0x13, 0x01, 0x10, 0x02, 0x0E, 0x01, 
00253         0x08, 0x0A, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x1A, 0x01, 0x1A, 0x0A, 0x02, 0x02, 0x03, 0x01, 0x03, 0x02, 0x16, 0x06, 0x06, 0x06, 0x08, 0x01, 0x06, 0x02, 0x0A, 0x03, 0x03, 0x0A, 0x02, 0x1C, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00254   0x02, 0x03, 0x01, 0x01, 0x0F, 0x04, 0x04, 0x11, 0x01, 0x01, 0x01, 0x20, 0x04, 0x04, 0x0C, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0E, 0x02, 0x19, 0x01, 0x01, 0x1A, 0x02, 0x02, 0x01, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x16, 0x02, 0x10, 0x14, 
00255         0x01, 0x01, 0x0D, 0x02, 0x03, 0x01, 0x15, 0x02, 0x1C, 0x14, 0x01, 0x01, 0x16, 0x02, 0x03, 0x01, 0x03, 0x02, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x02, 0x03, 0x01, 0x01, 0x06, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00256   0x02, 0x03, 0x01, 0x01, 0x04, 0x04, 0x0C, 0x07, 0x01, 0x01, 0x01, 0x05, 0x04, 0x0B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0E, 0x02, 0x02, 0x03, 0x16, 0x10, 0x02, 0x15, 0x01, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0A, 0x1A, 0x13, 0x0A, 0x02, 0x0A, 
00257         0x03, 0x1C, 0x02, 0x02, 0x03, 0x01, 0x08, 0x0A, 0x02, 0x0A, 0x03, 0x10, 0x02, 0x02, 0x03, 0x01, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x19, 0x06, 0x02, 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x01, 0x01, 0x01, 0x03, 0x02,
00258   0x02, 0x03, 0x01, 0x01, 0x21, 0x0F, 0x09, 0x01, 0x01, 0x01, 0x01, 0x09, 0x11, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x1C, 0x02, 0x02, 0x10, 0x16, 0x14, 0x01, 0x0D, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x08, 0x01, 0x13, 0x16, 0x0A, 
00259         0x02, 0x0A, 0x1F, 0x15, 0x15, 0x01, 0x01, 0x08, 0x15, 0x0A, 0x02, 0x10, 0x0D, 0x03, 0x15, 0x01, 0x19, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x1A, 0x08, 0x03, 0x0D, 0x01, 0x01, 0x01, 0x15, 0x10, 0x13, 0x01, 0x01, 0x01, 0x03, 0x02,
00260   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00261         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00262   0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00263         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
00264   0x02, 0x02, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
00265         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x02, 0x02,
00266   0x02, 0x02, 0x0A, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
00267         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0A, 0x02, 0x02,
00268   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
00269         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
00270 };
00271 
00272 static GUI_CONST_STORAGE GUI_BITMAP _bmSeggerLogo_80x40 = {
00273   80, // xSize
00274   40, // ySize
00275   80, // BytesPerLine
00276   8, // BitsPerPixel
00277   _acSeggerLogo_80x40,  // Pointer to picture data (indices)
00278   &_PalSeggerLogo_80x40   // Pointer to palette
00279 };
00280 
00281 static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0042[152] = { /* code 0042, LATIN CAPITAL LETTER B */
00282   0x5E, 0xFF, 0xFF, 0xFF, 0xFE, 0xC7, 0x00, 0x00,
00283   0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0x00,
00284   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00,
00285   0xFF, 0xFF, 0x00, 0x00, 0x19, 0xFF, 0xFE, 0x00,
00286   0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00,
00287   0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00,
00288   0xFF, 0xFF, 0x00, 0x00, 0x19, 0xFF, 0xFA, 0x00,
00289   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x00,
00290   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
00291   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00,
00292   0xFF, 0xFF, 0x00, 0x00, 0x04, 0xDF, 0xFF, 0x70,
00293   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xC0,
00294   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0,
00295   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0,
00296   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xC0,
00297   0xFF, 0xFF, 0x00, 0x00, 0x04, 0xDF, 0xFF, 0x80,
00298   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x10,
00299   0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x00,
00300   0x6E, 0xFF, 0xFF, 0xFF, 0xFE, 0xB6, 0x00, 0x00
00301 };
00302 
00303 static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0063[ 84] = { /* code 0063, LATIN SMALL LETTER C */
00304   0x00, 0x06, 0xBE, 0xFE, 0xB6, 0x00,
00305   0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xC1,
00306   0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
00307   0x5F, 0xFF, 0xE4, 0x02, 0xBF, 0xFF,
00308   0xAF, 0xFF, 0x60, 0x00, 0x1B, 0xF8,
00309   0xEF, 0xFF, 0x20, 0x00, 0x00, 0x00,
00310   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
00311   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
00312   0xEF, 0xFF, 0x20, 0x00, 0x00, 0x00,
00313   0xBF, 0xFF, 0x70, 0x00, 0x1A, 0xF8,
00314   0x5F, 0xFF, 0xE4, 0x02, 0xBF, 0xFF,
00315   0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA,
00316   0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xB1,
00317   0x00, 0x07, 0xCF, 0xFE, 0xB5, 0x00
00318 };
00319 
00320 static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0065[ 98] = { /* code 0065, LATIN SMALL LETTER E */
00321   0x00, 0x06, 0xCE, 0xFE, 0xB6, 0x00, 0x00,
00322   0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xC1, 0x00,
00323   0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
00324   0x5F, 0xFF, 0xD3, 0x03, 0xDF, 0xFF, 0x60,
00325   0xBF, 0xFF, 0x50, 0x00, 0x4F, 0xFF, 0xB0,
00326   0xEF, 0xFF, 0x10, 0x00, 0x1F, 0xFF, 0xE0,
00327   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
00328   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0,
00329   0xDF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00,
00330   0xAF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00,
00331   0x5F, 0xFF, 0xE4, 0x00, 0x4B, 0xFB, 0x00,
00332   0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
00333   0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xE3, 0x00,
00334   0x00, 0x06, 0xCE, 0xFE, 0xB7, 0x10, 0x00
00335 };
00336 
00337 static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_006E[ 84] = { /* code 006E, LATIN SMALL LETTER N */
00338   0x6E, 0xE5, 0x06, 0xCF, 0xEB, 0x30,
00339   0xEF, 0xFC, 0x9F, 0xFF, 0xFF, 0xF3,
00340   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA,
00341   0xFF, 0xFF, 0xC2, 0x08, 0xFF, 0xFE,
00342   0xFF, 0xFF, 0x30, 0x02, 0xFF, 0xFF,
00343   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00344   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00345   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00346   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00347   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00348   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00349   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00350   0xEF, 0xFE, 0x00, 0x00, 0xEF, 0xFE,
00351   0x6E, 0xE6, 0x00, 0x00, 0x6E, 0xE6
00352 };
00353 
00354 static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_006F[ 98] = { /* code 006F, LATIN SMALL LETTER O */
00355   0x00, 0x04, 0xAD, 0xFF, 0xDA, 0x40, 0x00,
00356   0x01, 0xAF, 0xFF, 0xFF, 0xFF, 0xFA, 0x10,
00357   0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0,
00358   0x4F, 0xFF, 0xF6, 0x11, 0x6F, 0xFF, 0xF4,
00359   0xAF, 0xFF, 0x70, 0x00, 0x07, 0xFF, 0xFA,
00360   0xDF, 0xFF, 0x30, 0x00, 0x03, 0xFF, 0xFD,
00361   0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF,
00362   0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF,
00363   0xDF, 0xFF, 0x30, 0x00, 0x03, 0xFF, 0xFD,
00364   0xAF, 0xFF, 0x70, 0x00, 0x07, 0xFF, 0xFA,
00365   0x4F, 0xFF, 0xF6, 0x11, 0x6F, 0xFF, 0xF4,
00366   0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0,
00367   0x01, 0xAF, 0xFF, 0xFF, 0xFF, 0xFA, 0x10,
00368   0x00, 0x04, 0xAD, 0xFF, 0xDA, 0x40, 0x00
00369 };
00370 
00371 static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0075[ 84] = { /* code 0075, LATIN SMALL LETTER U */
00372   0x6E, 0xE6, 0x00, 0x00, 0x6E, 0xE6,
00373   0xEF, 0xFE, 0x00, 0x00, 0xEF, 0xFE,
00374   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00375   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00376   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00377   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00378   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00379   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00380   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
00381   0xFF, 0xFF, 0x10, 0x03, 0xFF, 0xFF,
00382   0xEF, 0xFF, 0x80, 0x2C, 0xFF, 0xFF,
00383   0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00384   0x3F, 0xFF, 0xFF, 0xF9, 0xCF, 0xFE,
00385   0x04, 0xBF, 0xFC, 0x60, 0x5E, 0xE6
00386 };
00387 
00388 static GUI_CONST_STORAGE GUI_CHARINFO_EXT GUI_Font32_AA4_Bounce_CharInfo[6] = {
00389    {  15,  19,   2,   7,  18, acGUI_Font32_AA4_Bounce_0042 } /* code 0042, LATIN CAPITAL LETTER B */
00390   ,{  12,  14,   1,  12,  14, acGUI_Font32_AA4_Bounce_0063 } /* code 0063, LATIN SMALL LETTER C */
00391   ,{  13,  14,   1,  12,  15, acGUI_Font32_AA4_Bounce_0065 } /* code 0065, LATIN SMALL LETTER E */
00392   ,{  12,  14,   2,  12,  16, acGUI_Font32_AA4_Bounce_006E } /* code 006E, LATIN SMALL LETTER N */
00393   ,{  14,  14,   1,  12,  16, acGUI_Font32_AA4_Bounce_006F } /* code 006F, LATIN SMALL LETTER O */
00394   ,{  12,  14,   2,  12,  16, acGUI_Font32_AA4_Bounce_0075 } /* code 0075, LATIN SMALL LETTER U */
00395 };
00396 
00397 static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop5 = {
00398    0x0075 /* first character */
00399   ,0x0075 /* last character  */
00400   ,&GUI_Font32_AA4_Bounce_CharInfo[  5] /* address of first character */
00401   ,(GUI_CONST_STORAGE GUI_FONT_PROP_EXT *)0 /* pointer to next GUI_FONT_PROP_EXT */
00402 };
00403 
00404 static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop4 = {
00405    0x006E /* first character */
00406   ,0x006F /* last character  */
00407   ,&GUI_Font32_AA4_Bounce_CharInfo[  3] /* address of first character */
00408   ,&GUI_Font32_AA4_Bounce_Prop5 /* pointer to next GUI_FONT_PROP_EXT */
00409 };
00410 
00411 static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop3 = {
00412    0x0065 /* first character */
00413   ,0x0065 /* last character  */
00414   ,&GUI_Font32_AA4_Bounce_CharInfo[  2] /* address of first character */
00415   ,&GUI_Font32_AA4_Bounce_Prop4 /* pointer to next GUI_FONT_PROP_EXT */
00416 };
00417 
00418 static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop2 = {
00419    0x0063 /* first character */
00420   ,0x0063 /* last character  */
00421   ,&GUI_Font32_AA4_Bounce_CharInfo[  1] /* address of first character */
00422   ,&GUI_Font32_AA4_Bounce_Prop3 /* pointer to next GUI_FONT_PROP_EXT */
00423 };
00424 
00425 static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop1 = {
00426    0x0042 /* first character */
00427   ,0x0042 /* last character  */
00428   ,&GUI_Font32_AA4_Bounce_CharInfo[  0] /* address of first character */
00429   ,&GUI_Font32_AA4_Bounce_Prop2 /* pointer to next GUI_FONT_PROP_EXT */
00430 };
00431 
00432 static GUI_CONST_STORAGE GUI_FONT GUI_Font32_AA4_Bounce = {
00433    GUI_FONTTYPE_PROP_AA4_EXT /* type of font    */
00434   ,32 /* height of font  */
00435   ,32 /* space of font y */
00436   ,1 /* magnification x */
00437   ,1 /* magnification y */
00438   ,{&GUI_Font32_AA4_Bounce_Prop1}
00439   ,26 /* Baseline */
00440   ,14 /* Height of lowercase characters */
00441   ,19 /* Height of capital characters */
00442 };
00443 
00444 static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
00445   { WINDOW_CreateIndirect,   "Window",   ID_WINDOW_0,     0,   0, 280, 130, 0, 0x0,  0 },
00446   { BUTTON_CreateIndirect,   "Button",   ID_BUTTON_0,    10,  10, 120,  20, 0, 0x0,  0 },
00447   { BUTTON_CreateIndirect,   "Button",   ID_BUTTON_1,    10,  40, 120,  20, 0, 0x0,  0 },
00448   { BUTTON_CreateIndirect,   "Button",   ID_BUTTON_2,    10, 100, 260,  20, 0, 0x0,  0 },
00449   { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_0, 150,  40, 120,  20, 0, 0x0,  0 },
00450   { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_1, 150,  10, 120,  20, 0, 0x0,  0 },
00451   { TEXT_CreateIndirect,     "Text",     ID_TEXT_0,      10,  73, 120,  20, 0, 0x64, 0 },
00452   { SLIDER_CreateIndirect,   "Slider",   ID_SLIDER_0,   150,  70, 120,  20, 0, 0x0,  0 },
00453 };
00454 
00455 /*********************************************************************
00456 *
00457 *       Static code: Helper(s)
00458 *
00459 **********************************************************************
00460 */
00461 /*********************************************************************
00462 *
00463 *       _Square
00464 */
00465 static float _Square(float x) { 
00466   return x * x;
00467 }
00468 
00469 /*********************************************************************
00470 *
00471 *       _GetRandomNumber
00472 */
00473 static float _GetRandomNumber(float min, float max) {
00474   return (max - min) * rand() / RAND_MAX + min;
00475 }
00476 
00477 #ifdef WIN32
00478 static size_t _AllocatedBytes;
00479 #endif
00480 
00481 /*********************************************************************
00482 *
00483 *       _Free
00484 */
00485 static void _Free(void * p) {
00486 #ifdef WIN32
00487   _AllocatedBytes -= _msize(p);
00488 #endif
00489   free(p);
00490 }
00491 
00492 /*********************************************************************
00493 *
00494 *       _Calloc
00495 */
00496 static void * _Calloc(size_t Num, size_t Size) {
00497   void * p;
00498   p = calloc(Num, Size);
00499 #ifdef WIN32
00500   _AllocatedBytes += _msize(p);
00501 #endif
00502   return calloc(Num, Size);
00503 }
00504 
00505 /*********************************************************************
00506 *
00507 *       Static code: VECTOR
00508 *
00509 **********************************************************************
00510 */
00511 /*********************************************************************
00512 *
00513 *       _VECTOR_Create
00514 */
00515 static VECTOR * _VECTOR_Create(float x, float y) {
00516   VECTOR * pVectorNew;
00517   
00518   pVectorNew = (VECTOR *)_Calloc(sizeof(VECTOR), 1);
00519   pVectorNew->x = x;
00520   pVectorNew->y = y;
00521   return pVectorNew;
00522 }
00523 
00524 /*********************************************************************
00525 *
00526 *       _VECTOR_CreateCopy
00527 */
00528 static VECTOR * _VECTOR_CreateCopy(VECTOR * pVector) {
00529   return _VECTOR_Create(pVector->x, pVector->y);
00530 }
00531 
00532 /*********************************************************************
00533 *
00534 *       _VECTOR_CreateCopyPlus
00535 */
00536 static VECTOR * _VECTOR_CreateCopyPlus(VECTOR * pVector, VECTOR * pVector1) {
00537   return _VECTOR_Create(pVector->x + pVector1->x, pVector->y + pVector1->y);
00538 }
00539 
00540 /*********************************************************************
00541 *
00542 *       _VECTOR_CreateCopyMinus
00543 */
00544 static VECTOR * _VECTOR_CreateCopyMinus(VECTOR * pVector, VECTOR * pVector1) {
00545   return _VECTOR_Create(pVector->x - pVector1->x, pVector->y - pVector1->y);
00546 }
00547 
00548 /*********************************************************************
00549 *
00550 *       _VECTOR_CreateCopyMult
00551 */
00552 static VECTOR * _VECTOR_CreateCopyMult(VECTOR * pVector, float c) {
00553   return _VECTOR_Create(pVector->x * c, pVector->y * c);
00554 }
00555 
00556 /*********************************************************************
00557 *
00558 *       _VECTOR_Delete
00559 */
00560 static void _VECTOR_Delete(VECTOR * pVector) {
00561   _Free(pVector);
00562 }
00563 
00564 /*********************************************************************
00565 *
00566 *       _VECTOR_SetX
00567 */
00568 static void _VECTOR_SetX(VECTOR * pVector, float x) {
00569   pVector->x = x;
00570 }
00571 
00572 /*********************************************************************
00573 *
00574 *       _VECTOR_SetY
00575 */
00576 static void _VECTOR_SetY(VECTOR * pVector, float y) {
00577   pVector->y = y;
00578 }
00579 
00580 /*********************************************************************
00581 *
00582 *       _VECTOR_SetXY
00583 */
00584 static void _VECTOR_SetXY(VECTOR * pVector, float x, float y) {
00585   pVector->x = x;
00586   pVector->y = y;
00587 }
00588 
00589 /*********************************************************************
00590 *
00591 *       _VECTOR_Magnitude
00592 */
00593 static float _VECTOR_Magnitude(VECTOR * pVector) { 
00594   return sqrt(pVector->x * pVector->x + pVector->y * pVector->y);
00595 }
00596 
00597 /*********************************************************************
00598 *
00599 *       _VECTOR_CreateUnitVector
00600 */
00601 static VECTOR * _VECTOR_CreateUnitVector(VECTOR * pVector) {
00602   VECTOR * pVectorNew;
00603   float    Mag;
00604 
00605   Mag = _VECTOR_Magnitude(pVector);
00606   if (Mag != 0.f) {
00607     pVectorNew = _VECTOR_Create(pVector->x / Mag, pVector->y / Mag);
00608   } else {
00609     pVectorNew = _VECTOR_Create(0.f, 0.f);
00610   }
00611   return pVectorNew;
00612 }
00613 
00614 /*********************************************************************
00615 *
00616 *       _VECTOR_DotProduct
00617 */
00618 static float _VECTOR_DotProduct(VECTOR * pVector, VECTOR * pVector1) {
00619   float DotProduct;
00620 
00621   DotProduct = pVector->x * pVector1->x + pVector->y * pVector1->y;
00622   return DotProduct;
00623 }
00624 
00625 /*********************************************************************
00626 *
00627 *       Static code: WALLS
00628 *
00629 **********************************************************************
00630 */
00631 /*********************************************************************
00632 *
00633 *       _WALLS_Create
00634 */
00635 static WALLS * _WALLS_Create(float x1, float y1, float x2, float y2) {
00636   WALLS * pWall;
00637   
00638   pWall = (WALLS *)_Calloc(sizeof(WALLS), 1);
00639   pWall->x1 = x1;
00640   pWall->y1 = y1;
00641   pWall->x2 = x2;
00642   pWall->y2 = y2;
00643   return pWall;
00644 }
00645 
00646 /*********************************************************************
00647 *
00648 *       _WALLS_CreateEmpty
00649 */
00650 static WALLS * _WALLS_CreateEmpty(void) {
00651   return _WALLS_Create(0.f, 0.f, 0.f, 0.f);
00652 }
00653 
00654 /*********************************************************************
00655 *
00656 *       Static code: BALL
00657 *
00658 **********************************************************************
00659 */
00660 /*********************************************************************
00661 *
00662 *       _BALL_Create
00663 */
00664 static BALL * _BALL_Create(void) {
00665   BALL * pBall;
00666   
00667   pBall = (BALL *)_Calloc(sizeof(BALL), 1);
00668   pBall->m = 0.f;
00669   pBall->r = 0.f;
00670   return pBall;
00671 }
00672 
00673 /*********************************************************************
00674 *
00675 *       _BALL_AdvanceBallPosition
00676 */
00677 static void _BALL_AdvanceBallPosition(BALL * pBall, const float dt) {
00678   _VECTOR_SetXY(&pBall->p, pBall->p.x + pBall->v.x * dt, pBall->p.y + pBall->v.y * dt);
00679 }
00680 
00681 /*********************************************************************
00682 *
00683 *        _BALL_DoBallGravity
00684 */
00685 static void _BALL_DoBallGravity(BALL * pb0, BALL * pb1, const float dt, float g) {
00686   VECTOR * v_n;
00687   VECTOR * v_un;
00688   float    r, f, a0, a1, v0, v1;
00689 
00690   v_n  = _VECTOR_CreateCopyMinus(&pb0->p, &pb1->p);  // v_n = normal vec. - a vector normal to the collision surface
00691   v_un = _VECTOR_CreateUnitVector(v_n);              // unit normal vector
00692   r = _VECTOR_Magnitude(v_n);
00693   f = g * (pb0->m * pb1->m) / (r * r);
00694   a0 = f / pb0->m;
00695   a1 = f / pb1->m;
00696   v0 = a0 * dt;
00697   v1 = a1 * dt;
00698   _VECTOR_SetXY(&pb0->v, pb0->v.x - v_un->x * v0, pb0->v.y - v_un->y * v0);
00699   _VECTOR_SetXY(&pb1->v, pb1->v.x + v_un->x * v1, pb1->v.y + v_un->y * v1);
00700   _VECTOR_Delete(v_n);
00701   _VECTOR_Delete(v_un);
00702 }
00703 
00704 /*********************************************************************
00705 *
00706 *        _BALL_DoGroundGravity
00707 */
00708 static void _BALL_DoGroundGravity(BALL * pb, const float dt, float g) {
00709   _VECTOR_SetY(&pb->v, pb->v.y + g * dt * 0.95);
00710 }
00711 
00712 /*********************************************************************
00713 *
00714 *       Static code: COLLISION
00715 *
00716 **********************************************************************
00717 */
00718 /*********************************************************************
00719 *
00720 *       _COLLISION_Reset
00721 */
00722 static void _COLLISION_Reset(COLLISION * pCollision) {
00723   pCollision->CollisionType   = TYPE_NONE;
00724   pCollision->WhichWall       = WALL_NONE;
00725   pCollision->TimeToCollision = 0.f;
00726 }
00727 
00728 /*********************************************************************
00729 *
00730 *       _COLLISION_Create
00731 */
00732 static COLLISION * _COLLISION_Create(void) {
00733   COLLISION * pCollision;
00734   
00735   pCollision = (COLLISION *)_Calloc(sizeof(COLLISION), 1);
00736   _COLLISION_Reset(pCollision);
00737   return pCollision;
00738 }
00739 
00740 /*********************************************************************
00741 *
00742 *       _COLLISION_SetCollisionWithWall
00743 */
00744 static void _COLLISION_SetCollisionWithWall(COLLISION * pCollision, const float t, int WhichWall) {
00745   pCollision->CollisionType   = TYPE_WALL;
00746   pCollision->WhichWall       = WhichWall;
00747   pCollision->TimeToCollision = t;
00748 }
00749 
00750 /*********************************************************************
00751 *
00752 *       _COLLISION_SetCollisionWithBall
00753 */
00754 static void _COLLISION_SetCollisionWithBall(COLLISION * pCollision, const float t) {
00755   pCollision->CollisionType   = TYPE_BALL;
00756   pCollision->WhichWall       = WALL_NONE;
00757   pCollision->TimeToCollision = t;
00758 }
00759 
00760 /*********************************************************************
00761 *
00762 *       _COLLISION_Ball1HasCollision
00763 */
00764 static int _COLLISION_Ball1HasCollision(COLLISION * pCollision) {
00765   return pCollision->CollisionType != TYPE_NONE;
00766 }
00767 
00768 /*********************************************************************
00769 *
00770 *       _COLLISION_Ball2HasCollision
00771 */
00772 static int _COLLISION_Ball2HasCollision(COLLISION * pCollision) {
00773   return pCollision->CollisionType == TYPE_BALL;
00774 }
00775 
00776 /*********************************************************************
00777 *
00778 *       _COLLISION_Ball1HasCollisionWithWall
00779 */
00780 static int _COLLISION_Ball1HasCollisionWithWall(COLLISION * pCollision) {
00781   return pCollision->CollisionType == TYPE_WALL;
00782 }
00783 
00784 /*********************************************************************
00785 *
00786 *       _COLLISION_Ball1HasCollisionWithBall
00787 */
00788 static int _COLLISION_Ball1HasCollisionWithBall(COLLISION * pCollision) {
00789   return pCollision->CollisionType == TYPE_BALL;
00790 }
00791 
00792 /*********************************************************************
00793 *
00794 *       _COLLISION_GetCollisionWall
00795 */
00796 static int _COLLISION_GetCollisionWall(COLLISION * pCollision) {
00797   return (int)pCollision->WhichWall;
00798 }
00799 
00800 /*********************************************************************
00801 *
00802 *        _COLLISION_FindTimeUntilTwoBallsCollide
00803 *
00804 * Function description:
00805 *   Finds the time until two specified balls collide. If they don't collide,
00806 *   the returned Collision will indicate that. If the balls are overlapping
00807 *   a collision is NOT detected.
00808 */
00809 static COLLISION _COLLISION_FindTimeUntilTwoBallsCollide(const BALL * pb1, const BALL * pb2) {
00810   COLLISION clsn = {0};
00811   float     a, b, c, det, t;
00812   
00813   // Compute parts of quadratic formula
00814   //
00815   // a = (v2x - v1x) ^ 2 + (v2y - v1y) ^ 2
00816   //
00817   a = _Square(pb2->v.x - pb1->v.x) + _Square(pb2->v.y - pb1->v.y);
00818   //
00819   // b = 2 * ((x20 - x10) * (v2x - v1x) + (y20 - y10) * (v2y - v1y))
00820   //
00821   b = 2.f * ((pb2->p.x - pb1->p.x) * (pb2->v.x - pb1->v.x) + (pb2->p.y - pb1->p.y) * (pb2->v.y - pb1->v.y));
00822   //
00823   // c = (x20 - x10) ^ 2 + (y20 - y10) ^ 2 - (r1 + r2) ^ 2
00824   //
00825   c = _Square(pb2->p.x - pb1->p.x) + _Square(pb2->p.y - pb1->p.y) - _Square(pb1->r + pb2->r);
00826   //
00827   // Determinant = b^2 - 4ac
00828   //
00829   det = _Square(b) - 4 * a * c;
00830   if (a != 0.f) {                     // If a == 0 then v2x==v1x and v2y==v1y and there will be no collision
00831     t = (-b - sqrt(det)) / (2. * a);  // Quadratic formula. t = time to collision
00832     if (t >= 0.) {                    // If collision occurs...
00833       _COLLISION_SetCollisionWithBall(&clsn, t);
00834     }
00835   }
00836   return clsn;
00837 }
00838 
00839 /*********************************************************************
00840 *
00841 *        _COLLISION_FindTimeUntilBallCollidesWithWall
00842 *
00843 * Function description:
00844 *   Finds time until specified ball collides with any wall. If they
00845 *   don't collide, the returned Collision indicates that. If there
00846 *   will be collisions with more than one wall, this function returns
00847 *   the earliest collision.
00848 *
00849 * IMPORTANT: This function assumes that the ball is bounded within 
00850 *   the specified walls.
00851 */
00852 static COLLISION _COLLISION_FindTimeUntilBallCollidesWithWall(const BALL * pb, const WALLS * pw) {
00853   COLLISION clsn = {0};
00854   float     timeToCollision;
00855   float     t;
00856   int       whichWall;
00857   
00858   timeToCollision = 0.f;
00859   whichWall       = WALL_NONE;
00860   //
00861   // Check for collision with wall X1
00862   //
00863   if (pb->v.x < 0.f) {
00864     t = (pb->r - pb->p.x + pw->x1) / pb->v.x;
00865     if (t >= 0.f) {  // If t < 0 then ball is headed away from wall
00866       timeToCollision = t;
00867       whichWall = WALL_X1;
00868     }
00869   }
00870   //
00871   // Check for collision with wall Y1
00872   //
00873   if (pb->v.y < 0.f) {
00874     t = (pb->r - pb->p.y + pw->y1) / pb->v.y;
00875     if (t >= 0.f) {
00876       if (whichWall == WALL_NONE || t < timeToCollision) {
00877         timeToCollision = t;
00878         whichWall = WALL_Y1;
00879       }
00880     }
00881   }
00882   //
00883   // Check for collision with wall X2
00884   //
00885   if (pb->v.x > 0.f) {
00886     t = (pw->x2 - pb->r - pb->p.x) / pb->v.x;
00887     if (t >= 0.f) {
00888       if (whichWall == WALL_NONE || t < timeToCollision) {
00889         timeToCollision = t;
00890         whichWall = WALL_X2;
00891       }
00892     }
00893   }
00894   //
00895   // Check for collision with wall Y2
00896   //
00897   if (pb->v.y > 0.f) {
00898     t = (pw->y2 - pb->r - pb->p.y) / pb->v.y;
00899     if (t >= 0.f) {
00900       if (whichWall == WALL_NONE || t < timeToCollision) {
00901         timeToCollision = t;
00902         whichWall = WALL_Y2;
00903       }
00904     }
00905   }
00906   //
00907   // Setup Collision return value
00908   //
00909   if (whichWall != WALL_NONE) {  // If there is a collision...
00910     _COLLISION_SetCollisionWithWall(&clsn, timeToCollision, whichWall);
00911   }
00912   return clsn;
00913 }
00914 
00915 /*********************************************************************
00916 *
00917 *        _COLLISION_DoElasticCollisionTwoBalls
00918 *
00919 * Function description:
00920 *   Updates the velocities of b1 and b2 to reflect the effect of an elastic
00921 *   collision between the two. IMPORTANT: This function does NOT check the
00922 *   positions of the balls to see if they're actually colliding. It just
00923 *   assumes that they are. Use findTimeUntilTwoBallsCollide() to see
00924 *   if the balls are colliding.
00925 */
00926 static void _COLLISION_DoElasticCollisionTwoBalls(BALL * pb1, BALL * pb2) {
00927   VECTOR * v_n;
00928   VECTOR * v_un;
00929   VECTOR * v_ut;
00930   VECTOR * v_v1nPrime;
00931   VECTOR * v_v1tPrime;
00932   VECTOR * v_v2nPrime;
00933   VECTOR * v_v2tPrime;
00934   float    v1n, v1t, v2n, v2t;
00935   float    v1tPrime, v2tPrime;
00936   float    v1nPrime, v2nPrime;
00937 
00938   //
00939   // Avoid division by zero below in computing new normal velocities
00940   // Doing a collision where both balls have no mass makes no sense anyway
00941   //
00942   if ((pb1->m == 0.f) && (pb2->m == 0.f)) {
00943     return;
00944   }
00945   //
00946   // Compute unit normal and unit tangent vectors
00947   //
00948   v_n  = _VECTOR_CreateCopyMinus(&pb2->p, &pb1->p);  // v_n = normal vec. - a vector normal to the collision surface
00949   v_un = _VECTOR_CreateUnitVector(v_n);              // unit normal vector
00950   v_ut = _VECTOR_Create(-v_un->y, v_un->x);          // unit tangent vector
00951   //
00952   // Compute scalar projections of velocities onto v_un and v_ut
00953   //
00954   v1n = _VECTOR_DotProduct(v_un, &pb1->v);  // Dot product
00955   v1t = _VECTOR_DotProduct(v_ut, &pb1->v);
00956   v2n = _VECTOR_DotProduct(v_un, &pb2->v);
00957   v2t = _VECTOR_DotProduct(v_ut, &pb2->v);
00958   //
00959   // Compute new tangential velocities
00960   //
00961   v1tPrime = v1t;  // Note: in reality, the tangential velocities do not change after the collision
00962   v2tPrime = v2t;
00963   //
00964   // Compute new normal velocities using one-dimensional elastic collision equations in the normal direction
00965   // Division by zero avoided. See early return above.
00966   //
00967   v1nPrime = (v1n * (pb1->m - pb2->m) + 2.f * pb2->m * v2n) / (pb1->m + pb2->m);
00968   v2nPrime = (v2n * (pb2->m - pb1->m) + 2.f * pb1->m * v1n) / (pb1->m + pb2->m);
00969   //
00970   // Compute new normal and tangential velocity vectors
00971   //
00972   v_v1nPrime = _VECTOR_CreateCopyMult(v_un, v1nPrime);  // Multiplication by a scalar
00973   v_v1tPrime = _VECTOR_CreateCopyMult(v_ut, v1tPrime);
00974   v_v2nPrime = _VECTOR_CreateCopyMult(v_un, v2nPrime);
00975   v_v2tPrime = _VECTOR_CreateCopyMult(v_ut, v2tPrime);
00976   //
00977   // Set new velocities in x and y coordinates
00978   //
00979   _VECTOR_SetXY(&pb1->v, v_v1nPrime->x + v_v1tPrime->x, v_v1nPrime->y + v_v1tPrime->y);
00980   _VECTOR_SetXY(&pb2->v, v_v2nPrime->x + v_v2tPrime->x, v_v2nPrime->y + v_v2tPrime->y);
00981   //
00982   // CleanUp
00983   //
00984   _VECTOR_Delete(v_n);
00985   _VECTOR_Delete(v_un);
00986   _VECTOR_Delete(v_ut);
00987   _VECTOR_Delete(v_v1nPrime);
00988   _VECTOR_Delete(v_v1tPrime);
00989   _VECTOR_Delete(v_v2nPrime);
00990   _VECTOR_Delete(v_v2tPrime);
00991 }
00992 
00993 /*********************************************************************
00994 *
00995 *        _COLLISION_DoElasticCollisionWithWall
00996 */
00997 static void _COLLISION_DoElasticCollisionWithWall(BALL * pb, int w) {
00998   switch (w) {
00999   case WALL_X1:
01000     _VECTOR_SetX(&pb->v, fabs(pb->v.x));
01001     break;
01002   case WALL_Y1:
01003     _VECTOR_SetY(&pb->v, fabs(pb->v.y));
01004     break;
01005   case WALL_X2:
01006     _VECTOR_SetX(&pb->v, -fabs(pb->v.x));
01007     break;
01008   case WALL_Y2:
01009     _VECTOR_SetY(&pb->v, -fabs(pb->v.y));
01010     break;
01011   }
01012 }
01013 
01014 /*********************************************************************
01015 *
01016 *       Static code: BALLSIM
01017 *
01018 **********************************************************************
01019 */
01020 /*********************************************************************
01021 *
01022 *        _BALLSIM_ResetBalls
01023 */
01024 static void _BALLSIM_ResetBalls(BALLSIM * pBallsim) {
01025   BALL * pBalli;
01026   BALL * pBalld;
01027   
01028   pBallsim->NextId        = 0;   // Reset ID counter
01029   pBallsim->MinArea       = 0.;
01030   pBallsim->MaxDiameter   = 0.;
01031   pBallsim->MaxCollisions = 10;  // This will be overwritten on the first call to addBall()
01032   //
01033   // Delete all balls
01034   //
01035   pBalli = pBallsim->pFirstBall;
01036   while (pBalli) {
01037     pBalld = pBalli;
01038     pBalli = pBalli->pNext;
01039     _Free(pBalld);
01040   }
01041 }
01042 
01043 /*********************************************************************
01044 *
01045 *        _BALLSIM_Create
01046 */
01047 static BALLSIM * _BALLSIM_Create(void) {
01048   BALLSIM * pBallsim;
01049 
01050   pBallsim = (BALLSIM *)_Calloc(sizeof(BALLSIM), 1);
01051   pBallsim->HasWalls = 0;
01052   pBallsim->MaxCollisionsPerBall = 10;
01053   _BALLSIM_ResetBalls(pBallsim);
01054   return pBallsim;
01055 }
01056 
01057 /*********************************************************************
01058 *
01059 *        _BALLSIM_AdvanceBallPositions
01060 */
01061 static void _BALLSIM_AdvanceBallPositions(BALLSIM * pBallsim, const float dt) {
01062   BALL * pBalli;
01063 
01064   pBalli = pBallsim->pFirstBall;
01065   while (pBalli) {
01066     _BALL_AdvanceBallPosition(pBalli, dt);
01067     pBalli = pBalli->pNext;
01068   }
01069 }
01070 
01071 /*********************************************************************
01072 *
01073 *        BALLSSIM_FindEarliestCollisionOfTwoBalls
01074 */
01075 static COLLISION BALLSSIM_FindEarliestCollisionOfTwoBalls(BALLSIM * pBallsim, BALL ** ppb1, BALL ** ppb2) {
01076   COLLISION earliestCollision;
01077   COLLISION c;
01078   BALL    * pBalli;
01079   BALL    * pBallj;
01080   
01081   _COLLISION_Reset(&earliestCollision);
01082   //
01083   // Compare each pair of balls. Index i runs from the first
01084   // ball up through the second-to-last ball. For each value of
01085   // i, index j runs from the ball after i up through the last ball.
01086   //
01087   pBalli = pBallsim->pFirstBall;
01088   while (pBalli) {
01089     pBallj = pBallsim->pFirstBall;
01090     while (pBallj) {
01091       c = _COLLISION_FindTimeUntilTwoBallsCollide(pBalli, pBallj);
01092       if (_COLLISION_Ball1HasCollisionWithBall(&c)) {
01093         if (!_COLLISION_Ball1HasCollision(&earliestCollision) || c.TimeToCollision < earliestCollision.TimeToCollision) {
01094           earliestCollision = c;
01095           *ppb1 = pBalli;
01096           *ppb2 = pBallj;
01097         }
01098       }
01099       pBallj = pBallj->pNext;
01100     }
01101     pBalli = pBalli->pNext;
01102   }
01103   return earliestCollision;
01104 }
01105 
01106 /*********************************************************************
01107 *
01108 *        BALLSSIM_FindEarliestCollisionWithWall
01109 */
01110 static COLLISION BALLSSIM_FindEarliestCollisionWithWall(BALLSIM * pBallsim, BALL ** ppb) {
01111   COLLISION earliestCollision;
01112   COLLISION c;
01113   BALL    * pBalli;
01114   
01115   _COLLISION_Reset(&earliestCollision);
01116   //
01117   // If there are no walls, return no collision
01118   //
01119   if (!pBallsim->HasWalls) {
01120     return earliestCollision;
01121   }
01122   //
01123   // Check each ball to see if any collide. Store the earliest colliding ball.
01124   //
01125   pBalli = pBallsim->pFirstBall;
01126   while (pBalli) {
01127     c = _COLLISION_FindTimeUntilBallCollidesWithWall(pBalli, &pBallsim->Walls);
01128     if (_COLLISION_Ball1HasCollisionWithWall(&c)) {
01129       if (!_COLLISION_Ball1HasCollision(&earliestCollision) || c.TimeToCollision < earliestCollision.TimeToCollision) {
01130         earliestCollision = c;
01131         *ppb = pBalli;
01132       }
01133     }
01134     pBalli = pBalli->pNext;
01135   }
01136   return earliestCollision;
01137 }
01138 
01139 /*********************************************************************
01140 *
01141 *        BALLSSIM_FindEarliestCollision
01142 */
01143 static COLLISION BALLSSIM_FindEarliestCollision(BALLSIM * pBallsim, BALL ** ppb1, BALL ** ppb2) {
01144   COLLISION earliestCollision;
01145   COLLISION cWalls;
01146   BALL    * pbCollideWithWall;
01147   
01148   earliestCollision = BALLSSIM_FindEarliestCollisionOfTwoBalls(pBallsim, ppb1, ppb2);
01149   if (pBallsim->HasWalls) {
01150     cWalls = BALLSSIM_FindEarliestCollisionWithWall(pBallsim, &pbCollideWithWall);
01151     if (_COLLISION_Ball1HasCollisionWithWall(&cWalls)) {
01152       if (!_COLLISION_Ball1HasCollisionWithBall(&earliestCollision) || cWalls.TimeToCollision < earliestCollision.TimeToCollision) {
01153         earliestCollision = cWalls;
01154         *ppb1 = pbCollideWithWall;
01155       }
01156     }
01157   }
01158   return earliestCollision;
01159 }
01160 
01161 /*********************************************************************
01162 *
01163 *        _BALLSIM_AdvanceBallGravity
01164 */
01165 static void _BALLSIM_AdvanceBallGravity(BALLSIM * pBallsim, const float dt) {
01166   BALL    * pBalli;
01167   BALL    * pBallj;
01168   
01169   pBalli = pBallsim->pFirstBall;
01170   while (pBalli) {
01171     pBallj = pBalli->pNext;
01172     while (pBallj) {
01173       _BALL_DoBallGravity(pBalli, pBallj, dt, pBallsim->pConfig->Gravity);
01174       pBallj = pBallj->pNext;
01175     }
01176     pBalli = pBalli->pNext;
01177   }
01178 }
01179 
01180 /*********************************************************************
01181 *
01182 *       _BALLSIM_AdvanceGroundGravity
01183 */
01184 static void _BALLSIM_AdvanceGroundGravity(BALLSIM * pBallsim, const float dt) {
01185   BALL * pBalli;
01186 
01187   pBalli = pBallsim->pFirstBall;
01188   while (pBalli) {
01189     _BALL_DoGroundGravity(pBalli, dt, pBallsim->pConfig->Gravity);
01190     pBalli = pBalli->pNext;
01191   }
01192 }
01193 
01194 /*********************************************************************
01195 *
01196 *        BALLSSIM_AdvanceSim
01197 */
01198 static void BALLSSIM_AdvanceSim(BALLSIM * pBallsim, const float dt) {
01199   float     tElapsed;
01200   COLLISION c;
01201   BALL    * pb1;
01202   BALL    * pb2;
01203   unsigned  i;
01204 
01205   tElapsed = 0.f;
01206   for (i = 0; i < pBallsim->MaxCollisions; i++) {
01207     //
01208     // Find earliest collision
01209     //
01210     c = BALLSSIM_FindEarliestCollision(pBallsim, &pb1, &pb2);
01211     //
01212     // If no collisions, break
01213     //
01214     if (!_COLLISION_Ball1HasCollision(&c)) {
01215       break;
01216     }
01217     //
01218     // Is collision within the time frame?
01219     // Note: condition is tElapsed + timeToCollision strictly < dt, not <=, because if the two were exactly
01220     // equal, we would perform the velocity adjustment for collision but not move the balls any more, so the
01221     // collision could be detected again on the next call to advanceSim().
01222     //
01223     if (tElapsed + c.TimeToCollision < dt) {
01224       //
01225       // Collision is within time frame
01226       // Advance balls to point of collision
01227       //
01228       _BALLSIM_AdvanceBallPositions(pBallsim, c.TimeToCollision);
01229       //
01230       // Collision is now occuring. Do collision calculation
01231       //
01232       if (_COLLISION_Ball1HasCollisionWithWall(&c)) {
01233         _COLLISION_DoElasticCollisionWithWall(pb1, c.WhichWall);
01234       } else if (_COLLISION_Ball1HasCollisionWithBall(&c)) {
01235         _COLLISION_DoElasticCollisionTwoBalls(pb1, pb2);
01236       }
01237       tElapsed += c.TimeToCollision;  // Move time counter forward
01238     } else {
01239       break;  // Break if collision is not within this frame
01240     }
01241   }
01242   //
01243   // Advance ball positions further if necessary after any collisions to complete the time frame
01244   //
01245   _BALLSIM_AdvanceBallPositions(pBallsim, dt - tElapsed);
01246   //
01247   // Manage ball gravity
01248   //
01249   if (pBallsim->pConfig->HasBallGravity) {
01250     _BALLSIM_AdvanceBallGravity(pBallsim, dt);
01251   }
01252   //
01253   // Manage ground gravity
01254   //
01255   if (pBallsim->pConfig->HasGroundGravity) {
01256     _BALLSIM_AdvanceGroundGravity(pBallsim, dt);
01257   }
01258 }
01259 
01260 /*********************************************************************
01261 *
01262 *        BALLSSIM_MoveBallToWithinBounds
01263 */
01264 static void BALLSSIM_MoveBallToWithinBounds(BALLSIM * pBallsim, BALL * pb) {
01265   //
01266   // Check wall X1
01267   //
01268   if (pb->p.x - pb->r < pBallsim->Walls.x1) {
01269     _VECTOR_SetX(&pb->p, pBallsim->Walls.x1 + pb->r);
01270   }
01271   //
01272   // Check wall Y1
01273   //
01274   if (pb->p.y - pb->r < pBallsim->Walls.y1) {
01275     _VECTOR_SetY(&pb->p, pBallsim->Walls.y1 + pb->r);
01276   }
01277   //
01278   // Check wall X2
01279   //
01280   if (pb->p.x + pb->r > pBallsim->Walls.x2) {
01281     _VECTOR_SetX(&pb->p, pBallsim->Walls.x2 - pb->r);
01282   }
01283   //
01284   // Check wall Y2
01285   //
01286   if (pb->p.y + pb->r > pBallsim->Walls.y2) {
01287     _VECTOR_SetY(&pb->p, pBallsim->Walls.y2 - pb->r);
01288   }
01289 }
01290 
01291 /*********************************************************************
01292 *
01293 *        BALLSSIM_MoveWalls
01294 */
01295 static void BALLSSIM_MoveWalls(BALLSIM * pBallsim, const WALLS * pNewWalls) {
01296   BALL * pBalli;
01297 
01298   pBallsim->Walls = *pNewWalls;
01299   pBallsim->HasWalls = 1;
01300   pBalli = pBallsim->pFirstBall;
01301   while (pBalli) {
01302     BALLSSIM_MoveBallToWithinBounds(pBallsim, pBalli);
01303     pBalli = pBalli->pNext;
01304   }
01305 }
01306 
01307 /*********************************************************************
01308 *
01309 *        BALLSSIM_GetMinWallDimension
01310 */
01311 static float BALLSSIM_GetMinWallDimension(BALLSIM * pBallsim, float fixedWallDimension) {
01312   float minDimension;
01313   
01314   minDimension = 0.f;
01315   if (fixedWallDimension > 0.f) {
01316     minDimension = 4.f * pBallsim->MinArea / fixedWallDimension;
01317   }
01318   if (minDimension <= pBallsim->MaxDiameter) {
01319     minDimension = pBallsim->MaxDiameter + 1;
01320   }
01321   return minDimension;
01322 }
01323 
01324 /*********************************************************************
01325 *
01326 *        BALLSSIM_AddBall
01327 */
01328 static void BALLSSIM_AddBall(BALLSIM * pBallsim, BALL * pNewBall) {
01329   BALL * pBalli;
01330 
01331   pBallsim->NumBalls = 0;
01332   pBalli = pBallsim->pFirstBall;
01333   if (pBalli) {
01334     pBallsim->NumBalls++;
01335     while (pBalli->pNext) {
01336       pBallsim->NumBalls++;
01337       pBalli = pBalli->pNext;
01338     }
01339     pBallsim->NumBalls++;
01340     pBalli->pNext = pNewBall;
01341   } else {
01342     pBallsim->NumBalls++;
01343     pBallsim->pFirstBall = pNewBall;
01344     pNewBall->pNext = NULL;
01345   }
01346   pBallsim->MaxCollisions = pBallsim->MaxCollisionsPerBall * pBallsim->NumBalls;
01347   BALLSSIM_MoveBallToWithinBounds(pBallsim, pNewBall);
01348   if (pNewBall->r * 2.f > pBallsim->MaxDiameter) {
01349     pBallsim->MaxDiameter = pNewBall->r * 2.f;
01350     pBallsim->MinArea += 4.f * pNewBall->r * pNewBall->r;
01351   }
01352 }
01353 
01354 /*********************************************************************
01355 *
01356 *       _BALLSIM_GetBallFromPos
01357 */
01358 static BALL * _BALLSIM_GetBallFromPos(BALLSIM * pBallsim, float xPos, float yPos) {
01359   float d, dx, dy;
01360   BALL * pBalli;
01361   
01362   pBalli = pBallsim->pFirstBall;
01363   while (pBalli) {
01364     dx = xPos - pBalli->p.x;
01365     dy = yPos - pBalli->p.y;
01366     d = sqrt(dx * dx + dy * dy);
01367     if (d < pBalli->r) {
01368       return pBalli;
01369     }
01370     pBalli = pBalli->pNext;
01371   }
01372   return NULL;
01373 }
01374 
01375 /*********************************************************************
01376 *
01377 *       _BALLSIM_DeleteBall
01378 */
01379 static void _BALLSIM_DeleteBall(BALLSIM * pBallsim, BALL * pBall) {
01380   BALL * pBalli;
01381   BALL * pBallPrev = NULL;
01382 
01383   pBalli = pBallsim->pFirstBall;
01384   while (pBalli) {
01385     if (pBalli == pBall) {
01386       if (pBallPrev) {
01387         pBallPrev->pNext = pBalli->pNext;
01388       } else {
01389         pBallsim->pFirstBall = pBallsim->pFirstBall->pNext;
01390       }
01391       pBallsim->NumBalls--;
01392       _Free(pBall);
01393       break;
01394     }
01395     pBallPrev = pBalli;
01396     pBalli = pBalli->pNext;
01397   }
01398 }
01399 
01400 /*********************************************************************
01401 *
01402 *       _BALLSIM_StopMoving
01403 */
01404 static void _BALLSIM_StopMoving(BALLSIM * pBallsim) {
01405   BALL * pBalli;
01406 
01407   pBalli = pBallsim->pFirstBall;
01408   while (pBalli) {
01409     _VECTOR_SetXY(&pBalli->v, 0.f, 0.f);
01410     pBalli = pBalli->pNext;
01411   }
01412 }
01413 
01414 /*********************************************************************
01415 *
01416 *       _BALLSIM_Delete
01417 */
01418 static void _BALLSIM_Delete(BALLSIM * pBallsim) {
01419   _BALLSIM_ResetBalls(pBallsim);
01420   _Free(pBallsim);
01421 }
01422 
01423 /*********************************************************************
01424 *
01425 *       Static code: Ballsim Window
01426 *
01427 **********************************************************************
01428 */
01429 /*********************************************************************
01430 *
01431 *       _UpdateDisplay
01432 */
01433 static void _UpdateDisplay(WM_HWIN hWin, BALLSIM * pBallsim) {
01434   BALL * pBalli;
01435   U32    Color;
01436 
01437   //
01438   // Draw background
01439   //
01440   if (pBallsim->pConfig->pfDrawBk) {
01441     pBallsim->pConfig->pfDrawBk(hWin, pBallsim->pConfig);
01442   } else {
01443     GUI_SetBkColor(pBallsim->pConfig->ColorBk);
01444     GUI_Clear();
01445   }
01446   //
01447   // Draw all balls
01448   //
01449   pBalli = pBallsim->pFirstBall;
01450   while (pBalli) {
01451     if (pBallsim->pConfig->pfDrawBall) {
01452       pBallsim->pConfig->pfDrawBall(hWin, pBallsim->pConfig, pBalli->Index, pBalli->p.x, pBalli->p.y, pBalli->r);
01453     } else {
01454       Color = GUI_MAKE_COLOR(pBalli->Index);
01455       GUI_SetColor(Color);
01456       GUI_FillCircle(pBalli->p.x, pBalli->p.y, pBalli->r);
01457     }
01458     pBalli = pBalli->pNext;
01459   }
01460 }
01461 
01462 /*********************************************************************
01463 *
01464 *       _AddRandomBalls
01465 */
01466 static void _AddRandomBalls(BALLSIM * pBallsim) {
01467   unsigned i, PosOccupied, Cnt;
01468   float d, dx, dy;
01469   BALL * pBall;
01470   BALL * pBalli;
01471   BALLSIM_CONFIG * pConfig;
01472 
01473   pConfig = pBallsim->pConfig;
01474   for (i = 0; i < pConfig->NumBalls; i++) {
01475     pBall = _BALL_Create();
01476     if (pBallsim->pConfig->HasInitialVelocity) {
01477       pBall->v.x = _GetRandomNumber(pConfig->vMin, pConfig->vMax);
01478       pBall->v.y = _GetRandomNumber(pConfig->vMin, pConfig->vMax);
01479     }
01480     pBall->Index = (U32)_GetRandomNumber(0, pConfig->Range);
01481     if (pConfig->pRadius) {
01482       pBall->r = *(pConfig->pRadius + pBall->Index);
01483     } else {
01484       pBall->r = _GetRandomNumber(pConfig->rMin, pConfig->rMax);
01485     }
01486     pBall->m = M_TO_A_RATIO * M_PI * pBall->r * pBall->r;
01487     //
01488     // Generate legal position
01489     //
01490     Cnt = 0;
01491     do {
01492       pBall->p.x = _GetRandomNumber((float)pBall->r, (float)(pConfig->xSize) - pBall->r);
01493       pBall->p.y = _GetRandomNumber((float)pBall->r, (float)(pConfig->ySize) - pBall->r);
01494       PosOccupied = 0;
01495       pBalli = pBallsim->pFirstBall;
01496       while (pBalli) {
01497         dx = pBalli->p.x - pBall->p.x;
01498         dy = pBalli->p.y - pBall->p.y;
01499         d = sqrt(dx * dx + dy * dy);
01500         if (d < pBalli->r + pBall->r) {
01501           PosOccupied = 1;
01502           break;
01503         }
01504         pBalli = pBalli->pNext;
01505       }
01506     } while (PosOccupied && (Cnt++ < 10));
01507     //
01508     // Add ball to array
01509     //
01510     if (PosOccupied == 0) {
01511       BALLSSIM_AddBall(pBallsim, pBall);
01512     }
01513   }
01514 }
01515 
01516 /*********************************************************************
01517 *
01518 *       _cbConfig
01519 */
01520 static void _cbConfig(WM_MESSAGE * pMsg) {
01521   WM_HWIN                     hItem;
01522   static BALLSIM            * pBallsim;
01523   int                         Id, NCode;
01524   int                         xSize, ySize;
01525   WM_PID_STATE_CHANGED_INFO * pInfo;
01526   GUI_PID_STATE             * pState;
01527   static int                  IsDown;
01528   static GUI_POINT            pDown;
01529 
01530   switch (pMsg->MsgId) {
01531   case WM_PAINT:
01532     xSize = WM_GetWindowSizeX(pMsg->hWin);
01533     ySize = WM_GetWindowSizeY(pMsg->hWin);
01534     GUI_SetColor(GUI_BLACK);
01535     GUI_DrawRect(0, 0, xSize - 1, ySize - 1);
01536     break;
01537   case WM_PID_STATE_CHANGED:
01538     pInfo = (WM_PID_STATE_CHANGED_INFO *)pMsg->Data.p;
01539     if (pInfo->StatePrev == 0) {
01540       IsDown = 1;
01541       pDown.x = pInfo->x;
01542       pDown.y = pInfo->y;
01543       WM_SetCapture(pMsg->hWin, 1);
01544     } else {
01545       IsDown = 0;
01546     }
01547     break;
01548   case WM_TOUCH:
01549     if (IsDown) {
01550       pState = (GUI_PID_STATE *)pMsg->Data.p;
01551       if (pState) {
01552         WM_MoveWindow(pMsg->hWin, pState->x - pDown.x, pState->y - pDown.y);
01553       }
01554     }
01555     break;
01556   case WM_USER_DATA:
01557     WM_GetUserData(pMsg->hWin, &pBallsim, sizeof(void *));
01558     WINDOW_SetBkColor(pMsg->hWin, GUI_WHITE);
01559     WM_MakeModal(pMsg->hWin);
01560     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
01561     BUTTON_SetText(hItem, "Stop moving");
01562     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
01563     BUTTON_SetText(hItem, "Create random balls");
01564     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
01565     BUTTON_SetText(hItem, "Back");
01566     hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);
01567     CHECKBOX_SetText(hItem, "Ball Gravity");
01568     if (pBallsim->pConfig->HasBallGravity) {
01569       CHECKBOX_Check(hItem);
01570     } else {
01571       CHECKBOX_Uncheck(hItem);
01572     }
01573     hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_1);
01574     CHECKBOX_SetText(hItem, "Ground Gravity");
01575     if (pBallsim->pConfig->HasGroundGravity) {
01576       CHECKBOX_Check(hItem);
01577     } else {
01578       CHECKBOX_Uncheck(hItem);
01579     }
01580     hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
01581     TEXT_SetText(hItem, "Gravity:");
01582     TEXT_SetTextAlign(hItem, GUI_TA_RIGHT | GUI_TA_VCENTER);
01583     hItem = WM_GetDialogItem(pMsg->hWin, ID_SLIDER_0);
01584     SLIDER_SetRange(hItem, 0, 400);
01585     SLIDER_SetValue(hItem, (int)pBallsim->pConfig->Gravity);
01586     break;
01587   case WM_NOTIFY_PARENT:
01588     Id    = WM_GetId(pMsg->hWinSrc);
01589     NCode = pMsg->Data.v;
01590     switch(Id) {
01591     case ID_BUTTON_0:
01592       switch(NCode) {
01593       case WM_NOTIFICATION_RELEASED:
01594         _BALLSIM_StopMoving(pBallsim);
01595         break;
01596       }
01597       break;
01598     case ID_BUTTON_1:
01599       switch(NCode) {
01600       case WM_NOTIFICATION_RELEASED:
01601         _AddRandomBalls(pBallsim);
01602         break;
01603       }
01604       break;
01605     case ID_BUTTON_2:
01606       switch(NCode) {
01607       case WM_NOTIFICATION_RELEASED:
01608         WM_DeleteWindow(pMsg->hWin);
01609         break;
01610       }
01611       break;
01612     case ID_CHECKBOX_0:
01613       switch(NCode) {
01614       case WM_NOTIFICATION_VALUE_CHANGED:
01615         pBallsim->pConfig->HasBallGravity = CHECKBOX_IsChecked(pMsg->hWinSrc) ? 1 : 0;
01616         break;
01617       }
01618       break;
01619     case ID_CHECKBOX_1:
01620       switch(NCode) {
01621       case WM_NOTIFICATION_VALUE_CHANGED:
01622         pBallsim->pConfig->HasGroundGravity = CHECKBOX_IsChecked(pMsg->hWinSrc) ? 1 : 0;
01623         break;
01624       }
01625       break;
01626     case ID_SLIDER_0:
01627       switch(NCode) {
01628       case WM_NOTIFICATION_VALUE_CHANGED:
01629         pBallsim->pConfig->Gravity = (float)SLIDER_GetValue(pMsg->hWinSrc);
01630         break;
01631       }
01632       break;
01633     }
01634     break;
01635   default:
01636     WM_DefaultProc(pMsg);
01637   }
01638 }
01639 
01640 /*********************************************************************
01641 *
01642 *       _CreateConfigWindow
01643 */
01644 static void _CreateConfigWindow(BALLSIM * pBallsim, WM_HWIN hParent) {
01645   WM_HWIN hWin;
01646   int xPos, yPos;
01647 
01648   xPos = (pBallsim->pConfig->xSize - _aDialogCreate[0].xSize) / 2;
01649   yPos = (pBallsim->pConfig->ySize - _aDialogCreate[0].ySize) / 3;
01650   hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbConfig, WM_HBKWIN, xPos, yPos);
01651   WM_SetUserData(hWin, &pBallsim, sizeof(void *));
01652 }
01653 
01654 /*********************************************************************
01655 *
01656 *       _CreateBallsim
01657 */
01658 static BALLSIM * _CreateBallsim(WM_HWIN hWin) {
01659   BALLSIM_CONFIG * pConfig;
01660   BALLSIM        * pBallsim;
01661   WALLS          * pWalls;
01662 
01663   WM_GetUserData(hWin, &pConfig, sizeof(void *));
01664   pBallsim = _BALLSIM_Create();
01665   pBallsim->pConfig = pConfig;
01666   pWalls = _WALLS_Create(0.f, 0.f, (float)pConfig->xSize, (float)pConfig->ySize);
01667   BALLSSIM_MoveWalls(pBallsim, pWalls);
01668   _AddRandomBalls(pBallsim);
01669   _Free(pWalls);
01670   return pBallsim;
01671 }
01672 
01673 /*********************************************************************
01674 *
01675 *       _cbBallsim
01676 */
01677 static void _cbBallsim(WM_MESSAGE * pMsg) {
01678   static BALLSIM            * pBallsim;
01679   static GUI_TIMER_TIME       Time;
01680   GUI_TIMER_TIME              tNow;
01681   WM_HTIMER                   hTimer;
01682   WM_PID_STATE_CHANGED_INFO * pInfo;
01683   BALL                      * pBall;
01684   
01685   switch (pMsg->MsgId) {
01686   case WM_PID_STATE_CHANGED:
01687     pInfo = (WM_PID_STATE_CHANGED_INFO *)pMsg->Data.p;
01688     if (pInfo->StatePrev == 0) {
01689       pBall = _BALLSIM_GetBallFromPos(pBallsim, (float)pInfo->x, (float)pInfo->y);
01690       if (pBall) {
01691         _BALLSIM_DeleteBall(pBallsim, pBall);
01692       } else {
01693         _CreateConfigWindow(pBallsim, pMsg->hWin);
01694       }
01695     }
01696     break;
01697   case WM_DELETE:
01698     _BALLSIM_Delete(pBallsim);
01699     break;
01700   case WM_USER_DATA:
01701     pBallsim = _CreateBallsim(pMsg->hWin);
01702     hTimer   = WM_CreateTimer(pMsg->hWin, 0, TIME_SLICE, 0);
01703     Time     = GUI_GetTime();
01704     break;
01705   case WM_PAINT:
01706     _UpdateDisplay(pMsg->hWin, pBallsim);
01707     break;
01708   case WM_TIMER:
01709     WM_RestartTimer(pMsg->Data.v, pBallsim->pConfig->TimeSlice);
01710     tNow = GUI_GetTime();
01711     BALLSSIM_AdvanceSim(pBallsim, (float)(tNow - Time) / 1000);
01712     Time = tNow;
01713     WM_InvalidateWindow(pMsg->hWin);
01714     break;
01715   default:
01716     WM_DefaultProc(pMsg);
01717   }
01718 }
01719 
01720 /*********************************************************************
01721 *
01722 *       _CreateBallsimWindow
01723 */
01724 static WM_HWIN _CreateBallsimWindow(BALLSIM_CONFIG * pConfig, WM_HWIN hParent) {
01725   WM_HWIN hWin;
01726   
01727   hWin = WM_CreateWindowAsChild(pConfig->xPos, pConfig->yPos, pConfig->xSize, pConfig->ySize, hParent, WM_CF_SHOW, _cbBallsim, sizeof(void *));
01728   WM_SetUserData(hWin, &pConfig, sizeof(void *));
01729 #if GUI_VERSION < 54400
01730   WM_SendMessageNoPara(hWin, WM_USER_DATA);
01731 #endif
01732   return hWin;
01733 }
01734 /*********************************************************************
01735 *
01736 *       Static code: Application
01737 *
01738 **********************************************************************
01739 */
01740 /*********************************************************************
01741 *
01742 *       _DrawBk
01743 */
01744 static void _DrawBk(WM_HWIN hWin, void * pVoid) {
01745   GUI_SetBkColor(GUI_MAKE_COLOR(0x202020));
01746   GUI_Clear();
01747 }
01748 
01749 /*********************************************************************
01750 *
01751 *       _DrawBall
01752 */
01753 static void _DrawBall(WM_HWIN hWin, void * pVoid, U32 Index, float x, float y, float r) {
01754   GUI_SetColor(GUI_MAKE_COLOR(Index));
01755   GUI_AA_FillCircle((int)x, (int)y, (int)r); 
01756 }
01757 
01758 /*********************************************************************
01759 *
01760 *       _cbSplash
01761 */
01762 static void _cbSplash(WM_MESSAGE * pMsg) {
01763   int xSize, ySize;
01764   const GUI_BITMAP * pBm;
01765 
01766   switch (pMsg->MsgId) {
01767   case WM_PAINT:
01768     xSize = WM_GetWindowSizeX(pMsg->hWin);
01769     ySize = WM_GetWindowSizeY(pMsg->hWin);
01770     GUI_SetBkColor(GUI_WHITE);
01771     GUI_Clear();
01772     pBm = &_bmSeggerLogo_80x40;
01773     GUI_DrawBitmap(pBm, xSize - pBm->XSize - 10, 5);
01774     GUI_SetColor(GUI_BLACK);
01775     GUI_SetFont(&GUI_Font32_AA4_Bounce);
01776     GUI_DispStringAt("Bounce", 10, 10);
01777     GUI_SetFont(GUI_FONT_13_ASCII);
01778     GUI_DispStringHCenterAt("Press screen for config dialog,\n"
01779                             "Tap balls to remove them.\n\n"
01780                             "Have fun...", xSize / 2, pBm->YSize + 20);
01781     break;
01782   case WM_CREATE:
01783     WM_CreateTimer(pMsg->hWin, 0, PERIOD_SPLASH, 0);
01784     WM_MakeModal(pMsg->hWin);
01785     break;
01786   case WM_TIMER:
01787     WM_DeleteWindow(pMsg->hWin);
01788     break;
01789   default:
01790     WM_DefaultProc(pMsg);
01791   }
01792 }
01793 
01794 /*********************************************************************
01795 *
01796 *       _Test
01797 */
01798 static void _Test(void) {
01799   int xSize, ySize;
01800   int xPos, yPos;
01801   WM_HWIN hWin;
01802   static BALLSIM_CONFIG Config;
01803 
01804   xSize             = LCD_GetXSize();
01805   ySize             = LCD_GetYSize();
01806   //
01807   // Configuration of ball simulation
01808   //
01809   Config.xSize      = xSize;
01810   Config.ySize      = ySize;
01811   Config.Range      = 0xE0E0E0;
01812   Config.NumBalls   = NUM_BALLS;
01813   Config.TimeSlice  = TIME_SLICE;
01814   Config.vMin       = MIN_RANDOM_V;
01815   Config.vMax       = MAX_RANDOM_V;
01816   Config.rMin       = MIN_RANDOM_R;
01817   Config.rMax       = MAX_RANDOM_R;
01818   Config.Gravity    = GRAVITY;
01819   Config.pfDrawBk   = _DrawBk;
01820   Config.pfDrawBall = _DrawBall;
01821   hWin = _CreateBallsimWindow(&Config, WM_HBKWIN);
01822   //
01823   // Create splash screen
01824   //
01825   xPos = (xSize - XSIZE_SPLASH) / 2;
01826   yPos = (ySize - YSIZE_SPLASH) / 3;
01827   WM_CreateWindowAsChild(xPos, yPos, XSIZE_SPLASH, YSIZE_SPLASH, hWin, WM_CF_SHOW, _cbSplash, 0);
01828 }
01829 
01830 /*********************************************************************
01831 *
01832 *       Public code
01833 *
01834 **********************************************************************
01835 */
01836 /*********************************************************************
01837 *
01838 *       MainTask
01839 */
01840 void MainTask(void) {
01841   GUI_Init();
01842   WM_MULTIBUF_Enable(1);
01843   BUTTON_SetReactOnLevel();
01844   _Test();
01845   while (1) {
01846     GUI_Delay(100);
01847   }
01848 }
01849 
01850 /*************************** End of file ****************************/