X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsdl.c;h=406c022638499282e91080006e5e328b7150e11c;hb=e8b94b38c4be1bf3ada57ade9eb3a96adb080775;hp=1bc222a958c49c227bfc9fa9a6a23bf853cd8a33;hpb=391f8c019bdd5591015f8f310d97cf077de93fa2;p=rocksndiamonds.git diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 1bc222a9..406c0226 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -24,7 +24,7 @@ /* ========================================================================= */ /* functions from SGE library */ -inline void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32); +void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32); /* #ifdef PLATFORM_WIN32 */ #define FULLSCREEN_BUG @@ -38,7 +38,7 @@ static int fullscreen_yoffset; static int video_xoffset; static int video_yoffset; -inline void SDLInitVideoDisplay(void) +void SDLInitVideoDisplay(void) { putenv("SDL_VIDEO_CENTERED=1"); @@ -50,8 +50,8 @@ inline void SDLInitVideoDisplay(void) video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; } -inline void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window, - boolean fullscreen) +void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window, + boolean fullscreen) { #ifdef FULLSCREEN_BUG int i; @@ -109,7 +109,7 @@ inline void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window, *window = CreateBitmap(video.width, video.height, video.depth); } -inline boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) +boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) { boolean success = TRUE; int surface_flags_fullscreen = SURFACE_FLAGS | SDL_FULLSCREEN; @@ -172,8 +172,8 @@ inline boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) return success; } -inline void SDLCreateBitmapContent(Bitmap *new_bitmap, - int width, int height, int depth) +void SDLCreateBitmapContent(Bitmap *new_bitmap, int width, int height, + int depth) { SDL_Surface *surface_tmp, *surface_native; @@ -190,7 +190,7 @@ inline void SDLCreateBitmapContent(Bitmap *new_bitmap, new_bitmap->surface = surface_native; } -inline void SDLFreeBitmapPointers(Bitmap *bitmap) +void SDLFreeBitmapPointers(Bitmap *bitmap) { if (bitmap->surface) SDL_FreeSurface(bitmap->surface); @@ -200,10 +200,9 @@ inline void SDLFreeBitmapPointers(Bitmap *bitmap) bitmap->surface_masked = NULL; } -inline void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap, - int src_x, int src_y, - int width, int height, - int dst_x, int dst_y, int mask_mode) +void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap, + int src_x, int src_y, int width, int height, + int dst_x, int dst_y, int mask_mode) { Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap); SDL_Rect src_rect, dst_rect; @@ -243,16 +242,11 @@ inline void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap, SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height); } -inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, - int width, int height, Uint32 color) +void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, + int width, int height, Uint32 color) { Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap); SDL_Rect rect; -#if 0 - unsigned int color_r = (color >> 16) & 0xff; - unsigned int color_g = (color >> 8) & 0xff; - unsigned int color_b = (color >> 0) & 0xff; -#endif #ifdef FULLSCREEN_BUG if (dst_bitmap == backbuffer || dst_bitmap == window) @@ -267,28 +261,144 @@ inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, rect.w = width; rect.h = height; -#if 1 SDL_FillRect(real_dst_bitmap->surface, &rect, color); -#else - SDL_FillRect(real_dst_bitmap->surface, &rect, - SDL_MapRGB(real_dst_bitmap->surface->format, - color_r, color_g, color_b)); -#endif if (dst_bitmap == window) SDL_UpdateRect(backbuffer->surface, x, y, width, height); } -inline void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, - int to_x, int to_y, Uint32 color) +void SDLFadeScreen(Bitmap *bitmap_cross, int fade_mode, int fade_delay, + int post_delay) { - SDL_Surface *surface = dst_bitmap->surface; - SDL_Rect rect; + static boolean initialization_needed = TRUE; + static SDL_Surface *surface_screen_copy = NULL; + static SDL_Surface *surface_black = NULL; + SDL_Surface *surface_screen = backbuffer->surface; + SDL_Surface *surface_cross; /* initialized later */ + SDL_Rect src_rect, dst_rect; + int src_x = 0, src_y = 0; + int dst_x = 0, dst_y = 0; + boolean fade_reverse = (fade_mode == FADE_MODE_FADE_IN ? TRUE : FALSE); + unsigned int time_last, time_current; + float alpha; + int alpha_final; + + src_rect.x = src_x; + src_rect.y = src_y; + src_rect.w = video.width; + src_rect.h = video.height; + +#ifdef FULLSCREEN_BUG + dst_x += video_xoffset; + dst_y += video_yoffset; +#endif + + dst_rect.x = dst_x; + dst_rect.y = dst_y; + dst_rect.w = video.width; + dst_rect.h = video.height; + #if 0 - unsigned int color_r = (color >> 16) & 0xff; - unsigned int color_g = (color >> 8) & 0xff; - unsigned int color_b = (color >> 0) & 0xff; + if (!initialization_needed) + { + /* check if screen size has changed (can happen when toggling fullscreen) */ + if (surface_screen_copy->w != surface_screen->w || + surface_screen_copy->h != surface_screen->h) + { + SDL_FreeSurface(surface_screen_copy); + SDL_FreeSurface(surface_black); + + initialization_needed = TRUE; + } + } +#endif + + if (initialization_needed) + { + unsigned int flags = SDL_SRCALPHA; + + /* use same surface type as screen surface */ + if ((surface_screen->flags & SDL_HWSURFACE)) + flags |= SDL_HWSURFACE; + else + flags |= SDL_SWSURFACE; + + /* create surface for temporary copy of screen buffer */ + if ((surface_screen_copy = + SDL_CreateRGBSurface(flags, +#if 1 + video.width, + video.height, +#else + surface_screen->w, + surface_screen->h, +#endif + surface_screen->format->BitsPerPixel, + surface_screen->format->Rmask, + surface_screen->format->Gmask, + surface_screen->format->Bmask, + surface_screen->format->Amask)) == NULL) + Error(ERR_EXIT, "SDL_CreateRGBSurface( ) failed: %s", SDL_GetError()); + + /* create black surface for fading from/to black */ + if ((surface_black = + SDL_CreateRGBSurface(flags, +#if 1 + video.width, + video.height, +#else + surface_screen->w, + surface_screen->h, #endif + surface_screen->format->BitsPerPixel, + surface_screen->format->Rmask, + surface_screen->format->Gmask, + surface_screen->format->Bmask, + surface_screen->format->Amask)) == NULL) + Error(ERR_EXIT, "SDL_CreateRGBSurface( ) failed: %s", SDL_GetError()); + + /* completely fill the surface with black color pixels */ + SDL_FillRect(surface_black, NULL, + SDL_MapRGB(surface_screen->format, 0, 0, 0)); + + initialization_needed = FALSE; + } + + /* copy the current screen backbuffer to the temporary screen copy buffer */ + SDL_BlitSurface(surface_screen, &dst_rect, surface_screen_copy, &src_rect); + + surface_cross = (fade_mode == FADE_MODE_CROSSFADE ? bitmap_cross->surface : + surface_black); + + time_current = SDL_GetTicks(); + + for (alpha = 0.0; alpha < 255.0;) + { + time_last = time_current; + time_current = SDL_GetTicks(); + alpha += 255 * ((float)(time_current - time_last) / fade_delay); + alpha_final = (int)(fade_reverse ? 255.0 - alpha : alpha); + alpha_final = MIN(MAX(0, alpha_final), 255); + + /* draw existing image to screen buffer */ + SDL_BlitSurface(surface_screen_copy, &src_rect, surface_screen, &dst_rect); + + /* draw new image to screen buffer using alpha blending */ + SDL_SetAlpha(surface_cross, SDL_SRCALPHA, alpha_final); + SDL_BlitSurface(surface_cross, &src_rect, surface_screen, &dst_rect); + + /* draw screen buffer to visible display */ + SDL_Flip(surface_screen); + } + + Delay(post_delay); +} + +void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, + int to_x, int to_y, Uint32 color) +{ + SDL_Surface *surface = dst_bitmap->surface; + SDL_Rect rect; if (from_x > to_x) swap_numbers(&from_x, &to_x); @@ -309,16 +419,11 @@ inline void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, } #endif -#if 1 SDL_FillRect(surface, &rect, color); -#else - SDL_FillRect(surface, &rect, - SDL_MapRGB(surface->format, color_r, color_g, color_b)); -#endif } -inline void SDLDrawLine(Bitmap *dst_bitmap, int from_x, int from_y, - int to_x, int to_y, Uint32 color) +void SDLDrawLine(Bitmap *dst_bitmap, int from_x, int from_y, + int to_x, int to_y, Uint32 color) { #ifdef FULLSCREEN_BUG if (dst_bitmap == backbuffer || dst_bitmap == window) @@ -334,8 +439,8 @@ inline void SDLDrawLine(Bitmap *dst_bitmap, int from_x, int from_y, } #if 0 -inline void SDLDrawLines(SDL_Surface *surface, struct XY *points, - int num_points, Uint32 color) +void SDLDrawLines(SDL_Surface *surface, struct XY *points, + int num_points, Uint32 color) { int i, x, y; int line_width = 4; @@ -363,7 +468,7 @@ inline void SDLDrawLines(SDL_Surface *surface, struct XY *points, } #endif -inline Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y) +Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y) { SDL_Surface *surface = src_bitmap->surface; @@ -864,7 +969,7 @@ void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, sge_Line(Surface, x1, y1, x2, y2, SDL_MapRGB(Surface->format, R, G, B)); } -inline void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel) +void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel) { #ifdef FULLSCREEN_BUG if (dst_bitmap == backbuffer || dst_bitmap == window) @@ -884,8 +989,8 @@ inline void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel) ----------------------------------------------------------------------------- */ -inline void SDLInvertArea(Bitmap *bitmap, int src_x, int src_y, - int width, int height, Uint32 color) +void SDLInvertArea(Bitmap *bitmap, int src_x, int src_y, + int width, int height, Uint32 color) { int x, y; @@ -900,9 +1005,9 @@ inline void SDLInvertArea(Bitmap *bitmap, int src_x, int src_y, } } -inline void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap, - int src_x, int src_y, int width, int height, - int dst_x, int dst_y) +void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap, + int src_x, int src_y, int width, int height, + int dst_x, int dst_y) { int x, y; @@ -941,12 +1046,69 @@ typedef struct Uint8 a; } tColorRGBA; +int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst) +{ + int x, y; + tColorRGBA *sp, *csp, *dp; + int sgap, dgap; + + /* pointer setup */ + sp = csp = (tColorRGBA *) src->pixels; + dp = (tColorRGBA *) dst->pixels; + sgap = src->pitch - src->w * 4; + dgap = dst->pitch - dst->w * 4; + + for (y = 0; y < dst->h; y++) + { + sp = csp; + + for (x = 0; x < dst->w; x++) + { + tColorRGBA *sp0 = sp; + tColorRGBA *sp1 = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + tColorRGBA *sp00 = &sp0[0]; + tColorRGBA *sp01 = &sp0[1]; + tColorRGBA *sp10 = &sp1[0]; + tColorRGBA *sp11 = &sp1[1]; + tColorRGBA new; + + /* create new color pixel from all four source color pixels */ + new.r = (sp00->r + sp01->r + sp10->r + sp11->r) / 4; + new.g = (sp00->g + sp01->g + sp10->g + sp11->g) / 4; + new.b = (sp00->b + sp01->b + sp10->b + sp11->b) / 4; + new.a = (sp00->a + sp01->a + sp10->a + sp11->a) / 4; + + /* draw */ + *dp = new; + + /* advance source pointers */ + sp += 2; + + /* advance destination pointer */ + dp++; + } + + /* advance source pointer */ + csp = (tColorRGBA *) ((Uint8 *) csp + 2 * src->pitch); + + /* advance destination pointers */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + return 0; +} + int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst) { int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy; tColorRGBA *sp, *csp, *dp; int sgap, dgap; + /* use specialized zoom function when scaling down to exactly half size */ + if (src->w == 2 * dst->w && + src->h == 2 * dst->h) + return zoomSurfaceRGBA_scaleDownBy2(src, dst); + /* variable setup */ sx = (int) (65536.0 * (float) src->w / (float) dst->w); sy = (int) (65536.0 * (float) src->h / (float) dst->h); @@ -1303,9 +1465,9 @@ void SDLSetMouseCursor(struct MouseCursorInfo *cursor_info) /* audio functions */ /* ========================================================================= */ -inline void SDLOpenAudio(void) +void SDLOpenAudio(void) { - if (strcmp(setup.system.sdl_audiodriver, ARG_DEFAULT) != 0) + if (!strEqual(setup.system.sdl_audiodriver, ARG_DEFAULT)) putenv(getStringCat2("SDL_AUDIODRIVER=", setup.system.sdl_audiodriver)); if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) @@ -1335,7 +1497,7 @@ inline void SDLOpenAudio(void) Mixer_InitChannels(); } -inline void SDLCloseAudio(void) +void SDLCloseAudio(void) { Mix_HaltMusic(); Mix_HaltChannel(-1); @@ -1349,7 +1511,7 @@ inline void SDLCloseAudio(void) /* event functions */ /* ========================================================================= */ -inline void SDLNextEvent(Event *event) +void SDLNextEvent(Event *event) { SDL_WaitEvent(event); @@ -1440,6 +1602,7 @@ void HandleJoystickEvent(Event *event) void SDLInitJoysticks() { static boolean sdl_joystick_subsystem_initialized = FALSE; + boolean print_warning = !sdl_joystick_subsystem_initialized; int i; if (!sdl_joystick_subsystem_initialized) @@ -1455,15 +1618,24 @@ void SDLInitJoysticks() for (i = 0; i < MAX_PLAYERS; i++) { + /* get configured joystick for this player */ char *device_name = setup.input[i].joy.device_name; int joystick_nr = getJoystickNrFromDeviceName(device_name); if (joystick_nr >= SDL_NumJoysticks()) + { + if (setup.input[i].use_joystick && print_warning) + Error(ERR_WARN, "cannot find joystick %d", joystick_nr); + joystick_nr = -1; + } /* misuse joystick file descriptor variable to store joystick number */ joystick.fd[i] = joystick_nr; + if (joystick_nr == -1) + continue; + /* this allows subsequent calls to 'InitJoysticks' for re-initialization */ if (SDLCheckJoystickOpened(joystick_nr)) SDLCloseJoystick(joystick_nr); @@ -1473,7 +1645,9 @@ void SDLInitJoysticks() if (!SDLOpenJoystick(joystick_nr)) { - Error(ERR_WARN, "cannot open joystick %d", joystick_nr); + if (print_warning) + Error(ERR_WARN, "cannot open joystick %d", joystick_nr); + continue; }