4
4
* All rights reserved.
5
5
*/
6
6
7
+ #include <SDL.h>
8
+ #include <SDL_render.h>
7
9
#include <stdio.h>
10
+ #include <twin.h>
8
11
9
- #include "twin_private.h"
10
- #include "twin_sdl.h"
12
+ #include "twin_backend.h"
13
+
14
+ typedef struct {
15
+ SDL_Window * win ;
16
+ int * pixels ;
17
+ SDL_Renderer * render ;
18
+ SDL_Texture * texture ;
19
+ twin_coord_t width , height ;
20
+ int image_y ;
21
+ } twin_sdl_t ;
22
+
23
+ #define PRIV (x ) ((twin_sdl_t *) ((twin_context_t *) x)->priv)
11
24
12
25
static void _twin_sdl_put_begin (twin_coord_t left ,
13
26
twin_coord_t top ,
14
27
twin_coord_t right ,
15
28
twin_coord_t bottom ,
16
29
void * closure )
17
30
{
18
- twin_sdl_t * tx = closure ;
31
+ twin_sdl_t * tx = PRIV ( closure ) ;
19
32
tx -> width = right - left ;
20
33
tx -> height = bottom - top ;
21
34
tx -> image_y = top ;
@@ -27,41 +40,55 @@ static void _twin_sdl_put_span(twin_coord_t left,
27
40
twin_argb32_t * pixels ,
28
41
void * closure )
29
42
{
30
- twin_sdl_t * tx = closure ;
43
+ twin_screen_t * screen = ((twin_context_t * ) closure )-> screen ;
44
+ twin_sdl_t * tx = PRIV (closure );
31
45
32
46
for (twin_coord_t ix = left , iy = top ; ix < right ; ix ++ ) {
33
47
twin_argb32_t pixel = * pixels ++ ;
34
-
35
- if (tx -> depth == 16 )
36
- pixel = twin_argb32_to_rgb16 (pixel );
37
-
38
- tx -> pixels [iy * tx -> screen -> width + ix ] = pixel ;
48
+ tx -> pixels [iy * screen -> width + ix ] = pixel ;
39
49
}
40
50
if ((top + 1 - tx -> image_y ) == tx -> height ) {
41
51
SDL_UpdateTexture (tx -> texture , NULL , tx -> pixels ,
42
- tx -> screen -> width * sizeof (uint32_t ));
52
+ screen -> width * sizeof (uint32_t ));
43
53
SDL_RenderCopy (tx -> render , tx -> texture , NULL , NULL );
44
54
SDL_RenderPresent (tx -> render );
45
55
}
46
56
}
47
57
58
+ static void _twin_sdl_destroy (twin_screen_t * screen , twin_sdl_t * tx )
59
+ {
60
+ twin_screen_destroy (screen );
61
+ SDL_DestroyRenderer (tx -> render );
62
+ SDL_DestroyWindow (tx -> win );
63
+ SDL_Quit ();
64
+ }
65
+
66
+ static void twin_sdl_damage (twin_screen_t * screen , twin_sdl_t * tx )
67
+ {
68
+ int width , height ;
69
+ SDL_GetWindowSize (tx -> win , & width , & height );
70
+ twin_screen_damage (screen , 0 , 0 , width , height );
71
+ }
72
+
48
73
static bool twin_sdl_read_events (int file maybe_unused ,
49
74
twin_file_op_t ops maybe_unused ,
50
75
void * closure )
51
76
{
52
- twin_sdl_t * tx = closure ;
77
+ twin_screen_t * screen = ((twin_context_t * ) closure )-> screen ;
78
+ twin_sdl_t * tx = PRIV (closure );
79
+
53
80
SDL_Event ev ;
54
81
while (SDL_PollEvent (& ev )) {
55
82
twin_event_t tev ;
56
83
switch (ev .type ) {
57
84
case SDL_WINDOWEVENT :
58
85
if (ev .window .event == SDL_WINDOWEVENT_EXPOSED ||
59
86
ev .window .event == SDL_WINDOWEVENT_SHOWN ) {
60
- twin_sdl_damage (tx , & ev );
87
+ twin_sdl_damage (screen , tx );
61
88
}
62
89
break ;
63
90
case SDL_QUIT :
64
- twin_sdl_destroy ( tx );
91
+ _twin_sdl_destroy ( screen , tx );
65
92
return false;
66
93
case SDL_MOUSEBUTTONDOWN :
67
94
case SDL_MOUSEBUTTONUP :
@@ -71,21 +98,21 @@ static bool twin_sdl_read_events(int file maybe_unused,
71
98
((ev .button .state >> 8 ) | (1 << (ev .button .button - 1 )));
72
99
tev .kind = ((ev .type == SDL_MOUSEBUTTONDOWN ) ? TwinEventButtonDown
73
100
: TwinEventButtonUp );
74
- twin_screen_dispatch (tx -> screen , & tev );
101
+ twin_screen_dispatch (screen , & tev );
75
102
break ;
76
103
case SDL_KEYDOWN :
77
104
case SDL_KEYUP :
78
105
tev .u .key .key = ev .key .keysym .sym ;
79
106
tev .kind = ((ev .key .type == SDL_KEYDOWN ) ? TwinEventKeyDown
80
107
: TwinEventKeyUp );
81
- twin_screen_dispatch (tx -> screen , & tev );
108
+ twin_screen_dispatch (screen , & tev );
82
109
break ;
83
110
case SDL_MOUSEMOTION :
84
111
tev .u .pointer .screen_x = ev .motion .x ;
85
112
tev .u .pointer .screen_y = ev .motion .y ;
86
113
tev .kind = TwinEventMotion ;
87
114
tev .u .pointer .button = ev .motion .state ;
88
- twin_screen_dispatch (tx -> screen , & tev );
115
+ twin_screen_dispatch (screen , & tev );
89
116
break ;
90
117
}
91
118
}
@@ -94,85 +121,89 @@ static bool twin_sdl_read_events(int file maybe_unused,
94
121
95
122
static bool twin_sdl_work (void * closure )
96
123
{
97
- twin_sdl_t * tx = closure ;
124
+ twin_screen_t * screen = (( twin_context_t * ) closure ) -> screen ;
98
125
99
- if (twin_screen_damaged (tx -> screen ))
100
- twin_sdl_update ( tx );
126
+ if (twin_screen_damaged (screen ))
127
+ twin_screen_update ( screen );
101
128
return true;
102
129
}
103
130
104
- twin_sdl_t * twin_sdl_create (int width , int height )
131
+ twin_context_t * twin_sdl_init (int width , int height )
105
132
{
106
- static char * title = "twin-sdl" ;
107
-
108
- twin_sdl_t * tx = malloc (sizeof (twin_sdl_t ));
109
- if (!tx )
133
+ twin_context_t * ctx = calloc (1 , sizeof (twin_context_t ));
134
+ if (!ctx )
135
+ return NULL ;
136
+ ctx -> priv = calloc (1 , sizeof (twin_sdl_t ));
137
+ if (!ctx -> priv )
110
138
return NULL ;
111
139
112
- if (SDL_Init (SDL_INIT_VIDEO ) < 0 )
140
+ if (SDL_Init (SDL_INIT_VIDEO ) < 0 ) {
113
141
printf ("error : %s\n" , SDL_GetError ());
142
+ goto bail ;
143
+ }
144
+
145
+ twin_sdl_t * tx = ctx -> priv ;
146
+
147
+ static char * title = "twin-sdl" ;
114
148
tx -> win = SDL_CreateWindow (title , SDL_WINDOWPOS_UNDEFINED ,
115
149
SDL_WINDOWPOS_UNDEFINED , width , height ,
116
150
SDL_WINDOW_SHOWN );
117
- if (!tx -> win )
151
+ if (!tx -> win ) {
118
152
printf ("error : %s\n" , SDL_GetError ());
153
+ goto bail ;
154
+ }
155
+
119
156
tx -> pixels = malloc (width * height * sizeof (uint32_t ));
120
157
memset (tx -> pixels , 255 , width * height * sizeof (uint32_t ));
121
158
122
159
tx -> render = SDL_CreateRenderer (tx -> win , -1 , SDL_RENDERER_ACCELERATED );
123
- if (!tx -> render )
160
+ if (!tx -> render ) {
124
161
printf ("error : %s\n" , SDL_GetError ());
162
+ goto bail_pixels ;
163
+ }
125
164
SDL_SetRenderDrawColor (tx -> render , 255 , 255 , 255 , 255 );
126
165
SDL_RenderClear (tx -> render );
127
166
128
167
tx -> texture = SDL_CreateTexture (tx -> render , SDL_PIXELFORMAT_ARGB8888 ,
129
168
SDL_TEXTUREACCESS_STREAMING , width , height );
130
169
131
- tx -> screen = twin_screen_create (width , height , _twin_sdl_put_begin ,
132
- _twin_sdl_put_span , tx );
133
-
134
- twin_set_file (twin_sdl_read_events , 0 , TWIN_READ , tx );
170
+ ctx -> screen = twin_screen_create (width , height , _twin_sdl_put_begin ,
171
+ _twin_sdl_put_span , ctx );
135
172
136
- twin_set_work ( twin_sdl_work , TWIN_WORK_REDISPLAY , tx );
173
+ twin_set_file ( twin_sdl_read_events , 0 , TWIN_READ , ctx );
137
174
138
- return tx ;
139
- }
175
+ twin_set_work (twin_sdl_work , TWIN_WORK_REDISPLAY , ctx );
140
176
141
- void twin_sdl_destroy (twin_sdl_t * tx )
142
- {
143
- SDL_DestroyRenderer (tx -> render );
144
- SDL_DestroyWindow (tx -> win );
145
- tx -> win = 0 ;
146
- twin_screen_destroy (tx -> screen );
147
- SDL_Quit ();
148
- }
177
+ return ctx ;
149
178
150
- void twin_sdl_damage (twin_sdl_t * tx , SDL_Event * ev maybe_unused )
151
- {
152
- int width , height ;
153
- SDL_GetWindowSize (tx -> win , & width , & height );
154
- twin_screen_damage (tx -> screen , 0 , 0 , width , height );
179
+ bail_pixels :
180
+ free (tx -> pixels );
181
+ bail :
182
+ free (ctx -> priv );
183
+ free (ctx );
184
+ return NULL ;
155
185
}
156
186
157
- void twin_sdl_configure (twin_sdl_t * tx , SDL_Event * ev maybe_unused )
187
+ static void twin_sdl_configure (twin_context_t * ctx )
158
188
{
159
189
int width , height ;
160
- SDL_GetWindowSize (tx -> win , & width , & height );
161
- twin_screen_resize (tx -> screen , width , height );
190
+ SDL_GetWindowSize (PRIV ( ctx ) -> win , & width , & height );
191
+ twin_screen_resize (ctx -> screen , width , height );
162
192
}
163
193
164
- void twin_sdl_update ( twin_sdl_t * tx )
194
+ static void twin_sdl_exit ( twin_context_t * ctx )
165
195
{
166
- twin_screen_update (tx -> screen );
196
+ if (!ctx )
197
+ return ;
198
+ free (PRIV (ctx )-> pixels );
199
+ free (ctx -> priv );
200
+ free (ctx );
167
201
}
168
202
169
- bool twin_sdl_process_events (twin_sdl_t * tx )
170
- {
171
- bool result ;
203
+ /* Register the SDL backend */
172
204
173
- _twin_run_work ();
174
- result = twin_sdl_read_events (0 , 0 , tx );
175
- _twin_run_work ();
176
-
177
- return result ;
178
- }
205
+ const twin_backend_t g_twin_backend = {
206
+ .init = twin_sdl_init ,
207
+ .configure = twin_sdl_configure ,
208
+ .exit = twin_sdl_exit ,
209
+ };
0 commit comments