News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Altered Window Sizes When Returning from DirectX

Started by satpro, January 08, 2015, 06:25:13 AM

Previous topic - Next topic

satpro

Hi Everyone,

Here's one I've been struggling with a bit.  It concerns DirectX (in this case 9) and what happens when exiting and restoring the previous display mode in Windows. I wonder if (and hope) someone here has encountered this and knows the answer.  I'm officially stuck and coming down the home stretch.

As the example, my monitor is 1920x1080, although it could be anything, while the program's on-screen pixels are set to 800x600 bordering a centered 640x400 screen.  In my case it's a project with an emulated 65816 cpu in a spiffy version of the old C64 with 16 64x64 sprites, etc., and an 8-bit, table-driven software palette.  It's basically an 80x25-column, 640x400 hires, 256-color C64 with 16 sprites and an always-native 65816 (not at all like a SuperCPU).  Something new and different.  The C64 stuff is irrelevant actually and only for problem explanation; it's placing all that properly on the PC screen which has me befuddled.  I've been successful doing this Windows-only but would really like to use DirectX, if only for the personal reason of accomplishing this in 100% ASM.  This issue is only about returning from screen resolution changes.  The conversion and transfer to back buffer from a color code in emulated "screen video RAM" to 32-bit XRGB color is no problem, sprites included (heck, even the '816 cpu code works fine), but the problem I'm having trouble with is returning from the program's resolution to the original user's resolution.  The previous on-screen windows (only if NOT maximized) come back re-rendered as if they were sized in an 800x600 environment.  The same thing happens at any resolution less than the user's original.  To me this seems extremely inconvenient for the program's end user.

Does anyone know why this is, and if there's a remedy?  I feel perhaps I'm doing something out of order when returning from full-screen -- or is that just the way it is with DirectX?  Surely it can't be.  I have tried keeping the original resolution and then it's just some math to center (and stretch) the emulated video on the larger "real" screen, even with an algo to stretch (say 1/2 or even 3/4) of the way to the outer edges of horizontal and vertical monitor limits, which gives the look of a border, albeit variable (which is okay, especially with a variable X/Y algo), depending on the user's monitor type.  It would be nice to stay with some kind of "authentic" and comfortable full-screen resolution which makes one feel like it's an old computer, especially the somewhat "blocky" look.

I have messed with fixed-width borders, variable-width borders, and just the lower resolution altogether, but I feel there must be a better way to get it right.  Worst-case scenario at this point is putting up with the smaller (only non-maximized) windows upon return from DirectX at 800x600.

Does anyone here know the answer?  I'm not a "game guy" by trade so this is an area where solid information has been hard to come by.  The C/C++ forum people think the very idea of an all-assembly program is nuts to begin with, even if the finished program (bells, whistles, and a basket of fruit  :biggrin: ) will be nowhere close to 1 MB in size, so I'm no longer going that route -- too much antagonism.

Thank you in advance,
Bert

Tedd

If you're switching modes with ChangeDisplaySettings then this is expected.
When you change the screen mode, this results in the desktop being resized -- so then the windows on the 'new' desktop must be moved/resized so they remain on screen. Then when you switch back (to the original higher resolution) the windows are already in visible positions and so don't require moving again (there's no knowledge of where they 'were.')

The correct way to do it is using IDirect3D9::CreateDevice, which will change the screen device mode, but not the desktop size; so when you return, the desktop is just as it was.

I've just done a quick test with a few different resolutions and color formats, and it does work correctly.
If you are already using CreateDevice then you'll have to post a stripped version that changes mode, delays 3 seconds, then switches back and exits - then we can take a look.


As an additional point, I'd consider that with the majority of screens now being LCD/LED, changing mode can lead to pixel blurring when the current resolution isn't an exact multiple of the native resolution. And so the blocky pixel effect may be spoiled by this. In which case, it may be better to not change resolution and instead scale up your viewport by an exact multiple, with a small variance in the border size.
Potato2

satpro

Thanks for the quick reply, Tedd.  I am using CreateDevice but am also still working at understanding and fixing this, despite being "stuck".  The desktop hint gave me an idea in another direction as well.  :t

I realize this wasn't strictly an ASM question.

Siekmanski

Hi satpro,

You could show us your code, or I can give you my Direct3D9 initalisation code to look at.
It can togle between windowed and fullscreen mode.

Marinus
Creative coders use backward thinking techniques as a strategy.

satpro

Quote from: Siekmanski on January 08, 2015, 01:20:47 PM
Hi satpro,

You could show us your code, or I can give you my Direct3D9 initalisation code to look at.
It can togle between windowed and fullscreen mode.

Marinus

Hi Marinus,
Thank you for the offer.  I'll happily read and study from your Dx9 init code for sure (my toggle code is a bit hacky I think -- a sloppy C conversion from a book, and it doesn't always work right).  I definitely intend to share the program and its source here somewhere, and once I can get past this mind hangup with the screen resolutions it should not be that much longer.  I've been working on this for many years now; the 65816 cpu emu code is basically finished, the sound still needs some tightening up but does play files okay, and so fully moving from hard-coded DirectDraw pixels to the more-flexible Dx9 approach is like (almost) the last thing to do, other than adding functionality for some of the legacy C64 disk image files (for a bit of crossover compatibility), fixing some lame program artwork, and adapting the '816-based Winc64 OS for it (that part is from the 90s until about 2012, originally written for the SuperCPU) and so finishing the x86 container is where it's at now).  I'm using GoAsm and need to work on adapting some MS$ D3DX9 header file stuff yet, too.  I don't think we have any yet for GoAsm, or at least I don't.  MASM code is fine to read from and I mostly understand it -- GoAsm is just more like the older 65x assemblers so I have always felt very comfortable and familiar using it.

I wish to be mindful not to yap too much until it's all together and really working though (the whole thing is literally at least a couple hundred files), but I am very appreciative for the help and suggestions so far, and getting more excited about finishing it each day.  Thank you.

Tedd:  The Viewport was a good idea.  I was not originally sure how to go about it, but sat down and read most of the day about it and think tomorrow I'll write it.  Thank you, too.

P.S.  My avatar is a screenshot from the native-mode SuperCPU version at 320x200, with only 2 colors possible per 8x8 cell.  It has double buffering, uses a mouse, and the OS functions are patterned after the Windows API.  I just felt it would be much better in an expandable, colorful, linear video environment with lots of modern technology to work with, so...  along came this project to house it.

Siekmanski

#5
Hi satpro,

Here is my D3d9 initalization code, it has resizable windowed screens and can toggle between windowed and fullscreen.

edit: F1 to toggle screen

Marinus
Creative coders use backward thinking techniques as a strategy.

satpro

Thank you very much!
FS/Windowed works well.  I did actually look and found the "F1" when "ESC" wasn't getting it  :biggrin:
Will get something out as soon as possible.

One thing that is making me re-think some things:  MASM is soooo strong with macros and typedefs, it makes converting from C/C++ much easier IMO.

Siekmanski

Creative coders use backward thinking techniques as a strategy.