Post Thumbnail

2023/02/19 – eVX Progress #3: SokoBomber

Posted on Feb 19th, 2023

Spread the love

This week I’ve taken the deep dive into Shaders, which I’ve mostly forgotten, and some more animation.

Shaders aren’t working yet, here’s a chain explosion though

You’ll note, I’ve started mapping on the mechanics behind bombs to look cooler than the original on Window Phone 7/8. I’ve gotten some interesting things this week for the progress, at least. I’m unconvinced the top left corner workd for the bomb count downs, and I don’t have any knowledge near my shader work in the past – it’s a lovely refresh to try build better lighting in the near future.

1. Loading Shaders

I got close to getting my shaders in to begin experimenting at least; it helped me see what we’re meant to use in FNA. One thing to note, FNA works out the box with ps_2_0 and vs_2_0. As an important note, my shader below isn’t complete, doesn’t work as intended, just to share how they look to those who haven’t had any reason to look at them before:

float midX = 640;
float midY = 360;

float4x4 worldViewProjection  : WorldViewProjection;

Texture2D ScreenTexture : register(t0);

sampler TextureSampler : register(s0)
	Texture = (ScreenTexture);

struct PixelShaderIn
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;

float4 MainPS(PixelShaderIn input) : COLOR
	float4 tex = tex2D(TextureSampler, input.TextureCoordinates);
	float dist = min(max(1 - sqrt((midX - input.Position.x) * (midX - input.Position.x)) / 1024,1),0);
	tex.r = tex.r*dist;
	tex.g = tex.g*dist;
	tex.b = tex.b*dist;
	return input.Color * tex;

technique SpriteDrawing
	pass P0
		PixelShader = compile ps_2_0 MainPS();

The reason I’m sharing it is it’s important to know, it’s easiest to use a specific June 2010 DirectX SDK. This gives you fxc.exe found, usually in:

C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x64

You can add the SDK bin folder to your Path and use it in your content folder:

fxc.exe /T fx_2_0 baseEffect.fx /Fo baseEffect.fxb

As you can see, it uses fx_2_0 on baseEffect.fx and outputs baseEffect.fxb, the binary.

Engine.SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, Engine.Shader);

As you can tell, we obviously load an Effect like the old XNA days and if it’s set on Engine structure, which I use for ease of reference, we begin the SpriteBatch and with it. I’m stuck with the sense that I can’t remember how to use the full screens size and coordinates of the pixel itself.

Another note, I found out, thanks for the quick help flibitijibibo, I needed to use a hex editor to remove the blank space at the front of the fx file. To do this in a speedy manner I used my WSL2 instance, installed ghex, cleaned the whitespace, and the compiling worked. The error given from whitespace was this, incase anyone tries to find what the error means:

MOJOSHADER_compileEffect Error: Not an Effects Framework binary - illegal empty char at 1,1

Using ghex removed the small whitespace at the start, and further saves all compiled after.

2. Pay Attention to Your Rotation

Another thing I added in to eVX is also simple, rotating sprites at draw. Inside my content manager I made functions that are more minimal for use. The one thing I’m intrigued by is the float used for rotation.

    public void DrawRotated(ETex2D tex, Rectangle dest, float rotation)
        DrawRotated(tex.Texture2D, dest, rotation, Color.White);

    public void DrawRotated(ETex2D tex, Rectangle dest, float rotation, Color color)
        DrawRotated(tex.Texture2D, dest, rotation, color);

    public void DrawRotated(Texture2D tex, Rectangle dest, float rotation)
        DrawRotated(tex, dest, rotation, Color.White);

    public void DrawRotated(Texture2D tex, Rectangle dest, float rotation, Color color)
        // TODO: hmm, consider a reusable vector
        Engine.SpriteBatch.Draw(tex, dest, null, color, rotation, new Vector2(dest.Width / 2, dest.Height / 2), SpriteEffects.None, 0);

I couldn’t, for the life of me, remember what they used to be. And thanks to Load Shedding couldn’t do more, so I experimented. As it turns out, 360 degrees is 2 Pi.

public static class Degrees
    public static float Zero => 0;
    public static float Ninety => float.Pi / 2;
    public static float OneEighty => float.Pi;
    public static float TwoSeventy => float.Pi * 1.5f;

I should likely get tons more in, I just didn’t feel like it yet as the SokoBomber side only needs 0, 90, 180, and 270. Well, for now, as I need to throw in more animations which use rotations as well.

Just sharing to make a mental note for myself, 2 Pi.

Make it not start with whitespace

Other Thoughts

It’s going well, at least, since it’s almost playable. Then I can move to organising the content management a little more, and do some procedural gen. I had the idea way back when, but never got around to it. Something along the lines of focusing on my studies to try get a degree, back then. Now that everything is going way better for me, despite my injury, it’s great to take my time at home and use it for my hobbies. This month turned into starting with the SokoBomber remake, and I’m enjoying it as I’m comfortably using Vulkan in the easiest manner!