X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsystem.c;h=f08c88c762aa1519e71965eee0e58f6a2b92eb1a;hb=f6477461020eebe6489d4997ac973c985d82e4aa;hp=8a5942da4af6ca6984b540c1ef99f4c8e1686ebf;hpb=59ee473b86e7cbc1d9b09a3c22b0bbd3a410f16f;p=rocksndiamonds.git diff --git a/src/libgame/system.c b/src/libgame/system.c index 8a5942da..f08c88c7 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -46,6 +46,8 @@ LevelDirTree *leveldir_first = NULL; LevelDirTree *leveldir_current = NULL; int level_nr; +struct LevelStats level_stats[MAX_LEVELS]; + Display *display = NULL; Visual *visual = NULL; int screen = 0; @@ -57,6 +59,9 @@ DrawBuffer *drawto = NULL; int button_status = MB_NOT_PRESSED; boolean motion_status = FALSE; +#if defined(TARGET_SDL2) +boolean keyrepeat_status = TRUE; +#endif int redraw_mask = REDRAW_NONE; int redraw_tiles = 0; @@ -103,6 +108,11 @@ void InitProgramInfo(char *argv0, program.error_file = stderr; } +void InitExitMessageFunction(void (*exit_message_function)(char *, va_list)) +{ + program.exit_message_function = exit_message_function; +} + void InitExitFunction(void (*exit_function)(int)) { program.exit_function = exit_function; @@ -119,6 +129,9 @@ void InitExitFunction(void (*exit_function)(int)) void InitPlatformDependentStuff(void) { + // this is initialized in GetOptions(), but may already be used before + options.verbose = TRUE; + #if defined(PLATFORM_MSDOS) _fmode = O_BINARY; #endif @@ -127,12 +140,22 @@ void InitPlatformDependentStuff(void) updateUserGameDataDir(); #endif +#if 1 + openErrorFile(); +#else #if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX) openErrorFile(); #endif +#endif #if defined(TARGET_SDL) - if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0) +#if defined(TARGET_SDL2) + int sdl_init_flags = SDL_INIT_EVENTS | SDL_INIT_NOPARACHUTE; +#else + int sdl_init_flags = SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE; +#endif + + if (SDL_Init(sdl_init_flags) < 0) Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError()); SDLNet_Init(); @@ -211,6 +234,15 @@ void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height) gfx.scrollbuffer_height = scrollbuffer_height; } +void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height) +{ + gfx.clipping_enabled = enabled; + gfx.clip_x = x; + gfx.clip_y = y; + gfx.clip_width = width; + gfx.clip_height = height; +} + void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)) { gfx.draw_busy_anim_function = draw_busy_anim_function; @@ -235,6 +267,8 @@ void SetDrawBackgroundMask(int draw_background_mask) gfx.draw_background_mask = draw_background_mask; } +#if 0 + static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile, int dest_x, int dest_y, int width, int height) { @@ -284,13 +318,42 @@ void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize); else if (mask == REDRAW_DOOR_1) - { DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile, gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize); - } } +#else + +void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) +{ + if (background_bitmap_tile != NULL) + gfx.background_bitmap_mask |= mask; + else + gfx.background_bitmap_mask &= ~mask; + +#if 0 + if (gfx.background_bitmap == NULL) + gfx.background_bitmap = CreateBitmap(video.width, video.height, + DEFAULT_DEPTH); +#endif + + if (background_bitmap_tile == NULL) /* empty background requested */ + return; + + if (mask == REDRAW_ALL) + BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0, + 0, 0, video.width, video.height); + else if (mask == REDRAW_FIELD) + BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0, + gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize); + else if (mask == REDRAW_DOOR_1) + BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0, + gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize); +} + +#endif + void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile) { /* remove every mask before setting mask for window */ @@ -348,6 +411,13 @@ inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap, #endif } +void LimitScreenUpdates(boolean enable) +{ +#if defined(TARGET_SDL) + SDLLimitScreenUpdates(enable); +#endif +} + void InitVideoDisplay(void) { #if defined(TARGET_SDL) @@ -371,17 +441,24 @@ void CloseVideoDisplay(void) void InitVideoBuffer(int width, int height, int depth, boolean fullscreen) { +#if 0 + printf("::: InitVideoBuffer\n"); +#endif + video.width = width; video.height = height; video.depth = GetRealDepth(depth); video.fullscreen_available = FULLSCREEN_STATUS; video.fullscreen_enabled = FALSE; + // video.fullscreen_initial = FALSE; #if 0 video.fullscreen_mode_current = NULL; video.fullscreen_modes = NULL; #endif + video.window_scaling_available = WINDOW_SCALING_STATUS; + #if defined(TARGET_SDL) SDLInitVideoBuffer(&backbuffer, &window, fullscreen); #else @@ -512,14 +589,115 @@ boolean DrawingOnBackground(int x, int y) CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask)); } +static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y, + int *width, int *height, boolean is_dest) +{ +#if 1 + int clip_x, clip_y, clip_width, clip_height; + + if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */ + { + clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width); + clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height); + clip_width = MIN(MAX(0, gfx.clip_width), bitmap->width - clip_x); + clip_height = MIN(MAX(0, gfx.clip_height), bitmap->height - clip_y); + } + else + { + clip_x = 0; + clip_y = 0; + clip_width = bitmap->width; + clip_height = bitmap->height; + } + + /* skip if rectangle completely outside bitmap */ + + if (*x + *width <= clip_x || + *y + *height <= clip_y || + *x >= clip_x + clip_width || + *y >= clip_y + clip_height) + return FALSE; + + /* clip if rectangle overlaps bitmap */ + + if (*x < clip_x) + { + *width -= clip_x - *x; + *x = clip_x; + } + else if (*x + *width > clip_x + clip_width) + { + *width = clip_x + clip_width - *x; + } + + if (*y < clip_y) + { + *height -= clip_y - *y; + *y = clip_y; + } + else if (*y + *height > clip_y + clip_height) + { + *height = clip_y + clip_height - *y; + } + + return TRUE; + +#else + + /* skip if rectangle completely outside bitmap */ + + if (*x + *width <= 0 || + *y + *height <= 0 || + *x >= bitmap->width || + *y >= bitmap->height) + return FALSE; + + /* clip if rectangle overlaps bitmap */ + + if (*x < 0) + { + *width += *x; + *x = 0; + } + else if (*x + *width > bitmap->width) + { + *width = bitmap->width - *x; + } + + if (*y < 0) + { + *height += *y; + *y = 0; + } + else if (*y + *height > bitmap->height) + { + *height = bitmap->height - *y; + } + + return TRUE; +#endif +} + void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, int src_x, int src_y, int width, int height, int dst_x, int dst_y) { + int dst_x_unclipped = dst_x; + int dst_y_unclipped = dst_y; + if (DrawingDeactivated(dst_x, dst_y, width, height)) return; #if 1 + if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) || + !InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE)) + return; + + /* source x/y might need adjustment if destination x/y was clipped top/left */ + src_x += dst_x - dst_x_unclipped; + src_y += dst_y - dst_y_unclipped; + +#else /* skip if rectangle starts outside bitmap */ if (src_x >= src_bitmap->width || src_y >= src_bitmap->height || @@ -538,14 +716,17 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, height = dst_bitmap->height - dst_y; #endif -#if 0 +#if 1 + /* !!! 2013-12-11: An "old friend" is back. Same bug in SDL2 2.0.1 !!! */ +#if 1 /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */ /* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13, but is already fixed in SVN and should therefore finally be fixed with the next official SDL release, which is probably version 1.2.14.) */ #if 1 /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */ -#if defined(TARGET_SDL) && defined(PLATFORM_WIN32) + //#if defined(TARGET_SDL) && defined(PLATFORM_WIN32) +#if defined(TARGET_SDL2) if (src_bitmap == dst_bitmap) { /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */ @@ -589,16 +770,56 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, } #endif #endif +#endif +#endif + +#if 0 + if (dst_x < gfx.sx + gfx.sxsize) + printf("::: %d: BlitBitmap(%d, %d, %d, %d)\n", + FrameCounter, dst_x, dst_y, width, height); #endif sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE); } +void BlitBitmapTiled(Bitmap *src_bitmap, Bitmap *dst_bitmap, + int src_x, int src_y, int src_width, int src_height, + int dst_x, int dst_y, int dst_width, int dst_height) +{ + int src_xsize = (src_width == 0 ? src_bitmap->width : src_width); + int src_ysize = (src_height == 0 ? src_bitmap->height : src_height); + int dst_xsize = dst_width; + int dst_ysize = dst_height; + int src_xsteps = (dst_xsize + src_xsize - 1) / src_xsize; + int src_ysteps = (dst_ysize + src_ysize - 1) / src_ysize; + int x, y; + + for (y = 0; y < src_ysteps; y++) + { + for (x = 0; x < src_xsteps; x++) + { + int draw_x = dst_x + x * src_xsize; + int draw_y = dst_y + y * src_ysize; + int draw_xsize = MIN(src_xsize, dst_xsize - x * src_xsize); + int draw_ysize = MIN(src_ysize, dst_ysize - y * src_ysize); + + BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, draw_xsize, draw_ysize, + draw_x, draw_y); + } + } +} + void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, int fade_mode, int fade_delay, int post_delay, void (*draw_border_function)(void)) { +#if 1 + /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */ + if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE)) + return; +#endif + #if defined(TARGET_SDL) SDLFadeRectangle(bitmap_cross, x, y, width, height, fade_mode, fade_delay, post_delay, draw_border_function); @@ -615,6 +836,9 @@ void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height, return; #if 1 + if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE)) + return; +#else /* skip if rectangle starts outside bitmap */ if (x >= bitmap->width || y >= bitmap->height) @@ -808,7 +1032,7 @@ Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color) /* execute all pending screen drawing operations */ void FlushDisplay(void) { -#ifndef TARGET_SDL +#if !defined(TARGET_SDL) XFlush(display); #endif } @@ -816,7 +1040,7 @@ void FlushDisplay(void) /* execute and wait for all pending screen drawing operations */ void SyncDisplay(void) { -#ifndef TARGET_SDL +#if !defined(TARGET_SDL) XSync(display, FALSE); #endif } @@ -824,9 +1048,13 @@ void SyncDisplay(void) void KeyboardAutoRepeatOn(void) { #if defined(TARGET_SDL) +#if defined(TARGET_SDL2) + keyrepeat_status = TRUE; +#else SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2, SDL_DEFAULT_REPEAT_INTERVAL / 2); SDL_EnableUNICODE(1); +#endif #else if (display) XAutoRepeatOn(display); @@ -836,8 +1064,12 @@ void KeyboardAutoRepeatOn(void) void KeyboardAutoRepeatOff(void) { #if defined(TARGET_SDL) +#if defined(TARGET_SDL2) + keyrepeat_status = FALSE; +#else SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); SDL_EnableUNICODE(0); +#endif #else if (display) XAutoRepeatOff(display); @@ -991,7 +1223,9 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, int width_4, height_4; int width_8, height_8; int width_16, height_16; +#if 0 int width_32, height_32; +#endif int new_width, new_height; /* calculate new image dimensions for normal sized image */ @@ -1022,8 +1256,10 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, height_8 = height_1 / 8; width_16 = width_1 / 16; height_16 = height_1 / 16; +#if 0 width_32 = width_1 / 32; height_32 = height_1 / 32; +#endif UPDATE_BUSY_STATE(); @@ -1086,11 +1322,11 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, if (old_bitmap->surface_masked) SDL_FreeSurface(old_bitmap->surface_masked); - SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY, + SDL_SetColorKey(tmp_surface_1, SET_TRANSPARENT_PIXEL, SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00)); if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL) Error(ERR_EXIT, "SDL_DisplayFormat() failed"); - SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */ + SDL_SetColorKey(tmp_surface_1, UNSET_TRANSPARENT_PIXEL, 0); #endif } #endif @@ -1177,11 +1413,11 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, if (old_bitmap->surface_masked) SDL_FreeSurface(old_bitmap->surface_masked); - SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY, + SDL_SetColorKey(old_surface, SET_TRANSPARENT_PIXEL, SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00)); if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL) Error(ERR_EXIT, "SDL_DisplayFormat() failed"); - SDL_SetColorKey(old_surface, 0, 0); /* reset transparent pixel */ + SDL_SetColorKey(old_surface, UNSET_TRANSPARENT_PIXEL, 0); #endif } #endif @@ -1419,10 +1655,14 @@ void SetAudioMode(boolean enabled) void InitEventFilter(EventFilter filter_function) { -#if defined(TARGET_SDL) /* set event filter to filter out certain events */ +#if defined(TARGET_SDL) +#if defined(TARGET_SDL2) + SDL_SetEventFilter(filter_function, NULL); +#else SDL_SetEventFilter(filter_function); #endif +#endif } boolean PendingEvent(void) @@ -1446,7 +1686,11 @@ void NextEvent(Event *event) void PeekEvent(Event *event) { #if defined(TARGET_SDL) +#if defined(TARGET_SDL2) + SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); +#else SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS); +#endif #else XPeekEvent(display, event); #endif @@ -1455,6 +1699,10 @@ void PeekEvent(Event *event) Key GetEventKey(KeyEvent *event, boolean with_modifiers) { #if defined(TARGET_SDL) +#if defined(TARGET_SDL2) + /* key up/down events in SDL2 do not return text characters anymore */ + return event->keysym.sym; +#else #if 0 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n", @@ -1470,6 +1718,7 @@ Key GetEventKey(KeyEvent *event, boolean with_modifiers) else return event->keysym.sym; +#endif #else #if 0