@@ -118,6 +118,94 @@ void programError(const char *e) {
118
118
l81 .luaerr = 1 ;
119
119
}
120
120
121
+ /* =============================== Sprites ================================== */
122
+
123
+ #include <SDL_image.h>
124
+
125
+ #define SPRITE_MT "l81.sprite_mt"
126
+
127
+ void spriteBlit (SDL_Surface * s , int x , int y )
128
+ {
129
+ if (s == NULL ) return ;
130
+ SDL_Rect dst = {x , l81 .fb -> height - 1 - y - s -> h , s -> w , s -> h };
131
+ SDL_BlitSurface (s , NULL , l81 .fb -> screen , & dst );
132
+ }
133
+
134
+ /* Load sprite. Return surface pointer and object on top of stack */
135
+ SDL_Surface * spriteLoad (const char * filename )
136
+ {
137
+ SDL_Surface * * pps ;
138
+
139
+ /* check if image was already loaded and cached */
140
+ lua_getglobal (l81 .L , "sprites" );
141
+ lua_getfield (l81 .L , -1 , filename );
142
+ if (lua_isnil (l81 .L , -1 ))
143
+ {
144
+ /* load image into surface */
145
+ SDL_Surface * ps = IMG_Load (filename );
146
+ if (ps == NULL )
147
+ {
148
+ luaL_error (l81 .L , "failed to load sprite %s" , filename );
149
+ return NULL ;
150
+ }
151
+
152
+ /* box the surface pointer in a userdata */
153
+ pps = (SDL_Surface * * )lua_newuserdata (l81 .L , sizeof (SDL_Surface * ));
154
+ * pps = ps ;
155
+
156
+ /* set sprite metatable */
157
+ luaL_getmetatable (l81 .L , SPRITE_MT );
158
+ lua_setmetatable (l81 .L , -2 );
159
+
160
+ /* cache loaded surface in sprite table */
161
+ lua_pushvalue (l81 .L , -1 );
162
+ lua_setfield (l81 .L , -4 , filename );
163
+ }
164
+ else
165
+ {
166
+ /* unbox surface pointer */
167
+ pps = (SDL_Surface * * )luaL_checkudata (l81 .L , -1 , SPRITE_MT );
168
+ }
169
+
170
+ return * pps ;
171
+ }
172
+
173
+ int spriteGC (lua_State * L ) {
174
+ SDL_Surface * * pps = (SDL_Surface * * )luaL_checkudata (L , 1 , SPRITE_MT );
175
+ if (pps ) SDL_FreeSurface (* pps );
176
+ return 0 ;
177
+ }
178
+
179
+ int spriteGetHeight (lua_State * L ) {
180
+ SDL_Surface * * pps = (SDL_Surface * * )luaL_checkudata (L , 1 , SPRITE_MT );
181
+ lua_pushnumber (L , (* pps )-> h );
182
+ return 1 ;
183
+ }
184
+
185
+ int spriteGetWidth (lua_State * L ) {
186
+ SDL_Surface * * pps = (SDL_Surface * * )luaL_checkudata (L , 1 , SPRITE_MT );
187
+ lua_pushnumber (L , (* pps )-> w );
188
+ return 1 ;
189
+ }
190
+
191
+ static const struct luaL_Reg sprite_m [] = {
192
+ { "__gc" , spriteGC },
193
+ { "getHeight" , spriteGetHeight },
194
+ { "getWidth" , spriteGetWidth },
195
+ { NULL , NULL }
196
+ };
197
+
198
+ int spriteBinding (lua_State * L ) {
199
+ const char * filename ;
200
+ int x , y ;
201
+
202
+ filename = lua_tostring (L , 1 );
203
+ x = lua_tonumber (L , 2 );
204
+ y = lua_tonumber (L , 3 );
205
+ spriteBlit (spriteLoad (filename ), x , y );
206
+ return 1 ;
207
+ }
208
+
121
209
/* ============================= Lua bindings ============================== */
122
210
int fillBinding (lua_State * L ) {
123
211
l81 .r = lua_tonumber (L ,-4 );
@@ -431,7 +519,8 @@ void initScreen(void) {
431
519
void resetProgram (void ) {
432
520
char * initscript =
433
521
"keyboard={}; keyboard['pressed']={};"
434
- "mouse={}; mouse['pressed']={};" ;
522
+ "mouse={}; mouse['pressed']={};"
523
+ "sprites={}" ;
435
524
436
525
l81 .epoch = 0 ;
437
526
if (l81 .L ) lua_close (l81 .L );
@@ -472,6 +561,14 @@ void resetProgram(void) {
472
561
lua_setglobal (l81 .L ,"setFPS" );
473
562
lua_pushcfunction (l81 .L ,getpixelBinding );
474
563
lua_setglobal (l81 .L ,"getpixel" );
564
+ lua_pushcfunction (l81 .L ,spriteBinding );
565
+ lua_setglobal (l81 .L ,"sprite" );
566
+
567
+ luaL_newmetatable (l81 .L , SPRITE_MT );
568
+ lua_pushvalue (l81 .L , -1 );
569
+ lua_setfield (l81 .L , -2 , "__index" );
570
+
571
+ luaL_register (l81 .L , NULL , sprite_m );
475
572
476
573
/* Start with a black screen */
477
574
fillBackground (l81 .fb ,0 ,0 ,0 );
0 commit comments