VOGONS


First post, by Yushatak

User metadata
Rank Member
Rank
Member

Where in the source tree in what file is the location of the scalers? In patched versions there is support for ".fx" D3D shaders, and those are separate files. I tried to use this for what I wanted but found the ".fx" language semantics required for DOSBox to use them infuriating. Thusly I turn to creating a traditional scaler, and thus my question.

Thanks.

Oh and for those who may be curious, my goal is to create a "CRT Emulation" scaler that will distort the image and possibly also add scanlines (of a different nature than the existing scanlines/tv scalers). In this regard I'm concerned that the traditional DOSBox scalers might require a uniform algorithm to apply to the screen and am not sure if it will be possible to achieve my goals..

Reply 2 of 8, by Yushatak

User metadata
Rank Member
Rank
Member

I didn't find the *language* confusing, I found trying to adapt shader code from the 'net to work with DOSBox confusing, as it seems to require extra things to get working. Anywho thanks, I'll be looking into this.. 😁

Reply 3 of 8, by Yushatak

User metadata
Rank Member
Rank
Member

Alright I made a new template section for my scaler in the render_templates.h file, and began to investigate the structure of the existing scalers. I found that they all had a good number of obscure variables in them, so I figured a good place to start would be to identify them.

I scrolled around and found the definitions for C1->D6, which appear to represent the structure of some kind of rectangular thing. I'd imagine that this is either a virtual pixel, a group of virtual pixels (each variable representing one), or the screen as a whole, most likely the middle option.

They are in the following arrangement both according to the variable definitions and according to a comment I found:

c0 c1 c2 d3
c3 c4 c5 d4
c6 c7 c8 d5
d0 d1 d2 d6

Can someone confirm that my theory as to their purpose is correct? Is there any documentation on this beyond source comments, or perhaps someone knows this bit of code inside and out and could write up a short explanation? Either way if my theory is right I'm beginning to understand it.

Reply 4 of 8, by Yushatak

User metadata
Rank Member
Rank
Member

Deciding that a "simple" scaler would be a bit easier to start with, and since I'm not sure of the differences between the types yet it might be all I need, I have created a simple scaler (does't achieve what I want yet, but I want to get something set up that I can see the results of before I pour effort into it) and successfully compiled DOSBox with it included.

Everything is going well, except that when I start the fresh copy of DOSBox with a configuration file indicating to use my new "crt2x" scaler, the console says:

"crt2x" is not a valid value for variable: type.
It might now be reset it to default value: normal2x

Now, from what I gather this means it won't run my scaler. I must have missed a list of valid input variables mapped to built-in scalers..

I've modified the following files:
- render_templates.h
- render.cpp
- render_scalers.h
- render_scalers.cpp

And I've looked through:
- render_loops.h (used for complex if I understand)
- render_simple.h (used for simple scalers if I understand)

Both of these seem to be generic routines for rendering and don't need to be modified for my purposes.

Any I've missed?

Reply 6 of 8, by Yushatak

User metadata
Rank Member
Rank
Member

Hah. Thanks - I knew it would be something obvious like that. 😀

Woo. My test worked great now - I created a version of the scanlines scaler that did vertical lines instead of horizontal, just for testing, and it performed exactly as intended. 😁 Now to see if I can get some CRT-emulating stuff up and running, either here or as a complex scaler..

Edit: I'm starting to think that perhaps a scaler isn't the right thing for this job.. I've figured out how to get both a simple and a complex scaler set up so I can muck with the settings and algorithms, and both seem to be focused strictly on small portions of the screen (size depending on how much you're upscaling the image).

What I'm looking to do is warp the entire image just before it's written to the window for viewing. I want to apply an algorithm that will bend the image as though it were being displayed on a curved CRT display, perhaps with a black overlay in the corners where the "virtual screen" would end.

It's possible that if I understood complex shader coding better I might be able to make one that would shift the positions of pixels based on distance form the center and in what direction. It's a matter of knowing what function/variable to query to determine the location of the current pixel(s) being worked on, then.. Could someone more experienced with scalers comment on the plausibility of this?

Perhaps I should be editing the rendering process itself, and then once complete add a configuration variable to toggle my new code? render.cpp then? Any suggestions?

Edit 2: Idea.. perhaps create a 3D rendering window for DOSBox's main window, and then render the output of DOSBox's video subsystem onto a 3d object of a curve or just warp it in 3D space to that shape? Not sure if that would be easier or harder, hah.

Edit 3: Alternatively to the above alternative (lol) - perhaps someone could convert this .fx shader to a form where DOSBox won't have trouble with it (in the patched versions that take .fx shaders, of course).. I tried and failed miserably before posting this thread in the first place.. :


1 sampler ColorMapSampler : register(s0);
2 sampler GradientSampler : register(s1);
3
4 float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
5 {
6 texCoord += (texCoord - (0.5, 0.5)) * tex2D(GradientSampler, texCoord).a * 0.1;
7
8 return tex2D(ColorMapSampler, texCoord);
9 }
10
11 technique Bend
12 {
13 pass Pass1
14 {
15 PixelShader = compile ps_2_0 PixelShader();
16 }
17 }

I, of course, can't be sure if it produces the desired output, but it's supposed to warp an image like a CRT, so it ought to.

Reply 7 of 8, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

you probably already have discovered it, but dosbox only updates the parts of the screen (lines) that have been changed for speed reasons. The scalers are written with that in mind. So scalers that should work between 2 instances of the same screen need to be aware of this. So you have to think in changed lines and apply the wanted effect to that.

Water flows down the stream
How to ask questions the smart way!

Reply 8 of 8, by Yushatak

User metadata
Rank Member
Rank
Member

Putting aside the problem of scalers only affecting lines that have changed, what of the ability to determine position?

As I can tell, I can affect a line at a time. Whether you're upscaling or not just means a single line is translated into X number of lines where X is 2 or 3 usually depending on the scaler, i.e., "normal2x" has two lines for every one.

That said, how can I get the current original screen width and height, and how can I tell what line I'm on?

If I could get this information, I could run a check against the height based on what line I am on to determine the appropriate vertical deformation, and check which pixel I am on horizontally using a loop with index and comparing it to the width. In this way I could come up with a proper algorithm through trial and error that would replicate the bend of a rounded CRT's sheet of glass.

From what I've read of the source (and I've read a fair amount now), it should be possible to toggle the screen's storage of previous frame data by changing some variables, if I'm not mistaken, by changing the "Clear Cache" functions from false to true in parts of sdlmain.cpp. I could be wrong of it's effects, though.

Anyway if pixels aren't changing the effect will remain as it should anywho - once deformed it shouldn't need to update until something changes anyway, and the effect will be calculated the same way as long as the resolution stays the same..

So yeah - anybody know how I can ascertain the above information from within a scaler?