Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(ready) Scaling dungeon visible area. Has enhanced xBRZ scaling and custom window size too. #331

Merged
merged 160 commits into from Apr 16, 2018

Conversation

AquariusPower
Copy link
Contributor

@AquariusPower AquariusPower commented Mar 28, 2018

So, I guess it is better I do not drop new features on this PR, only fixes to let it stabilize (and I think it is already).

So I created another branch (based on this one here): https://github.com/AquariusPower/ivan/tree/ES2P_ShowItemsUnderPlayer

Better I will create a PR for it after this one kick in I guess? (I cant create another PR now to be merged later as github sends me here, as it is based on this branch)

Here is what it does (above head or on corners V/H, all easily optional), mostly useful when you are "going" and stop above something and have to read the log or try to get things:

showitems2

It was crashing, I solved it, but I am still testing it very hard (mm.. actually just playing a lot :)).


Out of scope changes are (all of them expectedly, need to browse the code a bit more) in other PRs.
Tho all "merged back" here, so I single keep testing all of them at once, but not hard to remove or modify if needed.


So, it is playable now.
Also the configurations that require restart work properly too.

DONE: the non-visible dungeon squares should be stretched without xBRZ to blend better with the remaining ones (can't find who gave that tip, will link later when I find it).

Full dungeon xBRZ x6 scale is quite heavy on my machine (4 FPS), so I coded frame skip option.
If -2 will skip all frames and only draw when you move, quite responsive (as possible..), but no stand-by animations.
If -1, will use automatic frame skip values based on one frame rendering time if above 100ms.
From 0 to 100 is user fixed skip values.

I may update the screenshots later as some things changed a bit, but it is easier (for me hehe) if you just try the game itself.

I have coded some things out of this specific pull request scope, like some sounds additions and adjustments, some other options etc.
If you believe it is better to discuss them in other pull requests, I think it is not that hard to move them away to another branch.

To let travisci just retry (like when it fails to download something), I am using this: https://stackoverflow.com/a/31694534
But I think there is a way to enable a button that allows us to just make it retry w/o having to push dummy commits.

Obs.: if I am delayed for any reason, and cant complete this work in an "expected time" (w/e that could be), anyone feel free to do so, and release it :)


hi!

It is finally working well concerning speed and memory usage, only deleting allocated memory wasnt enough, I had to create caches to store tmp SDL surfaces (to be simply overwriten avoiding new mem allocations) and xbrzlib internal img data.

EDIT: But of course fully scaling the dungeon it is still slower than vanilla (x1 scale). May be optimizing xbrz to 16bit color (it works with 32bit color), may do the trick (one day).

I appreciate tips on the source code, if what I coded may make maintenance more complicated, please point out and preferably suggest an alternative :)

Todo list (may be :)):

  • (seems good to look better) the option to xBRZ only around player should only be applied to visible squares to speed up and look good.
  • (This one is required tho) grant that with all new options disabled or default (ex. in 800x600) the game is still working as vanilla: fast and that everything else looks ok.
  • (DONE) scale up shown equiped items when accessing inventory and equip menu.
  • (DONE) scale up items to dip/into, to eat, to open etc when browsing them
  • refinement: details like precise positioning, outline to stretched blits, no transparency where there shouldnt have and any other things that could push us away from perfeccionism :)

ideas to be tested one day (not for this pull req tho)

  • The scaled blit could be further intercepted. One day, after scaling being integrated for each square's layer drawing, instead of sourcing from a 16x16 graphics, we could redirect and source directly from a 64x64 graphics and then, instead of scaling it would blit directly the bigger image. Not completely sure it is really doable tho. - The game needs upscaling options. #324 (comment)

It is playable but there are still a few problems:

  • (FIXED) the text history log is shrinked (matching reduced dungeon visible area), need to find where it is setup.
  • (95% FIXED, 5% BAD for short dialogs) the original size x1 dungeon area will show up, tiny behind de dialog, when any dialog is opened, like equip menu
  • (FIXED) if you play with the configuration value concerning xbrz scale factor in-game menu, it will stretch the whole window up, still have no idea why...
  • (WORKAROUNDED) the dungeon area outline must be redrawed independently of the stretching
  • (FIXED) the player name may vanish if using any scale >=2 (it remains there just below the small dungeon drawed area that got scaled up)
  • (FIXED) if you use bigger window resolution than 800x600: the main menu background is messed; also some screen regions where text got drawn and arent cleaned after;
  • if, at config file, the default player name is empty, when you hit start (1) it will ask for a name, when you go back, and chose continue, the game will be utterly slow, requiring restart the engine.
  • scale dungeon above x3 is crashing
  • (FIXED) the smiley and message is not showing on death animation (all black) and new game
  • while talking to petrus the text is scaled up (unreadable the remainder out the screen)
  • while loading a new area, the spinning animation is blocked by scaledup black rectangle
  • (FIXED) main menu background messed up

Need tips:

  • if you scale up too much using dungeon xbrz, the x5 for the look mode becomes a bit useless, any suggestion here?

I wonder if someone could test it also to catch more problems so we try to fix b4 merging (just drop a pullreq for any changes u make). Tips also are welcome :)

new cfg options:
selection_071

Suggested config file values for performance, easy to read messages log and big graphics, for wide monitors 16:9 (the WxH will fit properly in full screen mode):

WindowWidth = 1062;
WindowHeight = 610;
LookZoom = 1;
XBRZScale = 0;
XBRZScaleLookMode = 1;
XBRZSquaresAroundPlayer = 3;
SilhouetteScale = 4;
DungeonGfxScale = 3;
GraphicsScale = 1;
AltListItemPos = 1;
AltListItemWidth = 460;
ShowTurn = 1;
FullScreenMode = 1;

and how it looks:
ivan 0 52_062

silhouette scaled when browsing inventory and selected iventory item scaled to same place of look zoom command
ivan 0 52_065
and with alternate positionin option enabled
ivan 0 52_073

another option added: xbrz only around player position, so the user can chose how much his/her machine/CPU can handle, looks like this, pay attention how farer squares are not xbrz:
ivan 0 52_060

PS.: I may need to revert/undo the changes about the .devPrefs folder b4 merging too: https://github.com/AquariusPower/ivan/tree/DevelopersPreferences

Obs2.: if I am delayed for any reason, and cant complete this work in an expected time, anyone feel free to do so and release it, it is getting really cool :)


some old screen shots:
ivan 0 52_058b
selection_059
ivan 0 52_053
ivan 0 52_064
selection_063
alternatelistitempos
ivan 0 52_074b
ivan 0 52_076

## Eclipse developers preferences over different operational systems
## and personalized configurations.
######

# link to some user folder at /.devsPrefs
/.devsPrefs/Current

# direct links to preferences at /.devsPrefs/Current
/.cproject
/.project
/.settings

# Git ignore files are special. They are relative to their current path!
# If the one at '/.devsPrefs/SomeUserName/.gitignore' remains named like that,
# git will recognize and ignore files as that sub folder is a root folder!
# Therefore ONLY that file must be named like: '/.devsPrefs/SomeUserName/.gitignore.SomeUserName'
# And after creating the link to it, the link itself must be renamed to '.gitignore' to be again recognized by git.
/.gitignore
custom full dungeon scaling (from 2 to 6) working well but a bit slow.
still too much memory hungry! needs fixing...
changing dungeon scaling option in game is messy if not in full screen mode.
Obs.: beware full screen mode tho, may be hard to get to other apps if the memory is swapping..
SurfaceCache is working but not preventing that yet...
@AquariusPower AquariusPower changed the title (not ready yet) Enhanced Scaling xbrz for dungeon visible area. (not ready yet) Scaling dungeon visible area. Has xbrz and custom window size too. Mar 28, 2018
@AquariusPower AquariusPower changed the title (not ready yet) Scaling dungeon visible area. Has xbrz and custom window size too. (not ready yet) Scaling dungeon visible area. Has enhanced xbrz scaling and custom window size too. Mar 28, 2018
@ryfactor
Copy link
Member

Looks like execinfo.h is Linux only. It will need some preprocessor directives to skip over it for a windows build. See https://stackoverflow.com/questions/28680323/the-execinfo-h-header-file-does-not-exist
Do you know where all the parts of the code are that depend on it?

@AquariusPower
Copy link
Contributor Author

AquariusPower commented Apr 16, 2018

You are right: should be: yes, no and disabled.
Also, the 'no' option is bugged, I will fix it!
EDIT: no=zoom box bottom right corner, yes = to the left of the tiny item

@ryfactor
Copy link
Member

It's like a new game. Have you considered adding your enhanced scaling to something like DosBox?

@ryfactor ryfactor merged commit 0c99b11 into Attnam:master Apr 16, 2018
ryfactor added a commit that referenced this pull request Apr 16, 2018
…ng and custom window size too. (#331)"

This reverts commit 0c99b11.
@ryfactor
Copy link
Member

Oops, take no notice of that revert step. Just some fat fingers. Actually, I had some squash regret and was wondering if I could just revert and do a plain merge, but then I thought better of that, and decided just to leave it squashed.

@AquariusPower
Copy link
Contributor Author

AquariusPower commented Apr 17, 2018

Despite DosBox already have full screen stretching, the version I have here has no xBRZ.

The "stretch region" code could be adapted I guess, as it work on the real output to improve just parts of that output (the dungeon, the silhouette, the list items).

So, the regions would be necessary to be specified for each game independently.

I guess Syndicate would work great because the whole interface is static, we just need to detect thru the pixel's colors if we are at the world map, at the team customization, at the game combat etc, and for each kind of screen, it would require a specific set of regions to be stretched, and put all that in simple user readable (text editor) config files, so anyone could help on improving it :)

But that would only work for DosBox.

I think compiz can do regions stretching, but that is simple 3D stretch and no xBRZ, and also that feature is experimental I guess.

But If it could be created an application that would read the screen output of other applications, it could work with any games, like UnrealWorld survival, ADOM, or even normal (non games) applications.
I guess the problem would just be transfering the mouse position and clicks to the real application.
NoMachine and VNC could be the real targets for it I guess.

Conclusion: a modification of some GPL VNC-like application, to work on the localhost in a loopback connection, would be the best shot to provide stretched xBRZ regions for any other application/game.

Unless I am wrong in any of these untested steps xD

EDIT: well, I just click the default merge and hope it will be accepted :), overall github has been work well, despite sometimes I fully drop a branch as it is not accepting my "fast forwards" (w/e that is), and just create a new branch with the same name...

@andrewtweber
Copy link
Member

@fejoa I think squash was the right call with 160 commits

@AquariusPower
Copy link
Contributor Author

Most of my commits were just "backup commits" (this is how much I trust HD and pendrives...) of incomplete or not fully tested steps, some were even just a "go travisci go..." kind. :)

@AquariusPower AquariusPower deleted the EnhancedScaling2ndPart branch April 19, 2018 19:39
@Asmageddon
Copy link

Many emulators include various scaling options, though xBRZ is a somewhat rare one to see.

Anyway, just to check in, does this rescale everything that's on screen, just the tiles, does it scale the whole screen or just a part of it like one of the screenshots earlier?

@AquariusPower
Copy link
Contributor Author

AquariusPower commented May 19, 2018

It scales by regions:

  • dungeon region
  • silhouette + equipments region
  • single square in look mode (not actually "a region" yet as the code is implemented)
  • squares around player region (this is used when the full dungeon is scaled w/o xBRZ and the user needs performance (like me), then only some squares around player will be xBRZ scaled again and over the full dungeon).
  • the alternate silhouette is actually double scaled (player 16x16pixels to x3 xBRZ (actually 3x4 to be taller like the vanilla silhouette) and then it is scaled again thru user silhouette scale option giving a max of x 18x24 from the original 16x16 pixels, goes to max 288x384pixels, but even xBRZ cant do so much magic 😉 )

(I think these are all the regions for now)

PS.: as xBRZ was plugged in like a library, if a new lib comes by it will be easy/fast to adapt the code to it.

@Asmageddon
Copy link

You could probably reuse scaling from the previous frames, e.g. you only need to re-apply xBRZ to animated tiles, tiles that change, and some neighboring pixels and other than that you can just reuse the previous frame's render, to have more performant full-screen scaling. Still, it likely is not that necessary :-P

@AquariusPower
Copy link
Contributor Author

Yes, indeed!

The initial goal was to provide a huge lot of spread features with good enough performance to be usable and make the game more cool to play.

After everything is stabilized and working correctly, we may spend time on performance improvements, unless there are other priorities xD

@AquariusPower
Copy link
Contributor Author

@Asmageddon
btw, one problem on only applying xBRZ to tiles that change was that the quality would be lowered, because applying in all adjacent tiles at once, they blend with each other and it looks much better! but I just thought about it, didnt actually test it..

@Asmageddon
Copy link

Asmageddon commented May 29, 2018

@AquariusPower There's a certain radius that changes affect. E.g. if 16x16 pixels change, the actual area you need to rescale is 20x20 or 24x24 (not sure), but since those 4/8 edge pixels don't change, pixels beyond that region do not need to be rescaled, and you can reuse last frame's results.

That kinda thing is what I meant - you can keep things nicely blending together while rescaling only changed areas, if you rescale their neighbouring pixels/tiles as well.

That way you could probably squeeze enough extra performance out of it to do full-screen scaling.

@AquariusPower
Copy link
Contributor Author

AquariusPower commented May 29, 2018

@Asmageddon
the same clue used to hint what squares must be updated in vanilla when using SendStrongDrawRequest call, could be used to update the stretched ones.

But there is some other problems: rain, snow and light variations (like when carring a crystal rock).

The only way I see to work around that would be to cache all the variations (like all snow/rain falling positions) but all possible light variations would not work well I guess..

So I think that or someone do the new tile size full code conversion, preferably not less that 64x64.
Or we multi-thread the xBRZ calculations, to unencumber the one core used for everything.
Or someone with the knowledge (CUDA code in GeForce at least), to let the GPU make xBRZ calculations (as there is no 3D going on, and the GPU is practically in stand by I guess?).
Or we can tweak xBRZ to make it more performant, not necessarily the code, just it's config file, yes it is a header as I remember.

But again, most of the time we keep the focus on the player and his surroundings.
That other moments we look farer is to check something but would be like what? 10-20% of the time?
So... another option in a brainstorming mode, would be:

  • install a camera to detect where you are looking at the monitor.
  • transfer that information to the game, like a mouse cursor would.
  • let xBRZ work around that spot.

And finally but much simpler would be to add support to xBRZ compute just around "Mouse Position" if it is moved, and fall back to player if he moves xD (mmm... this sounds really cool!)

@Asmageddon
Copy link

I'm not that familiar with xBRZ, but it seems like it could be done with GLSL 120 no problem, without the need for CUDA. I wanted to do it once, but... as shameful as it is to admit as someone whose only skill is programming, I cannot code, because of anxiety issues, these days...

Rain/snow could probably be done on a separate layer, same as UI and the fog of war overlay, and then do what I said for the main map. Light could still be problematic, but tiles out of view usually don't change so you'd still be cutting down from 100% of the dungeon needing rescaling per frame to 40%-15% or even less while not moving.

Honestly all of this would have been simpler if IVAN's rendering code was modular OpenGL from the start, it's so much faster and you don't really ever need to worry about needing to do temporal reprojection in 2D shaders because they tend to be more than fast enough even on old hardware.

@AquariusPower
Copy link
Contributor Author

AquariusPower commented May 31, 2018

GLSL120 uses the GPU then? that could suffice, the whole point is unencumber the single cpu ivan uses.

yes, rain/snow in separate layer with transparent mask is fine for sure!

actually ALL non visible squares could be ignored, scaled up almost only once, and not every frame!
in towns, in day light, is the biggest problem where practically all the visible area may be changing and being affected by lights.
By what I read on the code, they do a precise blending based on the distance of all light sources, including mutant blood to change every square,

I am not sure OpenGL does that well, if I am not wrong, when we have a lot of light sources in 3D (like when I use JMonkeyEngine 3D java that uses OpenGL), things start getting slow or glitchy, dont remember well, would have to confirm this tho...

If it helps, this is what I do to keep calm.

constantly lose focus to calm down, or be aware of everything else (Jiddu Krishnamurti),

and drink a lot of water sip by sip everytime you feel a bit thirsty what is relaxing, and shake your hands above head to lower stress on it (Unibiótica)

also, interestingly enough solutions to problems come when we forget or stop thinking about them, usually differently from what we initially thought how it should be :)

(how-to collapsible (but the links are plain html with href :))

@ryfactor
Copy link
Member

I wanted to do it once, but... as shameful as it is to admit as someone whose only skill is programming, I cannot code, because of anxiety issues, these days...

Your candidness moves me. It's no shame friend, and programming is not your only skill : )

@Asmageddon
Copy link

You likely don't need OpenGL to do tile-based lights. When I did a C++ demo, I could do 200 lights on a potato PC before running into any real slowness.

Lights in 3D are also significantly different from lights in 2D. In 3D, you usually render the scene from the point of view of the light(or up to 6 points of view, in the case of spherical lights), to generate a shadowmap, and then for every pixel, you check every light... well, it's simpler than it sounds actually, just not easy to describe with words. Also there's heaps of optimizations you might want to do, like cascading shadowmaps, or splitting the screen into tiles and checking which lights intersect which tiles and a lot more that I don't know enough about to talk about.

On the other hand, in 2D there are two main approaches, one is raytracing, the second is polygonal shadowcasting, IVAN doing the former - and with tiles, it's certainly fast enough to not need to be implemented in a shader.

What could benefit from being implemented in a shader though, is xBRZ, and blitting the tiles in general, since blitting bitmaps is a relatively expensive operation, and compared to that, several thousand properly batched triangles is essentially free(since modern GPUs can do many millions), and xBRZ implemented in a shader would probably be a few hundred times faster than what you've got here, too. MAME or something might have a GLSL implementation of it, there's few projects out there that have a lot of these shaders.

Still, I shouldn't be talking out of my butt here, it'd take some overhauling to get shaders going. Though I suppose you could always take what IVAN draws, upload it to VRAM, and render it via OpenGL with a shader. Kinda distastefully hacky, though.

@AquariusPower
Copy link
Contributor Author

AquariusPower commented May 31, 2018

Once I tried to read/code a shader, that language quite confuse to me, but some ppl seem to master it.
The best place to post a suggestion would be here I guess: https://sourceforge.net/projects/xbrz/
So in short: someone that master shaders and how xBRZ works would be required for the conversion.
I thought on CUDA because I believe it can run compiled code like from c++ and then conversion wouldnt be required, but then I think it is limited to geforce, what is not that bad, and being easier than a shader conversion will benefit at least geforce users.

Considering the complications, the easiest test would be multithread xBRZ computation and see what happens I guess, so even a potato with 2 cores and no 3D card will benefit from it, being a more broad option would be better as 1st perf improvement attempt :)

@Asmageddon
Copy link

Shaders are much easier to get into if you start with writing some simple stuff yourself, then understanding and tweaking slightly more complex examples.

In some ways they're like normal code, in others, they're mainly just math. Most of the friction comes from different conventions, e.g. Y coordinate is flipped, RGB values are 0-1, you can swizzle, e.g. do pixel.rb to get the equivalent of vec2(pixel.red, pixel.blue). Beyond that it's mainly just math on vectors, with limited branching(if) capability and syntax similar to C.

Also, I found this via a cursory search, libretro's implementation of xBRZ(4,5,6x and freescale ones, whichever the last one does) here: https://github.com/libretro/glsl-shaders/blob/master/xbrz/shaders/4xbrz.glsl

The lines prefixed with uniform are inputs, output is I think just the FragColor = vec4(res, 1.0); line unless I've missed something, and the file includes both vertex and pixel shaders wrapped in their respective #if defined(VERTEX) and then after one of the #else preprocessor macros.

I don't think it has any real libretro-specific code besides some unused uniforms, though I could try testing it tomorrow, it seems to be written for GLSL 130 which corresponds to OpenGL 3.0.

@AquariusPower
Copy link
Contributor Author

AquariusPower commented May 31, 2018

forked thx!
interesting... that code is quite readable and not that big. may be I put my hands in some confuse code and got a bad feeling about it...
despite sometimes we use 6xBRZ, for the full dungeon area 4xBRZ (the glsl one) could suffice!

so, basically, we have 4xBRZ shader,
now just need to plugin to ivan code as an alternative to the current full dungeon xBRZ scale option.

there is a stretch region configured for it,
when we use the "xBRZ around player" option, it will still stretch the "mini dungeon" (from doublebuffer) but w/o xBRZ (using vanilla simple stretch) and will stretch with xBRZ the area around player over it (into the stretchedbuffer (that actually has the same window size in pixels :))).
that is the place that can be transfered to the shader (I dont really know how to plugin shaders and how to send data to it btw)

@AquariusPower
Copy link
Contributor Author

@Asmageddon btw, I think this is a valid new issue: to improve xBRZ usage performance, if you prefer creating it.

@Asmageddon
Copy link

@AquariusPower That's up to you, you're a contributor, I haven't even tested this myself to ascertain how bad the performance issues are :-P

Either way, if you wanted to use GLSL xBRZ(and you could probably copy the other shaders from the linked repo, just be mindful of the licenses), the best way to do it would probably be to start with using OpenGL to render to screen, then take the (unscaled) dungeon bitmap, and instead of rendering it to the bitmap you'll draw to screen directly, render it with a shader via OpenGL. I've mostly worked with wrappers around OpenGL and it's been years since I've coded, so I can't tell you more than that. It might be a pain in the ass, if you've not used OpenGL previously, though.

Anyway, sorry for spamming this place.

@AquariusPower
Copy link
Contributor Author

@Asmageddon

oh no, I mean create a new issue because despite we are talking here, to others this is may be practically a dead thread.

So, being a new issue, ppl with actual OpenGL knowlege/experience may get interested and give tips on what to do, or even the easiest way to let it work on ivan.

Also, anyone can create an issue! :D

May be that issue could use as starting point this post: #331 (comment)

I shouldnt create it because I have very little OpenGL knowledge (if any at all hehe), so if ppl ask something I wont be able help them.

Though I learned a lot about how ivan currently works, and about it I can give tips.

@andrewtweber
Copy link
Member

andrewtweber commented Jun 13, 2018

sorry for the off topic interjection:

@AquariusPower are you a member on Attnam.com? That is the fan forum that I run (the rest of us continuation devs are on there) and it would be good to have you there.

I was finally able to try out the xBRZ scaling, this is amazing! Nice work

@AquariusPower
Copy link
Contributor Author

Cool, I'm still not there, but have read some posts :)
I expect all these new features bring more devs to further improve this great game! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants