44 * All rights reserved.
55 */
66
7+ #include <SDL.h>
8+ #include <SDL_render.h>
79#include <stdio.h>
10+ #include <twin.h>
811
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)
1124
1225static void _twin_sdl_put_begin (twin_coord_t left ,
1326 twin_coord_t top ,
1427 twin_coord_t right ,
1528 twin_coord_t bottom ,
1629 void * closure )
1730{
18- twin_sdl_t * tx = closure ;
31+ twin_sdl_t * tx = PRIV ( closure ) ;
1932 tx -> width = right - left ;
2033 tx -> height = bottom - top ;
2134 tx -> image_y = top ;
@@ -27,41 +40,55 @@ static void _twin_sdl_put_span(twin_coord_t left,
2740 twin_argb32_t * pixels ,
2841 void * closure )
2942{
30- twin_sdl_t * tx = closure ;
43+ twin_screen_t * screen = ((twin_context_t * ) closure )-> screen ;
44+ twin_sdl_t * tx = PRIV (closure );
3145
3246 for (twin_coord_t ix = left , iy = top ; ix < right ; ix ++ ) {
3347 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 ;
3949 }
4050 if ((top + 1 - tx -> image_y ) == tx -> height ) {
4151 SDL_UpdateTexture (tx -> texture , NULL , tx -> pixels ,
42- tx -> screen -> width * sizeof (uint32_t ));
52+ screen -> width * sizeof (uint32_t ));
4353 SDL_RenderCopy (tx -> render , tx -> texture , NULL , NULL );
4454 SDL_RenderPresent (tx -> render );
4555 }
4656}
4757
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+
4873static bool twin_sdl_read_events (int file maybe_unused ,
4974 twin_file_op_t ops maybe_unused ,
5075 void * closure )
5176{
52- twin_sdl_t * tx = closure ;
77+ twin_screen_t * screen = ((twin_context_t * ) closure )-> screen ;
78+ twin_sdl_t * tx = PRIV (closure );
79+
5380 SDL_Event ev ;
5481 while (SDL_PollEvent (& ev )) {
5582 twin_event_t tev ;
5683 switch (ev .type ) {
5784 case SDL_WINDOWEVENT :
5885 if (ev .window .event == SDL_WINDOWEVENT_EXPOSED ||
5986 ev .window .event == SDL_WINDOWEVENT_SHOWN ) {
60- twin_sdl_damage (tx , & ev );
87+ twin_sdl_damage (screen , tx );
6188 }
6289 break ;
6390 case SDL_QUIT :
64- twin_sdl_destroy ( tx );
91+ _twin_sdl_destroy ( screen , tx );
6592 return false;
6693 case SDL_MOUSEBUTTONDOWN :
6794 case SDL_MOUSEBUTTONUP :
@@ -71,21 +98,21 @@ static bool twin_sdl_read_events(int file maybe_unused,
7198 ((ev .button .state >> 8 ) | (1 << (ev .button .button - 1 )));
7299 tev .kind = ((ev .type == SDL_MOUSEBUTTONDOWN ) ? TwinEventButtonDown
73100 : TwinEventButtonUp );
74- twin_screen_dispatch (tx -> screen , & tev );
101+ twin_screen_dispatch (screen , & tev );
75102 break ;
76103 case SDL_KEYDOWN :
77104 case SDL_KEYUP :
78105 tev .u .key .key = ev .key .keysym .sym ;
79106 tev .kind = ((ev .key .type == SDL_KEYDOWN ) ? TwinEventKeyDown
80107 : TwinEventKeyUp );
81- twin_screen_dispatch (tx -> screen , & tev );
108+ twin_screen_dispatch (screen , & tev );
82109 break ;
83110 case SDL_MOUSEMOTION :
84111 tev .u .pointer .screen_x = ev .motion .x ;
85112 tev .u .pointer .screen_y = ev .motion .y ;
86113 tev .kind = TwinEventMotion ;
87114 tev .u .pointer .button = ev .motion .state ;
88- twin_screen_dispatch (tx -> screen , & tev );
115+ twin_screen_dispatch (screen , & tev );
89116 break ;
90117 }
91118 }
@@ -94,85 +121,89 @@ static bool twin_sdl_read_events(int file maybe_unused,
94121
95122static bool twin_sdl_work (void * closure )
96123{
97- twin_sdl_t * tx = closure ;
124+ twin_screen_t * screen = (( twin_context_t * ) closure ) -> screen ;
98125
99- if (twin_screen_damaged (tx -> screen ))
100- twin_sdl_update ( tx );
126+ if (twin_screen_damaged (screen ))
127+ twin_screen_update ( screen );
101128 return true;
102129}
103130
104- twin_sdl_t * twin_sdl_create (int width , int height )
131+ twin_context_t * twin_sdl_init (int width , int height )
105132{
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 )
110138 return NULL ;
111139
112- if (SDL_Init (SDL_INIT_VIDEO ) < 0 )
140+ if (SDL_Init (SDL_INIT_VIDEO ) < 0 ) {
113141 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" ;
114148 tx -> win = SDL_CreateWindow (title , SDL_WINDOWPOS_UNDEFINED ,
115149 SDL_WINDOWPOS_UNDEFINED , width , height ,
116150 SDL_WINDOW_SHOWN );
117- if (!tx -> win )
151+ if (!tx -> win ) {
118152 printf ("error : %s\n" , SDL_GetError ());
153+ goto bail ;
154+ }
155+
119156 tx -> pixels = malloc (width * height * sizeof (uint32_t ));
120157 memset (tx -> pixels , 255 , width * height * sizeof (uint32_t ));
121158
122159 tx -> render = SDL_CreateRenderer (tx -> win , -1 , SDL_RENDERER_ACCELERATED );
123- if (!tx -> render )
160+ if (!tx -> render ) {
124161 printf ("error : %s\n" , SDL_GetError ());
162+ goto bail_pixels ;
163+ }
125164 SDL_SetRenderDrawColor (tx -> render , 255 , 255 , 255 , 255 );
126165 SDL_RenderClear (tx -> render );
127166
128167 tx -> texture = SDL_CreateTexture (tx -> render , SDL_PIXELFORMAT_ARGB8888 ,
129168 SDL_TEXTUREACCESS_STREAMING , width , height );
130169
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 );
135172
136- twin_set_work ( twin_sdl_work , TWIN_WORK_REDISPLAY , tx );
173+ twin_set_file ( twin_sdl_read_events , 0 , TWIN_READ , ctx );
137174
138- return tx ;
139- }
175+ twin_set_work (twin_sdl_work , TWIN_WORK_REDISPLAY , ctx );
140176
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 ;
149178
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 ;
155185}
156186
157- void twin_sdl_configure (twin_sdl_t * tx , SDL_Event * ev maybe_unused )
187+ static void twin_sdl_configure (twin_context_t * ctx )
158188{
159189 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 );
162192}
163193
164- void twin_sdl_update ( twin_sdl_t * tx )
194+ static void twin_sdl_exit ( twin_context_t * ctx )
165195{
166- twin_screen_update (tx -> screen );
196+ if (!ctx )
197+ return ;
198+ free (PRIV (ctx )-> pixels );
199+ free (ctx -> priv );
200+ free (ctx );
167201}
168202
169- bool twin_sdl_process_events (twin_sdl_t * tx )
170- {
171- bool result ;
203+ /* Register the SDL backend */
172204
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