summaryrefslogtreecommitdiff
path: root/src/frontend_sdl.c
blob: e082e565aa4ca1116e3e16f08db7649c1e7186b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <SDL/SDL.h>

#include "libnsfb.h"
#include "nsfb.h"
#include "frontend.h"

static void
set_palette(nsfb_t *nsfb)
{
    SDL_Surface *sdl_screen = nsfb->frontend_priv;
    SDL_Color palette[256];
    int rloop, gloop, bloop;
    int loop = 0;

    /* build a linear R:3 G:3 B:2 colour cube palette. */
    for (rloop = 0; rloop < 8; rloop++) {
        for (gloop = 0; gloop < 8; gloop++) {
            for (bloop = 0; bloop < 4; bloop++) {
                palette[loop].r = (rloop << 5) | (rloop << 2) | (rloop >> 1);
                palette[loop].g = (gloop << 5) | (gloop << 2) | (gloop >> 1);
                palette[loop].b = (bloop << 6) | (bloop << 4) | (bloop << 2) | (bloop);
                nsfb->palette[loop] = palette[loop].r | 
                                      palette[loop].g << 8 | 
                                      palette[loop].b << 16;
                loop++;
            }
        }
    }

    /* Set palette */
    SDL_SetColors(sdl_screen, palette, 0, 256);

}

static int sdl_initialise(nsfb_t *nsfb)
{
    SDL_Surface *sdl_screen;

    if (nsfb->frontend_priv != NULL)
        return -1;

    /* sanity checked depth. */
    if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8))
        nsfb->bpp = 16; 

    /* initialise SDL library */
    if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        return -1;
    }
    atexit(SDL_Quit);

    sdl_screen = SDL_SetVideoMode(nsfb->width, 
                                  nsfb->height, 
                                  nsfb->bpp, 
                                  SDL_SWSURFACE);

    if (sdl_screen == NULL ) {
        fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
        return -1;
    }

    nsfb->frontend_priv = sdl_screen;

    if (nsfb->bpp == 8)
        set_palette(nsfb);

    nsfb->ptr = sdl_screen->pixels;
    nsfb->linelen = sdl_screen->pitch;
    
    SDL_ShowCursor(SDL_DISABLE);

    return 0;
}

static int sdl_finalise(nsfb_t *nsfb)
{
    nsfb=nsfb;
    return 0;
}

static int sdl_input(nsfb_t *nsfb)
{
    int got_event;
    SDL_Event event;

    got_event = SDL_WaitEvent(&event);
    if (event.type == SDL_QUIT)
        exit(0);
    nsfb=nsfb;
    return 1;
}

static int sdl_release(nsfb_t *nsfb, nsfb_bbox_t *box)
{
    SDL_Surface *sdl_screen = nsfb->frontend_priv;

    SDL_UpdateRect(sdl_screen, 
                   box->x0, 
                   box->y0, 
                   box->x1 - box->x0, 
                   box->y1 - box->y0);

    return 0;
}

const nsfb_frontend_rtns_t sdl_rtns = {
    .initialise = sdl_initialise,
    .finalise = sdl_finalise,
    .input = sdl_input,
    .release = sdl_release,
};

NSFB_FRONTEND_DEF(sdl, NSFB_FRONTEND_SDL, &sdl_rtns)