1 /***************************************************************************
2                           sdl.c  -  description
3                              -------------------
4     begin                : Thu Apr 20 2000
5     copyright            : (C) 2000 by Michael Speck
6     email                : kulkanie@gmx.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "sdl.h"
19 #include <stdlib.h>
20 #include <string.h>
21 
22 /*
23     if you are using SDL 1.1.5 keep this defined
24 */
25 //#define SDL_1_1_5
26 
27 extern char *src_dir;
28 extern int  fast_quit;
29 
30 DrawRgn dr_src, dr_dst;
31 
32 /* I kept these '#ifdef USE_ASM' but these functions are not implemented in this version so you should not
33 define USE_ASM */
34 
35 // sdl surface //
36 
SSur_Load(char * fname,int f)37 SDL_Surface* SSur_Load(char *fname, int f)
38 {
39     SDL_Surface *buf;
40     SDL_Surface *new_sur;
41     char path[strlen(src_dir)+ strlen(fname) + 1];
42     sprintf(path, "%s%s", src_dir, fname);
43     buf = SDL_LoadBMP(path);
44     if (buf == 0) {
45         fprintf(stderr, "ERR: ssur_load: file not found: %s\n", path);
46         return 0;
47     }
48     if (f & SDL_SWSURFACE)
49         return buf;
50     new_sur = SSur_Create(buf->w, buf->h, f);
51     SDL_BlitSurface(buf, 0, new_sur, 0);
52     SDL_FreeSurface(buf);
53     return new_sur;
54 }
55 
SSur_Create(int w,int h,int f)56 SDL_Surface* SSur_Create(int w, int h, int f)
57 {
58     SDL_Surface *sur;
59     SDL_PixelFormat *spf = SDL_GetVideoSurface()->format;
60     if ((sur = SDL_CreateRGBSurface(f, w, h, spf->BitsPerPixel, spf->Rmask, spf->Gmask, spf->Bmask, spf->Amask)) == 0) {
61         fprintf(stderr, "ERR: ssur_create: not enough memory to create surface...\n");
62         exit(1);
63     }
64 /*    if (f & SDL_HWSURFACE && !(sur->flags & SDL_HWSURFACE))
65         fprintf(stderr, "unable to create surface (%ix%ix%i) in hardware memory...\n", w, h, spf->BitsPerPixel);*/
66     SDL_SetColorKey(sur, SDL_SRCCOLORKEY, 0x0);
67     SDL_SetAlpha(sur, 0, 0); // no alpha //
68     return sur;
69 }
70 
SSur_DisplayFormat(SDL_Surface * sur)71 int SSur_DisplayFormat(SDL_Surface *sur)
72 {
73     if ((sur = SDL_DisplayFormat(sur)) == 0) {
74         fprintf(stderr, "ERR: ssur_displayformat: convertion failed\n");
75         return 1;
76     }
77     return 0;
78 }
79 
SSur_Begin(SDL_Surface * sur)80 void SSur_Begin(SDL_Surface *sur)
81 {
82     if (SDL_MUSTLOCK(sur))
83         SDL_LockSurface(sur);
84 }
85 
SSur_End(SDL_Surface * sur)86 void SSur_End(SDL_Surface *sur)
87 {
88     if (SDL_MUSTLOCK(sur))
89         SDL_UnlockSurface(sur);
90 }
91 
SSur_Blit(void)92 void SSur_Blit(void)
93 {
94 #ifdef USE_ASM
95     if (dr_src.s->flags & SDL_SRCALPHA) {
96         SC_Trp_X(dr_dst.s->pixels, dr_dst.s->w, dr_dst.r.x, dr_dst.r.y, dr_src.s->pixels, dr_src.s->w, dr_src.r.x, dr_src.r.y, dr_src.r.w, dr_src.r.h, 255 - dr_src.s->format->alpha);
97     }
98     else
99         if (dr_src.s->flags & SDL_SRCCOLORKEY)
100             SC_Clp(dr_dst.s->pixels, dr_dst.s->w, dr_dst.r.x, dr_dst.r.y, dr_src.s->pixels, dr_src.s->w, dr_src.r.x, dr_src.r.y, dr_src.r.w, dr_src.r.h);
101         else
102             SC_Opq(dr_dst.s->pixels, dr_dst.s->w, dr_dst.r.x, dr_dst.r.y, dr_src.s->pixels, dr_src.s->w, dr_src.r.x, dr_src.r.y, dr_src.r.w, dr_src.r.h);
103 #else
104 #ifdef SDL_1_1_5
105     if (dr_src.s->flags & SDL_SRCALPHA)
106         SDL_SetAlpha(dr_src.s, SDL_SRCALPHA, 255 - dr_src.s->format->alpha);
107 #endif
108     SDL_BlitSurface(dr_src.s, &dr_src.r, dr_dst.s, &dr_dst.r);
109 #ifdef SDL_1_1_5
110     if (dr_src.s->flags & SDL_SRCALPHA)
111         SDL_SetAlpha(dr_src.s, SDL_SRCALPHA, 255 - dr_src.s->format->alpha);
112 #endif
113 #endif
114 }
115 
SSur_AlphaBlit(int alpha)116 void SSur_AlphaBlit(int alpha)
117 {
118 #ifdef USE_ASM
119     if (alpha == 127)
120         SC_Trp_11(dr_dst.s->pixels, dr_dst.s->w, dr_dst.r.x, dr_dst.r.y, dr_src.s->pixels, dr_src.s->w, dr_src.r.x, dr_src.r.y, dr_src.r.w, dr_src.r.h);
121     else
122         SC_Trp_X(dr_dst.s->pixels, dr_dst.s->w, dr_dst.r.x, dr_dst.r.y, dr_src.s->pixels, dr_src.s->w, dr_src.r.x, dr_src.r.y, dr_src.r.w, dr_src.r.h, 255 - alpha);
123 #else
124 #ifdef SDL_1_1_5
125     SDL_SetAlpha(dr_src.s, SDL_SRCALPHA, 255 - alpha);
126 #else
127     SDL_SetAlpha(dr_src.s, SDL_SRCALPHA, alpha);
128 #endif
129     SDL_BlitSurface(dr_src.s, &dr_src.r, dr_dst.s, &dr_dst.r);
130     SDL_SetAlpha(dr_src.s, 0, 0);
131 #endif
132 }
133 
SSur_Fill(int c)134 void SSur_Fill(int c)
135 {
136 #ifdef USE_ASM
137     SD_Box(dr_dst.s->pixels, dr_dst.s->w, 0, 0, dr_dst.s->w, dr_dst.s->h, c);
138 #else
139     SDL_FillRect(dr_dst.s, &dr_dst.r, SDL_MapRGB(dr_dst.s->format, c >> 16, (c >> 8) & 0xFF, c & 0xFF));
140 #endif
141 }
142 
143 // sdl font //
144 
SFnt_Load(char * fname)145 SFnt* SFnt_Load(char *fname)
146 {
147     SFnt    *fnt = 0;
148     FILE    *file = 0;
149     char    path[strlen(src_dir)+ strlen(fname) + 1];
150     int     i;
151 
152     sprintf(path, "%s%s", src_dir, fname);
153 
154     fnt = malloc(sizeof(SFnt));
155     if (fnt == 0) {
156         fprintf(stderr, "ERR: sfnt_load: not enough memory\n");
157         exit(1);
158     }
159 
160     if ((fnt->sur = SSur_Load(fname, SDL_SWSURFACE)) == 0)
161         exit(1);
162 
163     fnt->algn = TA_X_LEFT | TA_Y_TOP;
164     fnt->clr = 0x00FFFFFF;
165     fnt->lh = fnt->sur->h;
166 
167     //table
168     file = fopen(path, "r");
169     fseek(file, -1, SEEK_END);
170     fread(&fnt->off, 1, 1, file);
171 #ifdef DEBUG
172     printf("offset: %i\n", fnt->off);
173 #endif
174     fseek(file, -2, SEEK_END);
175     fread(&fnt->num, 1, 1, file);
176 #ifdef DEBUG
177     printf("number: %i\n", fnt->num);
178 #endif
179     fseek(file, -2 - fnt->num, SEEK_END);
180     fread(fnt->lw, 1, fnt->num, file);
181 #ifdef DEBUG
182     printf("letter width: %i\n", fnt->num);
183     for (i = 0; i < fnt->num; i++)
184         printf("%i ", fnt->lw[i]);
185     printf("\n");
186 #endif
187     fclose(file);
188 
189     //letter offsets
190     fnt->loff[0] = 0;
191     for (i = 1; i < fnt->num; i++)
192         fnt->loff[i] = fnt->loff[i - 1] + fnt->lw[i - 1];
193 
194     //allowed keys
195     memset(fnt->keys, 0, 256);
196     for (i = 0; i < fnt->num; i++) {
197         fnt->keys[i + fnt->off] = 1;
198     }
199 
200     fnt->lastX = fnt->lastY = fnt->lastW = fnt->lastH = 0;
201     return fnt;
202 }
203 
SFnt_LoadFixed(char * f,int off,int len,int w)204 SFnt* SFnt_LoadFixed(char *f, int off, int len, int w)
205 {
206     int     i;
207     SFnt    *fnt;
208     char    path[strlen(src_dir)+ strlen(f) + 1];
209 
210     sprintf(path, "%s%s", src_dir, f);
211 
212     fnt = malloc(sizeof(SFnt));
213     if (fnt == 0) {
214         fprintf(stderr, "ERR: sfnt_load: not enough memory\n");
215         exit(1);
216     }
217 
218     if ((fnt->sur = SSur_Load(f, SDL_SWSURFACE)) == 0)
219         exit(1);
220 
221     fnt->algn = TA_X_LEFT | TA_Y_TOP;
222     fnt->clr = 0x00FFFFFF;
223     fnt->lh = fnt->sur->h;
224 
225 	fnt->off = off;
226 	fnt->num = len;
227 
228 	for (i = 0; i < len; i++)
229 	    fnt->lw[i] = w;
230 
231     //letter offsets
232     fnt->loff[0] = 0;
233     for (i = 1; i < fnt->num; i++)
234         fnt->loff[i] = fnt->loff[i - 1] + w;
235 
236     //allowed keys
237     memset(fnt->keys, 0, 256);
238     for (i = 0; i < fnt->num; i++) {
239         fnt->keys[i + fnt->off] = 1;
240     }
241 
242     fnt->lastX = fnt->lastY = fnt->lastW = fnt->lastH = 0;
243     return fnt;
244 }
245 
SFnt_Free(SFnt * fnt)246 void SFnt_Free(SFnt *fnt)
247 {
248     if (fnt->sur) SDL_FreeSurface(fnt->sur);
249     free(fnt);
250 }
251 
SFnt_Write(SFnt * fnt,SDL_Surface * dest,int x,int y,char * str,int alpha)252 int SFnt_Write(SFnt *fnt, SDL_Surface *dest, int x, int y, char *str, int alpha)
253 {
254     int	c_abs;
255     int len = strlen(str);
256     int pix_len = 0;
257     int px = x, py = y;
258     int i;
259     SDL_Surface *spf = SDL_GetVideoSurface();
260 
261     pix_len = SFnt_TextWidth(fnt, str);
262 	for (i = 0; i < len; i++)
263 	    if (!fnt->keys[(int)str[i]])
264 	        str[i] = ' ';
265 
266     //alignment
267     if (fnt->algn & TA_X_CENTER)
268         px -= pix_len >> 1;
269     else
270         if (fnt->algn & TA_X_RIGHT)
271             px -= pix_len;
272     if (fnt->algn & TA_Y_CENTER)
273         py -= fnt->lh >> 1;
274     else
275         if (fnt->algn & TA_Y_BOTTOM)
276             py -= fnt->lh;
277 
278     fnt->lastX = px; if (fnt->lastX < 0) fnt->lastX = 0;
279     fnt->lastY = py; if (fnt->lastY < 0) fnt->lastY = 0;
280     fnt->lastW = pix_len; if (fnt->lastX + fnt->lastW >= spf->w) fnt->lastW = spf->w - fnt->lastX;
281     fnt->lastH = fnt->lh; if (fnt->lastY + fnt->lastH >= spf->h) fnt->lastH = spf->h - fnt->lastY;
282 
283     if (alpha != 0)
284         SDL_SetAlpha(fnt->sur, SDL_SRCALPHA, alpha);
285     else
286         SDL_SetAlpha(fnt->sur, 0, 0);
287     for (i = 0; i < len; i++) {
288        	c_abs = str[i] - fnt->off;
289        	DR_SETDST(dest, px, py, fnt->lw[c_abs], fnt->lh);
290        	DR_SETSRC(fnt->sur, fnt->loff[c_abs], 0);
291        	SSur_Blit();
292         px += fnt->lw[c_abs];
293     }
294 
295     return 0;
296 }
297 
SFnt_Begin(SFnt * fnt)298 void SFnt_Begin(SFnt *fnt)
299 {
300     SSur_Begin(fnt->sur);
301 }
302 
SFnt_End(SFnt * fnt)303 void SFnt_End(SFnt *fnt)
304 {
305     SSur_End(fnt->sur);
306 }
307 
SFnt_LastRect(SFnt * fnt)308 SDL_Rect SFnt_LastRect(SFnt *fnt)
309 {
310     SDL_Rect    rect={fnt->lastX, fnt->lastY, fnt->lastW, fnt->lastH};
311     return rect;
312 }
313 
SFnt_TextWidth(SFnt * fnt,char * str)314 int SFnt_TextWidth(SFnt *fnt, char *str)
315 {
316     unsigned int i;
317     int pix_len = 0;
318     for (i = 0; i < strlen(str); i++)
319         pix_len += fnt->lw[str[i] - fnt->off];
320     return pix_len;
321 }
322 
323 // sdl //
324 
325 Sdl sdl;
326 
Sdl_Init(int f)327 void Sdl_Init(int f)
328 {
329     sdl.scr = 0;
330     if (SDL_Init(f) < 0) {
331         fprintf(stderr, "ERR: sdl_init: %s", SDL_GetError());
332         exit(1);
333     }
334     SDL_EnableUNICODE(1);
335     atexit(SDL_Quit);
336 }
337 
Sdl_Quit()338 void Sdl_Quit()
339 {
340     if (sdl.scr) SDL_FreeSurface(sdl.scr);
341 }
342 
Sdl_SetVideoMode(int w,int h,int d,int f)343 int	Sdl_SetVideoMode(int w, int h, int d, int f)
344 {
345     const SDL_VideoInfo	*vi = SDL_GetVideoInfo();
346     char *ny[2] = {"No", "Yes"};
347     SDL_PixelFormat	*fmt;
348 
349     if (sdl.scr) SDL_FreeSurface(sdl.scr);
350     if ((sdl.scr = SDL_SetVideoMode(w, h, d, f)) == 0) {
351         fprintf(stderr, "ERR: sdl_setvideomode: %s", SDL_GetError());
352         return 1;
353     }
354 
355 #ifdef USE_ASM
356     //set gfx format
357     fmt = sdl.scr->format;
358     rMask = fmt->Rmask;
359     gMask = fmt->Gmask;
360     bMask = fmt->Bmask;
361     bpp   = fmt->BitsPerPixel;
362     rlShft = fmt->Rshift;
363     glShft = fmt->Gshift;
364     blShft = fmt->Bshift;
365     rrShft = fmt->Rloss;
366     grShft = fmt->Gloss;
367     brShft = fmt->Bloss;
368     Gfx_SetClipRgn(0, 0, w,  h);
369 #endif
370 
371 #ifdef DEBUG
372     if (f & SDL_HWSURFACE && !(sdl.scr->flags & SDL_HWSURFACE))
373        	fprintf(stderr, "unable to create screen in hardware memory...\n");
374     if (f & SDL_DOUBLEBUF && !(sdl.scr->flags & SDL_DOUBLEBUF))
375         fprintf(stderr, "unable to create double buffered screen...\n");
376     if (f & SDL_FULLSCREEN && !(sdl.scr->flags & SDL_FULLSCREEN))
377         fprintf(stderr, "unable to switch to fullscreen...\n");
378 
379 /*    printf("video mode format:\n");
380     printf("Masks: R=%i, G=%i, B=%i\n", fmt->Rmask, fmt->Gmask, fmt->Bmask);
381     printf("LShft: R=%i, G=%i, B=%i\n", fmt->Rshift, fmt->Gshift, fmt->Bshift);
382     printf("RShft: R=%i, G=%i, B=%i\n", fmt->Rloss, fmt->Gloss, fmt->Bloss);
383     printf("BBP: %i\n", fmt->BitsPerPixel);*/
384 
385     printf("video hardware capabilities:\n");
386     printf("Hardware Surfaces: %s\n", ny[vi->hw_available]);
387     printf("HW_Blit (CC, A): %s (%s, %s)\n", ny[vi->blit_hw], ny[vi->blit_hw_CC], ny[vi->blit_hw_A]);
388     printf("SW_Blit (CC, A): %s (%s, %s)\n", ny[vi->blit_sw], ny[vi->blit_sw_CC], ny[vi->blit_sw_A]);
389     printf("HW_Fill: %s\n", ny[vi->blit_fill]);
390     printf("Video Memory: %i\n", vi->video_mem);
391 #endif
392 
393     return 0;
394 }
395 
Sdl_Update(int x,int y,int w,int h)396 void Sdl_Update(int x, int y, int w, int h)
397 {
398     SDL_UpdateRect(sdl.scr, x, y, w, h);
399 }
400 
Sdl_FullUpdate()401 void Sdl_FullUpdate()
402 {
403     SDL_UpdateRect(sdl.scr, 0, 0, 0 ,0);
404 }
405 
Sdl_Dim(int steps,int delay,int trp)406 void Sdl_Dim(int steps, int delay, int trp)
407 {
408     SDL_Surface    *buffer;
409     int per_step = trp / steps;
410     int i;
411 #ifndef USE_ASM
412     per_step *= 2;
413 #endif
414     if (fast_quit) return;
415     buffer = SSur_Create(sdl.scr->w, sdl.scr->h, SDL_SWSURFACE);
416     SDL_SetColorKey(buffer, 0, 0);
417     DR_SETFULLDST(buffer);
418     DR_SETFULLSRC(sdl.scr);
419     SSur_Blit();
420     for (i = 0; i <= trp; i += per_step) {
421 #ifdef USE_ASM
422         SC_Opq(sdl.scr->pixels, sdl.scr->w, 0, 0,
423             buffer->pixels, buffer->w,
424             0, 0, sdl.scr->w, sdl.scr->h);
425         SD_CBx(sdl.scr->pixels, sdl.scr->w, 0, 0, sdl.scr->w, sdl.scr->h, 0x0, i);
426 #else
427         DR_SETFULLDST(sdl.scr);
428         SSur_Fill(0x0);
429         DR_SETFULLSRC(buffer);
430         SSur_AlphaBlit(i);
431 #endif
432         Sdl_FullUpdate();
433         SDL_Delay(delay);
434     }
435     if (trp == 255) {
436         DR_SETFULLDST(sdl.scr);
437         SSur_Fill(0x0);
438         Sdl_FullUpdate();
439     }
440     SDL_FreeSurface(buffer);
441 }
442 
Sdl_UnDim(int steps,int delay,int trp)443 void Sdl_UnDim(int steps, int delay, int trp)
444 {
445     SDL_Surface    *buffer;
446     int per_step = trp / steps;
447     int i;
448 #ifndef USE_ASM
449     per_step *= 2;
450 #endif
451     if (fast_quit) return;
452     buffer = SSur_Create(sdl.scr->w, sdl.scr->h, SDL_SWSURFACE);
453     SDL_SetColorKey(buffer, 0, 0);
454     DR_SETFULLDST(buffer);
455     DR_SETFULLSRC(sdl.scr);
456     SSur_Blit();
457     for (i = trp; i >= 0; i -= per_step) {
458 #ifdef USE_ASM
459         SC_Opq(sdl.scr->pixels, sdl.scr->w, 0, 0,
460             buffer->pixels, buffer->w,
461             0, 0, sdl.scr->w, sdl.scr->h);
462         SD_CBx(sdl.scr->pixels, sdl.scr->w, 0, 0, sdl.scr->w, sdl.scr->h, 0x0, i);
463 #else
464         DR_SETFULLDST(sdl.scr);
465         SSur_Fill(0x0);
466         DR_SETFULLSRC(buffer);
467         SSur_AlphaBlit(i);
468 #endif
469         Sdl_FullUpdate();
470         SDL_Delay(delay);
471     }
472     DR_SETFULLDST(sdl.scr);
473     DR_SETFULLSRC(buffer);
474     SSur_Blit();
475     Sdl_FullUpdate();
476     SDL_FreeSurface(buffer);
477 }
478 
Sdl_WaitForKey()479 int Sdl_WaitForKey()
480 {
481     //wait for key
482     SDL_Event event;
483     while (1) {
484         SDL_WaitEvent(&event);
485         if (event.type == SDL_QUIT) {
486             fast_quit = 1;
487             return 0;
488         }
489         if (event.type == SDL_KEYUP)
490             return event.key.keysym.sym;
491     }
492 }
493 
Sdl_WaitForClick()494 void Sdl_WaitForClick()
495 {
496     //wait for key or button
497     SDL_Event event;
498     while (1) {
499         SDL_WaitEvent(&event);
500         if (event.type == SDL_QUIT) {
501             fast_quit = 1;
502             return;
503         }
504         if (event.type == SDL_KEYUP || event.type == SDL_MOUSEBUTTONUP)
505             return;
506     }
507 }
508 /*
509 void Sdl_Begin()
510 {
511     if (SDL_MUSTLOCK(sdl.scr))
512         SDL_LockSurface(sdl.scr);
513 }
514 
515 void Sdl_End()
516 {
517     if (SDL_MUSTLOCK(sdl.scr))
518         SDL_UnlockSurface(sdl.scr);
519 }
520 
521 void Sdl_Flip()
522 {
523     SDL_Flip(sdl.scr);
524 }
525 
526 void Sdl_SetClipRgn(int x, int y, int w, int h)
527 {
528     SDL_SetClipping(sdl.scr, x, y, x + w, y + h);
529 }
530 */
531