cscg22-gearboy

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

SDL_uikitmodes.m (7609B)


      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#include "../../SDL_internal.h"
     22
     23#if SDL_VIDEO_DRIVER_UIKIT
     24
     25#include "SDL_assert.h"
     26#include "SDL_uikitmodes.h"
     27
     28
     29static int
     30UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
     31    UIScreenMode * uiscreenmode, CGFloat scale)
     32{
     33    SDL_DisplayModeData *data = NULL;
     34
     35    if (uiscreenmode != nil) {
     36        /* Allocate the display mode data */
     37        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
     38        if (!data) {
     39            return SDL_OutOfMemory();
     40        }
     41
     42        data->uiscreenmode = uiscreenmode;
     43        [data->uiscreenmode retain];
     44
     45        data->scale = scale;
     46    }
     47
     48    mode->driverdata = data;
     49
     50    return 0;
     51}
     52
     53static void
     54UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
     55{
     56    if (mode->driverdata != NULL) {
     57        SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
     58        [data->uiscreenmode release];
     59        SDL_free(data);
     60        mode->driverdata = NULL;
     61    }
     62}
     63
     64static int
     65UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
     66    UIScreenMode * uiscreenmode, CGFloat scale)
     67{
     68    SDL_DisplayMode mode;
     69    SDL_zero(mode);
     70
     71    mode.format = SDL_PIXELFORMAT_ABGR8888;
     72    mode.refresh_rate = 0;
     73    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
     74        return -1;
     75    }
     76
     77    mode.w = w;
     78    mode.h = h;
     79    if (SDL_AddDisplayMode(display, &mode)) {
     80        return 0;
     81    } else {
     82        UIKit_FreeDisplayModeData(&mode);
     83        return -1;
     84    }
     85}
     86
     87static int
     88UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
     89                     UIScreenMode * uiscreenmode, SDL_bool addRotation)
     90{
     91    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
     92        return -1;
     93    }
     94
     95    if (addRotation) {
     96        /* Add the rotated version */
     97        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
     98            return -1;
     99        }
    100    }
    101
    102    return 0;
    103}
    104
    105static int
    106UIKit_AddDisplay(UIScreen *uiscreen)
    107{
    108    CGSize size = [uiscreen bounds].size;
    109
    110    /* Make sure the width/height are oriented correctly */
    111    if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
    112        CGFloat height = size.width;
    113        size.width = size.height;
    114        size.height = height;
    115    }
    116
    117    /* When dealing with UIKit all coordinates are specified in terms of
    118     * what Apple refers to as points. [UIScreen scale] indicates the
    119     * relationship between points and pixels. Since SDL has no notion
    120     * of points, we must compensate in all cases where dealing with such
    121     * units.
    122     */
    123    CGFloat scale = [uiscreen scale];
    124
    125    SDL_VideoDisplay display;
    126    SDL_DisplayMode mode;
    127    SDL_zero(mode);
    128    mode.format = SDL_PIXELFORMAT_ABGR8888;
    129    mode.w = (int)(size.width * scale);
    130    mode.h = (int)(size.height * scale);
    131
    132    UIScreenMode * uiscreenmode = [uiscreen currentMode];
    133
    134    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
    135        return -1;
    136    }
    137
    138    SDL_zero(display);
    139    display.desktop_mode = mode;
    140    display.current_mode = mode;
    141
    142    /* Allocate the display data */
    143    SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
    144    if (!data) {
    145        UIKit_FreeDisplayModeData(&display.desktop_mode);
    146        return SDL_OutOfMemory();
    147    }
    148
    149    [uiscreen retain];
    150    data->uiscreen = uiscreen;
    151    data->scale = scale;
    152
    153    display.driverdata = data;
    154    SDL_AddVideoDisplay(&display);
    155
    156    return 0;
    157}
    158
    159SDL_bool
    160UIKit_IsDisplayLandscape(UIScreen *uiscreen)
    161{
    162    if (uiscreen == [UIScreen mainScreen]) {
    163        return UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
    164    } else {
    165        CGSize size = [uiscreen bounds].size;
    166        return (size.width > size.height);
    167    }
    168}
    169
    170int
    171UIKit_InitModes(_THIS)
    172{
    173    for (UIScreen *uiscreen in [UIScreen screens]) {
    174        if (UIKit_AddDisplay(uiscreen) < 0) {
    175            return -1;
    176        }
    177    }
    178
    179    return 0;
    180}
    181
    182void
    183UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
    184{
    185    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    186
    187    SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
    188    SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
    189
    190    for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
    191        CGSize size = [uimode size];
    192        int w = (int)size.width;
    193        int h = (int)size.height;
    194
    195        /* Make sure the width/height are oriented correctly */
    196        if (isLandscape != (w > h)) {
    197            int tmp = w;
    198            w = h;
    199            h = tmp;
    200        }
    201
    202        /* Add the native screen resolution. */
    203        UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation);
    204
    205        if (data->scale != 1.0f) {
    206            /* Add the native screen resolution divided by its scale.
    207             * This is so devices capable of e.g. 640x960 also advertise 320x480.
    208             */
    209            UIKit_AddDisplayMode(display,
    210                (int)(size.width / data->scale),
    211                (int)(size.height / data->scale),
    212                1.0f, uimode, addRotation);
    213        }
    214    }
    215}
    216
    217int
    218UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
    219{
    220    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    221    SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
    222
    223    [data->uiscreen setCurrentMode:modedata->uiscreenmode];
    224
    225    if (data->uiscreen == [UIScreen mainScreen]) {
    226        if (mode->w > mode->h) {
    227            if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
    228                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
    229            }
    230        } else if (mode->w < mode->h) {
    231            if (UIKit_IsDisplayLandscape(data->uiscreen)) {
    232                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
    233            }
    234        }
    235    }
    236
    237    return 0;
    238}
    239
    240void
    241UIKit_QuitModes(_THIS)
    242{
    243    /* Release Objective-C objects, so higher level doesn't free() them. */
    244    int i, j;
    245    for (i = 0; i < _this->num_displays; i++) {
    246        SDL_VideoDisplay *display = &_this->displays[i];
    247
    248        UIKit_FreeDisplayModeData(&display->desktop_mode);
    249        for (j = 0; j < display->num_display_modes; j++) {
    250            SDL_DisplayMode *mode = &display->display_modes[j];
    251            UIKit_FreeDisplayModeData(mode);
    252        }
    253
    254        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    255        [data->uiscreen release];
    256        SDL_free(data);
    257        display->driverdata = NULL;
    258    }
    259}
    260
    261#endif /* SDL_VIDEO_DRIVER_UIKIT */
    262
    263/* vi: set ts=4 sw=4 expandtab: */