Merge pull request #9334 from Broxzier/feature/1260-transparent-giant-screenshot

Implement #1260: Transparent Giant Screenshots
This commit is contained in:
Michael Steenbeek 2019-06-09 11:34:42 +02:00 committed by GitHub
commit 66b6a2b65c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 171 additions and 133 deletions

View File

@ -3774,6 +3774,8 @@ STR_6323 :Simulating
STR_6324 :Simulate
STR_6325 :{SMALLFONT}{BLACK}Simulate ride/attraction
STR_6326 :Can't simulate {POP16}{POP16}{POP16}{STRINGID}...
STR_6327 :Transparent background for giant screenshots
STR_6328 :{SMALLFONT}{BLACK}With this option enabled, giant screenshots will have a transparent background instead of the default black colour.
#############
# Scenarios #

View File

@ -1,6 +1,7 @@
0.2.2+ (in development)
------------------------------------------------------------------------
- Feature: [#485] Rides can now be simulated with ghost trains during construction.
- Feature: [#1260] Option for making giant screenshots have a transparent background.
- Feature: [#2339] Find local servers automatically when fetching servers.
- Feature: [#7296] Allow assigning a keyboard shortcut for the scenery picker.
- Feature: [#8029] Add the Hungarian Forint (HUF) to the list of available currencies.

View File

@ -97,6 +97,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
WIDX_GRIDLINES_CHECKBOX,
WIDX_UPPER_CASE_BANNERS_CHECKBOX,
WIDX_SHOW_GUEST_PURCHASES_CHECKBOX,
WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX,
WIDX_VIRTUAL_FLOOR_LABEL,
WIDX_VIRTUAL_FLOOR,
WIDX_VIRTUAL_FLOOR_DROPDOWN,
@ -245,16 +246,17 @@ static rct_widget window_options_display_widgets[] = {
static rct_widget window_options_rendering_widgets[] = {
MAIN_OPTIONS_WIDGETS,
#define FRAME_RENDERING_START 53
{ WWT_GROUPBOX, 1, 5, 304, FRAME_RENDERING_START + 0, FRAME_RENDERING_START + 92, STR_RENDERING_GROUP, STR_NONE }, // Rendering group
{ WWT_GROUPBOX, 1, 5, 304, FRAME_RENDERING_START + 0, FRAME_RENDERING_START + 107, STR_RENDERING_GROUP, STR_NONE }, // Rendering group
{ WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 15, FRAME_RENDERING_START + 26, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP }, // Landscape smoothing
{ WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 30, FRAME_RENDERING_START + 41, STR_GRIDLINES, STR_GRIDLINES_TIP }, // Gridlines
{ WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 45, FRAME_RENDERING_START + 56, STR_UPPERCASE_BANNERS, STR_UPPERCASE_BANNERS_TIP }, // Uppercase banners
{ WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 60, FRAME_RENDERING_START + 71, STR_SHOW_GUEST_PURCHASES, STR_SHOW_GUEST_PURCHASES_TIP }, // Guest purchases
{ WWT_LABEL, 1, 10, 290, FRAME_RENDERING_START + 75, FRAME_RENDERING_START + 86, STR_VIRTUAL_FLOOR_STYLE, STR_NONE }, // Virtual floor
{ WWT_DROPDOWN, 1, 155, 299, FRAME_RENDERING_START + 75, FRAME_RENDERING_START + 86, STR_NONE, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown
{ WWT_BUTTON, 1, 288, 298, FRAME_RENDERING_START + 76, FRAME_RENDERING_START + 85, STR_DROPDOWN_GLYPH, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown
{ WWT_CHECKBOX, 1, 10, 290, FRAME_RENDERING_START + 75, FRAME_RENDERING_START + 86, STR_TRANSPARENT_SCREENSHOT, STR_TRANSPARENT_SCREENSHOT_TIP }, // Transparent screenshot
{ WWT_LABEL, 1, 10, 290, FRAME_RENDERING_START + 90, FRAME_RENDERING_START + 101, STR_VIRTUAL_FLOOR_STYLE, STR_NONE }, // Virtual floor
{ WWT_DROPDOWN, 1, 155, 299, FRAME_RENDERING_START + 90, FRAME_RENDERING_START + 101, STR_NONE, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown
{ WWT_BUTTON, 1, 288, 298, FRAME_RENDERING_START + 91, FRAME_RENDERING_START + 100, STR_DROPDOWN_GLYPH, STR_VIRTUAL_FLOOR_STYLE_TIP }, // Virtual floor dropdown
#undef FRAME_RENDERING_START
#define FRAME_EFFECTS_START 148
#define FRAME_EFFECTS_START 163
{ WWT_GROUPBOX, 1, 5, 304, FRAME_EFFECTS_START + 0, FRAME_EFFECTS_START + 78, STR_EFFECTS_GROUP, STR_NONE }, // Rendering group
{ WWT_CHECKBOX, 1, 10, 290, FRAME_EFFECTS_START + 15, FRAME_EFFECTS_START + 26, STR_CYCLE_DAY_NIGHT, STR_CYCLE_DAY_NIGHT_TIP }, // Cycle day-night
{ WWT_CHECKBOX, 1, 25, 290, FRAME_EFFECTS_START + 30, FRAME_EFFECTS_START + 41, STR_ENABLE_LIGHTING_EFFECTS, STR_ENABLE_LIGHTING_EFFECTS_TIP }, // Enable light fx
@ -536,6 +538,7 @@ static uint64_t window_options_page_enabled_widgets[] = {
(1 << WIDX_GRIDLINES_CHECKBOX) |
(1 << WIDX_UPPER_CASE_BANNERS_CHECKBOX) |
(1 << WIDX_SHOW_GUEST_PURCHASES_CHECKBOX) |
(1 << WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX) |
(1 << WIDX_VIRTUAL_FLOOR) |
(1 << WIDX_VIRTUAL_FLOOR_DROPDOWN) |
(1 << WIDX_DAY_NIGHT_CHECKBOX) |
@ -764,6 +767,11 @@ static void window_options_mouseup(rct_window* w, rct_widgetindex widgetIndex)
config_save_default();
window_invalidate(w);
break;
case WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX:
gConfigGeneral.transparent_screenshot ^= 1;
config_save_default();
window_invalidate(w);
break;
}
break;
@ -1731,6 +1739,7 @@ static void window_options_invalidate(rct_window* w)
widget_set_checkbox_value(w, WIDX_GRIDLINES_CHECKBOX, gConfigGeneral.always_show_gridlines);
widget_set_checkbox_value(w, WIDX_DAY_NIGHT_CHECKBOX, gConfigGeneral.day_night_cycle);
widget_set_checkbox_value(w, WIDX_SHOW_GUEST_PURCHASES_CHECKBOX, gConfigGeneral.show_guest_purchases);
widget_set_checkbox_value(w, WIDX_TRANSPARENT_SCREENSHOTS_CHECKBOX, gConfigGeneral.transparent_screenshot);
widget_set_checkbox_value(w, WIDX_UPPER_CASE_BANNERS_CHECKBOX, gConfigGeneral.upper_case_banners);
rct_string_id VirtualFloorStyleStrings[] = { STR_VIRTUAL_FLOOR_STYLE_DISABLED, STR_VIRTUAL_FLOOR_STYLE_TRANSPARENT,

View File

@ -24,6 +24,7 @@ static constexpr const CommandLineOptionDefinition ScreenshotOptionsDef[]
{ CMDLINE_TYPE_SWITCH, &options.fix_vandalism, NAC, "fix-vandalism", "fix vandalism for the screenshot" },
{ CMDLINE_TYPE_SWITCH, &options.remove_litter, NAC, "remove-litter", "remove litter for the screenshot" },
{ CMDLINE_TYPE_SWITCH, &options.tidy_up_park, NAC, "tidy-up-park", "clear grass, water plants, fix vandalism and remove litter" },
{ CMDLINE_TYPE_SWITCH, &options.transparent, NAC, "transparent", "make the background transparent" },
OptionTableEnd
};

View File

@ -208,6 +208,7 @@ namespace Config
model->show_guest_purchases = reader->GetBoolean("show_guest_purchases", false);
model->show_real_names_of_guests = reader->GetBoolean("show_real_names_of_guests", true);
model->allow_early_completion = reader->GetBoolean("allow_early_completion", false);
model->transparent_screenshot = reader->GetBoolean("transparent_screenshot", true);
}
}
@ -281,6 +282,7 @@ namespace Config
writer->WriteBoolean("show_real_names_of_guests", model->show_real_names_of_guests);
writer->WriteBoolean("allow_early_completion", model->allow_early_completion);
writer->WriteEnum<int32_t>("virtual_floor_style", model->virtual_floor_style, Enum_VirtualFloorStyle);
writer->WriteBoolean("transparent_screenshot", model->transparent_screenshot);
}
static void ReadInterface(IIniReader* reader)

View File

@ -46,6 +46,7 @@ struct GeneralConfiguration
bool render_weather_gloom;
bool disable_lightning_effect;
bool show_guest_purchases;
bool transparent_screenshot;
// Localisation
int32_t language;

View File

@ -275,6 +275,12 @@ void screenshot_giant()
dpi.zoom_level = 0;
dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height);
if (gConfigGeneral.transparent_screenshot)
{
std::memset(dpi.bits, PALETTE_INDEX_0, dpi.width * dpi.height);
viewport.flags |= VIEWPORT_FLAG_TRANSPARENT_BACKGROUND;
}
auto drawingEngine = std::make_unique<X8DrawingEngine>(GetContext()->GetUiContext());
dpi.DrawingEngine = drawingEngine.get();
@ -469,139 +475,150 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption
gOpenRCT2Headless = true;
auto context = CreateContext();
if (context->Initialise())
if (!context->Initialise())
{
drawing_engine_init();
std::puts("Failed to initialize context.");
return -1;
}
try
drawing_engine_init();
try
{
context->LoadParkFromFile(inputPath);
}
catch (const std::exception& e)
{
std::printf("%s\n", e.what());
drawing_engine_dispose();
return -1;
}
gIntroState = INTRO_STATE_NONE;
gScreenFlags = SCREEN_FLAGS_PLAYING;
int32_t mapSize = gMapSize;
if (resolutionWidth == 0 || resolutionHeight == 0)
{
resolutionWidth = (mapSize * 32 * 2) >> customZoom;
resolutionHeight = (mapSize * 32 * 1) >> customZoom;
resolutionWidth += 8;
resolutionHeight += 128;
}
rct_viewport viewport;
viewport.x = 0;
viewport.y = 0;
viewport.width = resolutionWidth;
viewport.height = resolutionHeight;
viewport.view_width = viewport.width;
viewport.view_height = viewport.height;
viewport.var_11 = 0;
viewport.flags = 0;
if (customLocation)
{
if (centreMapX)
customX = (mapSize / 2) * 32 + 16;
if (centreMapY)
customY = (mapSize / 2) * 32 + 16;
int32_t z = tile_element_height(customX, customY);
CoordsXYZ coords3d = { customX, customY, z };
CoordsXY coords2d = translate_3d_to_2d_with_z(customRotation, coords3d);
viewport.view_x = coords2d.x - ((viewport.view_width << customZoom) / 2);
viewport.view_y = coords2d.y - ((viewport.view_height << customZoom) / 2);
viewport.zoom = customZoom;
gCurrentRotation = customRotation;
}
else
{
viewport.view_x = gSavedViewX - (viewport.view_width / 2);
viewport.view_y = gSavedViewY - (viewport.view_height / 2);
viewport.zoom = gSavedViewZoom;
gCurrentRotation = gSavedViewRotation;
}
if (options->weather != 0)
{
if (options->weather < 1 || options->weather > 6)
{
context->LoadParkFromFile(inputPath);
}
catch (const std::exception& e)
{
std::printf("%s\n", e.what());
std::printf("Weather can only be set to an integer value from 1 till 6.");
drawing_engine_dispose();
return -1;
}
gIntroState = INTRO_STATE_NONE;
gScreenFlags = SCREEN_FLAGS_PLAYING;
int32_t mapSize = gMapSize;
if (resolutionWidth == 0 || resolutionHeight == 0)
{
resolutionWidth = (mapSize * 32 * 2) >> customZoom;
resolutionHeight = (mapSize * 32 * 1) >> customZoom;
resolutionWidth += 8;
resolutionHeight += 128;
}
rct_viewport viewport;
viewport.x = 0;
viewport.y = 0;
viewport.width = resolutionWidth;
viewport.height = resolutionHeight;
viewport.view_width = viewport.width;
viewport.view_height = viewport.height;
viewport.var_11 = 0;
viewport.flags = 0;
if (customLocation)
{
if (centreMapX)
customX = (mapSize / 2) * 32 + 16;
if (centreMapY)
customY = (mapSize / 2) * 32 + 16;
int32_t z = tile_element_height(customX, customY);
CoordsXYZ coords3d = { customX, customY, z };
CoordsXY coords2d = translate_3d_to_2d_with_z(customRotation, coords3d);
viewport.view_x = coords2d.x - ((viewport.view_width << customZoom) / 2);
viewport.view_y = coords2d.y - ((viewport.view_height << customZoom) / 2);
viewport.zoom = customZoom;
gCurrentRotation = customRotation;
}
else
{
viewport.view_x = gSavedViewX - (viewport.view_width / 2);
viewport.view_y = gSavedViewY - (viewport.view_height / 2);
viewport.zoom = gSavedViewZoom;
gCurrentRotation = gSavedViewRotation;
}
if (options->weather != 0)
{
if (options->weather < 1 || options->weather > 6)
{
std::printf("Weather can only be set to an integer value from 1 till 6.");
drawing_engine_dispose();
return -1;
}
uint8_t customWeather = options->weather - 1;
climate_force_weather(customWeather);
}
// Ensure sprites appear regardless of rotation
reset_all_sprite_quadrant_placements();
rct_drawpixelinfo dpi;
dpi.x = 0;
dpi.y = 0;
dpi.width = resolutionWidth;
dpi.height = resolutionHeight;
dpi.pitch = 0;
dpi.zoom_level = 0;
dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height);
dpi.DrawingEngine = context->GetDrawingEngine();
if (options->hide_guests)
{
viewport.flags |= VIEWPORT_FLAG_INVISIBLE_PEEPS;
}
if (options->hide_sprites)
{
viewport.flags |= VIEWPORT_FLAG_INVISIBLE_SPRITES;
}
if (options->mowed_grass)
{
CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED);
}
if (options->clear_grass || options->tidy_up_park)
{
CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0);
}
if (options->water_plants || options->tidy_up_park)
{
CheatsSet(CheatType::WaterPlants);
}
if (options->fix_vandalism || options->tidy_up_park)
{
CheatsSet(CheatType::FixVandalism);
}
if (options->remove_litter || options->tidy_up_park)
{
CheatsSet(CheatType::RemoveLitter);
}
viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height);
rct_palette renderedPalette;
screenshot_get_rendered_palette(&renderedPalette);
WriteDpiToFile(outputPath, &dpi, renderedPalette);
free(dpi.bits);
drawing_engine_dispose();
uint8_t customWeather = options->weather - 1;
climate_force_weather(customWeather);
}
// Ensure sprites appear regardless of rotation
reset_all_sprite_quadrant_placements();
rct_drawpixelinfo dpi;
dpi.x = 0;
dpi.y = 0;
dpi.width = resolutionWidth;
dpi.height = resolutionHeight;
dpi.pitch = 0;
dpi.zoom_level = 0;
dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height);
dpi.DrawingEngine = context->GetDrawingEngine();
std::memset(dpi.bits, PALETTE_INDEX_0, dpi.width * dpi.height);
if (options->hide_guests)
{
viewport.flags |= VIEWPORT_FLAG_INVISIBLE_PEEPS;
}
if (options->hide_sprites)
{
viewport.flags |= VIEWPORT_FLAG_INVISIBLE_SPRITES;
}
if (options->mowed_grass)
{
CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED);
}
if (options->clear_grass || options->tidy_up_park)
{
CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0);
}
if (options->water_plants || options->tidy_up_park)
{
CheatsSet(CheatType::WaterPlants);
}
if (options->fix_vandalism || options->tidy_up_park)
{
CheatsSet(CheatType::FixVandalism);
}
if (options->remove_litter || options->tidy_up_park)
{
CheatsSet(CheatType::RemoveLitter);
}
if (options->transparent || gConfigGeneral.transparent_screenshot)
{
viewport.flags |= VIEWPORT_FLAG_TRANSPARENT_BACKGROUND;
}
viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height);
rct_palette renderedPalette;
screenshot_get_rendered_palette(&renderedPalette);
WriteDpiToFile(outputPath, &dpi, renderedPalette);
free(dpi.bits);
drawing_engine_dispose();
return 1;
}

View File

@ -28,6 +28,7 @@ struct ScreenshotOptions
bool fix_vandalism = false;
bool remove_litter = false;
bool tidy_up_park = false;
bool transparent = false;
};
void screenshot_check();

View File

@ -46,6 +46,7 @@ enum
VIEWPORT_FLAG_SEETHROUGH_PATHS = (1 << 16),
VIEWPORT_FLAG_CLIP_VIEW = (1 << 17),
VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES = (1 << 18),
VIEWPORT_FLAG_TRANSPARENT_BACKGROUND = (1 << 19),
};
enum

View File

@ -3962,6 +3962,9 @@ enum
STR_SIMULATE_RIDE_TIP = 6325,
STR_CANT_SIMULATE = 6326,
STR_TRANSPARENT_SCREENSHOT = 6327,
STR_TRANSPARENT_SCREENSHOT_TIP = 6328,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
STR_COUNT = 32768
};

View File

@ -57,7 +57,7 @@ void tile_element_paint_setup(paint_session* session, int32_t x, int32_t y)
sub_68B3FB(session, x, y);
}
else
else if (!(session->ViewFlags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND))
{
blank_tiles_paint(session, x, y);
}
@ -78,7 +78,7 @@ void sub_68B2B7(paint_session* session, int32_t x, int32_t y)
sub_68B3FB(session, x, y);
}
else
else if (!(session->ViewFlags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND))
{
blank_tiles_paint(session, x, y);
}