cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_rpivideo.c (10236B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21
     22#include "../../SDL_internal.h"
     23
     24#if SDL_VIDEO_DRIVER_RPI
     25
     26/* References
     27 * http://elinux.org/RPi_VideoCore_APIs
     28 * https://github.com/raspberrypi/firmware/blob/master/opt/vc/src/hello_pi/hello_triangle/triangle.c
     29 * http://cgit.freedesktop.org/wayland/weston/tree/src/rpi-renderer.c
     30 * http://cgit.freedesktop.org/wayland/weston/tree/src/compositor-rpi.c
     31 */
     32
     33/* SDL internals */
     34#include "../SDL_sysvideo.h"
     35#include "SDL_version.h"
     36#include "SDL_syswm.h"
     37#include "SDL_loadso.h"
     38#include "SDL_events.h"
     39#include "../../events/SDL_mouse_c.h"
     40#include "../../events/SDL_keyboard_c.h"
     41
     42#ifdef SDL_INPUT_LINUXEV
     43#include "../../core/linux/SDL_evdev.h"
     44#endif
     45
     46/* RPI declarations */
     47#include "SDL_rpivideo.h"
     48#include "SDL_rpievents_c.h"
     49#include "SDL_rpiopengles.h"
     50#include "SDL_rpimouse.h"
     51
     52static int
     53RPI_Available(void)
     54{
     55    return 1;
     56}
     57
     58static void
     59RPI_Destroy(SDL_VideoDevice * device)
     60{
     61    /*    SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */
     62
     63    if (device->driverdata != NULL) {
     64        device->driverdata = NULL;
     65    }
     66}
     67
     68static SDL_VideoDevice *
     69RPI_Create()
     70{
     71    SDL_VideoDevice *device;
     72    SDL_VideoData *phdata;
     73
     74    /* Initialize SDL_VideoDevice structure */
     75    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
     76    if (device == NULL) {
     77        SDL_OutOfMemory();
     78        return NULL;
     79    }
     80
     81    /* Initialize internal data */
     82    phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
     83    if (phdata == NULL) {
     84        SDL_OutOfMemory();
     85        SDL_free(device);
     86        return NULL;
     87    }
     88
     89    device->driverdata = phdata;
     90
     91    /* Setup amount of available displays and current display */
     92    device->num_displays = 0;
     93
     94    /* Set device free function */
     95    device->free = RPI_Destroy;
     96
     97    /* Setup all functions which we can handle */
     98    device->VideoInit = RPI_VideoInit;
     99    device->VideoQuit = RPI_VideoQuit;
    100    device->GetDisplayModes = RPI_GetDisplayModes;
    101    device->SetDisplayMode = RPI_SetDisplayMode;
    102    device->CreateWindow = RPI_CreateWindow;
    103    device->CreateWindowFrom = RPI_CreateWindowFrom;
    104    device->SetWindowTitle = RPI_SetWindowTitle;
    105    device->SetWindowIcon = RPI_SetWindowIcon;
    106    device->SetWindowPosition = RPI_SetWindowPosition;
    107    device->SetWindowSize = RPI_SetWindowSize;
    108    device->ShowWindow = RPI_ShowWindow;
    109    device->HideWindow = RPI_HideWindow;
    110    device->RaiseWindow = RPI_RaiseWindow;
    111    device->MaximizeWindow = RPI_MaximizeWindow;
    112    device->MinimizeWindow = RPI_MinimizeWindow;
    113    device->RestoreWindow = RPI_RestoreWindow;
    114    device->SetWindowGrab = RPI_SetWindowGrab;
    115    device->DestroyWindow = RPI_DestroyWindow;
    116    device->GetWindowWMInfo = RPI_GetWindowWMInfo;
    117    device->GL_LoadLibrary = RPI_GLES_LoadLibrary;
    118    device->GL_GetProcAddress = RPI_GLES_GetProcAddress;
    119    device->GL_UnloadLibrary = RPI_GLES_UnloadLibrary;
    120    device->GL_CreateContext = RPI_GLES_CreateContext;
    121    device->GL_MakeCurrent = RPI_GLES_MakeCurrent;
    122    device->GL_SetSwapInterval = RPI_GLES_SetSwapInterval;
    123    device->GL_GetSwapInterval = RPI_GLES_GetSwapInterval;
    124    device->GL_SwapWindow = RPI_GLES_SwapWindow;
    125    device->GL_DeleteContext = RPI_GLES_DeleteContext;
    126
    127    device->PumpEvents = RPI_PumpEvents;
    128
    129    return device;
    130}
    131
    132VideoBootStrap RPI_bootstrap = {
    133    "RPI",
    134    "RPI Video Driver",
    135    RPI_Available,
    136    RPI_Create
    137};
    138
    139/*****************************************************************************/
    140/* SDL Video and Display initialization/handling functions                   */
    141/*****************************************************************************/
    142int
    143RPI_VideoInit(_THIS)
    144{
    145    SDL_VideoDisplay display;
    146    SDL_DisplayMode current_mode;
    147    SDL_DisplayData *data;
    148    uint32_t w,h;
    149
    150    /* Initialize BCM Host */
    151    bcm_host_init();
    152
    153    SDL_zero(current_mode);
    154
    155    if (graphics_get_display_size( 0, &w, &h) < 0) {
    156        return -1;
    157    }
    158
    159    current_mode.w = w;
    160    current_mode.h = h;
    161    /* FIXME: Is there a way to tell the actual refresh rate? */
    162    current_mode.refresh_rate = 60;
    163    /* 32 bpp for default */
    164    current_mode.format = SDL_PIXELFORMAT_ABGR8888;
    165
    166    current_mode.driverdata = NULL;
    167
    168    SDL_zero(display);
    169    display.desktop_mode = current_mode;
    170    display.current_mode = current_mode;
    171
    172    /* Allocate display internal data */
    173    data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
    174    if (data == NULL) {
    175        return SDL_OutOfMemory();
    176    }
    177
    178    data->dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    179
    180    display.driverdata = data;
    181
    182    SDL_AddVideoDisplay(&display);
    183
    184#ifdef SDL_INPUT_LINUXEV    
    185    SDL_EVDEV_Init();
    186#endif    
    187    
    188    RPI_InitMouse(_this);
    189
    190    return 1;
    191}
    192
    193void
    194RPI_VideoQuit(_THIS)
    195{
    196#ifdef SDL_INPUT_LINUXEV    
    197    SDL_EVDEV_Quit();
    198#endif    
    199}
    200
    201void
    202RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
    203{
    204    /* Only one display mode available, the current one */
    205    SDL_AddDisplayMode(display, &display->current_mode);
    206}
    207
    208int
    209RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
    210{
    211    return 0;
    212}
    213
    214int
    215RPI_CreateWindow(_THIS, SDL_Window * window)
    216{
    217    SDL_WindowData *wdata;
    218    SDL_VideoDisplay *display;
    219    SDL_DisplayData *displaydata;
    220    VC_RECT_T dst_rect;
    221    VC_RECT_T src_rect;
    222    VC_DISPMANX_ALPHA_T         dispman_alpha;
    223    DISPMANX_UPDATE_HANDLE_T dispman_update;
    224
    225    /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
    226    dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; 
    227    dispman_alpha.opacity = 0xFF; 
    228    dispman_alpha.mask = 0;
    229
    230    /* Allocate window internal data */
    231    wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
    232    if (wdata == NULL) {
    233        return SDL_OutOfMemory();
    234    }
    235    display = SDL_GetDisplayForWindow(window);
    236    displaydata = (SDL_DisplayData *) display->driverdata;
    237
    238    /* Windows have one size for now */
    239    window->w = display->desktop_mode.w;
    240    window->h = display->desktop_mode.h;
    241
    242    /* OpenGL ES is the law here, buddy */
    243    window->flags |= SDL_WINDOW_OPENGL;
    244
    245    /* Create a dispman element and associate a window to it */
    246    dst_rect.x = 0;
    247    dst_rect.y = 0;
    248    dst_rect.width = window->w;
    249    dst_rect.height = window->h;
    250
    251    src_rect.x = 0;
    252    src_rect.y = 0;
    253    src_rect.width = window->w << 16;
    254    src_rect.height = window->h << 16;
    255
    256    dispman_update = vc_dispmanx_update_start( 0 );
    257    wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/);
    258    wdata->dispman_window.width = window->w;
    259    wdata->dispman_window.height = window->h;
    260    vc_dispmanx_update_submit_sync( dispman_update );
    261    
    262    if (!_this->egl_data) {
    263        if (SDL_GL_LoadLibrary(NULL) < 0) {
    264            return -1;
    265        }
    266    }
    267    wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window);
    268
    269    if (wdata->egl_surface == EGL_NO_SURFACE) {
    270        return SDL_SetError("Could not create GLES window surface");
    271    }
    272
    273    /* Setup driver data for this window */
    274    window->driverdata = wdata;
    275    
    276    /* One window, it always has focus */
    277    SDL_SetMouseFocus(window);
    278    SDL_SetKeyboardFocus(window);
    279
    280    /* Window has been successfully created */
    281    return 0;
    282}
    283
    284void
    285RPI_DestroyWindow(_THIS, SDL_Window * window)
    286{
    287    SDL_WindowData *data;
    288        
    289    if(window->driverdata) {
    290        data = (SDL_WindowData *) window->driverdata;
    291        if (data->egl_surface != EGL_NO_SURFACE) {
    292            SDL_EGL_DestroySurface(_this, data->egl_surface);
    293            data->egl_surface = EGL_NO_SURFACE;
    294        }
    295        SDL_free(window->driverdata);
    296        window->driverdata = NULL;
    297    }
    298}
    299
    300int
    301RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
    302{
    303    return -1;
    304}
    305
    306void
    307RPI_SetWindowTitle(_THIS, SDL_Window * window)
    308{
    309}
    310void
    311RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
    312{
    313}
    314void
    315RPI_SetWindowPosition(_THIS, SDL_Window * window)
    316{
    317}
    318void
    319RPI_SetWindowSize(_THIS, SDL_Window * window)
    320{
    321}
    322void
    323RPI_ShowWindow(_THIS, SDL_Window * window)
    324{
    325}
    326void
    327RPI_HideWindow(_THIS, SDL_Window * window)
    328{
    329}
    330void
    331RPI_RaiseWindow(_THIS, SDL_Window * window)
    332{
    333}
    334void
    335RPI_MaximizeWindow(_THIS, SDL_Window * window)
    336{
    337}
    338void
    339RPI_MinimizeWindow(_THIS, SDL_Window * window)
    340{
    341}
    342void
    343RPI_RestoreWindow(_THIS, SDL_Window * window)
    344{
    345}
    346void
    347RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
    348{
    349
    350}
    351
    352/*****************************************************************************/
    353/* SDL Window Manager function                                               */
    354/*****************************************************************************/
    355SDL_bool
    356RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
    357{
    358    if (info->version.major <= SDL_MAJOR_VERSION) {
    359        return SDL_TRUE;
    360    } else {
    361        SDL_SetError("application not compiled with SDL %d.%d\n",
    362                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
    363        return SDL_FALSE;
    364    }
    365
    366    /* Failed to get window manager information */
    367    return SDL_FALSE;
    368}
    369
    370#endif /* SDL_VIDEO_DRIVER_RPI */
    371
    372/* vi: set ts=4 sw=4 expandtab: */