Cocktail table effect

can this effect be done with a shader?

http://toastedtechs.com/cocktail/wp-content/uploads/2013/05/mame_icon_cocktail.png

mirrored images for use on arcade cocktail tables.

thanks!

I finally got to work on this a little bit and I have something that works, though it’s likely suboptimal since it currently has to be hardcoded for each resolution :frowning:

Luckily, it’s not hard to tweak the settings (I put 3 #defines at the top of the shader where you can adjust to fit the height, width and location of the images), so you can have one for each of the games you want to play. Also, you’ll need to set your RetroArch aspect ratio to 16:9.

I included SNES/NES, Genesis and Street Fighter (tested working on SFA2 and Third Strike) versions as examples of how to adjust them: http://www.mediafire.com/download/7e58v … haders.zip

Here’s what the code looks like (this is the SNES one) in case anyone would like to come up with a better, more universal way of doing it:

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

#define height -1.145
#define width 2.0
#define location 0.75

struct input
{
  float2 video_size;
  float2 texture_size;
  float2 output_size;
  float  frame_count;
  float  frame_direction;
  float frame_rotation;
  sampler2D texture;
};

void main_vertex
(
	float4 position	: POSITION,
	float4 color	: COLOR,
	float2 texCoord1 : TEXCOORD0,
	float2 texCoord2 : TEXCOORD1,

    uniform float4x4 modelViewProj,
	uniform input IN,

	out float4 oPosition : POSITION,
	out float4 oColor    : COLOR,
	out float2 otexCoord1 : TEXCOORD0,
	out float2 otexCoord2 : TEXCOORD1
)
{
float4x4 RotationMatrix = float4x4( height, 0.0, 0.0, 0.0,
									0.0, width, 0.0, 0.0,
									0.0, 0.0, 1.0, 0.0,
									0.0, 0.0, 0.0, 1.0 );
															
	oPosition = mul(mul(modelViewProj, position), RotationMatrix);
	oColor = color;
	otexCoord1 = mul(position.st , float2x2(0.0, 1.0, -1.0, 0.0)) + float2(location, -0.500);
	otexCoord2 = -1.0 * (mul(position.st , float2x2(0.0, 1.0, -1.0, 0.0)) + float2((1.0 - location), -0.500));
}

struct output 
{
  float4 color    : COLOR;
};

float4 main_fragment(float2 texCoord1 : TEXCOORD0, float2 texCoord2 : TEXCOORD1, uniform input IN) : COLOR
{
float4 color = float4(tex2D(IN.texture, texCoord1) + tex2D(IN.texture, texCoord2));
   return color;
}

With RGUI parameter-editing, this shader is actually reasonably useful :open_mouth:

#pragma parameter height "Image Height" -1.145 -3.0 3.0 0.01
#pragma parameter width "Image Width" 2.0 1.0 5.0 0.05
#pragma parameter location "Image Location" 0.75 -2.0 2.0 0.005
#ifdef PARAMETER_UNIFORM
uniform float height;
uniform float width;
uniform float location;
#else
#define height -1.145
#define width 2.0
#define location 0.75
#endif

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

struct input
{
  float2 video_size;
  float2 texture_size;
  float2 output_size;
  float  frame_count;
  float  frame_direction;
  float frame_rotation;
  sampler2D texture;
};

void main_vertex
(
   float4 position   : POSITION,
   float4 color   : COLOR,
   float2 texCoord1 : TEXCOORD0,
   float2 texCoord2 : TEXCOORD1,

    uniform float4x4 modelViewProj,
   uniform input IN,

   out float4 oPosition : POSITION,
   out float4 oColor    : COLOR,
   out float2 otexCoord1 : TEXCOORD0,
   out float2 otexCoord2 : TEXCOORD1
)
{
float4x4 RotationMatrix = float4x4( height, 0.0, 0.0, 0.0,
                           0.0, width, 0.0, 0.0,
                           0.0, 0.0, 1.0, 0.0,
                           0.0, 0.0, 0.0, 1.0 );
                                             
   oPosition = mul(mul(modelViewProj, position), RotationMatrix);
   oColor = color;
   otexCoord1 = mul(position.st , float2x2(0.0, 1.0, -1.0, 0.0)) + float2(location, -0.500);
   otexCoord2 = -1.0 * (mul(position.st , float2x2(0.0, 1.0, -1.0, 0.0)) + float2((1.0 - location), -0.500));
}

struct output 
{
  float4 color    : COLOR;
};

float4 main_fragment(float2 texCoord1 : TEXCOORD0, float2 texCoord2 : TEXCOORD1, uniform input IN) : COLOR
{
float4 color = float4(tex2D(IN.texture, texCoord1) + tex2D(IN.texture, texCoord2));
   return color;
}

Also uploaded to common-shaders repo.

I know this thread is a couple years old but… I can not figure out how to edit the rotation of the screen 90 degrees clockwise. Can anybody clue me as to what needs to change? Thank you!

What are you wanting to do? You mean with this shader? Or are you just trying to rotate your screen without doing the double-image cocktail table effect?

My screen is set to portrait. So this shaders current config has the screens side by side left and right just as its intended for a landscape screen. I was hoping I could edit the shader so that it’s just rotated vertically or specifically 90 degrees clockwise from its current setting.

Sure, it’s just a matrix that you multiply the modelviewproj against. However, in settings > video, there’s a rotation option that will let you rotate the entire interface however you want. I think that might be more useful for you.

Thank you. That should do the trick.

I’ve looked around, but am having difficulty finding any clue as to how to convert the above source code into an installed and functioning shader. Where do I need to put it? What do I need to recompile to get it built and installed? What settings in what files need to happen? I’m missing a whole bunch of info, and instead of flailing around wildly, I thought I’d ask the folks who were actually using it successfully how they did it. I’m sure I’m not the only one in this situation.

Help please?

First, go to the online updater and update whatever sort of shaders you’re using (GLSL is the most compatible). Then, load up a core+content and go back into the menu and go to ‘shaders’. In that menu, you should see a line at the bottom that says: shader passes 0. Increment that to ‘1’ and it will make a couple more lines appear. Where it says “shader #0,” navigate to and select shaders_glsl/misc/cocktail-cabinet.glsl, then go to the top of the shader menu and choose ‘apply changes’. You should start seeing the effect, and it should be lined up properly for some cores (notably, S/NES). If the screens are not lined up, go back into the shader menu and you can move things around in the ‘preview’ shader settings menu. When you get things looking how you like them, reproduce those settings in ‘menu’ shader settings and then ‘save core [or game, as the case may be] preset’ to make RetroArch load it whenever the core (or game, if you saved a ‘game’ preset) is loaded.

Okay, so after updating the shaders (via the Emulation Station -> RetroPie -> RetroArch -> Online Updater -> Update GLSL Shaders), I started a game from the Emulation Station on the RetroPie, pressed F1 to get to the RetroArch menu, went to the Quick Menu (first option) -> Shaders -> Shader Passes and pressed right to up it to 1, then down to Shader #0 -> Shaders_GLSL / Misc / cocktail-cabinet.glsl, then up to Apply Changes, then back and Resume. Once I had confirmed it was working, I went back into the quick menu (F1), and went down and selected Save Core Overrides. Almost everything is good…

However, now every time I press Start, it brings up the RetroArch menu instead of sending Start to the game. Help???

Well, first off, you should use a core preset rather than a core override, which is a subtle difference but shader presets are not always captured by the regular overrides. I have no idea why ‘start’ would be going into the menu all of a sudden. Overrides don’t capture input settings, so that shouldn’t be related.

I’ve tried going into the Input section, but nothing there seems to have any effect on the “Start as F1” effect. Any ideas on stuff I should try? I’m at a complete loss here…

(BTW: Thanks for all the help you’ve given! It’s been invaluable in getting this working right!)

The only thing that should be related is in settings > input > hotkey binds > menu toggle. Go over to it and try hitting start there (that is, don’t press the ‘accept’ button to make it listen to input, just hit ‘start’ over the option; that’s the mapping for ‘return setting to default’).

Weird. I’m not getting the behavior you’re describing. When I go to that menu option, pressing “Accept” does nothing (next keypad press goes on as normal), but left / right cycles between options. It’s set to None, and the Start button still acts as a menu button. Pressing the Start button on it just turns off the whole menu and resumes the game.

Nevermind… I found it. It said F1; I pressed Start and nothing happened. But when I left that menu, Start was no longer the Menu toggle. Weird. Where do I need to save to make sure this sticks?

That depends. If you have a core override loaded, your settings won’t save (this is on purpose, so your overrides don’t pollute your main config). If that’s the case, you’ll need to go change the setting before you load any cores that already have an associated override. After you change the setting, quit via the ‘quit retroarch’ menu option and it should write it to your config.

If the problem shows up only after you launch a core with an associated override, it’s because the setting resides in the override itself. If this is the case, load the core (and it will say ‘override loaded’ or whatever), change the setting and then save a new override, which should overwrite the old one.

Something else I’m noticing - The screen is being clipped (expanding height, moving X, and increasing zoom all cut the image off at a certain point) down to a much smaller size, long-wise (up-down in portrait mode) on the widescreen monitor, and the exact cut-off varies between arcade games; nes and snes seem to have a fixed cut-off for each as well. Is there any way to make it not cut off, and use the entire screen?

go to settings > video and set the aspect ratio to 16:9. That will let it use the entire screen area.

That did it! Thank you for all your help! You’ve been amazing!

1 Like