slang-shaders/bezel/Mega_Bezel/shaders/base/common/base-functions.inc
2022-10-10 16:26:21 -04:00

324 lines
11 KiB
SourcePawn

/*
Mega Bezel - Creates a graphic treatment for the game play area to give a retro feel
Copyright (C) 2019-2022 HyperspaceMadness - HyperspaceMadness@outlook.com
Incorporates much great feedback from the libretro forum, and thanks
to Hunterk who helped me get started
See more at the libretro forum
https://forums.libretro.com/t/hsm-mega-bezel-reflection-shader-feedback-and-updates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see [http://www.gnu.org/licenses/].
*/
// Returns 1 for vertical split, 2 for horizontal split
float HSM_GetCoreImageSplitDirection()
{
float core_image_split_direction = 1;
if (HSM_DUALSCREEN_CORE_IMAGE_SPLIT_MODE == 0)
{
if (HSM_DUALSCREEN_MODE == 1)
core_image_split_direction = 1;
if (HSM_DUALSCREEN_MODE == 2)
core_image_split_direction = 2;
}
else
{
core_image_split_direction = HSM_DUALSCREEN_CORE_IMAGE_SPLIT_MODE;
}
return core_image_split_direction;
}
vec2 HSM_GetCoordWithPositionOffset(vec2 in_coord, vec2 position_offset)
{
return in_coord - position_offset;
}
vec2 HSM_GetInverseScaledCoord(vec2 in_coord, vec2 in_scale)
{
vec2 middle = vec2(0.49999, 0.49999);
vec2 diff = in_coord.xy - middle;
vec2 screen_inverse_scale = 1.0 / in_scale;
vec2 scaled_coord = middle + diff * screen_inverse_scale;
return scaled_coord;
}
vec2 HSM_GetVTexCoordWithArgs(vec2 in_coord, vec2 in_scale, vec2 position_offset)
{
return HSM_GetInverseScaledCoord(HSM_GetCoordWithPositionOffset(in_coord, position_offset), in_scale);
}
// Rows and Columns are 1 based
vec4 HSM_GetCacheSampleRange(float column_index, float row_index)
{
float num_rows = 8;
float num_columns = 8;
float range_width = 1 / num_columns;
float range_height = 1 / num_rows;
float zero_based_row_index = row_index - 1;
float zero_based_column_index = column_index - 1;
vec4 out_sample_range = vec4(0);
out_sample_range.x = zero_based_column_index * range_width;
out_sample_range.y = zero_based_row_index * range_height;
out_sample_range.z = out_sample_range.x + range_width;
out_sample_range.w = out_sample_range.y + range_height;
return out_sample_range;
}
vec2 HSM_GetCacheSampleCoord(float column_index, float row_index)
{
float num_rows = 8;
float num_columns = 8;
float range_width = 1 / num_columns;
float range_height = 1 / num_rows;
vec4 sample_range = HSM_GetCacheSampleRange(column_index, row_index);
return vec2(sample_range.x + range_width/2, sample_range.y + range_height/2);
}
vec2 HSM_GetViewportCoordWithFlip(vec2 viewport_coord)
{
vec2 out_coord = viewport_coord;
// out_coord.y = HSM_FLIP_VIEWPORT_VERTICAL * (out_coord.y - 0.5) + 0.5;
// out_coord.x = HSM_FLIP_VIEWPORT_HORIZONTAL * (out_coord.x - 0.5) + 0.5;
if (HSM_FLIP_VIEWPORT_VERTICAL == -1)
out_coord.y = 1 - out_coord.y;
if (HSM_FLIP_VIEWPORT_HORIZONTAL == -1)
out_coord.x = 1 - out_coord.x;
return out_coord;
}
vec2 HSM_GetViewportCoordWithZoomAndPan(vec2 viewport_coord)
{
vec2 out_coord = HSM_GetViewportCoordWithFlip(viewport_coord);
out_coord = (out_coord - 0.5) / HSM_VIEWPORT_ZOOM + 0.5;
out_coord.x += HSM_VIEWPORT_POSITION_X;
out_coord.y -= HSM_VIEWPORT_POSITION_Y;
return out_coord;
}
float HSM_GetScreenIndex(vec2 viewport_coord)
{
float out_index = 1;
float output_aspect = global.FinalViewportSize.x / global.FinalViewportSize.y;
if (HSM_DUALSCREEN_MODE == 0)
out_index = 1;
if (HSM_DUALSCREEN_MODE == 1)
out_index = (viewport_coord.y < 0.5 + HSM_DUALSCREEN_VIEWPORT_SPLIT_LOCATION / output_aspect) ? 1 : 2;
if (HSM_DUALSCREEN_MODE == 2)
out_index = (viewport_coord.x < 0.5 + HSM_DUALSCREEN_VIEWPORT_SPLIT_LOCATION / output_aspect) ? 1 : 2;
return out_index;
}
vec4 HSM_UpdateGlobalScreenValuesFromCache(sampler2D in_cache_pass, vec2 vTexCoord)
{
float output_aspect = global.FinalViewportSize.x / global.FinalViewportSize.y;
vec2 flipped_viewport_coord = HSM_GetViewportCoordWithZoomAndPan(vTexCoord);
SCREEN_INDEX = HSM_GetScreenIndex(flipped_viewport_coord);
vec2 sample_coord = vec2(0);
vec4 texture_sample = vec4(0);
// Sample 1, 1
sample_coord = HSM_GetCacheSampleCoord(1, 1);
texture_sample = texture(in_cache_pass, sample_coord);
AVERAGE_LUMA = texture_sample.a;
float res_mult_size_sum = 0;
float res_mult_size_sum_feedback = 0;
float res_mult_size2_sum = 0;
float res_mult_size2_sum_feedback = 0;
if (SCREEN_INDEX == 1)
{
// Sample 2, 1
// r SCREEN_ASPECT
// ba SCREEN_SCALE
sample_coord = HSM_GetCacheSampleCoord(2, 1);
texture_sample = texture(in_cache_pass, sample_coord);
SCREEN_ASPECT = texture_sample.r;
SCREEN_SCALE = texture_sample.ba;
// Sample 3, 1
// rg TUBE_SCALE
// ba SCREEN_POS_OFFSET
sample_coord = HSM_GetCacheSampleCoord(3, 1);
texture_sample = texture(in_cache_pass, sample_coord);
TUBE_SCALE = texture_sample.rg;
SCREEN_POS_OFFSET = texture_sample.ba;
// Sample 3, 4
// rg TUBE_DIFFUSE_SCALE
sample_coord = HSM_GetCacheSampleCoord(3, 4);
texture_sample = texture(in_cache_pass, sample_coord);
TUBE_DIFFUSE_SCALE = texture_sample.rg;
TUBE_DIFFUSE_ASPECT = TUBE_DIFFUSE_SCALE.x / TUBE_DIFFUSE_SCALE.y * output_aspect;
// Sample 4, 1
// rg CROPPED_ROTATED_SIZE_WITH_RES_MULT
sample_coord = HSM_GetCacheSampleCoord(4, 1);
texture_sample = texture(in_cache_pass, sample_coord);
CROPPED_ROTATED_SIZE_WITH_RES_MULT = texture_sample.rg;
res_mult_size_sum = CROPPED_ROTATED_SIZE_WITH_RES_MULT.x + CROPPED_ROTATED_SIZE_WITH_RES_MULT.y;
ROTATED_CORE_PREPPED_SIZE = texture_sample.ba;
// Sample 1, 2
// rg CROPPED_ROTATED_SIZE
// ba SAMPLE_AREA_START_PIXEL_COORD
sample_coord = HSM_GetCacheSampleCoord(1, 2);
texture_sample = texture(in_cache_pass, sample_coord);
CROPPED_ROTATED_SIZE = texture_sample.rg;
SAMPLE_AREA_START_PIXEL_COORD = texture_sample.ba;
}
// If we are in the section of the viewport which is the second screen
if (SCREEN_INDEX == 2)
{
// Sample 2, 2 Sample - 2nd Screen
// r SCREEN_ASPECT
// ba SCREEN_SCALE
sample_coord = HSM_GetCacheSampleCoord(2, 2);
texture_sample = texture(in_cache_pass, sample_coord);
SCREEN_ASPECT = texture_sample.r;
SCREEN_SCALE = texture_sample.gb;
// Sample 3, 2 - 2nd Screen
// rg TUBE_SCALE
// ba SCREEN_POS_OFFSET
sample_coord = HSM_GetCacheSampleCoord(3, 2);
texture_sample = texture(in_cache_pass, sample_coord);
TUBE_SCALE = texture_sample.rg;
SCREEN_POS_OFFSET = texture_sample.ba;
// TODO need to add TUBE_DIFFUSE_ASPECT & deal with 2nd Screen
// Sample 3, 4
// ba TUBE_DIFFUSE_SCALE
sample_coord = HSM_GetCacheSampleCoord(3, 4);
texture_sample = texture(in_cache_pass, sample_coord);
TUBE_DIFFUSE_SCALE = texture_sample.ba;
TUBE_DIFFUSE_ASPECT = TUBE_DIFFUSE_SCALE.x / TUBE_DIFFUSE_SCALE.y * output_aspect;
// Sample 4, 2
// rg CROPPED_ROTATED_SIZE_WITH_RES_MULT
sample_coord = HSM_GetCacheSampleCoord(4, 2);
texture_sample = texture(in_cache_pass, sample_coord);
CROPPED_ROTATED_SIZE_WITH_RES_MULT = texture_sample.rg;
res_mult_size2_sum = CROPPED_ROTATED_SIZE_WITH_RES_MULT.x + CROPPED_ROTATED_SIZE_WITH_RES_MULT.y;
// Sample 1, 3
// rg CROPPED_ROTATED_SIZE
// ba SAMPLE_AREA_START_PIXEL_COORD
sample_coord = HSM_GetCacheSampleCoord(1, 3);
texture_sample = texture(in_cache_pass, sample_coord);
CROPPED_ROTATED_SIZE = texture_sample.rg;
SAMPLE_AREA_START_PIXEL_COORD = texture_sample.ba;
}
// Sample 3, 1
// rg TUBE_SCALE
// ba SCREEN_POS_OFFSET
sample_coord = HSM_GetCacheSampleCoord(3, 1);
texture_sample = texture(in_cache_pass, sample_coord);
// TUBE_SCALE_1ST_SCREEN = texture_sample.rg;
SCREEN_POS_OFFSET_1ST_SCREEN = texture_sample.ba;
// Sample 3, 4
// rg TUBE_DIFFUSE_SCALE_1ST_SCREEN
sample_coord = HSM_GetCacheSampleCoord(3, 4);
texture_sample = texture(in_cache_pass, sample_coord);
TUBE_DIFFUSE_SCALE_1ST_SCREEN = texture_sample.rg;
// TUBE_DIFFUSE_ASPECT_1ST_SCREEN = TUBE_DIFFUSE_SCALE_1ST_SCREEN.x / TUBE_DIFFUSE_SCALE_1ST_SCREEN.y * output_aspect;
// Sample 3, 2 - 2nd Screen
// rg TUBE_SCALE_2ND_SCREEN
// ba SCREEN_POS_OFFSET_2ND_SCREEN
sample_coord = HSM_GetCacheSampleCoord(3, 2);
texture_sample = texture(in_cache_pass, sample_coord);
// TUBE_SCALE_2ND_SCREEN = texture_sample.rg;
SCREEN_POS_OFFSET_2ND_SCREEN = texture_sample.ba;
// TODO need to add TUBE_DIFFUSE_ASPECT & deal with 2nd Screen
// Sample 3, 4
// ba TUBE_DIFFUSE_SCALE_2ND_SCREEN
sample_coord = HSM_GetCacheSampleCoord(3, 4);
texture_sample = texture(in_cache_pass, sample_coord);
TUBE_DIFFUSE_SCALE_2ND_SCREEN = texture_sample.ba;
// Sample 2, 3 Sample
// rg CORE_SIZE
sample_coord = HSM_GetCacheSampleCoord(2, 3);
texture_sample = texture(in_cache_pass, sample_coord);
CORE_SIZE = texture_sample.rg;
ROTATED_CORE_ORIGINAL_SIZE = texture_sample.ba;
// Sample 3, 3
// rg VIEWPORT_SCALE
// ba VIEWPORT_POS
sample_coord = HSM_GetCacheSampleCoord(3, 3);
texture_sample = texture(in_cache_pass, sample_coord);
VIEWPORT_SCALE = texture_sample.rg;
VIEWPORT_POS = texture_sample.ba;
// Sample 4, 3
// rg SCREEN_SCALE_2ND_SCREEN
// ba SCREEN_POS_OFFSET_2ND_SCREEN
sample_coord = HSM_GetCacheSampleCoord(4, 3);
texture_sample = texture(in_cache_pass, sample_coord);
SCREEN_SCALE_2ND_SCREEN = texture_sample.rg;
SCREEN_POS_OFFSET_2ND_SCREEN = texture_sample.ba;
// Sample 1, 4
// g CURRENT_FRAME_FROM_CACHE_INFO
// b ROTATED_DEREZED_SIZE
sample_coord = HSM_GetCacheSampleCoord(1, 4);
texture_sample = texture(in_cache_pass, sample_coord);
CURRENT_FRAME_FROM_CACHE_INFO = texture_sample.g;
ROTATED_DEREZED_SIZE = texture_sample.ba;
// Sample 2, 4
// r NEGATIVE_CROP_EXPAND_MULTIPLIER
// g MAX_NEGATIVE_CROP
sample_coord = HSM_GetCacheSampleCoord(2, 4);
texture_sample = texture(in_cache_pass, sample_coord);
NEGATIVE_CROP_EXPAND_MULTIPLIER = texture_sample.r;
MAX_NEGATIVE_CROP = texture_sample.g;
USE_VERTICAL_SCANLINES = texture_sample.b;
// Sample 4, 4
// r CACHE_INFO_CHANGED
sample_coord = HSM_GetCacheSampleCoord(4, 4);
texture_sample = texture(in_cache_pass, sample_coord);
CACHE_INFO_CHANGED = texture_sample.r > 0.5 ? true : false;
SCREEN_COORD = HSM_GetVTexCoordWithArgs(flipped_viewport_coord, SCREEN_SCALE, SCREEN_POS_OFFSET);
TUBE_DIFFUSE_COORD = HSM_GetVTexCoordWithArgs(flipped_viewport_coord, TUBE_DIFFUSE_SCALE, SCREEN_POS_OFFSET);
TUBE_DIFFUSE_COORD_MIXED_POS = HSM_GetVTexCoordWithArgs(flipped_viewport_coord, TUBE_DIFFUSE_SCALE_1ST_SCREEN, (SCREEN_POS_OFFSET_1ST_SCREEN + SCREEN_POS_OFFSET_2ND_SCREEN) / 2.0);
return vec4(0);
}