Browse code

Port to SDL3

Dario Rodriguez authored on 16/10/2024 18:40:40
Showing 1 changed files
... ...
@@ -1,10 +1,10 @@
1 1
 /*
2 2
  * boxui.c
3 3
  *
4
- * Multiplatform UI library for SDL2.
4
+ * Multiplatform UI library for SDL3.
5 5
  *
6
- * (c) 2023 Dario Rodriguez <antartica@box-ui.org>
7
- * Licensed under the terms of the GNU GPL v3.
6
+ * (c) 2023-2024 Dario Rodriguez <antartica@box-ui.org>
7
+ * Licensed under the terms of the MIT/X license.
8 8
  */
9 9
 
10 10
 #include <stdio.h>
... ...
@@ -13,287 +13,337 @@
13 13
 #include <string.h>
14 14
 #include <time.h>
15 15
 #include <signal.h>
16
+#include <stdarg.h>
16 17
 
17
-#include "SDL.h"
18
-#include "SDL_rwops.h"
19
-#include "SDL_ttf.h"
18
+#include "SDL3/SDL.h"
19
+#include "SDL3/SDL_iostream.h"
20
+#include "SDL3_ttf/SDL_ttf.h"
20 21
 
21 22
 #include "boxui.h"
22 23
 
23 24
 #include "notosans_regular_ttf.c"
24 25
 
25
-#define DEFAULT_FPS 30
26
+#define DEFAULTFONTSIZE 16
27
+
28
+#define MAXPENDINGSIGNAL 64
29
+#define BLOCKSIGNALACTION 16
30
+#define BLOCKWINDOW 8
31
+
32
+#ifdef DEBUG_BOXUI
33
+#define DEBUGFPRINTF(a) fprintf a
34
+#else
35
+#define DEBUGFPRINTF(a)
36
+#endif
37
+
38
+typedef enum datatype_t {
39
+        datatype_literal=0, /* inline string */
40
+        datatype_escapedquotedliteral, /* (only used when parsing) inline quoted string */
41
+        datatype_quotedliteral, /* quoted string (%s or unescaping escapedquotedliteral) */
42
+        datatype_integer, /* (only used when parsing) %i */
43
+        datatype_textvariable, /* %s%i */
44
+        datatype_asset, /* %p%i%i */
45
+        datatype_callback, /* %p%p */
46
+} datatype_t;
47
+
48
+typedef struct signalaction_t {
49
+        int nsignal;
50
+        char *actionstr;
51
+} signalaction_t;
52
+
53
+typedef struct signaldata_t {
54
+        int readpos;
55
+        int writepos;
56
+        int buf[MAXPENDINGSIGNAL];
57
+        int sizeactions;
58
+        int usedactions;
59
+        signalaction_t *actions;
60
+} signaldata_t;
26 61
 
27 62
 typedef struct intboxui_t {
28
-        char *title;
29
-        int defaultw,defaulth;
30
-        int fps;
31
-        long long fpsepoch;
32
-        long long fpsepochframeno;
33
-        void *userptr;
34
-        int isdirty;
35
-        long long lastrenderedframeno;
36
-        int sizeafterbuf;
37
-        int usedafterbuf;
38
-        char *afterbuf;
39
-        /* temporary members (to be able to test) */
40
-        int screenw;
41
-        int screenh;
42
-        SDL_Window *win;
63
+        SDL_Window *window;
43 64
         SDL_Renderer *renderer;
44
-        SDL_RWops *defaultfontdata;
65
+        int width;
66
+        int height;
67
+        signaldata_t signaldata;
68
+        SDL_IOStream *defaultfontdata;
45 69
         TTF_Font *defaultfont;
46
-        int defaultfontheight;
47 70
         int defaultfontwidth;
71
+        int defaultfontheight;
72
+        void *userptr;
73
+        int isdirty;
74
+        int haschanged;
75
+        SDL_Texture *texture;
76
+        /* temporary members (to be able to test) */
48 77
         char currenttext[1024];
49 78
         char currentclickevent[1024];
50 79
         char currentactionstr[1024];
51 80
         int flag_currentactionstrused;
52
-        /* end of temporary members (to be able to test) */
53 81
 } intboxui_t;
54 82
 
55
-int intboxui_waittick(intboxui_t *boxui);
56
-int intboxui_render(intboxui_t *boxui);
57
-int intboxui_after_doexpired(intboxui_t *boxui);
83
+static void intboxui_signalhandler_gen(int nsignal, int is_set, intboxui_t *boxuiset);
84
+static int intboxui_render(intboxui_t *boxui);
85
+static char *intboxuiutil_getnext(char *data, int *posdata, va_list valist, int *resl, datatype_t *datatype, char **ptr1, char **ptr2, int *int1, int *int2, int *in_error);
86
+static char *datatypedup_literalquotedliteral(datatype_t datatype, char *ptr1, char *ptr2, int int1, int int2);
87
+static int datatypedup_int(datatype_t datatype, char *ptr1, char *ptr2, int int1, int int2, int defaultint, int *in_error);
88
+static int datatypedup_istrue(datatype_t datatype, char *ptr1, char *ptr2, int int1, int int2, int *in_error);
89
+static int memstrcmp(char *ptr, int l, char *str);
58 90
 
59 91
 boxui_t *
60
-boxui_init(char *title,int defaultw, int defaulth, int flags)
92
+boxui_init(SDL_Window *window, SDL_Renderer *renderer, int width, int height)
61 93
 {
62 94
         intboxui_t *boxui;
63
-        title=(title==NULL)?"":title;
64
-        if((boxui=malloc(sizeof(intboxui_t)))==NULL)
95
+        if((boxui=malloc(sizeof(intboxui_t)))==NULL) {
96
+                SDL_Log("boxui: insufficient memory for main structure\n");
65 97
                 return(NULL); /* insuf. mem for boxui struct */
66
-        memset(boxui,0,sizeof(intboxui_t));
67
-        if((boxui->title=strdup(title))==NULL) {
68
-                boxui_free((boxui_t *)boxui),boxui=NULL;
69
-                return(NULL); /* insuf. mem for title string */
70
-        }
71
-        /* temporary initialization (to be able to test) */
72
-        if(SDL_Init(SDL_INIT_VIDEO)<0
73
-          || (boxui->win=SDL_CreateWindow(title,
74
-            SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,
75
-            defaultw,defaulth,0))==NULL
76
-          || (boxui->renderer=SDL_CreateRenderer(boxui->win,-1,
77
-            SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC))==NULL) {
78
-                boxui_free(boxui),boxui=NULL;
79
-                return(NULL); /* ERROR: Couldn't init video */
80
-        }
81
-        boxui->screenw=defaultw,boxui->screenh=defaulth;
82
-        if((boxui->defaultfontdata=SDL_RWFromConstMem(notosans_regular_ttf,notosans_regular_ttf_len))==NULL
83
-          || TTF_Init()==-1) {
84
-                boxui_free(boxui),boxui=NULL;
85
-                return(NULL); /* ERROR: Couldn't init font data */
86 98
         }
87
-        SDL_RWseek(boxui->defaultfontdata,0,RW_SEEK_SET);
88
-        if(boxui->defaultfontdata==NULL
89
-          || (boxui->defaultfont=TTF_OpenFontRW(boxui->defaultfontdata,0,/* default font size */ 16))==NULL) {
99
+        memset(boxui,0,sizeof(intboxui_t));
100
+        if(!TTF_Init()
101
+          || (boxui->defaultfontdata=SDL_IOFromConstMem(notosans_regular_ttf,notosans_regular_ttf_len))==NULL
102
+          || (boxui->defaultfont=TTF_OpenFontIO(boxui->defaultfontdata,0,DEFAULTFONTSIZE))==NULL
103
+        ) {
90 104
                 boxui_free(boxui),boxui=NULL;
91
-                return(NULL); /* ERROR: Couldn't init defaultfont */
105
+                SDL_Log("boxui: Couldn't initialize TTF: %s\n",SDL_GetError());
106
+                return(NULL);
92 107
         }
108
+        boxui->window=window;
109
+        boxui->renderer=renderer;
110
+        boxui->width=width;
111
+        boxui->height=height;
112
+        boxui->isdirty=1;
93 113
         /* font width and height */
94 114
         {
95
-                SDL_Surface *s;
96
-                SDL_Color c={0,0,0,0};
115
+                int w,h;
97 116
                 /* width */
98
-                if((s=TTF_RenderUTF8_Blended(boxui->defaultfont,"m",c))==NULL) {
99
-                        boxui_free(boxui),boxui=NULL;
100
-                        return(NULL); /* ERROR: Couldn't query font width */
101
-                }
102
-                boxui->defaultfontwidth=s->w;
103
-                SDL_FreeSurface(s),s=NULL;
117
+                TTF_GetStringSize(boxui->defaultfont,"m",0,&w,&h);
118
+                boxui->defaultfontwidth=w;
104 119
                 /* height */
105
-                if((s=TTF_RenderUTF8_Blended(boxui->defaultfont,"gjpqy_",c))==NULL) {
106
-                        boxui_free(boxui),boxui=NULL;
107
-                        return(NULL); /* ERROR: Couldn't query font height */
108
-                }
109
-                boxui->defaultfontheight=s->h;
110
-                SDL_FreeSurface(s),s=NULL;
120
+                boxui->defaultfontheight=TTF_GetFontHeight(boxui->defaultfont);
111 121
         }
112
-        /* end of temporary initialization (to be able to test) */
113
-        /* return the struct */
114 122
         return((boxui_t *)boxui);
115 123
 }
116 124
 
117 125
 void
118 126
 boxui_free(boxui_t *paramboxui)
119 127
 {
120
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
121
-        if(boxui==NULL)
122
-                return; /* sanity check failed */
123
-        if(boxui->title!=NULL)
124
-                free(boxui->title),boxui->title=NULL;
125
-        /* temporary initialization freeing */
128
+        int i;
129
+        intboxui_t *boxui;
130
+        if((boxui=(intboxui_t *)paramboxui)==NULL)
131
+                return; /* nothing to do */
132
+        intboxui_signalhandler_gen(0,1,NULL);
133
+        if(boxui->signaldata.actions!=NULL) {
134
+                signalaction_t *action;
135
+                for(i=0,action=boxui->signaldata.actions
136
+                  ;i<boxui->signaldata.usedactions
137
+                  ;i++,action++
138
+                ) {
139
+                        if(action->actionstr!=NULL)
140
+                                free(action->actionstr),action->actionstr=NULL;
141
+                }
142
+                free(boxui->signaldata.actions),boxui->signaldata.actions=NULL,boxui->signaldata.sizeactions=boxui->signaldata.usedactions=0;
143
+        }
126 144
         if(boxui->defaultfont!=NULL)
127 145
                 TTF_CloseFont(boxui->defaultfont),boxui->defaultfont=NULL;
128
-        if(TTF_WasInit())
129
-                TTF_Quit();
130 146
         if(boxui->defaultfontdata!=NULL)
131
-                SDL_FreeRW(boxui->defaultfontdata),boxui->defaultfontdata=NULL;
132
-        if(boxui->renderer!=NULL)
133
-                SDL_DestroyRenderer(boxui->renderer),boxui->renderer=NULL;
134
-        if(boxui->win!=NULL)
135
-                SDL_DestroyWindow(boxui->win),boxui->win=NULL;
136
-        SDL_Quit();
137
-        /* end of temporary initialization freeing */
138
-        free(boxui),boxui=NULL,paramboxui=NULL;
147
+                SDL_CloseIO(boxui->defaultfontdata),boxui->defaultfontdata=NULL;
148
+        if(boxui->texture!=NULL)
149
+                SDL_DestroyTexture(boxui->texture),boxui->texture=NULL;
150
+        free(boxui),boxui=NULL;
139 151
         return;
140 152
 }
141 153
 
142 154
 int
143
-boxui_setuserptr(boxui_t *paramboxui, void *userptr)
155
+boxui_resize(boxui_t *paramboxui, int width, int height)
144 156
 {
145 157
         intboxui_t *boxui=(intboxui_t *)paramboxui;
146
-        if(boxui==NULL)
147
-                return(-1); /* sanity check failed */
148
-        boxui->userptr=userptr;
158
+        if(boxui==NULL) {
159
+                /* XXX (OLD): DEBUGFPRINTF((stderr,"WARNING: %s%s%i: boxui_resize: called with NULL boxui", (filedubug!=NULL)?filedebug:"",(filedubug!=NULL)?":":"",linedebug)); */
160
+                return(-1);
161
+        }
162
+        boxui->width=width;
163
+        boxui->height=height;
164
+        boxui->isdirty=1;
149 165
         return(0);
150
-
151
-}
152
-
153
-void *
154
-boxui_getuserptr(boxui_t *paramboxui)
155
-{
156
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
157
-        if(boxui==NULL)
158
-                return(NULL); /* sanity check failed */
159
-        return(boxui->userptr);
160 166
 }
161 167
 
162 168
 int
163
-boxui_setfps(boxui_t *paramboxui, int fps)
169
+boxui_setuserptr(boxui_t *boxui, void *userptr)
164 170
 {
165
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
166
-        if(boxui==NULL || fps<1)
167
-                return(-1); /* sanity check failed */
168
-        boxui->fps=fps;
169
-#if SDL_VERSION_ATLEAST(2,0,18)
170
-        boxui->fpsepoch=(long long)SDL_GetTicks64();
171
-#else
172
-        boxui->fpsepoch=(long long)SDL_GetTicks();
173
-#endif
174
-        boxui->fpsepochframeno=boxui->lastrenderedframeno;
171
+        if(boxui==NULL)
172
+                return(-1);
173
+        ((intboxui_t *)boxui)->userptr=userptr;
175 174
         return(0);
176 175
 }
177 176
 
178
-int
179
-boxui_getfps(boxui_t *paramboxui)
177
+void *
178
+boxui_getuserptr(boxui_t *boxui)
180 179
 {
181
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
182 180
         if(boxui==NULL)
183
-                return(DEFAULT_FPS); /* sanity check failed */
184
-        return((boxui->fps==0)?DEFAULT_FPS:boxui->fps);
181
+                return(NULL);
182
+        return(((intboxui_t *)boxui)->userptr);
185 183
 }
186 184
 
187
-
188
-
189
-int
190
-boxui_tick(boxui_t *paramboxui)
185
+static void
186
+intboxui_signalhandler_gen(int nsignal, int is_set, intboxui_t *boxuiset)
191 187
 {
192
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
193
-        if(boxui==NULL) {
194
-                SDL_Delay(1);
195
-                return(-1); /* sanity check failed */
196
-        }
197
-        if(boxui->isdirty) {
198
-                boxui_ghostrender((boxui_t *)boxui);
199
-                intboxui_waittick(boxui);
200
-                intboxui_render(boxui);
201
-        } else {
202
-                intboxui_waittick(boxui);
188
+        static signaldata_t *signaldata;
189
+        int pos;
190
+        if(is_set) {
191
+                signaldata=(boxuiset!=NULL)?&(boxuiset->signaldata):NULL;
192
+                return;
203 193
         }
204
-        boxui->lastrenderedframeno++;
205
-        return(0);
194
+        if(signaldata==NULL)
195
+                return; /* no handler */
196
+        pos=signaldata->writepos;
197
+        pos%=MAXPENDINGSIGNAL;
198
+        signaldata->buf[pos]=nsignal;
199
+        pos++;
200
+        pos%=MAXPENDINGSIGNAL;
201
+        signaldata->writepos=pos;
202
+        return;
206 203
 }
207 204
 
208
-int
209
-boxui_ghostrender(boxui_t *boxui)
205
+void
206
+intboxui_signalhandler(int nsignal)
210 207
 {
211
-#warning TODO
212
-        return(-1);
208
+        intboxui_signalhandler_gen(nsignal, 0, NULL);
209
+        return;
213 210
 }
214 211
 
215 212
 int
216
-boxui_refreshevents(boxui_t *paramboxui)
213
+boxui_setsignal(boxui_t *paramboxui, int nsignal, char *actionstr)
217 214
 {
218 215
         intboxui_t *boxui=(intboxui_t *)paramboxui;
219
-        if(boxui==NULL)
216
+        int i;
217
+        signaldata_t *signaldata;
218
+        char *newstr;
219
+        if(boxui==NULL || actionstr==NULL)
220 220
                 return(-1); /* sanity check failed */
221
-        SDL_PumpEvents();
221
+        intboxui_signalhandler_gen(0,1,boxui);
222
+        signaldata=&(((intboxui_t*)boxui)->signaldata);
223
+        /* check if signal already registered */
224
+        for(i=0;i<signaldata->usedactions;i++) {
225
+                if(signaldata->actions[i].nsignal==nsignal) {
226
+                        if(strcmp(actionstr,signaldata->actions[i].actionstr)==0)
227
+                                return(0); /* already configured */
228
+                        if((newstr=strdup(actionstr))==NULL)
229
+                                return(-1); /* mem. insuf. */
230
+                        free(signaldata->actions[i].actionstr),signaldata->actions[i].actionstr=NULL;
231
+                        signaldata->actions[i].actionstr=newstr;
232
+                        return(0); /* all done */
233
+                }
234
+        }
235
+        /* enlarge array if necessary */
236
+        if(signaldata->usedactions==signaldata->sizeactions) {
237
+                signalaction_t *newactions;
238
+                int reqsize=sizeof(signalaction_t)*(signaldata->sizeactions+BLOCKSIGNALACTION);
239
+                if((newactions=realloc(signaldata->actions,reqsize))==NULL)
240
+                        return(-1); /* mem. insuf. */
241
+                signaldata->actions=newactions,newactions=NULL;
242
+                memset(signaldata->actions+signaldata->sizeactions,0,sizeof(signalaction_t)*BLOCKSIGNALACTION);
243
+                signaldata->sizeactions+=BLOCKSIGNALACTION;
244
+        }
245
+        /* add element */
246
+        if((signaldata->actions[signaldata->usedactions].actionstr=strdup(actionstr))==NULL)
247
+                return(-1); /* mem. insuf. */
248
+        signaldata->actions[signaldata->usedactions].nsignal=nsignal;
249
+        signaldata->usedactions++;
250
+        /* install signal handler */
222 251
         return(0);
223 252
 }
224 253
 
225 254
 int
226
-boxui_getevent(boxui_t *paramboxui, SDL_Event *event)
255
+boxui_event(boxui_t *paramboxui, SDL_Event *event)
227 256
 {
257
+#warning TODO: we do not have the position of the texture in the window
228 258
         intboxui_t *boxui=(intboxui_t *)paramboxui;
229 259
         if(boxui==NULL || event==NULL)
230 260
                 return(-1); /* sanity check failed */
231
-        while(SDL_PeepEvents(event,1,SDL_GETEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT)>0) {
261
+        if(event->type==SDL_EVENT_WINDOW_SHOWN
262
+          || event->type==SDL_EVENT_WINDOW_EXPOSED
263
+          || event->type==SDL_EVENT_WINDOW_RESIZED
264
+          || event->type==SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED
265
+          || event->type==SDL_EVENT_WINDOW_MINIMIZED
266
+          || event->type==SDL_EVENT_WINDOW_MAXIMIZED
267
+          || event->type==SDL_EVENT_WINDOW_RESTORED
268
+          || event->type==SDL_EVENT_WINDOW_OCCLUDED
269
+          || event->type==SDL_EVENT_WINDOW_ENTER_FULLSCREEN
270
+          || event->type==SDL_EVENT_WINDOW_LEAVE_FULLSCREEN
271
+        ) {
272
+                boxui->isdirty=1;
273
+        } else
232 274
 #if 1
233
-                /* test */
234
-                if(event->type==SDL_MOUSEBUTTONUP) {
235
-                        if(boxui->currentclickevent[0]!='\0') {
236
-                                boxui_putactionstr((boxui_t *)boxui,boxui->currentclickevent,NULL);
237
-                                continue; /* we have used the event */
238
-                        }
275
+        /* test */
276
+               if(event->type==SDL_EVENT_MOUSE_BUTTON_UP) {
277
+                if(boxui->currentclickevent[0]!='\0') {
278
+                        boxui_putaction((boxui_t *)boxui,boxui->currentclickevent,NULL);
239 279
                 }
240
-                /* end of test */
241
-#endif
242
-                return(0); /* event found and put into "event" */
243 280
         }
244
-        return(-1); /* no events remaining */
281
+        /* end of test */
282
+#endif
283
+        return(0);
245 284
 }
246 285
 
247 286
 int
248
-boxui_event_isquit(boxui_t *paramboxui, SDL_Event *event)
287
+boxui_tick(boxui_t *paramboxui)
249 288
 {
250 289
         intboxui_t *boxui=(intboxui_t *)paramboxui;
251
-        if(boxui==NULL || event==NULL)
252
-                return(0); /* sanity check failed */
253
-        if(event->type==SDL_WINDOWEVENT && event->window.event==SDL_WINDOWEVENT_CLOSE)
254
-                return(1);
290
+        if(boxui==NULL)
291
+                return(-1); /* sanity check failed */
292
+        if(boxui->isdirty)
293
+                intboxui_render(boxui);
255 294
         return(0);
256 295
 }
296
+
257 297
 int
258
-boxui_event_iskeydown(boxui_t *paramboxui, SDL_Event *event, int *keycode)
298
+boxui_haschanged(boxui_t *paramboxui)
259 299
 {
260 300
         intboxui_t *boxui=(intboxui_t *)paramboxui;
261
-        if(boxui==NULL || event==NULL)
301
+        if(boxui==NULL)
262 302
                 return(0); /* sanity check failed */
263
-        if(event->type==SDL_KEYDOWN) {
264
-                if(keycode!=NULL)
265
-                        *keycode=event->key.keysym.sym;
266
-                return(1);
267
-        }
268
-        return(0);
303
+        return(boxui->isdirty || boxui->haschanged);
269 304
 }
270 305
 
271
-int
272
-boxui_event_isresize(boxui_t *paramboxui, SDL_Event *event, int *neww, int *newh)
306
+SDL_Texture *
307
+boxui_gettexture(boxui_t *paramboxui)
273 308
 {
274 309
         intboxui_t *boxui=(intboxui_t *)paramboxui;
275
-        if(boxui==NULL || event==NULL)
276
-                return(0); /* sanity check failed */
277
-        if(event->type==SDL_WINDOWEVENT_RESIZED
278
-          || event->type==SDL_WINDOWEVENT_SIZE_CHANGED) {
279
-                if(neww!=NULL)
280
-                        *neww=event->window.data1;
281
-                if(newh!=NULL)
282
-                        *newh=event->window.data2;
283
-                return(1);
310
+        if(boxui==NULL)
311
+                return(NULL);
312
+#if 0
313
+fprintf(stderr,"GETTEXTURE\n");
314
+#endif
315
+        if(boxui->texture==NULL || boxui->isdirty) {
316
+                boxui->isdirty=1;
317
+                boxui_tick((boxui_t *) boxui);
318
+                if(boxui->texture==NULL) {
319
+                        SDL_Log("boxui: Couldn't generate texture\n");
320
+                        return(NULL);
321
+                }
284 322
         }
285
-        return(0);
323
+        boxui->haschanged=0;
324
+        return(boxui->texture);
286 325
 }
287 326
 
288
-void
289
-boxui_resize(boxui_t *boxui, int neww, int newh)
327
+
328
+
329
+char *
330
+boxui_getaction(boxui_t *paramboxui, char **actiondata)
290 331
 {
332
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
333
+        if(boxui==NULL)
334
+                return(NULL); /* sanity check failed */
335
+        /* test */
336
+        if(boxui->flag_currentactionstrused || boxui->currentactionstr[0]=='\0')
337
+                return(NULL);
338
+        boxui->flag_currentactionstrused=1;
339
+        return(boxui->currentactionstr);
340
+        /* end of test */
291 341
 #warning TODO
292
-        return;
342
+        return(NULL);
293 343
 }
294 344
 
295 345
 int
296
-boxui_putactionstr(boxui_t *paramboxui, char *firstelem, ...)
346
+boxui_putaction(boxui_t *paramboxui, char *firstelem, ...)
297 347
 {
298 348
         intboxui_t *boxui=(intboxui_t *)paramboxui;
299 349
         if(boxui==NULL || firstelem==NULL)
... ...
@@ -307,22 +357,6 @@ boxui_putactionstr(boxui_t *paramboxui, char *firstelem, ...)
307 357
         return(-1);
308 358
 }
309 359
 
310
-char *
311
-boxui_getactionstr(boxui_t *paramboxui, char **secondelemtoend)
312
-{
313
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
314
-        if(boxui==NULL)
315
-                return(NULL); /* sanity check failed */
316
-        /* test */
317
-        if(boxui->flag_currentactionstrused || boxui->currentactionstr[0]=='\0')
318
-                return(NULL);
319
-        boxui->flag_currentactionstrused=1;
320
-        return(boxui->currentactionstr);
321
-        /* end of test */
322
-#warning TODO
323
-        return(NULL);
324
-}
325
-
326 360
 char *
327 361
 boxui_add(boxui_t *paramboxui, char *filedebug, int linedebug, char *classwiname, char *format, ...)
328 362
 {
... ...
@@ -332,9 +366,9 @@ boxui_add(boxui_t *paramboxui, char *filedebug, int linedebug, char *classwiname
332 366
         /* test */
333 367
         if(strchr(format,'%')==NULL)
334 368
                 boxui_config(boxui,NULL,-1,classwiname,format);
369
+        return(classwiname);
335 370
         /* end of test */
336 371
 #warning TODO
337
-        return(NULL);
338 372
 }
339 373
 
340 374
 char *
... ...
@@ -371,86 +405,266 @@ boxui_config(boxui_t *paramboxui, char *filedebug, int linedebug, char *winame,
371 405
 
372 406
                 }
373 407
         }
408
+        return(winame);
374 409
         /* end of test */
375 410
 #warning TODO
376
-        return(NULL);
377 411
 }
378 412
 
379
-char *
380
-boxui_pack(boxui_t *boxui, char *filedebug, int linedebug, char *winame, char *format, ...)
413
+int
414
+boxuiutil_datacmp(char *datastr,char *key,char *value)
381 415
 {
382 416
 #warning TODO
383
-        return(NULL);
417
+        return(-1);
384 418
 }
385 419
 
386 420
 int
387
-intboxui_waittick(intboxui_t *paramboxui)
421
+boxui_pack(boxui_t *boxui, char *filedebug, int linedebug, char *winame, char *format, ...)
388 422
 {
389
-        long long delay;
390
-        intboxui_t *boxui=(intboxui_t *)paramboxui;
391
-        if(boxui==NULL) {
392
-                SDL_Delay(1);
393
-                return(-1); /* sanity check failed */
394
-        }
395
-#if SDL_VERSION_ATLEAST(2,0,18)
396
-        delay=((long long)SDL_GetTicks64());
397
-#else
398
-        delay=((long long)SDL_GetTicks());
399
-#endif
400
-        delay-=boxui->fpsepoch;
401
-        delay=(((boxui->lastrenderedframeno-boxui->fpsepochframeno)+1)*1000/((boxui->fps==0)?DEFAULT_FPS:boxui->fps))-delay;
402
-        if(delay>0) {
403
-                SDL_Delay(delay);
404
-        } else if(delay<-1000) {
405
-                /* reset epoch if unsyncronized by more than 1s */
406
-#if SDL_VERSION_ATLEAST(2,0,18)
407
-                boxui->fpsepoch=((long long)SDL_GetTicks64());
408
-#else
409
-                boxui->fpsepoch=((long long)SDL_GetTicks());
410
-#endif
411
-                boxui->fpsepochframeno=boxui->lastrenderedframeno;
412
-        }
413
-        intboxui_after_doexpired(boxui);
423
+#warning TODO
414 424
         return(0);
415 425
 }
416 426
 
417
-int
427
+static int
418 428
 intboxui_render(intboxui_t *paramboxui)
419 429
 {
420 430
         intboxui_t *boxui=(intboxui_t *)paramboxui;
421 431
         if(boxui==NULL)
422 432
                 return(-1); /* sanity check failed */
423 433
         /* test */
434
+#if 0
435
+fprintf(stderr,"RENDER: START\n");
436
+#endif
437
+        if(boxui->texture==NULL) {
438
+                if((boxui->texture=SDL_CreateTexture(boxui->renderer,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,boxui->width,boxui->height))==NULL) {
439
+                        SDL_Log("boxui: couldn't create output texture\n");
440
+                        return(-1);
441
+                }
442
+        }
443
+        SDL_SetRenderTarget(boxui->renderer,boxui->texture);
424 444
         SDL_SetRenderDrawColor(boxui->renderer,0xff,0xff,0xff,0xff);
425 445
         SDL_RenderClear(boxui->renderer);
426 446
         if(boxui->currenttext[0]!='\0') {
427 447
                 SDL_Surface *fgsurface=NULL;
428
-                SDL_Texture *fg=NULL;
429
-                SDL_Rect dstrect;
430
-                SDL_Color c={0x00,0x00,0x00,0xff};
431
-                if((fgsurface=TTF_RenderUTF8_Blended(boxui->defaultfont,boxui->currenttext,c))!=NULL
432
-                  && (fg=SDL_CreateTextureFromSurface(boxui->renderer,fgsurface))!=NULL) {
433
-                        dstrect.x=(boxui->screenw-fgsurface->w)/2;
434
-                        dstrect.y=(boxui->screenh-fgsurface->h)/2;
448
+                SDL_Texture *fgtexture=NULL;
449
+                SDL_FRect dstrect;
450
+                SDL_Color bg={0x00,0x00,0x00,0x00};
451
+                SDL_Color fg={0x00,0x00,0x00,0xff};
452
+                if((fgsurface=TTF_RenderText_Shaded(boxui->defaultfont,boxui->currenttext,0,fg,bg))!=NULL
453
+                  && (fgtexture=SDL_CreateTextureFromSurface(boxui->renderer,fgsurface))!=NULL) {
454
+#if 0
455
+fprintf(stderr,"RENDER: text (w:%i h:%i)\n",fgsurface->w,fgsurface->h);
456
+#endif
457
+                        dstrect.x=(boxui->width-fgsurface->w)/2;
458
+                        dstrect.y=(boxui->height-fgsurface->h)/2;
435 459
                         dstrect.w=fgsurface->w,dstrect.h=fgsurface->h;
436
-                        SDL_RenderCopy(boxui->renderer,fg,NULL,&dstrect);
460
+#if 0
461
+fprintf(stderr,"RENDER: text (w:%i h:%i) dstrect:%ix%i+%i+%i\n",fgsurface->w,fgsurface->h,dstrect.w,dstrect.h,dstrect.x,dstrect.y);
462
+#endif
463
+                        SDL_RenderTexture(boxui->renderer,fgtexture,NULL,&dstrect);
437 464
                 }
438 465
                 if(fgsurface!=NULL)
439
-                        SDL_FreeSurface(fgsurface),fgsurface=NULL;
440
-                if(fg!=NULL)
441
-                        SDL_DestroyTexture(fg),fg=NULL;
466
+                        SDL_DestroySurface(fgsurface),fgsurface=NULL;
467
+                if(fgtexture!=NULL)
468
+                        SDL_DestroyTexture(fgtexture),fgtexture=NULL;
442 469
         }
443
-        SDL_RenderPresent(boxui->renderer);
470
+        SDL_SetRenderTarget(boxui->renderer,NULL);
444 471
         boxui->isdirty=0;
472
+        boxui->haschanged=1;
473
+#if 0
474
+fprintf(stderr,"RENDER: START\n");
475
+#endif
445 476
         /* end of test */
446 477
 #warning TODO
447 478
         return(0);
448 479
 }
449 480
 
450
-int
451
-intboxui_after_doexpired(intboxui_t *boxui)
481
+
482
+static char *
483
+intboxuiutil_getnext(char *data, int *posdata, va_list valist, int *resl, datatype_t *datatype, char **ptr1, char **ptr2, int *int1, int *int2, int *in_error)
452 484
 {
453
-#warning TODO
485
+        char *ptr;
486
+        char *res;
487
+        ptr=data+*posdata;
488
+        /* skip trailing spaces */
489
+        while(*ptr==' ')
490
+                ptr++;
491
+        if(*ptr!='-') {
492
+                *in_error=1;
493
+                DEBUGFPRINTF((stderr,"WARNING: intboxuiutil_getnext(): wrong data in \"%s\", analyzing \"%s\", '-' not found at \"%s\"\n",data,data+*posdata,ptr));
494
+                return(NULL);
495
+        }
496
+        /* get keyword (including the '-') */
497
+        res=ptr;
498
+        while(*ptr!=' ' && *ptr!='\0')
499
+                ptr++;
500
+        *resl=ptr-res;
501
+        /* skip the space */
502
+        ptr++;
503
+        /* get value */
504
+        if(*ptr!='\"' && *ptr!='%') {
505
+                *datatype=datatype_literal;
506
+                *ptr1=ptr;
507
+                while(*ptr!=' ' && *ptr!='\0')
508
+                        ptr++;
509
+
510
+                *int1=ptr-*ptr1;
511
+        } else if(*ptr=='\"') {
512
+                int flag_esc;
513
+                *datatype=datatype_escapedquotedliteral;
514
+                ptr++;
515
+                *ptr1=ptr;
516
+                for(flag_esc=0;!(flag_esc==0 && *ptr=='\"') && *ptr!='\0';ptr++) {
517
+                        if(flag_esc)
518
+                                flag_esc=0;
519
+                        else if(*ptr=='\\')
520
+                                flag_esc=1;
521
+                }
522
+                if(*ptr!='\"') {
523
+                        *in_error=1;
524
+                        DEBUGFPRINTF((stderr,"WARNING: intboxuiutil_getnext(): wrong data in \"%s\", analyzing \"%s\", unterminated string at \"%s\"\n",data,data+*posdata,*ptr1));
525
+                        return(NULL);
526
+                }
527
+                *int1=ptr-*ptr1;
528
+                ptr++;
529
+        } else if(ptr[0]=='%' && ptr[1]=='s' && (ptr[2]=='\0' || ptr[2]==' ')) {
530
+                *datatype=datatype_quotedliteral;
531
+                *ptr1=va_arg(valist, char *);
532
+                *int1=strlen(*ptr1);
533
+                ptr+=2;
534
+        } else if(ptr[0]=='%' && ptr[1]=='i' && (ptr[2]=='\0' || ptr[2]==' ')) {
535
+                *datatype=datatype_integer;
536
+                *int1=va_arg(valist, int);
537
+                ptr+=2;
538
+        } else if(ptr[0]=='%' && ptr[1]=='s' && ptr[2]=='%' && ptr[3]=='i' && (ptr[4]=='\0' || ptr[4]==' ')) {
539
+                *datatype=datatype_textvariable;
540
+                *ptr1=va_arg(valist, char *);
541
+                *int1=va_arg(valist, int);
542
+                ptr+=4;
543
+        } else if(ptr[0]=='%' && ptr[1]=='p' && ptr[2]=='%' && ptr[3]=='i' && ptr[4]=='%' && ptr[5]=='i' && (ptr[6]=='\0' || ptr[6]==' ')) {
544
+                *datatype=datatype_asset;
545
+                *ptr1=va_arg(valist, char *);
546
+                *int1=va_arg(valist, int);
547
+                *int2=va_arg(valist, int);
548
+                ptr+=6;
549
+        } else if(ptr[0]=='%' && ptr[1]=='p' && ptr[2]=='%' && ptr[3]=='p' && (ptr[4]=='\0' || ptr[4]==' ')) {
550
+                *datatype=datatype_callback;
551
+                *ptr1=va_arg(valist, char *);
552
+                *ptr2=va_arg(valist, char *);
553
+                ptr+=4;
554
+        } else {
555
+                *in_error=1;
556
+                DEBUGFPRINTF((stderr,"WARNING: intboxuiutil_getnext(): wrong data in \"%s\", analyzing \"%s\", unrecognized value type at \"%s\"\n",data,data+*posdata,ptr));
557
+                return(NULL);
558
+        }
559
+        /* save the current position and return the key */
560
+        *posdata=ptr-data;
561
+        return(res);
562
+}
563
+
564
+static char *
565
+datatypedup_literalquotedliteral(datatype_t datatype, char *ptr1, char *ptr2, int int1, int int2)
566
+{
567
+        char *res,*aux;
568
+        int t,i;
569
+        int flag_esc;
570
+        res=NULL;
571
+        int req;
572
+        /* two passes; first calculates needed storage space, second copies the data */
573
+        for(t=0,req=0;t<2;t++) {
574
+                if(datatype==datatype_literal || datatype==datatype_quotedliteral) {
575
+                        req=int1+1;
576
+                        if(t) {
577
+                                memcpy(res,ptr1,req);
578
+                                ptr1[int1]='\0';
579
+                        }
580
+                } else if(datatype==datatype_escapedquotedliteral) {
581
+                        for(req=0,aux=ptr1,flag_esc=0,i=0;!(flag_esc==0 && *aux=='\"') && *aux!='\0' && i<int1;aux++) {
582
+                                if(flag_esc) {
583
+                                        if(t)
584
+                                                res[req]=*aux;
585
+                                        req++;
586
+                                        flag_esc=0;
587
+                                } else if(*aux=='\\') {
588
+                                        flag_esc=1;
589
+                                } else {
590
+                                        if(t)
591
+                                                res[req]=*aux;
592
+                                        req++;
593
+                                }
594
+                        }
595
+                        if(t)
596
+                                res[req]='\0';
597
+                        req++;
598
+                } else if(datatype==datatype_integer) {
599
+                        int l=req;
600
+                        for(i=int1,req=0;i>0 || req==0;) {
601
+                                if(t)
602
+                                        res[(l-2)-req]=(i%10)+'0';
603
+                                req++;
604
+                                i/=10;
605
+                        }
606
+                        if(t)
607
+                                res[l-1]='\0';
608
+                        req++;
609
+                } else {
610
+                        return(NULL); /* type is not amenable to strdup */
611
+                }
612
+                if(t==0) {
613
+                        if((res=malloc(req))==NULL)
614
+                                return(NULL); /* insuf. mem. */
615
+                }
616
+        }
617
+        return(res);
618
+}
619
+
620
+static int
621
+datatypedup_int(datatype_t datatype, char *ptr1, char *ptr2, int int1, int int2, int defaultint, int *in_error)
622
+{
623
+        if(in_error!=NULL)
624
+                *in_error=0;
625
+        if(datatype==datatype_integer)
626
+                return(int1);
627
+        else if(datatype==datatype_literal || datatype==datatype_escapedquotedliteral || datatype==datatype_quotedliteral) {
628
+                int i,res;
629
+                if(int1==0)
630
+                        return(defaultint); /* no data */
631
+                for(i=0,res=0;i<int1;i++) {
632
+                        if(!(ptr1[i]>='0' && ptr1[i]<='9')) {
633
+                                if(in_error!=NULL)
634
+                                        *in_error=1;
635
+                                return(defaultint);
636
+                        }
637
+                        res=(res*10)+(ptr1[i]-'0');
638
+                }
639
+                return(res);
640
+        }
641
+        if(in_error!=NULL)
642
+                *in_error=1;
643
+        return(defaultint);
644
+}
645
+
646
+static int
647
+datatypedup_istrue(datatype_t datatype, char *ptr1, char *ptr2, int int1, int int2, int *in_error)
648
+{
649
+        if(in_error!=NULL)
650
+                *in_error=0;
651
+        if(datatype==datatype_literal || datatype==datatype_escapedquotedliteral || datatype==datatype_quotedliteral) {
652
+                if(memstrcmp(ptr1,int1,"true")==0)
653
+                        return(1);
654
+                return(0);
655
+        }
656
+        if(in_error!=NULL)
657
+                *in_error=1;
454 658
         return(0);
455 659
 }
456 660
 
661
+static int
662
+memstrcmp(char *ptr, int l, char *str)
663
+{
664
+        int res;
665
+        res=memcmp(ptr,str,l);
666
+        if(res==0 && str[l]=='\0')
667
+                return(0);
668
+        return((res==0)?1:res);
669
+}
670
+
Browse code

Add boxui_demo_helloworld. Write just enough of boxui.c to make it work and test the linux, windows and html5 toolchains

Dario Rodriguez authored on 17/06/2023 18:18:28
Showing 1 changed files
... ...
@@ -7,4 +7,450 @@
7 7
  * Licensed under the terms of the GNU GPL v3.
8 8
  */
9 9
 
10
+#include <stdio.h>
11
+#include <stdlib.h>
12
+#include <unistd.h>
13
+#include <string.h>
14
+#include <time.h>
15
+#include <signal.h>
16
+
17
+#include "SDL.h"
18
+#include "SDL_rwops.h"
19
+#include "SDL_ttf.h"
20
+
21
+#include "boxui.h"
22
+
23
+#include "notosans_regular_ttf.c"
24
+
25
+#define DEFAULT_FPS 30
26
+
27
+typedef struct intboxui_t {
28
+        char *title;
29
+        int defaultw,defaulth;
30
+        int fps;
31
+        long long fpsepoch;
32
+        long long fpsepochframeno;
33
+        void *userptr;
34
+        int isdirty;
35
+        long long lastrenderedframeno;
36
+        int sizeafterbuf;
37
+        int usedafterbuf;
38
+        char *afterbuf;
39
+        /* temporary members (to be able to test) */
40
+        int screenw;
41
+        int screenh;
42
+        SDL_Window *win;
43
+        SDL_Renderer *renderer;
44
+        SDL_RWops *defaultfontdata;
45
+        TTF_Font *defaultfont;
46
+        int defaultfontheight;
47
+        int defaultfontwidth;
48
+        char currenttext[1024];
49
+        char currentclickevent[1024];
50
+        char currentactionstr[1024];
51
+        int flag_currentactionstrused;
52
+        /* end of temporary members (to be able to test) */
53
+} intboxui_t;
54
+
55
+int intboxui_waittick(intboxui_t *boxui);
56
+int intboxui_render(intboxui_t *boxui);
57
+int intboxui_after_doexpired(intboxui_t *boxui);
58
+
59
+boxui_t *
60
+boxui_init(char *title,int defaultw, int defaulth, int flags)
61
+{
62
+        intboxui_t *boxui;
63
+        title=(title==NULL)?"":title;
64
+        if((boxui=malloc(sizeof(intboxui_t)))==NULL)
65
+                return(NULL); /* insuf. mem for boxui struct */
66
+        memset(boxui,0,sizeof(intboxui_t));
67
+        if((boxui->title=strdup(title))==NULL) {
68
+                boxui_free((boxui_t *)boxui),boxui=NULL;
69
+                return(NULL); /* insuf. mem for title string */
70
+        }
71
+        /* temporary initialization (to be able to test) */
72
+        if(SDL_Init(SDL_INIT_VIDEO)<0
73
+          || (boxui->win=SDL_CreateWindow(title,
74
+            SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,
75
+            defaultw,defaulth,0))==NULL
76
+          || (boxui->renderer=SDL_CreateRenderer(boxui->win,-1,
77
+            SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC))==NULL) {
78
+                boxui_free(boxui),boxui=NULL;
79
+                return(NULL); /* ERROR: Couldn't init video */
80
+        }
81
+        boxui->screenw=defaultw,boxui->screenh=defaulth;
82
+        if((boxui->defaultfontdata=SDL_RWFromConstMem(notosans_regular_ttf,notosans_regular_ttf_len))==NULL
83
+          || TTF_Init()==-1) {
84
+                boxui_free(boxui),boxui=NULL;
85
+                return(NULL); /* ERROR: Couldn't init font data */
86
+        }
87
+        SDL_RWseek(boxui->defaultfontdata,0,RW_SEEK_SET);
88
+        if(boxui->defaultfontdata==NULL
89
+          || (boxui->defaultfont=TTF_OpenFontRW(boxui->defaultfontdata,0,/* default font size */ 16))==NULL) {
90
+                boxui_free(boxui),boxui=NULL;
91
+                return(NULL); /* ERROR: Couldn't init defaultfont */
92
+        }
93
+        /* font width and height */
94
+        {
95
+                SDL_Surface *s;
96
+                SDL_Color c={0,0,0,0};
97
+                /* width */
98
+                if((s=TTF_RenderUTF8_Blended(boxui->defaultfont,"m",c))==NULL) {
99
+                        boxui_free(boxui),boxui=NULL;
100
+                        return(NULL); /* ERROR: Couldn't query font width */
101
+                }
102
+                boxui->defaultfontwidth=s->w;
103
+                SDL_FreeSurface(s),s=NULL;
104
+                /* height */
105
+                if((s=TTF_RenderUTF8_Blended(boxui->defaultfont,"gjpqy_",c))==NULL) {
106
+                        boxui_free(boxui),boxui=NULL;
107
+                        return(NULL); /* ERROR: Couldn't query font height */
108
+                }
109
+                boxui->defaultfontheight=s->h;
110
+                SDL_FreeSurface(s),s=NULL;
111
+        }
112
+        /* end of temporary initialization (to be able to test) */
113
+        /* return the struct */
114
+        return((boxui_t *)boxui);
115
+}
116
+
117
+void
118
+boxui_free(boxui_t *paramboxui)
119
+{
120
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
121
+        if(boxui==NULL)
122
+                return; /* sanity check failed */
123
+        if(boxui->title!=NULL)
124
+                free(boxui->title),boxui->title=NULL;
125
+        /* temporary initialization freeing */
126
+        if(boxui->defaultfont!=NULL)
127
+                TTF_CloseFont(boxui->defaultfont),boxui->defaultfont=NULL;
128
+        if(TTF_WasInit())
129
+                TTF_Quit();
130
+        if(boxui->defaultfontdata!=NULL)
131
+                SDL_FreeRW(boxui->defaultfontdata),boxui->defaultfontdata=NULL;
132
+        if(boxui->renderer!=NULL)
133
+                SDL_DestroyRenderer(boxui->renderer),boxui->renderer=NULL;
134
+        if(boxui->win!=NULL)
135
+                SDL_DestroyWindow(boxui->win),boxui->win=NULL;
136
+        SDL_Quit();
137
+        /* end of temporary initialization freeing */
138
+        free(boxui),boxui=NULL,paramboxui=NULL;
139
+        return;
140
+}
141
+
142
+int
143
+boxui_setuserptr(boxui_t *paramboxui, void *userptr)
144
+{
145
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
146
+        if(boxui==NULL)
147
+                return(-1); /* sanity check failed */
148
+        boxui->userptr=userptr;
149
+        return(0);
150
+
151
+}
152
+
153
+void *
154
+boxui_getuserptr(boxui_t *paramboxui)
155
+{
156
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
157
+        if(boxui==NULL)
158
+                return(NULL); /* sanity check failed */
159
+        return(boxui->userptr);
160
+}
161
+
162
+int
163
+boxui_setfps(boxui_t *paramboxui, int fps)
164
+{
165
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
166
+        if(boxui==NULL || fps<1)
167
+                return(-1); /* sanity check failed */
168
+        boxui->fps=fps;
169
+#if SDL_VERSION_ATLEAST(2,0,18)
170
+        boxui->fpsepoch=(long long)SDL_GetTicks64();
171
+#else
172
+        boxui->fpsepoch=(long long)SDL_GetTicks();
173
+#endif
174
+        boxui->fpsepochframeno=boxui->lastrenderedframeno;
175
+        return(0);
176
+}
177
+
178
+int
179
+boxui_getfps(boxui_t *paramboxui)
180
+{
181
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
182
+        if(boxui==NULL)
183
+                return(DEFAULT_FPS); /* sanity check failed */
184
+        return((boxui->fps==0)?DEFAULT_FPS:boxui->fps);
185
+}
186
+
187
+
188
+
189
+int
190
+boxui_tick(boxui_t *paramboxui)
191
+{
192
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
193
+        if(boxui==NULL) {
194
+                SDL_Delay(1);
195
+                return(-1); /* sanity check failed */
196
+        }
197
+        if(boxui->isdirty) {
198
+                boxui_ghostrender((boxui_t *)boxui);
199
+                intboxui_waittick(boxui);
200
+                intboxui_render(boxui);
201
+        } else {
202
+                intboxui_waittick(boxui);
203
+        }
204
+        boxui->lastrenderedframeno++;
205
+        return(0);
206
+}
207
+
208
+int
209
+boxui_ghostrender(boxui_t *boxui)
210
+{
211
+#warning TODO
212
+        return(-1);
213
+}
214
+
215
+int
216
+boxui_refreshevents(boxui_t *paramboxui)
217
+{
218
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
219
+        if(boxui==NULL)
220
+                return(-1); /* sanity check failed */
221
+        SDL_PumpEvents();
222
+        return(0);
223
+}
224
+
225
+int
226
+boxui_getevent(boxui_t *paramboxui, SDL_Event *event)
227
+{
228
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
229
+        if(boxui==NULL || event==NULL)
230
+                return(-1); /* sanity check failed */
231
+        while(SDL_PeepEvents(event,1,SDL_GETEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT)>0) {
232
+#if 1
233
+                /* test */
234
+                if(event->type==SDL_MOUSEBUTTONUP) {
235
+                        if(boxui->currentclickevent[0]!='\0') {
236
+                                boxui_putactionstr((boxui_t *)boxui,boxui->currentclickevent,NULL);
237
+                                continue; /* we have used the event */
238
+                        }
239
+                }
240
+                /* end of test */
241
+#endif
242
+                return(0); /* event found and put into "event" */
243
+        }
244
+        return(-1); /* no events remaining */
245
+}
246
+
247
+int
248
+boxui_event_isquit(boxui_t *paramboxui, SDL_Event *event)
249
+{
250
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
251
+        if(boxui==NULL || event==NULL)
252
+                return(0); /* sanity check failed */
253
+        if(event->type==SDL_WINDOWEVENT && event->window.event==SDL_WINDOWEVENT_CLOSE)
254
+                return(1);
255
+        return(0);
256
+}
257
+int
258
+boxui_event_iskeydown(boxui_t *paramboxui, SDL_Event *event, int *keycode)
259
+{
260
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
261
+        if(boxui==NULL || event==NULL)
262
+                return(0); /* sanity check failed */
263
+        if(event->type==SDL_KEYDOWN) {
264
+                if(keycode!=NULL)
265
+                        *keycode=event->key.keysym.sym;
266
+                return(1);
267
+        }
268
+        return(0);
269
+}
270
+
271
+int
272
+boxui_event_isresize(boxui_t *paramboxui, SDL_Event *event, int *neww, int *newh)
273
+{
274
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
275
+        if(boxui==NULL || event==NULL)
276
+                return(0); /* sanity check failed */
277
+        if(event->type==SDL_WINDOWEVENT_RESIZED
278
+          || event->type==SDL_WINDOWEVENT_SIZE_CHANGED) {
279
+                if(neww!=NULL)
280
+                        *neww=event->window.data1;
281
+                if(newh!=NULL)
282
+                        *newh=event->window.data2;
283
+                return(1);
284
+        }
285
+        return(0);
286
+}
287
+
288
+void
289
+boxui_resize(boxui_t *boxui, int neww, int newh)
290
+{
291
+#warning TODO
292
+        return;
293
+}
294
+
295
+int
296
+boxui_putactionstr(boxui_t *paramboxui, char *firstelem, ...)
297
+{
298
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
299
+        if(boxui==NULL || firstelem==NULL)
300
+                return(-1); /* sanity check failed */
301
+        /* test */
302
+        strncpy(boxui->currentactionstr,firstelem,sizeof(boxui->currentactionstr));
303
+        boxui->currentactionstr[sizeof(boxui->currentactionstr)-1]='\0';
304
+        boxui->flag_currentactionstrused=0;
305
+        /* end of test */
306
+#warning TODO
307
+        return(-1);
308
+}
309
+
310
+char *
311
+boxui_getactionstr(boxui_t *paramboxui, char **secondelemtoend)
312
+{
313
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
314
+        if(boxui==NULL)
315
+                return(NULL); /* sanity check failed */
316
+        /* test */
317
+        if(boxui->flag_currentactionstrused || boxui->currentactionstr[0]=='\0')
318
+                return(NULL);
319
+        boxui->flag_currentactionstrused=1;
320
+        return(boxui->currentactionstr);
321
+        /* end of test */
322
+#warning TODO
323
+        return(NULL);
324
+}
325
+
326
+char *
327
+boxui_add(boxui_t *paramboxui, char *filedebug, int linedebug, char *classwiname, char *format, ...)
328
+{
329
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
330
+        if(boxui==NULL || classwiname==NULL || format==NULL)
331
+                return(NULL); /* sanity check failed */
332
+        /* test */
333
+        if(strchr(format,'%')==NULL)
334
+                boxui_config(boxui,NULL,-1,classwiname,format);
335
+        /* end of test */
336
+#warning TODO
337
+        return(NULL);
338
+}
339
+
340
+char *
341
+boxui_config(boxui_t *paramboxui, char *filedebug, int linedebug, char *winame, char *format, ...)
342
+{
343
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
344
+        if(boxui==NULL || winame==NULL || format==NULL)
345
+                return(NULL); /* sanity check failed */
346
+        /* test */
347
+        {
348
+                char *start,*end;
349
+                int l;
350
+                /* text */
351
+                if((start=strchr(format,'\"'))!=NULL
352
+                  && (start=start+1)!=NULL
353
+                  && (end=strchr(start,'\"'))!=NULL) {
354
+                        l=end-start;
355
+                        l=(l>sizeof(boxui->currenttext))?sizeof(boxui->currenttext)-1:l;
356
+                        memcpy(boxui->currenttext,start,l);
357
+                        boxui->currenttext[l]='\0';
358
+                        boxui->isdirty=1;
359
+                }
360
+                /* click */
361
+                for(start=strchr(format,'-');start!=NULL;start=strchr(start+1,'-')) {
362
+                        if(memcmp(start,"-click ",7)==0) {
363
+                                start+=7;
364
+                                end=strchr(start,' ');
365
+                                end=(end==NULL)?start+strlen(start):end;
366
+                                l=end-start;
367
+                                l=(l>sizeof(boxui->currentclickevent))?sizeof(boxui->currentclickevent)-1:l;
368
+                                memcpy(boxui->currentclickevent,start,l);
369
+                                boxui->currentclickevent[l]='\0';
370
+                        }
371
+
372
+                }
373
+        }
374
+        /* end of test */
375
+#warning TODO
376
+        return(NULL);
377
+}
378
+
379
+char *
380
+boxui_pack(boxui_t *boxui, char *filedebug, int linedebug, char *winame, char *format, ...)
381
+{
382
+#warning TODO
383
+        return(NULL);
384
+}
385
+
386
+int
387
+intboxui_waittick(intboxui_t *paramboxui)
388
+{
389
+        long long delay;
390
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
391
+        if(boxui==NULL) {
392
+                SDL_Delay(1);
393
+                return(-1); /* sanity check failed */
394
+        }
395
+#if SDL_VERSION_ATLEAST(2,0,18)
396
+        delay=((long long)SDL_GetTicks64());
397
+#else
398
+        delay=((long long)SDL_GetTicks());
399
+#endif
400
+        delay-=boxui->fpsepoch;
401
+        delay=(((boxui->lastrenderedframeno-boxui->fpsepochframeno)+1)*1000/((boxui->fps==0)?DEFAULT_FPS:boxui->fps))-delay;
402
+        if(delay>0) {
403
+                SDL_Delay(delay);
404
+        } else if(delay<-1000) {
405
+                /* reset epoch if unsyncronized by more than 1s */
406
+#if SDL_VERSION_ATLEAST(2,0,18)
407
+                boxui->fpsepoch=((long long)SDL_GetTicks64());
408
+#else
409
+                boxui->fpsepoch=((long long)SDL_GetTicks());
410
+#endif
411
+                boxui->fpsepochframeno=boxui->lastrenderedframeno;
412
+        }
413
+        intboxui_after_doexpired(boxui);
414
+        return(0);
415
+}
416
+
417
+int
418
+intboxui_render(intboxui_t *paramboxui)
419
+{
420
+        intboxui_t *boxui=(intboxui_t *)paramboxui;
421
+        if(boxui==NULL)
422
+                return(-1); /* sanity check failed */
423
+        /* test */
424
+        SDL_SetRenderDrawColor(boxui->renderer,0xff,0xff,0xff,0xff);
425
+        SDL_RenderClear(boxui->renderer);
426
+        if(boxui->currenttext[0]!='\0') {
427
+                SDL_Surface *fgsurface=NULL;
428
+                SDL_Texture *fg=NULL;
429
+                SDL_Rect dstrect;
430
+                SDL_Color c={0x00,0x00,0x00,0xff};
431
+                if((fgsurface=TTF_RenderUTF8_Blended(boxui->defaultfont,boxui->currenttext,c))!=NULL
432
+                  && (fg=SDL_CreateTextureFromSurface(boxui->renderer,fgsurface))!=NULL) {
433
+                        dstrect.x=(boxui->screenw-fgsurface->w)/2;
434
+                        dstrect.y=(boxui->screenh-fgsurface->h)/2;
435
+                        dstrect.w=fgsurface->w,dstrect.h=fgsurface->h;
436
+                        SDL_RenderCopy(boxui->renderer,fg,NULL,&dstrect);
437
+                }
438
+                if(fgsurface!=NULL)
439
+                        SDL_FreeSurface(fgsurface),fgsurface=NULL;
440
+                if(fg!=NULL)
441
+                        SDL_DestroyTexture(fg),fg=NULL;
442
+        }
443
+        SDL_RenderPresent(boxui->renderer);
444
+        boxui->isdirty=0;
445
+        /* end of test */
446
+#warning TODO
447
+        return(0);
448
+}
449
+
450
+int
451
+intboxui_after_doexpired(intboxui_t *boxui)
452
+{
453
+#warning TODO
454
+        return(0);
455
+}
10 456
 
Browse code

Toolchain setup scripts and skeleton of demo Makefile

Dario Rodriguez authored on 16/06/2023 20:22:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,10 @@
1
+/*
2
+ * boxui.c
3
+ *
4
+ * Multiplatform UI library for SDL2.
5
+ *
6
+ * (c) 2023 Dario Rodriguez <antartica@box-ui.org>
7
+ * Licensed under the terms of the GNU GPL v3.
8
+ */
9
+
10
+