1 /* Definitive version of sdl-x. Please symlink here OR DIE */
9 #include <SDL/SDL_mixer.h>
10 Mix_Chunk
*sounds
[255];
15 #define SDL_CloneSurfaceX(SURFACE, SIZE) SDL_CreateRGBSurface(SURFACE->flags, SURFACE->w * SIZE, SURFACE->h * SIZE, SURFACE->format->BitsPerPixel, \
16 SURFACE->format->Rmask, SURFACE->format->Gmask, SURFACE->format->Bmask, SURFACE->format->Amask)
17 #define SDL_CloneSurfaceR(SURFACE) SDL_CreateRGBSurface(SURFACE->flags, SURFACE->h, SURFACE->w, SURFACE->format->BitsPerPixel, \
18 SURFACE->format->Rmask, SURFACE->format->Gmask, SURFACE->format->Bmask, SURFACE->format->Amask)
20 Uint32
getpixel(SDL_Surface
*surface
, int x
, int y
)
22 int bpp
= surface
->format
->BytesPerPixel
;
23 /* Here p is the address to the pixel we want to retrieve */
24 Uint8
*p
= (Uint8
*)surface
->pixels
+ y
* surface
->pitch
+ x
* bpp
;
36 if(SDL_BYTEORDER
== SDL_BIG_ENDIAN
)
37 return p
[0] << 16 | p
[1] << 8 | p
[2];
39 return p
[0] | p
[1] << 8 | p
[2] << 16;
47 return 0; /* shouldn't happen, but avoids warnings */
52 * Rotate surface 90 degrees (returns NEW surface)
54 SDL_Surface
* rot90_surface(SDL_Surface
* surface
)
56 SDL_Surface
* new_surface
= NULL
;
57 Uint8 bpp
= surface
->format
->BytesPerPixel
;
58 Uint8
*source
, *dest
, p
;
61 new_surface
= SDL_CloneSurfaceR(surface
);
62 // SDL_SetPalette(new_surface, SDL_LOGPAL | SDL_PHYSPAL, surface->format->palette->colors, 0, surface->format->palette->ncolors);
64 if (new_surface
== NULL
) {
65 fprintf(stderr
, "SDL_Init failed: %s\n", SDL_GetError());
69 source
= (Uint8
*)(surface
->pixels
);
70 dest
= (Uint8
*)(new_surface
->pixels
);
72 for(y
= 0; y
< surface
->h
; y
++)
73 for(x
= 0; x
< surface
->w
; x
++)
75 int dx
= new_surface
->h
- y
- 1;
77 for (p
= 0; p
< bpp
; p
++)
79 dest
[ dy
* (new_surface
->w
* bpp
) + (dx
* bpp
) + p
] =
80 source
[ y
* (surface
->w
* bpp
) + (x
* bpp
) + p
];
87 * Flip surface horizontally (returns NEW surface)
89 SDL_Surface
* flip_surface(SDL_Surface
* surface
)
91 SDL_Surface
* new_surface
= NULL
;
92 Uint8 bpp
= surface
->format
->BytesPerPixel
;
93 Uint8
*source
, *dest
, p
;
96 new_surface
= SDL_CloneSurfaceX(surface
, 1);
97 // SDL_SetPalette(new_surface, SDL_LOGPAL | SDL_PHYSPAL, surface->format->palette->colors, 0, surface->format->palette->ncolors);
99 if (new_surface
== NULL
) {
100 fprintf(stderr
, "SDL_Init failed: %s\n", SDL_GetError());
104 source
= (Uint8
*)(surface
->pixels
);
105 dest
= (Uint8
*)(new_surface
->pixels
);
107 for(y
= 0; y
< new_surface
->h
; y
++)
108 for(x
= 0; x
< new_surface
->w
; x
++)
109 for (p
= 0; p
< bpp
; p
++)
111 dest
[ y
* (new_surface
->w
* bpp
) + (x
* bpp
) + p
] =
112 source
[ (y
+ 1) * (new_surface
->w
* bpp
) - ((x
+1) * bpp
) + p
];
119 * Double surface in size (dumb)
121 void sizex(SDL_Surface
*surface
, SDL_Surface
*new_surface
, Uint8 size
)
124 Uint8 bpp
= surface
->format
->BytesPerPixel
, cx
, cy
, p
;
125 Uint8
*source
, *dest
;
127 source
= (Uint8
*)(surface
->pixels
);
128 dest
= (Uint8
*)(new_surface
->pixels
);
130 for(y
= 0; y
< surface
->h
; y
++)
131 for(x
= 0; x
< surface
->w
; x
++)
132 for (p
= 0; p
< bpp
; p
++)
133 for (cy
= 0; cy
< size
; cy
++)
134 for (cx
= 0; cx
< size
; cx
++)
136 dest
[ (y
* size
+ cy
) * (new_surface
->w
* bpp
) + ( (x
* size
+ cx
) * bpp
) + p
] =
137 source
[ y
* (surface
->w
* bpp
) + (x
* bpp
) + p
];
141 SDL_Surface
* sizex_surface(SDL_Surface
* surface
, Uint8 size
)
143 SDL_Surface
* new_surface
= NULL
;
145 new_surface
= SDL_CloneSurfaceX(surface
, size
);
146 // SDL_SetPalette(new_surface, SDL_LOGPAL | SDL_PHYSPAL, surface->format->palette->colors, 0, surface->format->palette->ncolors);
148 sizex(surface
, new_surface
, size
);
154 * Prepare matching surface and perform AdvancedMAME's scale2x implementation
157 SDL_Surface
* scale2x_surface(SDL_Surface
* surface
)
159 SDL_Surface
* new_surface
= NULL
;
161 new_surface
= SDL_CloneSurfaceX(surface
, 2);
162 SDL_SetPalette(new_surface
, SDL_LOGPAL
| SDL_PHYSPAL
, surface
->format
->palette
->colors
, 0, surface
->format
->palette
->ncolors
);
164 scale2x(surface
, new_surface
);
172 #ifndef HAVE_SDLMIXER
173 void init_sound() { }
174 int load_sound(const char * buf
) { return -1; }
175 void play_sound(int id
) { }
176 void close_sound() { }
182 /* Desired audio parameters */
189 /* Initialize variables */
190 audio_rate
= 44100;//MIX_DEFAULT_FREQUENCY;
191 audio_format
= MIX_DEFAULT_FORMAT
;
194 /* Open the audio device */
195 if (Mix_OpenAudio(audio_rate
, audio_format
, audio_channels
, 4096) < 0) {
196 fprintf(stderr
, "Couldn't open audio: %s\n", SDL_GetError());
198 Mix_QuerySpec(&audio_rate
, &audio_format
, &audio_channels
);
199 printf("Opened audio at %d Hz %d bit %s", audio_rate
,
201 (audio_channels
> 2) ? "surround" :
202 (audio_channels
> 1) ? "stereo" : "mono");
204 printf(" (looping)\n");
211 // allocate 16 mixing channels
212 //Mix_AllocateChannels(16);
213 //Mix_ChannelFinished(channel_complete_callback);
219 void assign_sound(int id
, Mix_Chunk
*wave
) {
222 int load_sound(const char * buf
) {
223 /* Load the requested wave file */
224 Mix_Chunk
*wave
= Mix_LoadWAV(buf
);
225 if ( wave
== NULL
) {
226 fprintf(stderr
, "Couldn't load %s: %s\n", buf
, SDL_GetError());
229 sounds
[loaded_wavs
++] = wave
;
230 printf("Sound %d = %s\n", loaded_wavs
-1, buf
);
231 return (loaded_wavs
-1);
237 void play_sound(int id
) {
238 Mix_Chunk
*wav
= sounds
[id
];
241 Mix_PlayChannel(-1, wav
, 0);
255 SDL_Rect
* lazy_rect(Uint32 x
, Uint32 y
, Uint32 w
, Uint32 h
) {
256 static SDL_Rect rects
[16];
257 static Uint8 index
= 0;
259 if (index
++ > 16) index
= 0;
266 return &rects
[index
];
268 Uint32
lazy_timer(Uint8 id
) {
269 static Uint32 times
[16] = /* Make sure 16 zeros are here :( */
270 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
271 Uint32 passed
, microsec
;
273 microsec
= SDL_GetTicks();
274 passed
= (!times
[id
] ? 0 : microsec
- times
[id
]);
275 times
[id
] = microsec
;
279 Uint32
lazy_delay(Uint8 id
, Uint32 test
) {
280 static Uint32 times
[16] = /* Make sure 16 zeros are here :( */
281 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
282 Uint32 passed
, microsec
;
284 microsec
= SDL_GetTicks();
285 if (!times
[id
]) times
[id
] = microsec
;
286 passed
= microsec
- times
[id
];
287 if (passed
>= test
) {
288 times
[id
] = microsec
;
297 /* Convert RGB to HSV (RGBSV are in 0-255 range, H might be not... :( ) */
298 void setHSV(Uint8 r
, Uint8 g
, Uint8 b
, Uint8
*h
, Uint8
*s
, Uint8
*v
)
300 // RGB are from 0..1, H is from 0..360, SV from 0..1
302 Uint8 maxC
= b
; if (maxC
< g
) maxC
= g
; if (maxC
< r
) maxC
= r
;
303 Uint8 minC
= b
; if (minC
> g
) minC
= g
; if (minC
> r
) minC
= r
;
305 double R
= (double)r
/ 255;
306 double G
= (double)g
/ 255;
307 double B
= (double)b
/ 255;
309 double M
= (double)maxC
/ 255;
310 double m
= (double)minC
/ 255;
324 double dR
= 60 * (M
- R
) / C
+ 180;
325 double dG
= 60 * (M
- G
) / C
+ 180;
326 double dB
= 60 * (M
- B
) / C
+ 180;
327 if (r
== maxC
) H
= dB
- dG
;
328 else if (g
== maxC
) H
= 120 + dR
- dB
;
329 else H
= 240 + dG
- dR
;
331 if (H
>= 360) H
-= 360;
338 /* Convert HSV to RGB */
339 void setRGB(Uint8 h
, Uint8 s
, Uint8 v
, Uint8
*r
, Uint8
*g
, Uint8
*b
)
349 f
= ((h
% 60) * 255) / 60;
351 p
= (v
* (256 - s
)) / 256;
352 q
= (v
* (256 - (s
* f
) / 256)) / 256;
353 t
= (v
* (256 - (s
* (256 - f
)) / 256)) / 256;
356 case 0: *r
= v
; *g
= t
; *b
= p
; break;
357 case 1: *r
= q
; *g
= v
; *b
= p
; break;
358 case 2: *r
= p
; *g
= v
; *b
= t
; break;
359 case 3: *r
= p
; *g
= q
; *b
= v
; break;
360 case 4: *r
= t
; *g
= p
; *b
= v
; break;
361 default: *r
= v
; *g
= p
; *b
= q
; break;
365 typedef struct SDL_Shade
{
372 void SDL_ComputeGradient(SDL_Color
*colors
, int n
, SDL_Color
*start
, SDL_Color
*stop
) {
377 setHSV(start
->r
, start
->g
, start
->b
, &_start
.h
, &_start
.s
, &_start
.v
);
378 setHSV(stop
->r
, stop
->g
, stop
->b
, &_stop
.h
, &_stop
.s
, &_stop
.v
);
382 double step
= 1.0f
/ n
;
383 //printf("STEP: %f\n", step);
384 for (i
= 0; i
< n
; i
++) {
386 //linear: pu = p0 + u(p1 - p0)
388 double H = (double)_start.h + f * (_stop.h - _start.h);
389 double S = (double)_start.s + f * (_stop.s - _start.s);
390 double V = (double)_start.v + f * (_stop.v - _start.v);
391 setRGB((int)H, (int)S, (int)V , &r, &g, &b);
394 double R
= (double)start
->r
+ f
* (stop
->r
- start
->r
);
395 double G
= (double)start
->g
+ f
* (stop
->g
- start
->g
);
396 double B
= (double)start
->b
+ f
* (stop
->b
- start
->b
);
397 r
= (int)R
; g
= (int)G
; b
= (int)B
;
399 //printf("COLOR %d - %02x %02x %02x \n", i, r,g,b);