+void getSizedGraphicSourceExt(int graphic, int frame, int tilesize_raw,
+ Bitmap **bitmap, int *x, int *y,
+ boolean get_backside)
+{
+ struct
+ {
+ int width_mult, width_div;
+ int height_mult, height_div;
+ }
+ offset_calc[6] =
+ {
+ { 15, 16, 2, 3 }, /* 1 x 1 */
+ { 7, 8, 2, 3 }, /* 2 x 2 */
+ { 3, 4, 2, 3 }, /* 4 x 4 */
+ { 1, 2, 2, 3 }, /* 8 x 8 */
+ { 0, 1, 2, 3 }, /* 16 x 16 */
+ { 0, 1, 0, 1 }, /* 32 x 32 */
+ };
+ struct GraphicInfo *g = &graphic_info[graphic];
+ Bitmap *src_bitmap = g->bitmap;
+ int tilesize = MIN(MAX(1, tilesize_raw), TILESIZE);
+ int offset_calc_pos = log_2(tilesize);
+ int bitmap_width = src_bitmap->width;
+ int bitmap_height = src_bitmap->height;
+ int width_mult = offset_calc[offset_calc_pos].width_mult;
+ int width_div = offset_calc[offset_calc_pos].width_div;
+ int height_mult = offset_calc[offset_calc_pos].height_mult;
+ int height_div = offset_calc[offset_calc_pos].height_div;
+ int startx = bitmap_width * width_mult / width_div;
+ int starty = bitmap_height * height_mult / height_div;
+ int src_x = (g->src_x + (get_backside ? g->offset2_x : 0)) *
+ tilesize_raw / TILESIZE;
+ int src_y = (g->src_y + (get_backside ? g->offset2_y : 0)) *
+ tilesize_raw / TILESIZE;
+ int width = g->width * tilesize_raw / TILESIZE;
+ int height = g->height * tilesize_raw / TILESIZE;
+ int offset_x = g->offset_x * tilesize_raw / TILESIZE;
+ int offset_y = g->offset_y * tilesize_raw / TILESIZE;
+
+ if (game.tile_size != TILESIZE)
+ {
+ int bitmap_width_std =
+ bitmap_width * TILESIZE / (TILESIZE + game.tile_size);
+ int bitmap_height_std =
+ bitmap_height * TILESIZE / game.tile_size * 3 / 2;
+
+ if (tilesize_raw == game.tile_size)
+ {
+ startx = bitmap_width_std;
+ starty = 0;
+ }
+ else
+ {
+ bitmap_width = bitmap_width_std;
+
+ if (game.tile_size > TILESIZE * 3 / 2)
+ bitmap_height = bitmap_height_std;
+
+ startx = bitmap_width * width_mult / width_div;
+ starty = bitmap_height * height_mult / height_div;
+ }
+ }
+
+ if (g->offset_y == 0) /* frames are ordered horizontally */
+ {
+ int max_width = g->anim_frames_per_line * width;
+ int pos = (src_y / height) * max_width + src_x + frame * offset_x;
+
+ src_x = pos % max_width;
+ src_y = src_y % height + pos / max_width * height;
+ }
+ else if (g->offset_x == 0) /* frames are ordered vertically */
+ {
+ int max_height = g->anim_frames_per_line * height;
+ int pos = (src_x / width) * max_height + src_y + frame * offset_y;
+
+ src_x = src_x % width + pos / max_height * width;
+ src_y = pos % max_height;
+ }
+ else /* frames are ordered diagonally */
+ {
+ src_x = src_x + frame * offset_x;
+ src_y = src_y + frame * offset_y;
+ }
+
+ *bitmap = src_bitmap;
+ *x = startx + src_x;
+ *y = starty + src_y;
+}
+
+void getFixedGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
+ int *x, int *y, boolean get_backside)
+{
+ getSizedGraphicSourceExt(graphic, frame, TILESIZE, bitmap, x, y,
+ get_backside);
+}
+
+void getSizedGraphicSource(int graphic, int frame, int tilesize_raw,
+ Bitmap **bitmap, int *x, int *y)
+{
+ getSizedGraphicSourceExt(graphic, frame, tilesize_raw, bitmap, x, y, FALSE);
+}
+
+void getFixedGraphicSource(int graphic, int frame,
+ Bitmap **bitmap, int *x, int *y)
+{
+ getSizedGraphicSourceExt(graphic, frame, TILESIZE, bitmap, x, y, FALSE);
+}
+
+void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+{
+ getSizedGraphicSource(graphic, 0, MINI_TILESIZE, bitmap, x, y);
+}
+