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