{ "viewport.window.width", "672" },
{ "viewport.window.height", "560" },
+ { "viewport.window.min_width", "-1" },
+ { "viewport.window.min_height", "-1" },
+ { "viewport.window.max_width", "-1" },
+ { "viewport.window.max_height", "-1" },
{ "viewport.window.TITLE.width", ARG_DEFAULT },
{ "viewport.window.TITLE.height", ARG_DEFAULT },
{ "viewport.playfield.y", "6" },
{ "viewport.playfield.width", "548" },
{ "viewport.playfield.height", "548" },
+ { "viewport.playfield.min_width", "-1" },
+ { "viewport.playfield.min_height", "-1" },
+ { "viewport.playfield.max_width", "-1" },
+ { "viewport.playfield.max_height", "-1" },
+ { "viewport.playfield.margin_left", "0" },
+ { "viewport.playfield.margin_right", "0" },
+ { "viewport.playfield.margin_top", "0" },
+ { "viewport.playfield.margin_bottom", "0" },
+ { "viewport.playfield.border_left", "-1" },
+ { "viewport.playfield.border_right", "-1" },
+ { "viewport.playfield.border_top", "-1" },
+ { "viewport.playfield.border_bottom", "-1" },
{ "viewport.playfield.border_size", "2" },
+ { "viewport.playfield.align_size", "16" },
+ { "viewport.playfield.align", "left" },
+ { "viewport.playfield.valign", "top" },
{ "viewport.playfield.MAIN.x", ARG_DEFAULT },
{ "viewport.playfield.MAIN.y", ARG_DEFAULT },
{ "viewport.playfield.MAIN.width", ARG_DEFAULT },
{ "viewport.playfield.MAIN.height", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.min_width", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.min_height", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.max_width", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.max_height", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.margin_left", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.margin_right", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.margin_top", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.margin_bottom", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.border_left", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.border_right", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.border_top", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.border_bottom", ARG_DEFAULT },
{ "viewport.playfield.MAIN.border_size", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.align_size", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.align", ARG_DEFAULT },
+ { "viewport.playfield.MAIN.valign", ARG_DEFAULT },
{ "viewport.playfield.SCORES.x", ARG_DEFAULT },
{ "viewport.playfield.SCORES.y", ARG_DEFAULT },
{ "viewport.playfield.SCORES.width", ARG_DEFAULT },
{ "viewport.playfield.SCORES.height", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.min_width", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.min_height", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.max_width", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.max_height", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.margin_left", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.margin_right", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.margin_top", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.margin_bottom", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.border_left", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.border_right", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.border_top", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.border_bottom", ARG_DEFAULT },
{ "viewport.playfield.SCORES.border_size", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.align_size", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.align", ARG_DEFAULT },
+ { "viewport.playfield.SCORES.valign", ARG_DEFAULT },
{ "viewport.playfield.EDITOR.x", ARG_DEFAULT },
{ "viewport.playfield.EDITOR.y", ARG_DEFAULT },
{ "viewport.playfield.EDITOR.width", ARG_DEFAULT },
{ "viewport.playfield.EDITOR.height", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.min_width", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.min_height", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.max_width", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.max_height", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.margin_left", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.margin_right", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.margin_top", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.margin_bottom", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.border_left", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.border_right", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.border_top", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.border_bottom", ARG_DEFAULT },
{ "viewport.playfield.EDITOR.border_size", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.align_size", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.align", ARG_DEFAULT },
+ { "viewport.playfield.EDITOR.valign", ARG_DEFAULT },
{ "viewport.playfield.PLAYING.x", ARG_DEFAULT },
{ "viewport.playfield.PLAYING.y", ARG_DEFAULT },
{ "viewport.playfield.PLAYING.width", ARG_DEFAULT },
{ "viewport.playfield.PLAYING.height", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.min_width", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.min_height", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.max_width", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.max_height", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.margin_left", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.margin_right", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.margin_top", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.margin_bottom", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.border_left", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.border_right", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.border_top", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.border_bottom", ARG_DEFAULT },
{ "viewport.playfield.PLAYING.border_size", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.align_size", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.align", ARG_DEFAULT },
+ { "viewport.playfield.PLAYING.valign", ARG_DEFAULT },
{ "viewport.door_1.x", "566" },
{ "viewport.door_1.y", "60" },
{ "viewport.door_1.width", "100" },
{ "viewport.door_1.height", "280" },
{ "viewport.door_1.border_size", "4" },
+ { "viewport.door_1.align", "left" },
+ { "viewport.door_1.valign", "top" },
{ "viewport.door_1.MAIN.x", ARG_DEFAULT },
{ "viewport.door_1.MAIN.y", ARG_DEFAULT },
{ "viewport.door_1.MAIN.width", ARG_DEFAULT },
{ "viewport.door_1.MAIN.height", ARG_DEFAULT },
{ "viewport.door_1.MAIN.border_size", ARG_DEFAULT },
+ { "viewport.door_1.MAIN.align", ARG_DEFAULT },
+ { "viewport.door_1.MAIN.valign", ARG_DEFAULT },
{ "viewport.door_1.SCORES.x", ARG_DEFAULT },
{ "viewport.door_1.SCORES.y", ARG_DEFAULT },
{ "viewport.door_1.SCORES.width", ARG_DEFAULT },
{ "viewport.door_1.SCORES.height", ARG_DEFAULT },
{ "viewport.door_1.SCORES.border_size", ARG_DEFAULT },
+ { "viewport.door_1.SCORES.align", ARG_DEFAULT },
+ { "viewport.door_1.SCORES.valign", ARG_DEFAULT },
{ "viewport.door_1.EDITOR.x", ARG_DEFAULT },
{ "viewport.door_1.EDITOR.y", ARG_DEFAULT },
{ "viewport.door_1.EDITOR.width", ARG_DEFAULT },
{ "viewport.door_1.EDITOR.height", ARG_DEFAULT },
{ "viewport.door_1.EDITOR.border_size", ARG_DEFAULT },
+ { "viewport.door_1.EDITOR.align", ARG_DEFAULT },
+ { "viewport.door_1.EDITOR.valign", ARG_DEFAULT },
{ "viewport.door_1.PLAYING.x", ARG_DEFAULT },
{ "viewport.door_1.PLAYING.y", ARG_DEFAULT },
{ "viewport.door_1.PLAYING.width", ARG_DEFAULT },
{ "viewport.door_1.PLAYING.height", ARG_DEFAULT },
{ "viewport.door_1.PLAYING.border_size", ARG_DEFAULT },
+ { "viewport.door_1.PLAYING.align", ARG_DEFAULT },
+ { "viewport.door_1.PLAYING.valign", ARG_DEFAULT },
{ "viewport.door_2.x", "566" },
{ "viewport.door_2.y", "400" },
{ "viewport.door_2.width", "100" },
{ "viewport.door_2.height", "100" },
{ "viewport.door_2.border_size", "4" },
+ { "viewport.door_2.align", "left" },
+ { "viewport.door_2.valign", "top" },
{ "viewport.door_2.MAIN.x", ARG_DEFAULT },
{ "viewport.door_2.MAIN.y", ARG_DEFAULT },
{ "viewport.door_2.MAIN.width", ARG_DEFAULT },
{ "viewport.door_2.MAIN.height", ARG_DEFAULT },
{ "viewport.door_2.MAIN.border_size", ARG_DEFAULT },
+ { "viewport.door_2.MAIN.align", ARG_DEFAULT },
+ { "viewport.door_2.MAIN.valign", ARG_DEFAULT },
{ "viewport.door_2.SCORES.x", ARG_DEFAULT },
{ "viewport.door_2.SCORES.y", ARG_DEFAULT },
{ "viewport.door_2.SCORES.width", ARG_DEFAULT },
{ "viewport.door_2.SCORES.height", ARG_DEFAULT },
{ "viewport.door_2.SCORES.border_size", ARG_DEFAULT },
+ { "viewport.door_2.SCORES.align", ARG_DEFAULT },
+ { "viewport.door_2.SCORES.valign", ARG_DEFAULT },
{ "viewport.door_2.EDITOR.x", "566" },
{ "viewport.door_2.EDITOR.y", "356" },
{ "viewport.door_2.EDITOR.width", "100" },
{ "viewport.door_2.EDITOR.height", "144" },
{ "viewport.door_2.EDITOR.border_size", "4" },
+ { "viewport.door_2.EDITOR.align", "left" },
+ { "viewport.door_2.EDITOR.valign", "top" },
{ "viewport.door_2.PLAYING.x", ARG_DEFAULT },
{ "viewport.door_2.PLAYING.y", ARG_DEFAULT },
{ "viewport.door_2.PLAYING.width", ARG_DEFAULT },
{ "viewport.door_2.PLAYING.height", ARG_DEFAULT },
{ "viewport.door_2.PLAYING.border_size", ARG_DEFAULT },
+ { "viewport.door_2.PLAYING.align", ARG_DEFAULT },
+ { "viewport.door_2.PLAYING.valign", ARG_DEFAULT },
{ NULL, NULL }
};
{ NULL, NULL }
};
- int i;
+ int i, j;
// special case: initialize later added SETUP list size from LEVELS value
if (menu.list_size[GAME_MODE_SETUP] == -1)
if ((*game_buttons_xy[i].dst).x == -1 &&
(*game_buttons_xy[i].dst).y == -1)
*game_buttons_xy[i].dst = *game_buttons_xy[i].src;
+
+ // --------------------------------------------------------------------------
+ // dynamic viewports (including playfield margins, borders and alignments)
+ // --------------------------------------------------------------------------
+
+ // dynamic viewports currently only supported for landscape mode
+ int display_width = MAX(video.display_width, video.display_height);
+ int display_height = MIN(video.display_width, video.display_height);
+
+ for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+ {
+ struct RectWithBorder *vp_window = &viewport.window[i];
+ struct RectWithBorder *vp_playfield = &viewport.playfield[i];
+ struct RectWithBorder *vp_door_1 = &viewport.door_1[i];
+ struct RectWithBorder *vp_door_2 = &viewport.door_2[i];
+ boolean dynamic_window_width = (vp_window->min_width != -1);
+ boolean dynamic_window_height = (vp_window->min_height != -1);
+ boolean dynamic_playfield_width = (vp_playfield->min_width != -1);
+ boolean dynamic_playfield_height = (vp_playfield->min_height != -1);
+
+ // adjust window size if min/max width/height is specified
+
+ if (vp_window->min_width != -1)
+ {
+ int window_width = display_width;
+
+ // when using static window height, use aspect ratio of display
+ if (vp_window->min_height == -1)
+ window_width = vp_window->height * display_width / display_height;
+
+ vp_window->width = MAX(vp_window->min_width, window_width);
+ }
+
+ if (vp_window->min_height != -1)
+ {
+ int window_height = display_height;
+
+ // when using static window width, use aspect ratio of display
+ if (vp_window->min_width == -1)
+ window_height = vp_window->width * display_height / display_width;
+
+ vp_window->height = MAX(vp_window->min_height, window_height);
+ }
+
+ if (vp_window->max_width != -1)
+ vp_window->width = MIN(vp_window->width, vp_window->max_width);
+
+ if (vp_window->max_height != -1)
+ vp_window->height = MIN(vp_window->height, vp_window->max_height);
+
+ int playfield_width = vp_window->width;
+ int playfield_height = vp_window->height;
+
+ // adjust playfield size and position according to specified margins
+
+ playfield_width -= vp_playfield->margin_left;
+ playfield_width -= vp_playfield->margin_right;
+
+ playfield_height -= vp_playfield->margin_top;
+ playfield_height -= vp_playfield->margin_bottom;
+
+ // adjust playfield size if min/max width/height is specified
+
+ if (vp_playfield->min_width != -1)
+ vp_playfield->width = MAX(vp_playfield->min_width, playfield_width);
+
+ if (vp_playfield->min_height != -1)
+ vp_playfield->height = MAX(vp_playfield->min_height, playfield_height);
+
+ if (vp_playfield->max_width != -1)
+ vp_playfield->width = MIN(vp_playfield->width, vp_playfield->max_width);
+
+ if (vp_playfield->max_height != -1)
+ vp_playfield->height = MIN(vp_playfield->height,vp_playfield->max_height);
+
+ // adjust playfield position according to specified alignment
+
+ if (vp_playfield->align == ALIGN_LEFT || vp_playfield->x > 0)
+ vp_playfield->x = ALIGNED_VP_XPOS(vp_playfield);
+ else if (vp_playfield->align == ALIGN_CENTER)
+ vp_playfield->x = playfield_width / 2 - vp_playfield->width / 2;
+ else if (vp_playfield->align == ALIGN_RIGHT)
+ vp_playfield->x += playfield_width - vp_playfield->width;
+
+ if (vp_playfield->valign == VALIGN_TOP || vp_playfield->y > 0)
+ vp_playfield->y = ALIGNED_VP_YPOS(vp_playfield);
+ else if (vp_playfield->valign == VALIGN_MIDDLE)
+ vp_playfield->y = playfield_height / 2 - vp_playfield->height / 2;
+ else if (vp_playfield->valign == VALIGN_BOTTOM)
+ vp_playfield->y += playfield_height - vp_playfield->height;
+
+ vp_playfield->x += vp_playfield->margin_left;
+ vp_playfield->y += vp_playfield->margin_top;
+
+ // adjust individual playfield borders if only default border is specified
+
+ if (vp_playfield->border_left == -1)
+ vp_playfield->border_left = vp_playfield->border_size;
+ if (vp_playfield->border_right == -1)
+ vp_playfield->border_right = vp_playfield->border_size;
+ if (vp_playfield->border_top == -1)
+ vp_playfield->border_top = vp_playfield->border_size;
+ if (vp_playfield->border_bottom == -1)
+ vp_playfield->border_bottom = vp_playfield->border_size;
+
+ // set dynamic playfield borders if borders are specified as undefined
+ // (but only if window size was dynamic and playfield size was static)
+
+ if (dynamic_window_width && !dynamic_playfield_width)
+ {
+ if (vp_playfield->border_left == -1)
+ {
+ vp_playfield->border_left = (vp_playfield->x -
+ vp_playfield->margin_left);
+ vp_playfield->x -= vp_playfield->border_left;
+ vp_playfield->width += vp_playfield->border_left;
+ }
+
+ if (vp_playfield->border_right == -1)
+ {
+ vp_playfield->border_right = (vp_window->width -
+ vp_playfield->x -
+ vp_playfield->width -
+ vp_playfield->margin_right);
+ vp_playfield->width += vp_playfield->border_right;
+ }
+ }
+
+ if (dynamic_window_height && !dynamic_playfield_height)
+ {
+ if (vp_playfield->border_top == -1)
+ {
+ vp_playfield->border_top = (vp_playfield->y -
+ vp_playfield->margin_top);
+ vp_playfield->y -= vp_playfield->border_top;
+ vp_playfield->height += vp_playfield->border_top;
+ }
+
+ if (vp_playfield->border_bottom == -1)
+ {
+ vp_playfield->border_bottom = (vp_window->height -
+ vp_playfield->y -
+ vp_playfield->height -
+ vp_playfield->margin_bottom);
+ vp_playfield->height += vp_playfield->border_bottom;
+ }
+ }
+
+ // adjust playfield size to be a multiple of a defined alignment tile size
+
+ int align_size = vp_playfield->align_size;
+ int playfield_xtiles = vp_playfield->width / align_size;
+ int playfield_ytiles = vp_playfield->height / align_size;
+ int playfield_width_corrected = playfield_xtiles * align_size;
+ int playfield_height_corrected = playfield_ytiles * align_size;
+ boolean is_playfield_mode = (i == GFX_SPECIAL_ARG_PLAYING ||
+ i == GFX_SPECIAL_ARG_EDITOR);
+
+ if (is_playfield_mode &&
+ dynamic_playfield_width &&
+ vp_playfield->width != playfield_width_corrected)
+ {
+ int playfield_xdiff = vp_playfield->width - playfield_width_corrected;
+
+ vp_playfield->width = playfield_width_corrected;
+
+ if (vp_playfield->align == ALIGN_LEFT)
+ {
+ vp_playfield->border_left += playfield_xdiff;
+ }
+ else if (vp_playfield->align == ALIGN_RIGHT)
+ {
+ vp_playfield->border_right += playfield_xdiff;
+ }
+ else if (vp_playfield->align == ALIGN_CENTER)
+ {
+ int border_left_diff = playfield_xdiff / 2;
+ int border_right_diff = playfield_xdiff - border_left_diff;
+
+ vp_playfield->border_left += border_left_diff;
+ vp_playfield->border_right += border_right_diff;
+ }
+ }
+
+ if (is_playfield_mode &&
+ dynamic_playfield_height &&
+ vp_playfield->height != playfield_height_corrected)
+ {
+ int playfield_ydiff = vp_playfield->height - playfield_height_corrected;
+
+ vp_playfield->height = playfield_height_corrected;
+
+ if (vp_playfield->valign == VALIGN_TOP)
+ {
+ vp_playfield->border_top += playfield_ydiff;
+ }
+ else if (vp_playfield->align == VALIGN_BOTTOM)
+ {
+ vp_playfield->border_right += playfield_ydiff;
+ }
+ else if (vp_playfield->align == VALIGN_MIDDLE)
+ {
+ int border_top_diff = playfield_ydiff / 2;
+ int border_bottom_diff = playfield_ydiff - border_top_diff;
+
+ vp_playfield->border_top += border_top_diff;
+ vp_playfield->border_bottom += border_bottom_diff;
+ }
+ }
+
+ // adjust door positions according to specified alignment
+
+ for (j = 0; j < 2; j++)
+ {
+ struct RectWithBorder *vp_door = (j == 0 ? vp_door_1 : vp_door_2);
+
+ if (vp_door->align == ALIGN_LEFT || vp_door->x > 0)
+ vp_door->x = ALIGNED_VP_XPOS(vp_door);
+ else if (vp_door->align == ALIGN_CENTER)
+ vp_door->x = vp_window->width / 2 - vp_door->width / 2;
+ else if (vp_door->align == ALIGN_RIGHT)
+ vp_door->x += vp_window->width - vp_door->width;
+
+ if (vp_door->valign == VALIGN_TOP || vp_door->y > 0)
+ vp_door->y = ALIGNED_VP_YPOS(vp_door);
+ else if (vp_door->valign == VALIGN_MIDDLE)
+ vp_door->y = vp_window->height / 2 - vp_door->height / 2;
+ else if (vp_door->valign == VALIGN_BOTTOM)
+ vp_door->y += vp_window->height - vp_door->height;
+ }
+ }
}
static void InitMenuDesignSettings_SpecialPostProcessing_AfterGraphics(void)
{ ".y", &vp_struct[j].struct_ptr->y },
{ ".width", &vp_struct[j].struct_ptr->width },
{ ".height", &vp_struct[j].struct_ptr->height },
- { ".border_size", &vp_struct[j].struct_ptr->border_size }
+ { ".min_width", &vp_struct[j].struct_ptr->min_width },
+ { ".min_height", &vp_struct[j].struct_ptr->min_height },
+ { ".max_width", &vp_struct[j].struct_ptr->max_width },
+ { ".max_height", &vp_struct[j].struct_ptr->max_height },
+ { ".margin_left", &vp_struct[j].struct_ptr->margin_left },
+ { ".margin_right", &vp_struct[j].struct_ptr->margin_right },
+ { ".margin_top", &vp_struct[j].struct_ptr->margin_top },
+ { ".margin_bottom", &vp_struct[j].struct_ptr->margin_bottom },
+ { ".border_left", &vp_struct[j].struct_ptr->border_left },
+ { ".border_right", &vp_struct[j].struct_ptr->border_right },
+ { ".border_top", &vp_struct[j].struct_ptr->border_top },
+ { ".border_bottom", &vp_struct[j].struct_ptr->border_bottom },
+ { ".border_size", &vp_struct[j].struct_ptr->border_size },
+ { ".align_size", &vp_struct[j].struct_ptr->align_size },
+ { ".align", &vp_struct[j].struct_ptr->align },
+ { ".valign", &vp_struct[j].struct_ptr->valign }
};
for (k = 0; k < ARRAY_SIZE(vp_config); k++)