From 4bc81a1cd7a68c67ffb8135ff8e402fbf276ef21 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Wed, 10 Jan 2024 00:04:26 +0100 Subject: [PATCH] Added Amstrad CPC 6128 mode --- base/devtools.cfg | 2 +- .../menus/MenuScreen_Shell_SystemOptions.cpp | 4 +- neo/renderer/Image_intrinsic.cpp | 45 ++- neo/renderer/RenderBackend.cpp | 6 + neo/renderer/RenderCommon.h | 2 + neo/renderer/RenderProgs.cpp | 1 + neo/renderer/RenderProgs.h | 6 + neo/renderer/RenderSystem_init.cpp | 2 +- neo/shaders/builtin/post/retro_c64.ps.hlsl | 16 + neo/shaders/builtin/post/retro_cpc.ps.hlsl | 367 ++++++++++++++++++ neo/shaders/builtin/post/retro_cpc.vs.hlsl | 55 +++ .../builtin/post/retro_genesis.ps.hlsl | 20 +- neo/shaders/global_inc.hlsl | 37 ++ neo/shaders/shaders.cfg | 2 + 14 files changed, 550 insertions(+), 15 deletions(-) create mode 100644 neo/shaders/builtin/post/retro_cpc.ps.hlsl create mode 100644 neo/shaders/builtin/post/retro_cpc.vs.hlsl diff --git a/base/devtools.cfg b/base/devtools.cfg index 1388508f..20dc3373 100644 --- a/base/devtools.cfg +++ b/base/devtools.cfg @@ -9,7 +9,7 @@ bind "F3" "toggle r_forceAmbient 0.5 1.0 0" bind "F4" "toggle r_skipInteractions" bind "F5" "savegame quick" bind "F6" "toggle r_showLightGrid 1 3 4 0" -bind "F7" "toggle r_renderMode 0 1 2 3 4 5" +bind "F7" "toggle r_renderMode 0 1 2 3 4 5 6 7" bind "F8" "toggle r_useCRTPostFX 0 1 2" bind "F9" "loadgame quick" //bind "F10" "toggle com_fixedTic" diff --git a/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp b/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp index ad9d113b..e1bc1c94 100755 --- a/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp +++ b/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp @@ -791,12 +791,14 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings } case SYSTEM_FIELD_RENDERMODE: { - static const int numValues = 6; + static const int numValues = 8; static const char* values[numValues] = { "Doom 3", "Commodore 64", "Commodore 64 Highres", + "Amstrad CPC 6128", + "Amstrad CPC 6128 Highres", "Sega Genesis", "Sega Genesis Highres", "Sony PSX", diff --git a/neo/renderer/Image_intrinsic.cpp b/neo/renderer/Image_intrinsic.cpp index 1642d444..ad570fc2 100644 --- a/neo/renderer/Image_intrinsic.cpp +++ b/neo/renderer/Image_intrinsic.cpp @@ -3,7 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. -Copyright (C) 2013-2023 Robert Beckebans +Copyright (C) 2013-2024 Robert Beckebans Copyright (C) 2022 Stephen Pridham This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -1239,9 +1239,6 @@ CONSOLE_COMMAND( makeImageHeader, "load an image and turn it into a .h file", NU CONSOLE_COMMAND( makePaletteHeader, "load a .pal palette, build an image from it and turn it into a .h file", NULL ) { - byte* buffer; - int width = 0, height = 0; - if( args.Argc() < 2 ) { common->Printf( "USAGE: makePaletteHeader filename [exportname]\n" ); @@ -1249,16 +1246,49 @@ CONSOLE_COMMAND( makePaletteHeader, "load a .pal palette, build an image from it } idStr filename = args.Argv( 1 ); + filename.DefaultFileExtension( ".pal" ); - R_LoadImage( filename, &buffer, &width, &height, NULL, true, NULL ); - if( !buffer ) + ID_TIME_T timeStamp; + char* palBuffer; + int palBufferLen = fileSystem->ReadFile( filename, ( void** )&palBuffer, &timeStamp ); + if( palBufferLen <= 0 || palBuffer == nullptr ) { - common->Printf( "loading %s failed.\n", filename.c_str() ); return; } + // parse JASC-PAL file + idLexer src; + idToken token, token2; + + src.LoadMemory( palBuffer, palBufferLen, filename, 0 ); + + src.ExpectTokenString( "JASC" ); + src.ExpectTokenString( "-" ); + src.ExpectTokenString( "PAL" ); + int palVersion = src.ParseInt(); + + int numColors = src.ParseInt(); + + //idListFreeFile( palBuffer ); + filename.StripFileExtension(); + // TODO build image and convert to header + //byte* buffer; + //int width = 0, height = 0; + + /* idStr exportname; if( args.Argc() == 3 ) @@ -1322,4 +1352,5 @@ CONSOLE_COMMAND( makePaletteHeader, "load a .pal palette, build an image from it headerFile->Printf( "\n};\n#endif\n" ); Mem_Free( buffer ); + */ } \ No newline at end of file diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 6eea515a..da237443 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -6122,6 +6122,12 @@ void idRenderBackend::PostProcess( const void* data ) renderProgManager.BindShader_PostProcess_RetroC64(); } + else if( r_renderMode.GetInteger() == RENDERMODE_CPC || r_renderMode.GetInteger() == RENDERMODE_CPC_HIGHRES ) + { + jitterTexScale[0] = r_renderMode.GetInteger() == RENDERMODE_CPC_HIGHRES ? 2.0 : 1.0; + + renderProgManager.BindShader_PostProcess_RetroCPC(); + } else if( r_renderMode.GetInteger() == RENDERMODE_GENESIS || r_renderMode.GetInteger() == RENDERMODE_GENESIS_HIGHRES ) { jitterTexScale[0] = r_renderMode.GetInteger() == RENDERMODE_GENESIS_HIGHRES ? 2.0 : 1.0; diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index 6cdf801c..12dc65f8 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -1301,6 +1301,8 @@ enum RenderMode RENDERMODE_DOOM, RENDERMODE_C64, RENDERMODE_C64_HIGHRES, + RENDERMODE_CPC, + RENDERMODE_CPC_HIGHRES, RENDERMODE_GENESIS, RENDERMODE_GENESIS_HIGHRES, RENDERMODE_PSX, diff --git a/neo/renderer/RenderProgs.cpp b/neo/renderer/RenderProgs.cpp index ceb9ed20..7a7cc931 100644 --- a/neo/renderer/RenderProgs.cpp +++ b/neo/renderer/RenderProgs.cpp @@ -522,6 +522,7 @@ void idRenderProgManager::Init( nvrhi::IDevice* device ) { BUILTIN_WOBBLESKY, "builtin/legacy/wobblesky", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT }, { BUILTIN_POSTPROCESS, "builtin/post/postprocess", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_POSTPROCESS_RETRO_C64, "builtin/post/retro_c64", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, + { BUILTIN_POSTPROCESS_RETRO_CPC, "builtin/post/retro_cpc", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_POSTPROCESS_RETRO_GENESIS, "builtin/post/retro_genesis", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_POSTPROCESS_RETRO_PSX, "builtin/post/retro_ps1", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_CRT_MATTIAS, "builtin/post/crt_mattias", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, diff --git a/neo/renderer/RenderProgs.h b/neo/renderer/RenderProgs.h index 72497da2..25f44899 100644 --- a/neo/renderer/RenderProgs.h +++ b/neo/renderer/RenderProgs.h @@ -367,6 +367,7 @@ enum BUILTIN_POSTPROCESS, // RB begin BUILTIN_POSTPROCESS_RETRO_C64, // Commodore 64 + BUILTIN_POSTPROCESS_RETRO_CPC, // Amstrad 6128 BUILTIN_POSTPROCESS_RETRO_GENESIS, // Sega Genesis / Megadrive BUILTIN_POSTPROCESS_RETRO_PSX, // Sony Playstation 1 BUILTIN_CRT_MATTIAS, @@ -827,6 +828,11 @@ public: BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_C64 ); } + void BindShader_PostProcess_RetroCPC() + { + BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_CPC ); + } + void BindShader_PostProcess_RetroGenesis() { BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_GENESIS ); diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 9b0528ab..a8dcb2f8 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -302,7 +302,7 @@ idCVar r_useCRTPostFX( "r_useCRTPostFX", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVA idCVar r_crtCurvature( "r_crtCurvature", "2", CVAR_RENDERER | CVAR_FLOAT, "rounded borders" ); idCVar r_crtVignette( "r_crtVignette", "0.8", CVAR_RENDERER | CVAR_FLOAT, "fading into the borders" ); -idCVar r_renderMode( "r_renderMode", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "0 = Doom, 1 = Commodore 64, 2 = Commodore 64 Highres, 3 = Sega Genesis, 4 = Sega Genesis Highres, 5 = Sony PSX", 0, 5 ); +idCVar r_renderMode( "r_renderMode", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "0 = Doom, 1 = Commodore 64, 2 = Commodore 64 Highres, 3 = Amstrad CPC 6128, 4 = Amstrad CPC 6128 Highres, 5 = Sega Genesis, 6 = Sega Genesis Highres, 7 = Sony PSX", 0, 7 ); // RB end const char* fileExten[4] = { "tga", "png", "jpg", "exr" }; diff --git a/neo/shaders/builtin/post/retro_c64.ps.hlsl b/neo/shaders/builtin/post/retro_c64.ps.hlsl index be36cfe4..65e1e775 100644 --- a/neo/shaders/builtin/post/retro_c64.ps.hlsl +++ b/neo/shaders/builtin/post/retro_c64.ps.hlsl @@ -152,6 +152,22 @@ void main( PS_IN fragment, out PS_OUT result ) // get pixellated base color float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb; +#if 0 + if( uv.y < 0.125 ) + { + color = HSVToRGB( float3( uv.x, 1.0, uv.y * 8.0 ) ); + color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) ); + + //result.color = float4( color, 1.0 ); + //return; + } + else if( uv.y < 0.1875 ) + { + color = _float3( uv.x ); + color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) ); + } +#endif + // add Bayer 8x8 dithering float2 uvDither = uvPixelated; //if( rpJitterTexScale.x > 1.0 ) diff --git a/neo/shaders/builtin/post/retro_cpc.ps.hlsl b/neo/shaders/builtin/post/retro_cpc.ps.hlsl new file mode 100644 index 00000000..850ed405 --- /dev/null +++ b/neo/shaders/builtin/post/retro_cpc.ps.hlsl @@ -0,0 +1,367 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2024 Robert Beckebans + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code 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. + +Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see . + +In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#include "global_inc.hlsl" + + +// *INDENT-OFF* +Texture2D t_BaseColor : register( t0 VK_DESCRIPTOR_SET( 0 ) ); +Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) ); + +SamplerState samp0 : register(s0 VK_DESCRIPTOR_SET( 1 ) ); +SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256 + +struct PS_IN +{ + float4 position : SV_Position; + float2 texcoord0 : TEXCOORD0_centroid; +}; + +struct PS_OUT +{ + float4 color : SV_Target0; +}; +// *INDENT-ON* + + +#define RESOLUTION_DIVISOR 4.0 +#define NUM_COLORS 32 // original 27 + + +float LinearTweak1( float c ) +{ + return ( c <= 0.04045 ) ? c / 12.92 : pow( ( c + 0.055 ) / 1.055, 1.4 ); +} + +float3 LinearTweak3( float3 c ) +{ + return float3( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ) ); +} + +// find nearest palette color using Euclidean distance +float3 LinearSearch( float3 c, float3 pal[NUM_COLORS] ) +{ + int idx = 0; + float nd = distance( c, pal[0] ); + + for( int i = 1; i < NUM_COLORS; i++ ) + { + //float d = distance( c, pal[i] ); + float d = distance( c, ( pal[i] ) ); + + if( d < nd ) + { + nd = d; + idx = i; + } + } + + return pal[idx]; +} + +#define RGB(r, g, b) float3(float(r)/255.0, float(g)/255.0, float(b)/255.0) + + + +void main( PS_IN fragment, out PS_OUT result ) +{ + float2 uv = ( fragment.texcoord0 ); + float2 uvPixelated = floor( fragment.position.xy / RESOLUTION_DIVISOR ) * RESOLUTION_DIVISOR; + + float3 quantizationPeriod = _float3( 1.0 / NUM_COLORS ); + + // get pixellated base color + float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb; + +#if 0 + if( uv.y < 0.125 ) + { + color = HSVToRGB( float3( uv.x, 1.0, uv.y * 8.0 ) ); + color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) ); + + //result.color = float4( color, 1.0 ); + //return; + } + else if( uv.y < 0.1875 ) + { + color = _float3( uv.x ); + color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) ); + } +#endif + + // add Bayer 8x8 dithering + float2 uvDither = uvPixelated; + //if( rpJitterTexScale.x > 1.0 ) + { + uvDither = fragment.position.xy / ( RESOLUTION_DIVISOR / rpJitterTexScale.x ); + } + float dither = ( DitherArray8x8( uvDither ) - 0.5 ) * 1.0; + + color.rgb += float3( dither, dither, dither ) * quantizationPeriod; + + +#if 1 + // Amstrad CPC colors https://www.cpcwiki.eu/index.php/CPC_Palette + const float3 palette[NUM_COLORS] = + { + RGB( 0, 0, 0 ), // black + RGB( 0, 0, 128 ), // blue + RGB( 0, 0, 255 ), // bright blue + RGB( 128, 0, 0 ), // red + RGB( 128, 0, 128 ), // magenta + RGB( 128, 0, 255 ), // mauve + RGB( 255, 0, 0 ), // bright red + RGB( 255, 0, 128 ), // purple + RGB( 255, 0, 255 ), // bright magenta + RGB( 0, 128, 0 ), // green + RGB( 0, 128, 128 ), // cyan + RGB( 0, 128, 255 ), // sky blue + RGB( 128, 128, 0 ), // yellow + RGB( 128, 128, 128 ), // white + RGB( 128, 128, 255 ), // pastel blue + RGB( 255, 128, 0 ), // orange + RGB( 255, 128, 128 ), // pink + RGB( 255, 128, 255 ), // pastel magenta + RGB( 0, 255, 0 ), // bright green + RGB( 0, 255, 128 ), // sea green + RGB( 0, 255, 255 ), // bright cyan + RGB( 128, 255, 0 ), // lime + RGB( 128, 255, 128 ), // pastel green + RGB( 128, 255, 255 ), // pastel cyan + RGB( 255, 255, 0 ), // bright yellow + RGB( 255, 255, 128 ), // pastel yellow + RGB( 255, 255, 255 ), // bright white + + //RGB( 79, 69, 0 ), // brown + //RGB( 120, 120, 120 ), // dark grey + //RGB( 164, 215, 142 ), // grey + +#if 0 + RGB( 68, 68, 68 ), // dark grey + RGB( 80, 80, 80 ), + RGB( 108, 108, 108 ), // grey + RGB( 120, 120, 120 ), + RGB( 149, 149, 149 ), // light grey +#else + //RGB( 4, 4, 4 ), // black + RGB( 16, 16, 16 ), // black + RGB( 0, 28, 28 ), // dark cyan + RGB( 128, 0, 255 ) * 0.9, // mauve + RGB( 111, 79, 37 ) * 1.2, // orange + //RGB( 149, 149, 149 ), // light grey + //RGB( 154, 210, 132 ), // light green + RGB( 112, 164, 178 ) * 1.3, // cyan +#endif + }; + +#elif 0 + // Tweaked LOSPEC CPC BOY PALETTE which is less saturated by Arne Niklas Jansson + // https://lospec.com/palette-list/cpc-boy + + const float3 palette[NUM_COLORS] = // 32 + { + RGB( 0, 0, 0 ), + RGB( 27, 27, 101 ), + RGB( 53, 53, 201 ), + RGB( 102, 30, 37 ), + RGB( 85, 51, 97 ), + RGB( 127, 53, 201 ), + RGB( 188, 53, 53 ), + RGB( 192, 70, 110 ), + RGB( 223, 109, 155 ), + RGB( 27, 101, 27 ), + RGB( 27, 110, 131 ), + RGB( 30, 121, 229 ), + RGB( 121, 95, 27 ), + RGB( 128, 128, 128 ), + RGB( 145, 148, 223 ), + RGB( 201, 127, 53 ), + RGB( 227, 155, 141 ), + RGB( 248, 120, 248 ), + RGB( 53, 175, 53 ), + RGB( 53, 183, 143 ), + RGB( 53, 193, 215 ), + RGB( 127, 201, 53 ), + RGB( 173, 200, 170 ), + RGB( 141, 225, 199 ), + RGB( 225, 198, 67 ), + RGB( 228, 221, 154 ), + RGB( 255, 255, 255 ), + RGB( 238, 234, 224 ), + RGB( 172, 181, 107 ), + RGB( 118, 132, 72 ), + RGB( 63, 80, 63 ), + RGB( 36, 49, 55 ), + }; + +#elif 1 + + // NES 1 very good + // https://lospec.com/palette-list/nintendo-entertainment-system + + const float3 palette[NUM_COLORS] = // 55 + { + RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + //RGB( 0, 0, 0 ), + + RGB( 252, 252, 252 ), + RGB( 248, 248, 248 ), + RGB( 188, 188, 188 ), + RGB( 124, 124, 124 ), + RGB( 164, 228, 252 ), + RGB( 60, 188, 252 ), + RGB( 0, 120, 248 ), + RGB( 0, 0, 252 ), + RGB( 184, 184, 248 ), + RGB( 104, 136, 252 ), + RGB( 0, 88, 248 ), + RGB( 0, 0, 188 ), + RGB( 216, 184, 248 ), + RGB( 152, 120, 248 ), + RGB( 104, 68, 252 ), + RGB( 68, 40, 188 ), + RGB( 248, 184, 248 ), + RGB( 248, 120, 248 ), + RGB( 216, 0, 204 ), + RGB( 148, 0, 132 ), + RGB( 248, 164, 192 ), + RGB( 248, 88, 152 ), + RGB( 228, 0, 88 ), + RGB( 168, 0, 32 ), + RGB( 240, 208, 176 ), + RGB( 248, 120, 88 ), + RGB( 248, 56, 0 ), + RGB( 168, 16, 0 ), + RGB( 252, 224, 168 ), + RGB( 252, 160, 68 ), + RGB( 228, 92, 16 ), + RGB( 136, 20, 0 ), + RGB( 248, 216, 120 ), + RGB( 248, 184, 0 ), + RGB( 172, 124, 0 ), + RGB( 80, 48, 0 ), + RGB( 216, 248, 120 ), + RGB( 184, 248, 24 ), + RGB( 0, 184, 0 ), + RGB( 0, 120, 0 ), + RGB( 184, 248, 184 ), + RGB( 88, 216, 84 ), + RGB( 0, 168, 0 ), + RGB( 0, 104, 0 ), + RGB( 184, 248, 216 ), + RGB( 88, 248, 152 ), + RGB( 0, 168, 68 ), + RGB( 0, 88, 0 ), + RGB( 0, 252, 252 ), + RGB( 0, 232, 216 ), + RGB( 0, 136, 136 ), + RGB( 0, 64, 88 ), + RGB( 248, 216, 248 ), + RGB( 120, 120, 120 ), + }; + +#elif 0 + + const float3 palette[NUM_COLORS] = // 32 + { + RGB( 0, 0, 0 ), + RGB( 192, 64, 80 ), + RGB( 240, 240, 240 ), + RGB( 192, 192, 176 ), + RGB( 128, 144, 144 ), + RGB( 96, 96, 112 ), + RGB( 96, 64, 64 ), + RGB( 64, 48, 32 ), + RGB( 112, 80, 48 ), + RGB( 176, 112, 64 ), + RGB( 224, 160, 80 ), + RGB( 224, 192, 128 ), + RGB( 240, 224, 96 ), + RGB( 224, 128, 48 ), + RGB( 208, 80, 32 ), + RGB( 144, 48, 32 ), + RGB( 96, 48, 112 ), + RGB( 176, 96, 160 ), + RGB( 224, 128, 192 ), + RGB( 192, 160, 208 ), + RGB( 112, 112, 192 ), + RGB( 48, 64, 144 ), + RGB( 32, 32, 64 ), + RGB( 32, 96, 208 ), + RGB( 64, 160, 224 ), + RGB( 128, 208, 224 ), + RGB( 160, 240, 144 ), + RGB( 48, 160, 96 ), + RGB( 48, 64, 48 ), + RGB( 48, 112, 32 ), + RGB( 112, 160, 48 ), + RGB( 160, 208, 80 ), + }; + +#elif 0 + + // Gameboy + const float3 palette[NUM_COLORS] = // 4 + { + RGB( 27, 42, 9 ), + RGB( 14, 69, 11 ), + RGB( 73, 107, 34 ), + RGB( 154, 158, 63 ), + }; + +#else + + // https://lospec.com/palette-list/existential-demo + const float3 palette[NUM_COLORS] = // 8 + { + RGB( 248, 243, 253 ), + RGB( 250, 198, 180 ), + RGB( 154, 218, 231 ), + RGB( 151, 203, 29 ), + RGB( 93, 162, 202 ), + RGB( 218, 41, 142 ), + RGB( 11, 134, 51 ), + RGB( 46, 43, 18 ), + }; + +#endif + + // find closest color match from CPC color palette + color = LinearSearch( color.rgb, palette ); + + result.color = float4( color, 1.0 ); +} diff --git a/neo/shaders/builtin/post/retro_cpc.vs.hlsl b/neo/shaders/builtin/post/retro_cpc.vs.hlsl new file mode 100644 index 00000000..75519fe8 --- /dev/null +++ b/neo/shaders/builtin/post/retro_cpc.vs.hlsl @@ -0,0 +1,55 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code 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. + +Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see . + +In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#include "global_inc.hlsl" + + +// *INDENT-OFF* +struct VS_IN +{ + float4 position : POSITION; + float2 texcoord : TEXCOORD0; + float4 normal : NORMAL; + float4 tangent : TANGENT; + float4 color : COLOR0; + float4 color2 : COLOR1; +}; + +struct VS_OUT { + float4 position : SV_Position; + float2 texcoord0 : TEXCOORD0_centroid; +}; +// *INDENT-ON* + +void main( VS_IN vertex, out VS_OUT result ) +{ + result.position = vertex.position; + result.position.y = -result.position.y; + + result.texcoord0 = vertex.texcoord; +} \ No newline at end of file diff --git a/neo/shaders/builtin/post/retro_genesis.ps.hlsl b/neo/shaders/builtin/post/retro_genesis.ps.hlsl index 60b1a4ce..4a0e1abb 100644 --- a/neo/shaders/builtin/post/retro_genesis.ps.hlsl +++ b/neo/shaders/builtin/post/retro_genesis.ps.hlsl @@ -118,8 +118,21 @@ void main( PS_IN fragment, out PS_OUT result ) // get pixellated base color float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb; - //color = _float3( uv.x ); - //color = Quantize( color, quantizationPeriod ); +#if 0 + if( uv.y < 0.125 ) + { + color = HSVToRGB( float3( uv.x, 1.0, uv.y * 8.0 ) ); + color = Quantize( color, quantizationPeriod ); + + //result.color = float4( color, 1.0 ); + //return; + } + else if( uv.y < 0.1875 ) + { + color = _float3( uv.x ); + color = Quantize( color, quantizationPeriod ); + } +#endif // add Bayer 8x8 dithering float2 uvDither = uvPixelated; @@ -134,8 +147,5 @@ void main( PS_IN fragment, out PS_OUT result ) // find closest color match from Sega Mega Drive color palette color = Quantize( color, quantizationPeriod ); - //color = LinearSearch( color.rgb, palette ); - //color = float4( BinarySearch( color.rgb, palette ), 1.0 ); - result.color = float4( color, 1.0 ); } diff --git a/neo/shaders/global_inc.hlsl b/neo/shaders/global_inc.hlsl index 70a09fec..7a769262 100644 --- a/neo/shaders/global_inc.hlsl +++ b/neo/shaders/global_inc.hlsl @@ -244,6 +244,43 @@ float4 LinearRGBToSRGB( float4 c ) #endif } +float3 HSVToRGB( float3 HSV ) +{ + float3 RGB = HSV.z; + + float var_h = HSV.x * 6; + float var_i = floor( var_h ); // Or ... var_i = floor( var_h ) + float var_1 = HSV.z * ( 1.0 - HSV.y ); + float var_2 = HSV.z * ( 1.0 - HSV.y * ( var_h - var_i ) ); + float var_3 = HSV.z * ( 1.0 - HSV.y * ( 1 - ( var_h - var_i ) ) ); + if( var_i == 0 ) + { + RGB = float3( HSV.z, var_3, var_1 ); + } + else if( var_i == 1 ) + { + RGB = float3( var_2, HSV.z, var_1 ); + } + else if( var_i == 2 ) + { + RGB = float3( var_1, HSV.z, var_3 ); + } + else if( var_i == 3 ) + { + RGB = float3( var_1, var_2, HSV.z ); + } + else if( var_i == 4 ) + { + RGB = float3( var_3, var_1, HSV.z ); + } + else + { + RGB = float3( HSV.z, var_1, var_2 ); + } + + return ( RGB ); +} + /** Efficient GPU implementation of the octahedral unit vector encoding from Cigolle, Donow, Evangelakos, Mara, McGuire, Meyer, diff --git a/neo/shaders/shaders.cfg b/neo/shaders/shaders.cfg index 7b52b129..48ca9524 100644 --- a/neo/shaders/shaders.cfg +++ b/neo/shaders/shaders.cfg @@ -54,6 +54,8 @@ builtin/post/postprocess.vs.hlsl -T vs_5_0 builtin/post/postprocess.ps.hlsl -T ps_5_0 builtin/post/retro_c64.vs.hlsl -T vs_5_0 builtin/post/retro_c64.ps.hlsl -T ps_5_0 +builtin/post/retro_cpc.vs.hlsl -T vs_5_0 +builtin/post/retro_cpc.ps.hlsl -T ps_5_0 builtin/post/retro_genesis.vs.hlsl -T vs_5_0 builtin/post/retro_genesis.ps.hlsl -T ps_5_0 builtin/post/retro_ps1.vs.hlsl -T vs_5_0