Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: middleware-emwin/Sample/Application/Bounce.c
- Revision:
- 5:f62a9e4a499a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/middleware-emwin/Sample/Application/Bounce.c Sat Nov 13 12:02:49 2021 +0000 @@ -0,0 +1,1850 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2018 SEGGER Microcontroller GmbH * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.48 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to Cypress Semiconductor Corporation, +whose registered office is situated at 198 Champion Ct. San Jose, CA +95134 USA solely for the purposes of creating libraries for Cypress +PSoC3 and PSoC5 processor-based devices, sublicensed and distributed +under the terms and conditions of the Cypress End User License +Agreement. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Microcontroller Systems LLC +Licensed to: Cypress Semiconductor Corp, 198 Champion Ct., San Jose, CA 95134, USA +Licensed SEGGER software: emWin +License number: GUI-00319 +License model: Services and License Agreement, signed June 10th, 2009 +Licensed platform: Any Cypress platform (Initial targets are: PSoC3, PSoC5) +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2009-06-12 - 2022-07-27 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : Bounce.c +Purpose : Bouncing balls demo +---------------------------END-OF-HEADER------------------------------ +*/ + +#include <stddef.h> +#include <stdlib.h> +#include <malloc.h> +#include <math.h> + +#include "DIALOG.h" + +/********************************************************************* +* +* Define +* +********************************************************************** +*/ +#define ID_WINDOW_0 (GUI_ID_USER + 0x00) +#define ID_BUTTON_0 (GUI_ID_USER + 0x01) +#define ID_BUTTON_1 (GUI_ID_USER + 0x02) +#define ID_BUTTON_2 (GUI_ID_USER + 0x03) +#define ID_CHECKBOX_0 (GUI_ID_USER + 0x04) +#define ID_CHECKBOX_1 (GUI_ID_USER + 0x05) +#define ID_TEXT_0 (GUI_ID_USER + 0x06) +#define ID_SLIDER_0 (GUI_ID_USER + 0x07) + +#define MIN_RANDOM_V 0 // Minimum velocity (x or y) to be used in generating random balls +#define MAX_RANDOM_V 80 // Maximum velocity (x or y) to be used in generating random balls +#define MIN_RANDOM_R 5 // Minimum radius to be used in generating random balls +#define MAX_RANDOM_R 40 // Maximum radius to be used in generating random balls +#define M_PI 3.1415926f +#define M_TO_A_RATIO 0.1f // Ratio of mass to area used in generating random balls + +#define TIME_SLICE 20 +#define NUM_BALLS 10 +#define GRAVITY 100 + +#define XSIZE_SPLASH 220 +#define YSIZE_SPLASH 120 +#define PERIOD_SPLASH 3000 + +#if GUI_VERSION < 54400 + #define WM_USER_DATA (WM_USER + 0) +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +enum Wall { WALL_NONE, WALL_X1, WALL_Y1, WALL_X2, WALL_Y2 }; +enum Type { TYPE_NONE, TYPE_WALL, TYPE_BALL }; + +typedef struct { + float x, y; +} VECTOR; + +typedef struct { + float x1, y1, x2, y2; +} WALLS; + +typedef struct BALL BALL; + +struct BALL { + VECTOR p; // Position + VECTOR v; // Velocity + float m; // Mass + float r; // Radius + U32 Index; // Normally used as color + int Id; // ID + BALL * pNext; +}; + +typedef struct { + int CollisionType; + int WhichWall; + float TimeToCollision; +} COLLISION; + +typedef struct { + int xPos, yPos; + int xSize, ySize; + void (* pfDrawBk) (WM_HWIN hWin, void * pConfig); + void (* pfDrawBall)(WM_HWIN hWin, void * pConfig, U32 Index, float x, float y, float r); + unsigned Range; + unsigned * pRadius; + unsigned NumBalls; + float vMin, vMax; + float rMin, rMax; + unsigned TimeSlice; + float Gravity; + int HasBallGravity; + int HasGroundGravity; + int HasInitialVelocity; + GUI_COLOR ColorBk; // Used if pfDrawBk() not set +} BALLSIM_CONFIG; + +typedef struct { + BALL * pFirstBall; // Stores all the balls + int HasWalls; // Have wall boundaries been set? + WALLS Walls; + int NextId; // Next ID to assign to an added ball + unsigned MaxCollisions; // Max number of collisions per frame in advanceSim + unsigned MaxCollisionsPerBall; // Max number of collisions per frame based on the number of balls + float MinArea; // Minimum area within walls + float MaxDiameter; // Maximum diameter out of all the balls + unsigned NumBalls; + BALLSIM_CONFIG * pConfig; +} BALLSIM; + +/********************************************************************* +* +* Static (const) data +* +********************************************************************** +*/ +static GUI_CONST_STORAGE GUI_COLOR _ColorsSeggerLogo_80x40[] = { +#if (GUI_USE_ARGB == 0) + 0x000000, 0xFFFFFF, 0x292929, 0x5F5F5F, + 0x96433D, 0xB0726E, 0xCACACA, 0xF8F3F3, + 0xD7D7D7, 0xEBDCDB, 0x363636, 0x9D4F49, + 0xAA6661, 0x949494, 0xA1A1A1, 0xB77E7A, + 0x444444, 0xBD8A86, 0xD1ADAA, 0xE4E4E4, + 0xF2F2F2, 0x6C6C6C, 0x797979, 0xA35B55, + 0xD8B9B6, 0xAFAFAF, 0xBCBCBC, 0xF2E8E7, + 0x515151, 0xCBA19E, 0xE5D0CF, 0x878787, + 0xC49592, 0xDEC4C2 +#else + 0xFF000000, 0xFFFFFFFF, 0xFF292929, 0xFF5F5F5F, + 0xFF3D4396, 0xFF6E72B0, 0xFFCACACA, 0xFFF3F3F8, + 0xFFD7D7D7, 0xFFDBDCEB, 0xFF363636, 0xFF494F9D, + 0xFF6166AA, 0xFF949494, 0xFFA1A1A1, 0xFF7A7EB7, + 0xFF444444, 0xFF868ABD, 0xFFAAADD1, 0xFFE4E4E4, + 0xFFF2F2F2, 0xFF6C6C6C, 0xFF797979, 0xFF555BA3, + 0xFFB6B9D8, 0xFFAFAFAF, 0xFFBCBCBC, 0xFFE7E8F2, + 0xFF515151, 0xFF9EA1CB, 0xFFCFD0E5, 0xFF878787, + 0xFF9295C4, 0xFFC2C4DE +#endif + +}; + +static GUI_CONST_STORAGE GUI_LOGPALETTE _PalSeggerLogo_80x40 = { + 34, // Number of entries + 1, // Has transparency + &_ColorsSeggerLogo_80x40[0] +}; + +static GUI_CONST_STORAGE unsigned char _acSeggerLogo_80x40[] = { + 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, + 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, 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, + 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, + 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, + 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, + 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, + 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 +}; + +static GUI_CONST_STORAGE GUI_BITMAP _bmSeggerLogo_80x40 = { + 80, // xSize + 40, // ySize + 80, // BytesPerLine + 8, // BitsPerPixel + _acSeggerLogo_80x40, // Pointer to picture data (indices) + &_PalSeggerLogo_80x40 // Pointer to palette +}; + +static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0042[152] = { /* code 0042, LATIN CAPITAL LETTER B */ + 0x5E, 0xFF, 0xFF, 0xFF, 0xFE, 0xC7, 0x00, 0x00, + 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x19, 0xFF, 0xFE, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x19, 0xFF, 0xFA, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x04, 0xDF, 0xFF, 0x70, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xC0, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x4F, 0xFF, 0xC0, + 0xFF, 0xFF, 0x00, 0x00, 0x04, 0xDF, 0xFF, 0x80, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x10, + 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0x00, + 0x6E, 0xFF, 0xFF, 0xFF, 0xFE, 0xB6, 0x00, 0x00 +}; + +static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0063[ 84] = { /* code 0063, LATIN SMALL LETTER C */ + 0x00, 0x06, 0xBE, 0xFE, 0xB6, 0x00, + 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xC1, + 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, + 0x5F, 0xFF, 0xE4, 0x02, 0xBF, 0xFF, + 0xAF, 0xFF, 0x60, 0x00, 0x1B, 0xF8, + 0xEF, 0xFF, 0x20, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xEF, 0xFF, 0x20, 0x00, 0x00, 0x00, + 0xBF, 0xFF, 0x70, 0x00, 0x1A, 0xF8, + 0x5F, 0xFF, 0xE4, 0x02, 0xBF, 0xFF, + 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, + 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xB1, + 0x00, 0x07, 0xCF, 0xFE, 0xB5, 0x00 +}; + +static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0065[ 98] = { /* code 0065, LATIN SMALL LETTER E */ + 0x00, 0x06, 0xCE, 0xFE, 0xB6, 0x00, 0x00, + 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xC1, 0x00, + 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x5F, 0xFF, 0xD3, 0x03, 0xDF, 0xFF, 0x60, + 0xBF, 0xFF, 0x50, 0x00, 0x4F, 0xFF, 0xB0, + 0xEF, 0xFF, 0x10, 0x00, 0x1F, 0xFF, 0xE0, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, + 0xDF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xAF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0xFF, 0xE4, 0x00, 0x4B, 0xFB, 0x00, + 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x01, 0xCF, 0xFF, 0xFF, 0xFF, 0xE3, 0x00, + 0x00, 0x06, 0xCE, 0xFE, 0xB7, 0x10, 0x00 +}; + +static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_006E[ 84] = { /* code 006E, LATIN SMALL LETTER N */ + 0x6E, 0xE5, 0x06, 0xCF, 0xEB, 0x30, + 0xEF, 0xFC, 0x9F, 0xFF, 0xFF, 0xF3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, + 0xFF, 0xFF, 0xC2, 0x08, 0xFF, 0xFE, + 0xFF, 0xFF, 0x30, 0x02, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xEF, 0xFE, 0x00, 0x00, 0xEF, 0xFE, + 0x6E, 0xE6, 0x00, 0x00, 0x6E, 0xE6 +}; + +static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_006F[ 98] = { /* code 006F, LATIN SMALL LETTER O */ + 0x00, 0x04, 0xAD, 0xFF, 0xDA, 0x40, 0x00, + 0x01, 0xAF, 0xFF, 0xFF, 0xFF, 0xFA, 0x10, + 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, + 0x4F, 0xFF, 0xF6, 0x11, 0x6F, 0xFF, 0xF4, + 0xAF, 0xFF, 0x70, 0x00, 0x07, 0xFF, 0xFA, + 0xDF, 0xFF, 0x30, 0x00, 0x03, 0xFF, 0xFD, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xDF, 0xFF, 0x30, 0x00, 0x03, 0xFF, 0xFD, + 0xAF, 0xFF, 0x70, 0x00, 0x07, 0xFF, 0xFA, + 0x4F, 0xFF, 0xF6, 0x11, 0x6F, 0xFF, 0xF4, + 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, + 0x01, 0xAF, 0xFF, 0xFF, 0xFF, 0xFA, 0x10, + 0x00, 0x04, 0xAD, 0xFF, 0xDA, 0x40, 0x00 +}; + +static GUI_CONST_STORAGE unsigned char acGUI_Font32_AA4_Bounce_0075[ 84] = { /* code 0075, LATIN SMALL LETTER U */ + 0x6E, 0xE6, 0x00, 0x00, 0x6E, 0xE6, + 0xEF, 0xFE, 0x00, 0x00, 0xEF, 0xFE, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x10, 0x03, 0xFF, 0xFF, + 0xEF, 0xFF, 0x80, 0x2C, 0xFF, 0xFF, + 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x3F, 0xFF, 0xFF, 0xF9, 0xCF, 0xFE, + 0x04, 0xBF, 0xFC, 0x60, 0x5E, 0xE6 +}; + +static GUI_CONST_STORAGE GUI_CHARINFO_EXT GUI_Font32_AA4_Bounce_CharInfo[6] = { + { 15, 19, 2, 7, 18, acGUI_Font32_AA4_Bounce_0042 } /* code 0042, LATIN CAPITAL LETTER B */ + ,{ 12, 14, 1, 12, 14, acGUI_Font32_AA4_Bounce_0063 } /* code 0063, LATIN SMALL LETTER C */ + ,{ 13, 14, 1, 12, 15, acGUI_Font32_AA4_Bounce_0065 } /* code 0065, LATIN SMALL LETTER E */ + ,{ 12, 14, 2, 12, 16, acGUI_Font32_AA4_Bounce_006E } /* code 006E, LATIN SMALL LETTER N */ + ,{ 14, 14, 1, 12, 16, acGUI_Font32_AA4_Bounce_006F } /* code 006F, LATIN SMALL LETTER O */ + ,{ 12, 14, 2, 12, 16, acGUI_Font32_AA4_Bounce_0075 } /* code 0075, LATIN SMALL LETTER U */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop5 = { + 0x0075 /* first character */ + ,0x0075 /* last character */ + ,&GUI_Font32_AA4_Bounce_CharInfo[ 5] /* address of first character */ + ,(GUI_CONST_STORAGE GUI_FONT_PROP_EXT *)0 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop4 = { + 0x006E /* first character */ + ,0x006F /* last character */ + ,&GUI_Font32_AA4_Bounce_CharInfo[ 3] /* address of first character */ + ,&GUI_Font32_AA4_Bounce_Prop5 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop3 = { + 0x0065 /* first character */ + ,0x0065 /* last character */ + ,&GUI_Font32_AA4_Bounce_CharInfo[ 2] /* address of first character */ + ,&GUI_Font32_AA4_Bounce_Prop4 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop2 = { + 0x0063 /* first character */ + ,0x0063 /* last character */ + ,&GUI_Font32_AA4_Bounce_CharInfo[ 1] /* address of first character */ + ,&GUI_Font32_AA4_Bounce_Prop3 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_Font32_AA4_Bounce_Prop1 = { + 0x0042 /* first character */ + ,0x0042 /* last character */ + ,&GUI_Font32_AA4_Bounce_CharInfo[ 0] /* address of first character */ + ,&GUI_Font32_AA4_Bounce_Prop2 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +static GUI_CONST_STORAGE GUI_FONT GUI_Font32_AA4_Bounce = { + GUI_FONTTYPE_PROP_AA4_EXT /* type of font */ + ,32 /* height of font */ + ,32 /* space of font y */ + ,1 /* magnification x */ + ,1 /* magnification y */ + ,{&GUI_Font32_AA4_Bounce_Prop1} + ,26 /* Baseline */ + ,14 /* Height of lowercase characters */ + ,19 /* Height of capital characters */ +}; + +static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { + { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 280, 130, 0, 0x0, 0 }, + { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 10, 10, 120, 20, 0, 0x0, 0 }, + { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 10, 40, 120, 20, 0, 0x0, 0 }, + { BUTTON_CreateIndirect, "Button", ID_BUTTON_2, 10, 100, 260, 20, 0, 0x0, 0 }, + { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_0, 150, 40, 120, 20, 0, 0x0, 0 }, + { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_1, 150, 10, 120, 20, 0, 0x0, 0 }, + { TEXT_CreateIndirect, "Text", ID_TEXT_0, 10, 73, 120, 20, 0, 0x64, 0 }, + { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 150, 70, 120, 20, 0, 0x0, 0 }, +}; + +/********************************************************************* +* +* Static code: Helper(s) +* +********************************************************************** +*/ +/********************************************************************* +* +* _Square +*/ +static float _Square(float x) { + return x * x; +} + +/********************************************************************* +* +* _GetRandomNumber +*/ +static float _GetRandomNumber(float min, float max) { + return (max - min) * rand() / RAND_MAX + min; +} + +#ifdef WIN32 +static size_t _AllocatedBytes; +#endif + +/********************************************************************* +* +* _Free +*/ +static void _Free(void * p) { +#ifdef WIN32 + _AllocatedBytes -= _msize(p); +#endif + free(p); +} + +/********************************************************************* +* +* _Calloc +*/ +static void * _Calloc(size_t Num, size_t Size) { + void * p; + p = calloc(Num, Size); +#ifdef WIN32 + _AllocatedBytes += _msize(p); +#endif + return calloc(Num, Size); +} + +/********************************************************************* +* +* Static code: VECTOR +* +********************************************************************** +*/ +/********************************************************************* +* +* _VECTOR_Create +*/ +static VECTOR * _VECTOR_Create(float x, float y) { + VECTOR * pVectorNew; + + pVectorNew = (VECTOR *)_Calloc(sizeof(VECTOR), 1); + pVectorNew->x = x; + pVectorNew->y = y; + return pVectorNew; +} + +/********************************************************************* +* +* _VECTOR_CreateCopy +*/ +static VECTOR * _VECTOR_CreateCopy(VECTOR * pVector) { + return _VECTOR_Create(pVector->x, pVector->y); +} + +/********************************************************************* +* +* _VECTOR_CreateCopyPlus +*/ +static VECTOR * _VECTOR_CreateCopyPlus(VECTOR * pVector, VECTOR * pVector1) { + return _VECTOR_Create(pVector->x + pVector1->x, pVector->y + pVector1->y); +} + +/********************************************************************* +* +* _VECTOR_CreateCopyMinus +*/ +static VECTOR * _VECTOR_CreateCopyMinus(VECTOR * pVector, VECTOR * pVector1) { + return _VECTOR_Create(pVector->x - pVector1->x, pVector->y - pVector1->y); +} + +/********************************************************************* +* +* _VECTOR_CreateCopyMult +*/ +static VECTOR * _VECTOR_CreateCopyMult(VECTOR * pVector, float c) { + return _VECTOR_Create(pVector->x * c, pVector->y * c); +} + +/********************************************************************* +* +* _VECTOR_Delete +*/ +static void _VECTOR_Delete(VECTOR * pVector) { + _Free(pVector); +} + +/********************************************************************* +* +* _VECTOR_SetX +*/ +static void _VECTOR_SetX(VECTOR * pVector, float x) { + pVector->x = x; +} + +/********************************************************************* +* +* _VECTOR_SetY +*/ +static void _VECTOR_SetY(VECTOR * pVector, float y) { + pVector->y = y; +} + +/********************************************************************* +* +* _VECTOR_SetXY +*/ +static void _VECTOR_SetXY(VECTOR * pVector, float x, float y) { + pVector->x = x; + pVector->y = y; +} + +/********************************************************************* +* +* _VECTOR_Magnitude +*/ +static float _VECTOR_Magnitude(VECTOR * pVector) { + return sqrt(pVector->x * pVector->x + pVector->y * pVector->y); +} + +/********************************************************************* +* +* _VECTOR_CreateUnitVector +*/ +static VECTOR * _VECTOR_CreateUnitVector(VECTOR * pVector) { + VECTOR * pVectorNew; + float Mag; + + Mag = _VECTOR_Magnitude(pVector); + if (Mag != 0.f) { + pVectorNew = _VECTOR_Create(pVector->x / Mag, pVector->y / Mag); + } else { + pVectorNew = _VECTOR_Create(0.f, 0.f); + } + return pVectorNew; +} + +/********************************************************************* +* +* _VECTOR_DotProduct +*/ +static float _VECTOR_DotProduct(VECTOR * pVector, VECTOR * pVector1) { + float DotProduct; + + DotProduct = pVector->x * pVector1->x + pVector->y * pVector1->y; + return DotProduct; +} + +/********************************************************************* +* +* Static code: WALLS +* +********************************************************************** +*/ +/********************************************************************* +* +* _WALLS_Create +*/ +static WALLS * _WALLS_Create(float x1, float y1, float x2, float y2) { + WALLS * pWall; + + pWall = (WALLS *)_Calloc(sizeof(WALLS), 1); + pWall->x1 = x1; + pWall->y1 = y1; + pWall->x2 = x2; + pWall->y2 = y2; + return pWall; +} + +/********************************************************************* +* +* _WALLS_CreateEmpty +*/ +static WALLS * _WALLS_CreateEmpty(void) { + return _WALLS_Create(0.f, 0.f, 0.f, 0.f); +} + +/********************************************************************* +* +* Static code: BALL +* +********************************************************************** +*/ +/********************************************************************* +* +* _BALL_Create +*/ +static BALL * _BALL_Create(void) { + BALL * pBall; + + pBall = (BALL *)_Calloc(sizeof(BALL), 1); + pBall->m = 0.f; + pBall->r = 0.f; + return pBall; +} + +/********************************************************************* +* +* _BALL_AdvanceBallPosition +*/ +static void _BALL_AdvanceBallPosition(BALL * pBall, const float dt) { + _VECTOR_SetXY(&pBall->p, pBall->p.x + pBall->v.x * dt, pBall->p.y + pBall->v.y * dt); +} + +/********************************************************************* +* +* _BALL_DoBallGravity +*/ +static void _BALL_DoBallGravity(BALL * pb0, BALL * pb1, const float dt, float g) { + VECTOR * v_n; + VECTOR * v_un; + float r, f, a0, a1, v0, v1; + + v_n = _VECTOR_CreateCopyMinus(&pb0->p, &pb1->p); // v_n = normal vec. - a vector normal to the collision surface + v_un = _VECTOR_CreateUnitVector(v_n); // unit normal vector + r = _VECTOR_Magnitude(v_n); + f = g * (pb0->m * pb1->m) / (r * r); + a0 = f / pb0->m; + a1 = f / pb1->m; + v0 = a0 * dt; + v1 = a1 * dt; + _VECTOR_SetXY(&pb0->v, pb0->v.x - v_un->x * v0, pb0->v.y - v_un->y * v0); + _VECTOR_SetXY(&pb1->v, pb1->v.x + v_un->x * v1, pb1->v.y + v_un->y * v1); + _VECTOR_Delete(v_n); + _VECTOR_Delete(v_un); +} + +/********************************************************************* +* +* _BALL_DoGroundGravity +*/ +static void _BALL_DoGroundGravity(BALL * pb, const float dt, float g) { + _VECTOR_SetY(&pb->v, pb->v.y + g * dt * 0.95); +} + +/********************************************************************* +* +* Static code: COLLISION +* +********************************************************************** +*/ +/********************************************************************* +* +* _COLLISION_Reset +*/ +static void _COLLISION_Reset(COLLISION * pCollision) { + pCollision->CollisionType = TYPE_NONE; + pCollision->WhichWall = WALL_NONE; + pCollision->TimeToCollision = 0.f; +} + +/********************************************************************* +* +* _COLLISION_Create +*/ +static COLLISION * _COLLISION_Create(void) { + COLLISION * pCollision; + + pCollision = (COLLISION *)_Calloc(sizeof(COLLISION), 1); + _COLLISION_Reset(pCollision); + return pCollision; +} + +/********************************************************************* +* +* _COLLISION_SetCollisionWithWall +*/ +static void _COLLISION_SetCollisionWithWall(COLLISION * pCollision, const float t, int WhichWall) { + pCollision->CollisionType = TYPE_WALL; + pCollision->WhichWall = WhichWall; + pCollision->TimeToCollision = t; +} + +/********************************************************************* +* +* _COLLISION_SetCollisionWithBall +*/ +static void _COLLISION_SetCollisionWithBall(COLLISION * pCollision, const float t) { + pCollision->CollisionType = TYPE_BALL; + pCollision->WhichWall = WALL_NONE; + pCollision->TimeToCollision = t; +} + +/********************************************************************* +* +* _COLLISION_Ball1HasCollision +*/ +static int _COLLISION_Ball1HasCollision(COLLISION * pCollision) { + return pCollision->CollisionType != TYPE_NONE; +} + +/********************************************************************* +* +* _COLLISION_Ball2HasCollision +*/ +static int _COLLISION_Ball2HasCollision(COLLISION * pCollision) { + return pCollision->CollisionType == TYPE_BALL; +} + +/********************************************************************* +* +* _COLLISION_Ball1HasCollisionWithWall +*/ +static int _COLLISION_Ball1HasCollisionWithWall(COLLISION * pCollision) { + return pCollision->CollisionType == TYPE_WALL; +} + +/********************************************************************* +* +* _COLLISION_Ball1HasCollisionWithBall +*/ +static int _COLLISION_Ball1HasCollisionWithBall(COLLISION * pCollision) { + return pCollision->CollisionType == TYPE_BALL; +} + +/********************************************************************* +* +* _COLLISION_GetCollisionWall +*/ +static int _COLLISION_GetCollisionWall(COLLISION * pCollision) { + return (int)pCollision->WhichWall; +} + +/********************************************************************* +* +* _COLLISION_FindTimeUntilTwoBallsCollide +* +* Function description: +* Finds the time until two specified balls collide. If they don't collide, +* the returned Collision will indicate that. If the balls are overlapping +* a collision is NOT detected. +*/ +static COLLISION _COLLISION_FindTimeUntilTwoBallsCollide(const BALL * pb1, const BALL * pb2) { + COLLISION clsn = {0}; + float a, b, c, det, t; + + // Compute parts of quadratic formula + // + // a = (v2x - v1x) ^ 2 + (v2y - v1y) ^ 2 + // + a = _Square(pb2->v.x - pb1->v.x) + _Square(pb2->v.y - pb1->v.y); + // + // b = 2 * ((x20 - x10) * (v2x - v1x) + (y20 - y10) * (v2y - v1y)) + // + 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)); + // + // c = (x20 - x10) ^ 2 + (y20 - y10) ^ 2 - (r1 + r2) ^ 2 + // + c = _Square(pb2->p.x - pb1->p.x) + _Square(pb2->p.y - pb1->p.y) - _Square(pb1->r + pb2->r); + // + // Determinant = b^2 - 4ac + // + det = _Square(b) - 4 * a * c; + if (a != 0.f) { // If a == 0 then v2x==v1x and v2y==v1y and there will be no collision + t = (-b - sqrt(det)) / (2. * a); // Quadratic formula. t = time to collision + if (t >= 0.) { // If collision occurs... + _COLLISION_SetCollisionWithBall(&clsn, t); + } + } + return clsn; +} + +/********************************************************************* +* +* _COLLISION_FindTimeUntilBallCollidesWithWall +* +* Function description: +* Finds time until specified ball collides with any wall. If they +* don't collide, the returned Collision indicates that. If there +* will be collisions with more than one wall, this function returns +* the earliest collision. +* +* IMPORTANT: This function assumes that the ball is bounded within +* the specified walls. +*/ +static COLLISION _COLLISION_FindTimeUntilBallCollidesWithWall(const BALL * pb, const WALLS * pw) { + COLLISION clsn = {0}; + float timeToCollision; + float t; + int whichWall; + + timeToCollision = 0.f; + whichWall = WALL_NONE; + // + // Check for collision with wall X1 + // + if (pb->v.x < 0.f) { + t = (pb->r - pb->p.x + pw->x1) / pb->v.x; + if (t >= 0.f) { // If t < 0 then ball is headed away from wall + timeToCollision = t; + whichWall = WALL_X1; + } + } + // + // Check for collision with wall Y1 + // + if (pb->v.y < 0.f) { + t = (pb->r - pb->p.y + pw->y1) / pb->v.y; + if (t >= 0.f) { + if (whichWall == WALL_NONE || t < timeToCollision) { + timeToCollision = t; + whichWall = WALL_Y1; + } + } + } + // + // Check for collision with wall X2 + // + if (pb->v.x > 0.f) { + t = (pw->x2 - pb->r - pb->p.x) / pb->v.x; + if (t >= 0.f) { + if (whichWall == WALL_NONE || t < timeToCollision) { + timeToCollision = t; + whichWall = WALL_X2; + } + } + } + // + // Check for collision with wall Y2 + // + if (pb->v.y > 0.f) { + t = (pw->y2 - pb->r - pb->p.y) / pb->v.y; + if (t >= 0.f) { + if (whichWall == WALL_NONE || t < timeToCollision) { + timeToCollision = t; + whichWall = WALL_Y2; + } + } + } + // + // Setup Collision return value + // + if (whichWall != WALL_NONE) { // If there is a collision... + _COLLISION_SetCollisionWithWall(&clsn, timeToCollision, whichWall); + } + return clsn; +} + +/********************************************************************* +* +* _COLLISION_DoElasticCollisionTwoBalls +* +* Function description: +* Updates the velocities of b1 and b2 to reflect the effect of an elastic +* collision between the two. IMPORTANT: This function does NOT check the +* positions of the balls to see if they're actually colliding. It just +* assumes that they are. Use findTimeUntilTwoBallsCollide() to see +* if the balls are colliding. +*/ +static void _COLLISION_DoElasticCollisionTwoBalls(BALL * pb1, BALL * pb2) { + VECTOR * v_n; + VECTOR * v_un; + VECTOR * v_ut; + VECTOR * v_v1nPrime; + VECTOR * v_v1tPrime; + VECTOR * v_v2nPrime; + VECTOR * v_v2tPrime; + float v1n, v1t, v2n, v2t; + float v1tPrime, v2tPrime; + float v1nPrime, v2nPrime; + + // + // Avoid division by zero below in computing new normal velocities + // Doing a collision where both balls have no mass makes no sense anyway + // + if ((pb1->m == 0.f) && (pb2->m == 0.f)) { + return; + } + // + // Compute unit normal and unit tangent vectors + // + v_n = _VECTOR_CreateCopyMinus(&pb2->p, &pb1->p); // v_n = normal vec. - a vector normal to the collision surface + v_un = _VECTOR_CreateUnitVector(v_n); // unit normal vector + v_ut = _VECTOR_Create(-v_un->y, v_un->x); // unit tangent vector + // + // Compute scalar projections of velocities onto v_un and v_ut + // + v1n = _VECTOR_DotProduct(v_un, &pb1->v); // Dot product + v1t = _VECTOR_DotProduct(v_ut, &pb1->v); + v2n = _VECTOR_DotProduct(v_un, &pb2->v); + v2t = _VECTOR_DotProduct(v_ut, &pb2->v); + // + // Compute new tangential velocities + // + v1tPrime = v1t; // Note: in reality, the tangential velocities do not change after the collision + v2tPrime = v2t; + // + // Compute new normal velocities using one-dimensional elastic collision equations in the normal direction + // Division by zero avoided. See early return above. + // + v1nPrime = (v1n * (pb1->m - pb2->m) + 2.f * pb2->m * v2n) / (pb1->m + pb2->m); + v2nPrime = (v2n * (pb2->m - pb1->m) + 2.f * pb1->m * v1n) / (pb1->m + pb2->m); + // + // Compute new normal and tangential velocity vectors + // + v_v1nPrime = _VECTOR_CreateCopyMult(v_un, v1nPrime); // Multiplication by a scalar + v_v1tPrime = _VECTOR_CreateCopyMult(v_ut, v1tPrime); + v_v2nPrime = _VECTOR_CreateCopyMult(v_un, v2nPrime); + v_v2tPrime = _VECTOR_CreateCopyMult(v_ut, v2tPrime); + // + // Set new velocities in x and y coordinates + // + _VECTOR_SetXY(&pb1->v, v_v1nPrime->x + v_v1tPrime->x, v_v1nPrime->y + v_v1tPrime->y); + _VECTOR_SetXY(&pb2->v, v_v2nPrime->x + v_v2tPrime->x, v_v2nPrime->y + v_v2tPrime->y); + // + // CleanUp + // + _VECTOR_Delete(v_n); + _VECTOR_Delete(v_un); + _VECTOR_Delete(v_ut); + _VECTOR_Delete(v_v1nPrime); + _VECTOR_Delete(v_v1tPrime); + _VECTOR_Delete(v_v2nPrime); + _VECTOR_Delete(v_v2tPrime); +} + +/********************************************************************* +* +* _COLLISION_DoElasticCollisionWithWall +*/ +static void _COLLISION_DoElasticCollisionWithWall(BALL * pb, int w) { + switch (w) { + case WALL_X1: + _VECTOR_SetX(&pb->v, fabs(pb->v.x)); + break; + case WALL_Y1: + _VECTOR_SetY(&pb->v, fabs(pb->v.y)); + break; + case WALL_X2: + _VECTOR_SetX(&pb->v, -fabs(pb->v.x)); + break; + case WALL_Y2: + _VECTOR_SetY(&pb->v, -fabs(pb->v.y)); + break; + } +} + +/********************************************************************* +* +* Static code: BALLSIM +* +********************************************************************** +*/ +/********************************************************************* +* +* _BALLSIM_ResetBalls +*/ +static void _BALLSIM_ResetBalls(BALLSIM * pBallsim) { + BALL * pBalli; + BALL * pBalld; + + pBallsim->NextId = 0; // Reset ID counter + pBallsim->MinArea = 0.; + pBallsim->MaxDiameter = 0.; + pBallsim->MaxCollisions = 10; // This will be overwritten on the first call to addBall() + // + // Delete all balls + // + pBalli = pBallsim->pFirstBall; + while (pBalli) { + pBalld = pBalli; + pBalli = pBalli->pNext; + _Free(pBalld); + } +} + +/********************************************************************* +* +* _BALLSIM_Create +*/ +static BALLSIM * _BALLSIM_Create(void) { + BALLSIM * pBallsim; + + pBallsim = (BALLSIM *)_Calloc(sizeof(BALLSIM), 1); + pBallsim->HasWalls = 0; + pBallsim->MaxCollisionsPerBall = 10; + _BALLSIM_ResetBalls(pBallsim); + return pBallsim; +} + +/********************************************************************* +* +* _BALLSIM_AdvanceBallPositions +*/ +static void _BALLSIM_AdvanceBallPositions(BALLSIM * pBallsim, const float dt) { + BALL * pBalli; + + pBalli = pBallsim->pFirstBall; + while (pBalli) { + _BALL_AdvanceBallPosition(pBalli, dt); + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* BALLSSIM_FindEarliestCollisionOfTwoBalls +*/ +static COLLISION BALLSSIM_FindEarliestCollisionOfTwoBalls(BALLSIM * pBallsim, BALL ** ppb1, BALL ** ppb2) { + COLLISION earliestCollision; + COLLISION c; + BALL * pBalli; + BALL * pBallj; + + _COLLISION_Reset(&earliestCollision); + // + // Compare each pair of balls. Index i runs from the first + // ball up through the second-to-last ball. For each value of + // i, index j runs from the ball after i up through the last ball. + // + pBalli = pBallsim->pFirstBall; + while (pBalli) { + pBallj = pBallsim->pFirstBall; + while (pBallj) { + c = _COLLISION_FindTimeUntilTwoBallsCollide(pBalli, pBallj); + if (_COLLISION_Ball1HasCollisionWithBall(&c)) { + if (!_COLLISION_Ball1HasCollision(&earliestCollision) || c.TimeToCollision < earliestCollision.TimeToCollision) { + earliestCollision = c; + *ppb1 = pBalli; + *ppb2 = pBallj; + } + } + pBallj = pBallj->pNext; + } + pBalli = pBalli->pNext; + } + return earliestCollision; +} + +/********************************************************************* +* +* BALLSSIM_FindEarliestCollisionWithWall +*/ +static COLLISION BALLSSIM_FindEarliestCollisionWithWall(BALLSIM * pBallsim, BALL ** ppb) { + COLLISION earliestCollision; + COLLISION c; + BALL * pBalli; + + _COLLISION_Reset(&earliestCollision); + // + // If there are no walls, return no collision + // + if (!pBallsim->HasWalls) { + return earliestCollision; + } + // + // Check each ball to see if any collide. Store the earliest colliding ball. + // + pBalli = pBallsim->pFirstBall; + while (pBalli) { + c = _COLLISION_FindTimeUntilBallCollidesWithWall(pBalli, &pBallsim->Walls); + if (_COLLISION_Ball1HasCollisionWithWall(&c)) { + if (!_COLLISION_Ball1HasCollision(&earliestCollision) || c.TimeToCollision < earliestCollision.TimeToCollision) { + earliestCollision = c; + *ppb = pBalli; + } + } + pBalli = pBalli->pNext; + } + return earliestCollision; +} + +/********************************************************************* +* +* BALLSSIM_FindEarliestCollision +*/ +static COLLISION BALLSSIM_FindEarliestCollision(BALLSIM * pBallsim, BALL ** ppb1, BALL ** ppb2) { + COLLISION earliestCollision; + COLLISION cWalls; + BALL * pbCollideWithWall; + + earliestCollision = BALLSSIM_FindEarliestCollisionOfTwoBalls(pBallsim, ppb1, ppb2); + if (pBallsim->HasWalls) { + cWalls = BALLSSIM_FindEarliestCollisionWithWall(pBallsim, &pbCollideWithWall); + if (_COLLISION_Ball1HasCollisionWithWall(&cWalls)) { + if (!_COLLISION_Ball1HasCollisionWithBall(&earliestCollision) || cWalls.TimeToCollision < earliestCollision.TimeToCollision) { + earliestCollision = cWalls; + *ppb1 = pbCollideWithWall; + } + } + } + return earliestCollision; +} + +/********************************************************************* +* +* _BALLSIM_AdvanceBallGravity +*/ +static void _BALLSIM_AdvanceBallGravity(BALLSIM * pBallsim, const float dt) { + BALL * pBalli; + BALL * pBallj; + + pBalli = pBallsim->pFirstBall; + while (pBalli) { + pBallj = pBalli->pNext; + while (pBallj) { + _BALL_DoBallGravity(pBalli, pBallj, dt, pBallsim->pConfig->Gravity); + pBallj = pBallj->pNext; + } + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* _BALLSIM_AdvanceGroundGravity +*/ +static void _BALLSIM_AdvanceGroundGravity(BALLSIM * pBallsim, const float dt) { + BALL * pBalli; + + pBalli = pBallsim->pFirstBall; + while (pBalli) { + _BALL_DoGroundGravity(pBalli, dt, pBallsim->pConfig->Gravity); + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* BALLSSIM_AdvanceSim +*/ +static void BALLSSIM_AdvanceSim(BALLSIM * pBallsim, const float dt) { + float tElapsed; + COLLISION c; + BALL * pb1; + BALL * pb2; + unsigned i; + + tElapsed = 0.f; + for (i = 0; i < pBallsim->MaxCollisions; i++) { + // + // Find earliest collision + // + c = BALLSSIM_FindEarliestCollision(pBallsim, &pb1, &pb2); + // + // If no collisions, break + // + if (!_COLLISION_Ball1HasCollision(&c)) { + break; + } + // + // Is collision within the time frame? + // Note: condition is tElapsed + timeToCollision strictly < dt, not <=, because if the two were exactly + // equal, we would perform the velocity adjustment for collision but not move the balls any more, so the + // collision could be detected again on the next call to advanceSim(). + // + if (tElapsed + c.TimeToCollision < dt) { + // + // Collision is within time frame + // Advance balls to point of collision + // + _BALLSIM_AdvanceBallPositions(pBallsim, c.TimeToCollision); + // + // Collision is now occuring. Do collision calculation + // + if (_COLLISION_Ball1HasCollisionWithWall(&c)) { + _COLLISION_DoElasticCollisionWithWall(pb1, c.WhichWall); + } else if (_COLLISION_Ball1HasCollisionWithBall(&c)) { + _COLLISION_DoElasticCollisionTwoBalls(pb1, pb2); + } + tElapsed += c.TimeToCollision; // Move time counter forward + } else { + break; // Break if collision is not within this frame + } + } + // + // Advance ball positions further if necessary after any collisions to complete the time frame + // + _BALLSIM_AdvanceBallPositions(pBallsim, dt - tElapsed); + // + // Manage ball gravity + // + if (pBallsim->pConfig->HasBallGravity) { + _BALLSIM_AdvanceBallGravity(pBallsim, dt); + } + // + // Manage ground gravity + // + if (pBallsim->pConfig->HasGroundGravity) { + _BALLSIM_AdvanceGroundGravity(pBallsim, dt); + } +} + +/********************************************************************* +* +* BALLSSIM_MoveBallToWithinBounds +*/ +static void BALLSSIM_MoveBallToWithinBounds(BALLSIM * pBallsim, BALL * pb) { + // + // Check wall X1 + // + if (pb->p.x - pb->r < pBallsim->Walls.x1) { + _VECTOR_SetX(&pb->p, pBallsim->Walls.x1 + pb->r); + } + // + // Check wall Y1 + // + if (pb->p.y - pb->r < pBallsim->Walls.y1) { + _VECTOR_SetY(&pb->p, pBallsim->Walls.y1 + pb->r); + } + // + // Check wall X2 + // + if (pb->p.x + pb->r > pBallsim->Walls.x2) { + _VECTOR_SetX(&pb->p, pBallsim->Walls.x2 - pb->r); + } + // + // Check wall Y2 + // + if (pb->p.y + pb->r > pBallsim->Walls.y2) { + _VECTOR_SetY(&pb->p, pBallsim->Walls.y2 - pb->r); + } +} + +/********************************************************************* +* +* BALLSSIM_MoveWalls +*/ +static void BALLSSIM_MoveWalls(BALLSIM * pBallsim, const WALLS * pNewWalls) { + BALL * pBalli; + + pBallsim->Walls = *pNewWalls; + pBallsim->HasWalls = 1; + pBalli = pBallsim->pFirstBall; + while (pBalli) { + BALLSSIM_MoveBallToWithinBounds(pBallsim, pBalli); + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* BALLSSIM_GetMinWallDimension +*/ +static float BALLSSIM_GetMinWallDimension(BALLSIM * pBallsim, float fixedWallDimension) { + float minDimension; + + minDimension = 0.f; + if (fixedWallDimension > 0.f) { + minDimension = 4.f * pBallsim->MinArea / fixedWallDimension; + } + if (minDimension <= pBallsim->MaxDiameter) { + minDimension = pBallsim->MaxDiameter + 1; + } + return minDimension; +} + +/********************************************************************* +* +* BALLSSIM_AddBall +*/ +static void BALLSSIM_AddBall(BALLSIM * pBallsim, BALL * pNewBall) { + BALL * pBalli; + + pBallsim->NumBalls = 0; + pBalli = pBallsim->pFirstBall; + if (pBalli) { + pBallsim->NumBalls++; + while (pBalli->pNext) { + pBallsim->NumBalls++; + pBalli = pBalli->pNext; + } + pBallsim->NumBalls++; + pBalli->pNext = pNewBall; + } else { + pBallsim->NumBalls++; + pBallsim->pFirstBall = pNewBall; + pNewBall->pNext = NULL; + } + pBallsim->MaxCollisions = pBallsim->MaxCollisionsPerBall * pBallsim->NumBalls; + BALLSSIM_MoveBallToWithinBounds(pBallsim, pNewBall); + if (pNewBall->r * 2.f > pBallsim->MaxDiameter) { + pBallsim->MaxDiameter = pNewBall->r * 2.f; + pBallsim->MinArea += 4.f * pNewBall->r * pNewBall->r; + } +} + +/********************************************************************* +* +* _BALLSIM_GetBallFromPos +*/ +static BALL * _BALLSIM_GetBallFromPos(BALLSIM * pBallsim, float xPos, float yPos) { + float d, dx, dy; + BALL * pBalli; + + pBalli = pBallsim->pFirstBall; + while (pBalli) { + dx = xPos - pBalli->p.x; + dy = yPos - pBalli->p.y; + d = sqrt(dx * dx + dy * dy); + if (d < pBalli->r) { + return pBalli; + } + pBalli = pBalli->pNext; + } + return NULL; +} + +/********************************************************************* +* +* _BALLSIM_DeleteBall +*/ +static void _BALLSIM_DeleteBall(BALLSIM * pBallsim, BALL * pBall) { + BALL * pBalli; + BALL * pBallPrev = NULL; + + pBalli = pBallsim->pFirstBall; + while (pBalli) { + if (pBalli == pBall) { + if (pBallPrev) { + pBallPrev->pNext = pBalli->pNext; + } else { + pBallsim->pFirstBall = pBallsim->pFirstBall->pNext; + } + pBallsim->NumBalls--; + _Free(pBall); + break; + } + pBallPrev = pBalli; + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* _BALLSIM_StopMoving +*/ +static void _BALLSIM_StopMoving(BALLSIM * pBallsim) { + BALL * pBalli; + + pBalli = pBallsim->pFirstBall; + while (pBalli) { + _VECTOR_SetXY(&pBalli->v, 0.f, 0.f); + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* _BALLSIM_Delete +*/ +static void _BALLSIM_Delete(BALLSIM * pBallsim) { + _BALLSIM_ResetBalls(pBallsim); + _Free(pBallsim); +} + +/********************************************************************* +* +* Static code: Ballsim Window +* +********************************************************************** +*/ +/********************************************************************* +* +* _UpdateDisplay +*/ +static void _UpdateDisplay(WM_HWIN hWin, BALLSIM * pBallsim) { + BALL * pBalli; + U32 Color; + + // + // Draw background + // + if (pBallsim->pConfig->pfDrawBk) { + pBallsim->pConfig->pfDrawBk(hWin, pBallsim->pConfig); + } else { + GUI_SetBkColor(pBallsim->pConfig->ColorBk); + GUI_Clear(); + } + // + // Draw all balls + // + pBalli = pBallsim->pFirstBall; + while (pBalli) { + if (pBallsim->pConfig->pfDrawBall) { + pBallsim->pConfig->pfDrawBall(hWin, pBallsim->pConfig, pBalli->Index, pBalli->p.x, pBalli->p.y, pBalli->r); + } else { + Color = GUI_MAKE_COLOR(pBalli->Index); + GUI_SetColor(Color); + GUI_FillCircle(pBalli->p.x, pBalli->p.y, pBalli->r); + } + pBalli = pBalli->pNext; + } +} + +/********************************************************************* +* +* _AddRandomBalls +*/ +static void _AddRandomBalls(BALLSIM * pBallsim) { + unsigned i, PosOccupied, Cnt; + float d, dx, dy; + BALL * pBall; + BALL * pBalli; + BALLSIM_CONFIG * pConfig; + + pConfig = pBallsim->pConfig; + for (i = 0; i < pConfig->NumBalls; i++) { + pBall = _BALL_Create(); + if (pBallsim->pConfig->HasInitialVelocity) { + pBall->v.x = _GetRandomNumber(pConfig->vMin, pConfig->vMax); + pBall->v.y = _GetRandomNumber(pConfig->vMin, pConfig->vMax); + } + pBall->Index = (U32)_GetRandomNumber(0, pConfig->Range); + if (pConfig->pRadius) { + pBall->r = *(pConfig->pRadius + pBall->Index); + } else { + pBall->r = _GetRandomNumber(pConfig->rMin, pConfig->rMax); + } + pBall->m = M_TO_A_RATIO * M_PI * pBall->r * pBall->r; + // + // Generate legal position + // + Cnt = 0; + do { + pBall->p.x = _GetRandomNumber((float)pBall->r, (float)(pConfig->xSize) - pBall->r); + pBall->p.y = _GetRandomNumber((float)pBall->r, (float)(pConfig->ySize) - pBall->r); + PosOccupied = 0; + pBalli = pBallsim->pFirstBall; + while (pBalli) { + dx = pBalli->p.x - pBall->p.x; + dy = pBalli->p.y - pBall->p.y; + d = sqrt(dx * dx + dy * dy); + if (d < pBalli->r + pBall->r) { + PosOccupied = 1; + break; + } + pBalli = pBalli->pNext; + } + } while (PosOccupied && (Cnt++ < 10)); + // + // Add ball to array + // + if (PosOccupied == 0) { + BALLSSIM_AddBall(pBallsim, pBall); + } + } +} + +/********************************************************************* +* +* _cbConfig +*/ +static void _cbConfig(WM_MESSAGE * pMsg) { + WM_HWIN hItem; + static BALLSIM * pBallsim; + int Id, NCode; + int xSize, ySize; + WM_PID_STATE_CHANGED_INFO * pInfo; + GUI_PID_STATE * pState; + static int IsDown; + static GUI_POINT pDown; + + switch (pMsg->MsgId) { + case WM_PAINT: + xSize = WM_GetWindowSizeX(pMsg->hWin); + ySize = WM_GetWindowSizeY(pMsg->hWin); + GUI_SetColor(GUI_BLACK); + GUI_DrawRect(0, 0, xSize - 1, ySize - 1); + break; + case WM_PID_STATE_CHANGED: + pInfo = (WM_PID_STATE_CHANGED_INFO *)pMsg->Data.p; + if (pInfo->StatePrev == 0) { + IsDown = 1; + pDown.x = pInfo->x; + pDown.y = pInfo->y; + WM_SetCapture(pMsg->hWin, 1); + } else { + IsDown = 0; + } + break; + case WM_TOUCH: + if (IsDown) { + pState = (GUI_PID_STATE *)pMsg->Data.p; + if (pState) { + WM_MoveWindow(pMsg->hWin, pState->x - pDown.x, pState->y - pDown.y); + } + } + break; + case WM_USER_DATA: + WM_GetUserData(pMsg->hWin, &pBallsim, sizeof(void *)); + WINDOW_SetBkColor(pMsg->hWin, GUI_WHITE); + WM_MakeModal(pMsg->hWin); + hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0); + BUTTON_SetText(hItem, "Stop moving"); + hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1); + BUTTON_SetText(hItem, "Create random balls"); + hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2); + BUTTON_SetText(hItem, "Back"); + hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0); + CHECKBOX_SetText(hItem, "Ball Gravity"); + if (pBallsim->pConfig->HasBallGravity) { + CHECKBOX_Check(hItem); + } else { + CHECKBOX_Uncheck(hItem); + } + hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_1); + CHECKBOX_SetText(hItem, "Ground Gravity"); + if (pBallsim->pConfig->HasGroundGravity) { + CHECKBOX_Check(hItem); + } else { + CHECKBOX_Uncheck(hItem); + } + hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0); + TEXT_SetText(hItem, "Gravity:"); + TEXT_SetTextAlign(hItem, GUI_TA_RIGHT | GUI_TA_VCENTER); + hItem = WM_GetDialogItem(pMsg->hWin, ID_SLIDER_0); + SLIDER_SetRange(hItem, 0, 400); + SLIDER_SetValue(hItem, (int)pBallsim->pConfig->Gravity); + break; + case WM_NOTIFY_PARENT: + Id = WM_GetId(pMsg->hWinSrc); + NCode = pMsg->Data.v; + switch(Id) { + case ID_BUTTON_0: + switch(NCode) { + case WM_NOTIFICATION_RELEASED: + _BALLSIM_StopMoving(pBallsim); + break; + } + break; + case ID_BUTTON_1: + switch(NCode) { + case WM_NOTIFICATION_RELEASED: + _AddRandomBalls(pBallsim); + break; + } + break; + case ID_BUTTON_2: + switch(NCode) { + case WM_NOTIFICATION_RELEASED: + WM_DeleteWindow(pMsg->hWin); + break; + } + break; + case ID_CHECKBOX_0: + switch(NCode) { + case WM_NOTIFICATION_VALUE_CHANGED: + pBallsim->pConfig->HasBallGravity = CHECKBOX_IsChecked(pMsg->hWinSrc) ? 1 : 0; + break; + } + break; + case ID_CHECKBOX_1: + switch(NCode) { + case WM_NOTIFICATION_VALUE_CHANGED: + pBallsim->pConfig->HasGroundGravity = CHECKBOX_IsChecked(pMsg->hWinSrc) ? 1 : 0; + break; + } + break; + case ID_SLIDER_0: + switch(NCode) { + case WM_NOTIFICATION_VALUE_CHANGED: + pBallsim->pConfig->Gravity = (float)SLIDER_GetValue(pMsg->hWinSrc); + break; + } + break; + } + break; + default: + WM_DefaultProc(pMsg); + } +} + +/********************************************************************* +* +* _CreateConfigWindow +*/ +static void _CreateConfigWindow(BALLSIM * pBallsim, WM_HWIN hParent) { + WM_HWIN hWin; + int xPos, yPos; + + xPos = (pBallsim->pConfig->xSize - _aDialogCreate[0].xSize) / 2; + yPos = (pBallsim->pConfig->ySize - _aDialogCreate[0].ySize) / 3; + hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbConfig, WM_HBKWIN, xPos, yPos); + WM_SetUserData(hWin, &pBallsim, sizeof(void *)); +} + +/********************************************************************* +* +* _CreateBallsim +*/ +static BALLSIM * _CreateBallsim(WM_HWIN hWin) { + BALLSIM_CONFIG * pConfig; + BALLSIM * pBallsim; + WALLS * pWalls; + + WM_GetUserData(hWin, &pConfig, sizeof(void *)); + pBallsim = _BALLSIM_Create(); + pBallsim->pConfig = pConfig; + pWalls = _WALLS_Create(0.f, 0.f, (float)pConfig->xSize, (float)pConfig->ySize); + BALLSSIM_MoveWalls(pBallsim, pWalls); + _AddRandomBalls(pBallsim); + _Free(pWalls); + return pBallsim; +} + +/********************************************************************* +* +* _cbBallsim +*/ +static void _cbBallsim(WM_MESSAGE * pMsg) { + static BALLSIM * pBallsim; + static GUI_TIMER_TIME Time; + GUI_TIMER_TIME tNow; + WM_HTIMER hTimer; + WM_PID_STATE_CHANGED_INFO * pInfo; + BALL * pBall; + + switch (pMsg->MsgId) { + case WM_PID_STATE_CHANGED: + pInfo = (WM_PID_STATE_CHANGED_INFO *)pMsg->Data.p; + if (pInfo->StatePrev == 0) { + pBall = _BALLSIM_GetBallFromPos(pBallsim, (float)pInfo->x, (float)pInfo->y); + if (pBall) { + _BALLSIM_DeleteBall(pBallsim, pBall); + } else { + _CreateConfigWindow(pBallsim, pMsg->hWin); + } + } + break; + case WM_DELETE: + _BALLSIM_Delete(pBallsim); + break; + case WM_USER_DATA: + pBallsim = _CreateBallsim(pMsg->hWin); + hTimer = WM_CreateTimer(pMsg->hWin, 0, TIME_SLICE, 0); + Time = GUI_GetTime(); + break; + case WM_PAINT: + _UpdateDisplay(pMsg->hWin, pBallsim); + break; + case WM_TIMER: + WM_RestartTimer(pMsg->Data.v, pBallsim->pConfig->TimeSlice); + tNow = GUI_GetTime(); + BALLSSIM_AdvanceSim(pBallsim, (float)(tNow - Time) / 1000); + Time = tNow; + WM_InvalidateWindow(pMsg->hWin); + break; + default: + WM_DefaultProc(pMsg); + } +} + +/********************************************************************* +* +* _CreateBallsimWindow +*/ +static WM_HWIN _CreateBallsimWindow(BALLSIM_CONFIG * pConfig, WM_HWIN hParent) { + WM_HWIN hWin; + + hWin = WM_CreateWindowAsChild(pConfig->xPos, pConfig->yPos, pConfig->xSize, pConfig->ySize, hParent, WM_CF_SHOW, _cbBallsim, sizeof(void *)); + WM_SetUserData(hWin, &pConfig, sizeof(void *)); +#if GUI_VERSION < 54400 + WM_SendMessageNoPara(hWin, WM_USER_DATA); +#endif + return hWin; +} +/********************************************************************* +* +* Static code: Application +* +********************************************************************** +*/ +/********************************************************************* +* +* _DrawBk +*/ +static void _DrawBk(WM_HWIN hWin, void * pVoid) { + GUI_SetBkColor(GUI_MAKE_COLOR(0x202020)); + GUI_Clear(); +} + +/********************************************************************* +* +* _DrawBall +*/ +static void _DrawBall(WM_HWIN hWin, void * pVoid, U32 Index, float x, float y, float r) { + GUI_SetColor(GUI_MAKE_COLOR(Index)); + GUI_AA_FillCircle((int)x, (int)y, (int)r); +} + +/********************************************************************* +* +* _cbSplash +*/ +static void _cbSplash(WM_MESSAGE * pMsg) { + int xSize, ySize; + const GUI_BITMAP * pBm; + + switch (pMsg->MsgId) { + case WM_PAINT: + xSize = WM_GetWindowSizeX(pMsg->hWin); + ySize = WM_GetWindowSizeY(pMsg->hWin); + GUI_SetBkColor(GUI_WHITE); + GUI_Clear(); + pBm = &_bmSeggerLogo_80x40; + GUI_DrawBitmap(pBm, xSize - pBm->XSize - 10, 5); + GUI_SetColor(GUI_BLACK); + GUI_SetFont(&GUI_Font32_AA4_Bounce); + GUI_DispStringAt("Bounce", 10, 10); + GUI_SetFont(GUI_FONT_13_ASCII); + GUI_DispStringHCenterAt("Press screen for config dialog,\n" + "Tap balls to remove them.\n\n" + "Have fun...", xSize / 2, pBm->YSize + 20); + break; + case WM_CREATE: + WM_CreateTimer(pMsg->hWin, 0, PERIOD_SPLASH, 0); + WM_MakeModal(pMsg->hWin); + break; + case WM_TIMER: + WM_DeleteWindow(pMsg->hWin); + break; + default: + WM_DefaultProc(pMsg); + } +} + +/********************************************************************* +* +* _Test +*/ +static void _Test(void) { + int xSize, ySize; + int xPos, yPos; + WM_HWIN hWin; + static BALLSIM_CONFIG Config; + + xSize = LCD_GetXSize(); + ySize = LCD_GetYSize(); + // + // Configuration of ball simulation + // + Config.xSize = xSize; + Config.ySize = ySize; + Config.Range = 0xE0E0E0; + Config.NumBalls = NUM_BALLS; + Config.TimeSlice = TIME_SLICE; + Config.vMin = MIN_RANDOM_V; + Config.vMax = MAX_RANDOM_V; + Config.rMin = MIN_RANDOM_R; + Config.rMax = MAX_RANDOM_R; + Config.Gravity = GRAVITY; + Config.pfDrawBk = _DrawBk; + Config.pfDrawBall = _DrawBall; + hWin = _CreateBallsimWindow(&Config, WM_HBKWIN); + // + // Create splash screen + // + xPos = (xSize - XSIZE_SPLASH) / 2; + yPos = (ySize - YSIZE_SPLASH) / 3; + WM_CreateWindowAsChild(xPos, yPos, XSIZE_SPLASH, YSIZE_SPLASH, hWin, WM_CF_SHOW, _cbSplash, 0); +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* MainTask +*/ +void MainTask(void) { + GUI_Init(); + WM_MULTIBUF_Enable(1); + BUTTON_SetReactOnLevel(); + _Test(); + while (1) { + GUI_Delay(100); + } +} + +/*************************** End of file ****************************/