Skip to content

Commit

Permalink
Merge pull request #6 from Hacktix/crt-shader
Browse files Browse the repository at this point in the history
CRT Shader
  • Loading branch information
Optix authored May 23, 2020
2 parents 2a26de3 + fdf1ca4 commit 43e031a
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 14 deletions.
6 changes: 5 additions & 1 deletion Chroma Invaders.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Chroma" Version="0.3.1-alpha" />
<PackageReference Include="Chroma" Version="0.4.0-alpha" />
<PackageReference Include="ChromaSynth" Version="1.0.0" />
</ItemGroup>

Expand All @@ -26,6 +26,10 @@
<None Update="roms\invaders.h">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

<None Update="shader.frag">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
49 changes: 36 additions & 13 deletions Emulator.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Chroma;
using Chroma.Graphics;
using Chroma.Graphics.Accelerated;
using Chroma.Input.EventArgs;
using System;
using System.Collections.Generic;
Expand All @@ -23,11 +24,16 @@ public class Emulator : Game
private bool UseColor = true;
private List<double> PerformanceBuffer = new List<double>();

private bool UseShader = false;
private PixelShader ArcadeShader;
private RenderTarget Frame;

public Emulator(byte[][] roms)
{
Machine = new Machine(roms);

Window.GoWindowed((ushort)(SCREEN_WIDTH * SCALE_FACTOR), (ushort)(SCREEN_HEIGHT * SCALE_FACTOR));
ArcadeShader = new PixelShader("shader.frag");
Frame = new RenderTarget((ushort)(SCREEN_WIDTH * SCALE_FACTOR), (ushort)(SCREEN_HEIGHT * SCALE_FACTOR));
}

protected override void FixedUpdate(float fixedDelta)
Expand Down Expand Up @@ -73,6 +79,9 @@ protected override void KeyPressed(KeyEventArgs e)
case Chroma.Input.KeyCode.C:
UseColor = !UseColor;
break;
case Chroma.Input.KeyCode.F1:
UseShader = !UseShader;
break;
}
}

Expand Down Expand Up @@ -100,28 +109,42 @@ protected override void KeyReleased(KeyEventArgs e)

protected override void Draw(RenderContext context)
{
for(int col = 0; col < SCREEN_WIDTH; col++)
context.RenderTo(Frame, () =>
{
for(int row = SCREEN_HEIGHT / 8; row >= 0; row--)
context.Clear(Color.Black);
for (int col = 0; col < SCREEN_WIDTH; col++)
{
for(byte bitmap = 1, bit = 0; bitmap > 0; bitmap <<= 1, bit++)
for (int row = SCREEN_HEIGHT / 8; row >= 0; row--)
{
int x = col * SCALE_FACTOR;
int y = (SCREEN_HEIGHT - (8 * row + bit)) * SCALE_FACTOR - SCALE_FACTOR;
if ((Machine.Memory[0x2400 + col * 0x20 + row] & bitmap) != 0)
for (byte bitmap = 1, bit = 0; bitmap > 0; bitmap <<= 1, bit++)
{
Color pxColor = Color.White;
if(UseColor)
int x = col * SCALE_FACTOR;
int y = (SCREEN_HEIGHT - (8 * row + bit)) * SCALE_FACTOR - SCALE_FACTOR;
if ((Machine.Memory[0x2400 + col * 0x20 + row] & bitmap) != 0)
{
if (y / SCALE_FACTOR > 32 && y / SCALE_FACTOR < 49) pxColor = Color.Red;
else if (y / SCALE_FACTOR >= 192 && y / SCALE_FACTOR <= 239) pxColor = Color.LimeGreen;
else if (y / SCALE_FACTOR > 239 && (x / SCALE_FACTOR >= 26 && x / SCALE_FACTOR <= 54)) pxColor = Color.LimeGreen;
Color pxColor = Color.White;
if (UseColor)
{
if (y / SCALE_FACTOR > 32 && y / SCALE_FACTOR < 49) pxColor = Color.Red;
else if (y / SCALE_FACTOR >= 192 && y / SCALE_FACTOR <= 239) pxColor = Color.LimeGreen;
else if (y / SCALE_FACTOR > 239 && (x / SCALE_FACTOR >= 26 && x / SCALE_FACTOR <= 54)) pxColor = Color.LimeGreen;
}
context.Rectangle(ShapeMode.Fill, new Vector2(x, y), SCALE_FACTOR, SCALE_FACTOR, pxColor);
}
context.Rectangle(ShapeMode.Fill, new Vector2(x, y), SCALE_FACTOR, SCALE_FACTOR, pxColor);
}
}
}
});

if(UseShader)
{
ArcadeShader.Activate();
ArcadeShader.SetUniform("CRT_CURVE_AMNTx", .2f);
ArcadeShader.SetUniform("CRT_CURVE_AMNTy", .2f);
}

context.DrawTexture(Frame, Vector2.Zero, Vector2.One, Vector2.Zero, 0f);
context.DeactivateShader();
}
}
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Chroma Invaders is an emulator of the classic Space Invaders arcade machine, bas
| Enter | Start Game |
| Arrow Keys (Left/Right) | Move Left/Right |
| Space | Shoot |
| C | Toggle Color |
| F1 | Toggle CRT |

# Technical Details
This project is being developed (more or less) side-by-side with another Space Invaders emulator called [THICCADE - Space Invaders](https://github.com/Hacktix/THICCADE-Space-Invaders), which is written in C++ and attempts to implement JIT-Recompilation. (Yes, I am aware that this isn't necessary for emulating an Intel 8080)
Expand Down
43 changes: 43 additions & 0 deletions shader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#version 130

#define CRT_CASE_BORDR 0.0125
#define SCAN_LINE_MULT 1250.0

uniform float CRT_CURVE_AMNTx; // curve amount on x
uniform float CRT_CURVE_AMNTy; // curve amount on y
uniform sampler2D texture;

in vec4 color;
in vec2 texCoord;

void main() {
vec2 tc = texCoord.xy;

// Distance from the center
float dx = abs(0.5-tc.x);
float dy = abs(0.5-tc.y);

// Square it to smooth the edges
dx *= dx;
dy *= dy;

tc.x -= 0.5;
tc.x *= 1.0 + (dy * CRT_CURVE_AMNTx);
tc.x += 0.5;

tc.y -= 0.5;
tc.y *= 1.0 + (dx * CRT_CURVE_AMNTy);
tc.y += 0.5;

// Get texel, and add in scanline if need be
vec4 cta = texture2D(texture, tc);

cta.rgb += sin(tc.y * SCAN_LINE_MULT) * 0.03;

// Cutoff
if(tc.y > 1.0 || tc.x < 0.0 || tc.x > 1.0 || tc.y < 0.0)
cta = vec4(0.0);

// Apply
gl_FragColor = cta * color;
}

0 comments on commit 43e031a

Please sign in to comment.