minesweeper

A minewseeper implementation to play around with Hare and Raylib
git clone https://git.tronto.net/minesweeper
Download | Log | Files | Refs | README | LICENSE

rcore_template.c (21085B)


      1 /**********************************************************************************************
      2 *
      3 *   rcore_<platform> template - Functions to manage window, graphics device and inputs
      4 *
      5 *   PLATFORM: <PLATFORM>
      6 *       - TODO: Define the target platform for the core
      7 *
      8 *   LIMITATIONS:
      9 *       - Limitation 01
     10 *       - Limitation 02
     11 *
     12 *   POSSIBLE IMPROVEMENTS:
     13 *       - Improvement 01
     14 *       - Improvement 02
     15 *
     16 *   ADDITIONAL NOTES:
     17 *       - TRACELOG() function is located in raylib [utils] module
     18 *
     19 *   CONFIGURATION:
     20 *       #define RCORE_PLATFORM_CUSTOM_FLAG
     21 *           Custom flag for rcore on target platform -not used-
     22 *
     23 *   DEPENDENCIES:
     24 *       - <platform-specific SDK dependency>
     25 *       - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
     26 *
     27 *
     28 *   LICENSE: zlib/libpng
     29 *
     30 *   Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors
     31 *
     32 *   This software is provided "as-is", without any express or implied warranty. In no event
     33 *   will the authors be held liable for any damages arising from the use of this software.
     34 *
     35 *   Permission is granted to anyone to use this software for any purpose, including commercial
     36 *   applications, and to alter it and redistribute it freely, subject to the following restrictions:
     37 *
     38 *     1. The origin of this software must not be misrepresented; you must not claim that you
     39 *     wrote the original software. If you use this software in a product, an acknowledgment
     40 *     in the product documentation would be appreciated but is not required.
     41 *
     42 *     2. Altered source versions must be plainly marked as such, and must not be misrepresented
     43 *     as being the original software.
     44 *
     45 *     3. This notice may not be removed or altered from any source distribution.
     46 *
     47 **********************************************************************************************/
     48 
     49 // TODO: Include the platform specific libraries
     50 
     51 //----------------------------------------------------------------------------------
     52 // Types and Structures Definition
     53 //----------------------------------------------------------------------------------
     54 typedef struct {
     55     // TODO: Define the platform specific variables required
     56 
     57     // Display data
     58     EGLDisplay device;                  // Native display device (physical screen connection)
     59     EGLSurface surface;                 // Surface to draw on, framebuffers (connected to context)
     60     EGLContext context;                 // Graphic context, mode in which drawing can be done
     61     EGLConfig config;                   // Graphic config
     62 } PlatformData;
     63 
     64 //----------------------------------------------------------------------------------
     65 // Global Variables Definition
     66 //----------------------------------------------------------------------------------
     67 extern CoreData CORE;                   // Global CORE state context
     68 
     69 static PlatformData platform = { 0 };   // Platform specific data
     70 
     71 //----------------------------------------------------------------------------------
     72 // Module Internal Functions Declaration
     73 //----------------------------------------------------------------------------------
     74 int InitPlatform(void);          // Initialize platform (graphics, inputs and more)
     75 bool InitGraphicsDevice(void);   // Initialize graphics device
     76 
     77 //----------------------------------------------------------------------------------
     78 // Module Functions Declaration
     79 //----------------------------------------------------------------------------------
     80 // NOTE: Functions declaration is provided by raylib.h
     81 
     82 //----------------------------------------------------------------------------------
     83 // Module Functions Definition: Window and Graphics Device
     84 //----------------------------------------------------------------------------------
     85 
     86 // Check if application should close
     87 bool WindowShouldClose(void)
     88 {
     89     if (CORE.Window.ready) return CORE.Window.shouldClose;
     90     else return true;
     91 }
     92 
     93 // Toggle fullscreen mode
     94 void ToggleFullscreen(void)
     95 {
     96     TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform");
     97 }
     98 
     99 // Toggle borderless windowed mode
    100 void ToggleBorderlessWindowed(void)
    101 {
    102     TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform");
    103 }
    104 
    105 // Set window state: maximized, if resizable
    106 void MaximizeWindow(void)
    107 {
    108     TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");
    109 }
    110 
    111 // Set window state: minimized
    112 void MinimizeWindow(void)
    113 {
    114     TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform");
    115 }
    116 
    117 // Set window state: not minimized/maximized
    118 void RestoreWindow(void)
    119 {
    120     TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");
    121 }
    122 
    123 // Set window configuration state using flags
    124 void SetWindowState(unsigned int flags)
    125 {
    126     TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform");
    127 }
    128 
    129 // Clear window configuration state flags
    130 void ClearWindowState(unsigned int flags)
    131 {
    132     TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform");
    133 }
    134 
    135 // Set icon for window
    136 void SetWindowIcon(Image image)
    137 {
    138     TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform");
    139 }
    140 
    141 // Set icon for window
    142 void SetWindowIcons(Image *images, int count)
    143 {
    144     TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform");
    145 }
    146 
    147 // Set title for window
    148 void SetWindowTitle(const char *title)
    149 {
    150     CORE.Window.title = title;
    151 }
    152 
    153 // Set window position on screen (windowed mode)
    154 void SetWindowPosition(int x, int y)
    155 {
    156     TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform");
    157 }
    158 
    159 // Set monitor for the current window
    160 void SetWindowMonitor(int monitor)
    161 {
    162     TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform");
    163 }
    164 
    165 // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)
    166 void SetWindowMinSize(int width, int height)
    167 {
    168     CORE.Window.screenMin.width = width;
    169     CORE.Window.screenMin.height = height;
    170 }
    171 
    172 // Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)
    173 void SetWindowMaxSize(int width, int height)
    174 {
    175     CORE.Window.screenMax.width = width;
    176     CORE.Window.screenMax.height = height;
    177 }
    178 
    179 // Set window dimensions
    180 void SetWindowSize(int width, int height)
    181 {
    182     TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform");
    183 }
    184 
    185 // Set window opacity, value opacity is between 0.0 and 1.0
    186 void SetWindowOpacity(float opacity)
    187 {
    188     TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");
    189 }
    190 
    191 // Set window focused
    192 void SetWindowFocused(void)
    193 {
    194     TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform");
    195 }
    196 
    197 // Get native window handle
    198 void *GetWindowHandle(void)
    199 {
    200     TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");
    201     return NULL;
    202 }
    203 
    204 // Get number of monitors
    205 int GetMonitorCount(void)
    206 {
    207     TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform");
    208     return 1;
    209 }
    210 
    211 // Get number of monitors
    212 int GetCurrentMonitor(void)
    213 {
    214     TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform");
    215     return 0;
    216 }
    217 
    218 // Get selected monitor position
    219 Vector2 GetMonitorPosition(int monitor)
    220 {
    221     TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform");
    222     return (Vector2){ 0, 0 };
    223 }
    224 
    225 // Get selected monitor width (currently used by monitor)
    226 int GetMonitorWidth(int monitor)
    227 {
    228     TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform");
    229     return 0;
    230 }
    231 
    232 // Get selected monitor height (currently used by monitor)
    233 int GetMonitorHeight(int monitor)
    234 {
    235     TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform");
    236     return 0;
    237 }
    238 
    239 // Get selected monitor physical width in millimetres
    240 int GetMonitorPhysicalWidth(int monitor)
    241 {
    242     TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform");
    243     return 0;
    244 }
    245 
    246 // Get selected monitor physical height in millimetres
    247 int GetMonitorPhysicalHeight(int monitor)
    248 {
    249     TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform");
    250     return 0;
    251 }
    252 
    253 // Get selected monitor refresh rate
    254 int GetMonitorRefreshRate(int monitor)
    255 {
    256     TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform");
    257     return 0;
    258 }
    259 
    260 // Get the human-readable, UTF-8 encoded name of the selected monitor
    261 const char *GetMonitorName(int monitor)
    262 {
    263     TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform");
    264     return "";
    265 }
    266 
    267 // Get window position XY on monitor
    268 Vector2 GetWindowPosition(void)
    269 {
    270     TRACELOG(LOG_WARNING, "GetWindowPosition() not implemented on target platform");
    271     return (Vector2){ 0, 0 };
    272 }
    273 
    274 // Get window scale DPI factor for current monitor
    275 Vector2 GetWindowScaleDPI(void)
    276 {
    277     TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
    278     return (Vector2){ 1.0f, 1.0f };
    279 }
    280 
    281 // Set clipboard text content
    282 void SetClipboardText(const char *text)
    283 {
    284     TRACELOG(LOG_WARNING, "SetClipboardText() not implemented on target platform");
    285 }
    286 
    287 // Get clipboard text content
    288 // NOTE: returned string is allocated and freed by GLFW
    289 const char *GetClipboardText(void)
    290 {
    291     TRACELOG(LOG_WARNING, "GetClipboardText() not implemented on target platform");
    292     return NULL;
    293 }
    294 
    295 // Show mouse cursor
    296 void ShowCursor(void)
    297 {
    298     CORE.Input.Mouse.cursorHidden = false;
    299 }
    300 
    301 // Hides mouse cursor
    302 void HideCursor(void)
    303 {
    304     CORE.Input.Mouse.cursorHidden = true;
    305 }
    306 
    307 // Enables cursor (unlock cursor)
    308 void EnableCursor(void)
    309 {
    310     // Set cursor position in the middle
    311     SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
    312 
    313     CORE.Input.Mouse.cursorHidden = false;
    314 }
    315 
    316 // Disables cursor (lock cursor)
    317 void DisableCursor(void)
    318 {
    319     // Set cursor position in the middle
    320     SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
    321 
    322     CORE.Input.Mouse.cursorHidden = true;
    323 }
    324 
    325 // Swap back buffer with front buffer (screen drawing)
    326 void SwapScreenBuffer(void)
    327 {
    328     eglSwapBuffers(platform.device, platform.surface);
    329 }
    330 
    331 //----------------------------------------------------------------------------------
    332 // Module Functions Definition: Misc
    333 //----------------------------------------------------------------------------------
    334 
    335 // Get elapsed time measure in seconds since InitTimer()
    336 double GetTime(void)
    337 {
    338     double time = 0.0;
    339     struct timespec ts = { 0 };
    340     clock_gettime(CLOCK_MONOTONIC, &ts);
    341     unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
    342 
    343     time = (double)(nanoSeconds - CORE.Time.base)*1e-9;  // Elapsed time since InitTimer()
    344 
    345     return time;
    346 }
    347 
    348 // Open URL with default system browser (if available)
    349 // NOTE: This function is only safe to use if you control the URL given.
    350 // A user could craft a malicious string performing another action.
    351 // Only call this function yourself not with user input or make sure to check the string yourself.
    352 // Ref: https://github.com/raysan5/raylib/issues/686
    353 void OpenURL(const char *url)
    354 {
    355     // Security check to (partially) avoid malicious code on target platform
    356     if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
    357     else
    358     {
    359         // TODO:
    360     }
    361 }
    362 
    363 //----------------------------------------------------------------------------------
    364 // Module Functions Definition: Inputs
    365 //----------------------------------------------------------------------------------
    366 
    367 // Set internal gamepad mappings
    368 int SetGamepadMappings(const char *mappings)
    369 {
    370     TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform");
    371     return 0;
    372 }
    373 
    374 // Set mouse position XY
    375 void SetMousePosition(int x, int y)
    376 {
    377     CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
    378     CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
    379 }
    380 
    381 // Set mouse cursor
    382 void SetMouseCursor(int cursor)
    383 {
    384     TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
    385 }
    386 
    387 // Get physical key name.
    388 const char *GetKeyName(int key)
    389 {
    390     TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
    391     return "";
    392 }
    393 
    394 // Register all input events
    395 void PollInputEvents(void)
    396 {
    397 #if defined(SUPPORT_GESTURES_SYSTEM)
    398     // NOTE: Gestures update must be called every frame to reset gestures correctly
    399     // because ProcessGestureEvent() is just called on an event, not every frame
    400     UpdateGestures();
    401 #endif
    402 
    403     // Reset keys/chars pressed registered
    404     CORE.Input.Keyboard.keyPressedQueueCount = 0;
    405     CORE.Input.Keyboard.charPressedQueueCount = 0;
    406 
    407     // Reset key repeats
    408     for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
    409 
    410     // Reset last gamepad button/axis registered state
    411     CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
    412     //CORE.Input.Gamepad.axisCount = 0;
    413 
    414     // Register previous touch states
    415     for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
    416 
    417     // Reset touch positions
    418     // TODO: It resets on target platform the mouse position and not filled again until a move-event,
    419     // so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!
    420     //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
    421 
    422     // Register previous keys states
    423     // NOTE: Android supports up to 260 keys
    424     for (int i = 0; i < 260; i++)
    425     {
    426         CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
    427         CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
    428     }
    429 
    430     // TODO: Poll input events for current platform
    431 }
    432 
    433 //----------------------------------------------------------------------------------
    434 // Module Internal Functions Definition
    435 //----------------------------------------------------------------------------------
    436 
    437 // Initialize platform: graphics, inputs and more
    438 int InitPlatform(void)
    439 {
    440     // TODO: Initialize graphic device: display/window
    441     // It usually requires setting up the platform display system configuration
    442     // and connexion with the GPU through some system graphic API
    443     // raylib uses OpenGL so, platform should create that kind of connection
    444     // Below example illustrates that process using EGL library
    445     //----------------------------------------------------------------------------
    446     CORE.Window.fullscreen = true;
    447     CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
    448 
    449     EGLint samples = 0;
    450     EGLint sampleBuffer = 0;
    451     if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
    452     {
    453         samples = 4;
    454         sampleBuffer = 1;
    455         TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");
    456     }
    457 
    458     const EGLint framebufferAttribs[] =
    459     {
    460         EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,      // Type of context support
    461         EGL_RED_SIZE, 8,            // RED color bit depth (alternative: 5)
    462         EGL_GREEN_SIZE, 8,          // GREEN color bit depth (alternative: 6)
    463         EGL_BLUE_SIZE, 8,           // BLUE color bit depth (alternative: 5)
    464         //EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI)
    465         EGL_DEPTH_SIZE, 16,         // Depth buffer size (Required to use Depth testing!)
    466         //EGL_STENCIL_SIZE, 8,      // Stencil buffer size
    467         EGL_SAMPLE_BUFFERS, sampleBuffer,    // Activate MSAA
    468         EGL_SAMPLES, samples,       // 4x Antialiasing if activated (Free on MALI GPUs)
    469         EGL_NONE
    470     };
    471 
    472     const EGLint contextAttribs[] =
    473     {
    474         EGL_CONTEXT_CLIENT_VERSION, 2,
    475         EGL_NONE
    476     };
    477 
    478     EGLint numConfigs = 0;
    479 
    480     // Get an EGL device connection
    481     platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    482     if (platform.device == EGL_NO_DISPLAY)
    483     {
    484         TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
    485         return false;
    486     }
    487 
    488     // Initialize the EGL device connection
    489     if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
    490     {
    491         // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
    492         TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
    493         return false;
    494     }
    495 
    496     // Get an appropriate EGL framebuffer configuration
    497     eglChooseConfig(platform.device, framebufferAttribs, &platform.config, 1, &numConfigs);
    498 
    499     // Set rendering API
    500     eglBindAPI(EGL_OPENGL_ES_API);
    501 
    502     // Create an EGL rendering context
    503     platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);
    504     if (platform.context == EGL_NO_CONTEXT)
    505     {
    506         TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
    507         return -1;
    508     }
    509 
    510     // Create an EGL window surface
    511     EGLint displayFormat = 0;
    512 
    513     // EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry()
    514     // As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID
    515     eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
    516 
    517     // Android specific call
    518     ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat);       // Force use of native display size
    519 
    520     platform.surface = eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL);
    521 
    522     // There must be at least one frame displayed before the buffers are swapped
    523     eglSwapInterval(platform.device, 1);
    524 
    525     EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context);
    526 
    527     // Check surface and context activation
    528     if (result != EGL_FALSE)
    529     {
    530         CORE.Window.ready = true;
    531 
    532         CORE.Window.render.width = CORE.Window.screen.width;
    533         CORE.Window.render.height = CORE.Window.screen.height;
    534         CORE.Window.currentFbo.width = CORE.Window.render.width;
    535         CORE.Window.currentFbo.height = CORE.Window.render.height;
    536 
    537         TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
    538         TRACELOG(LOG_INFO, "    > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
    539         TRACELOG(LOG_INFO, "    > Screen size:  %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
    540         TRACELOG(LOG_INFO, "    > Render size:  %i x %i", CORE.Window.render.width, CORE.Window.render.height);
    541         TRACELOG(LOG_INFO, "    > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
    542     }
    543     else
    544     {
    545         TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");
    546         return -1;
    547     }
    548     //----------------------------------------------------------------------------
    549 
    550     // If everything work as expected, we can continue
    551     CORE.Window.render.width = CORE.Window.screen.width;
    552     CORE.Window.render.height = CORE.Window.screen.height;
    553     CORE.Window.currentFbo.width = CORE.Window.render.width;
    554     CORE.Window.currentFbo.height = CORE.Window.render.height;
    555 
    556     TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
    557     TRACELOG(LOG_INFO, "    > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
    558     TRACELOG(LOG_INFO, "    > Screen size:  %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
    559     TRACELOG(LOG_INFO, "    > Render size:  %i x %i", CORE.Window.render.width, CORE.Window.render.height);
    560     TRACELOG(LOG_INFO, "    > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
    561 
    562     // TODO: Load OpenGL extensions
    563     // NOTE: GL procedures address loader is required to load extensions
    564     //----------------------------------------------------------------------------
    565     rlLoadExtensions(eglGetProcAddress);
    566     //----------------------------------------------------------------------------
    567 
    568     // TODO: Initialize input events system
    569     // It could imply keyboard, mouse, gamepad, touch...
    570     // Depending on the platform libraries/SDK it could use a callback mechanism
    571     // For system events and inputs evens polling on a per-frame basis, use PollInputEvents()
    572     //----------------------------------------------------------------------------
    573     // ...
    574     //----------------------------------------------------------------------------
    575 
    576     // TODO: Initialize timing system
    577     //----------------------------------------------------------------------------
    578     InitTimer();
    579     //----------------------------------------------------------------------------
    580 
    581     // TODO: Initialize storage system
    582     //----------------------------------------------------------------------------
    583     CORE.Storage.basePath = GetWorkingDirectory();
    584     //----------------------------------------------------------------------------
    585 
    586     TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully");
    587 
    588     return 0;
    589 }
    590 
    591 // Close platform
    592 void ClosePlatform(void)
    593 {
    594     // TODO: De-initialize graphics, inputs and more
    595 }
    596 
    597 // EOF