+ program.sdl_icon_filename = sdl_icon_filename;
+ program.msdos_cursor_filename = msdos_cursor_filename;
+
+ program.cookie_prefix = cookie_prefix;
+ program.filename_prefix = filename_prefix;
+
+ program.version_major = VERSION_MAJOR(program_version);
+ program.version_minor = VERSION_MINOR(program_version);
+ program.version_patch = VERSION_PATCH(program_version);
+
+ program.error_filename = getErrorFilename(ERROR_BASENAME);
+ program.error_file = stderr;
+}
+
+void InitExitFunction(void (*exit_function)(int))
+{
+ program.exit_function = exit_function;
+
+ /* set signal handlers to custom exit function */
+ signal(SIGINT, exit_function);
+ signal(SIGTERM, exit_function);
+
+#if defined(TARGET_SDL)
+ /* set exit function to automatically cleanup SDL stuff after exit() */
+ atexit(SDL_Quit);
+#endif
+}
+
+void InitPlatformDependentStuff(void)
+{
+#if defined(PLATFORM_MSDOS)
+ _fmode = O_BINARY;
+#endif
+
+#if defined(PLATFORM_MACOSX)
+ updateUserGameDataDir();
+#endif
+
+#if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX)
+ openErrorFile();
+#endif
+
+#if defined(TARGET_SDL)
+ if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
+ Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
+
+ SDLNet_Init();
+#endif
+}
+
+void ClosePlatformDependentStuff(void)
+{
+#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
+ closeErrorFile();
+#endif
+
+#if defined(PLATFORM_MSDOS)
+ dumpErrorFile();
+#endif
+}
+
+void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
+ int real_sx, int real_sy,
+ int full_sxsize, int full_sysize,
+ Bitmap *field_save_buffer)
+{
+ gfx.sx = sx;
+ gfx.sy = sy;
+ gfx.sxsize = sxsize;
+ gfx.sysize = sysize;
+ gfx.real_sx = real_sx;
+ gfx.real_sy = real_sy;
+ gfx.full_sxsize = full_sxsize;
+ gfx.full_sysize = full_sysize;
+
+ gfx.field_save_buffer = field_save_buffer;
+
+ gfx.background_bitmap = NULL;
+ gfx.background_bitmap_mask = REDRAW_NONE;
+
+ SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
+ SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
+}
+
+void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
+{
+ gfx.dx = dx;
+ gfx.dy = dy;
+ gfx.dxsize = dxsize;
+ gfx.dysize = dysize;
+}
+
+void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
+{
+ gfx.vx = vx;
+ gfx.vy = vy;
+ gfx.vxsize = vxsize;
+ gfx.vysize = vysize;
+}
+
+void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
+{
+ /* currently only used by MSDOS code to alloc VRAM buffer, if available */
+ gfx.scrollbuffer_width = scrollbuffer_width;
+ gfx.scrollbuffer_height = scrollbuffer_height;
+}
+
+void SetDrawDeactivationMask(int draw_deactivation_mask)
+{
+ gfx.draw_deactivation_mask = draw_deactivation_mask;
+}
+
+void SetDrawBackgroundMask(int draw_background_mask)
+{
+ gfx.draw_background_mask = draw_background_mask;
+}
+
+static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
+ int dest_x, int dest_y, int width, int height)
+{
+ int bitmap_xsize = width;
+ int bitmap_ysize = height;
+ int tile_xsize = tile->width;
+ int tile_ysize = tile->height;
+ int tile_xsteps = (bitmap_xsize + tile_xsize - 1) / tile_xsize;
+ int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
+ int x, y;
+
+ for (y = 0; y < tile_ysteps; y++)
+ {
+ for (x = 0; x < tile_xsteps; x++)
+ {
+ int draw_x = dest_x + x * tile_xsize;
+ int draw_y = dest_y + y * tile_ysize;
+ int draw_xsize = MIN(tile_xsize, bitmap_xsize - x * tile_xsize);
+ int draw_ysize = MIN(tile_ysize, bitmap_ysize - y * tile_ysize);
+
+ BlitBitmap(tile, bitmap, 0, 0, draw_xsize, draw_ysize, draw_x, draw_y);
+ }
+ }
+}
+
+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 (gfx.background_bitmap == NULL)
+ gfx.background_bitmap = CreateBitmap(video.width, video.height,
+ DEFAULT_DEPTH);
+
+ if (background_bitmap_tile == NULL) /* empty background requested */
+ return;
+
+ if (mask == REDRAW_FIELD)
+ DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
+ 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);
+ }
+}
+
+void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
+{
+ SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
+}
+
+void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
+{
+ SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
+}
+
+
+/* ========================================================================= */
+/* video functions */
+/* ========================================================================= */
+
+inline static int GetRealDepth(int depth)
+{
+ return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
+}
+
+inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
+ int width, int height, Pixel color)
+{
+#if defined(TARGET_SDL)
+ SDLFillRectangle(bitmap, x, y, width, height, color);
+#else
+ X11FillRectangle(bitmap, x, y, width, height, color);
+#endif