The MASM Forum

Projects => Rarely Used Projects => Custom Interface Components => Topic started by: fearless on June 28, 2019, 09:38:27 AM

Title: ModernUI_Spinner Control
Post by: fearless on June 28, 2019, 09:38:27 AM
I updated my spinner control (original version is here: http://masm32.com/board/index.php?topic=1179.0)

Download

The control can be downloaded via the ModernUI repository or downloaded directly from this link: https://github.com/mrfearless/ModernUI/blob/master/Release/ModernUI_Spinner.zip?raw=true


Example

I created an example project to demonstrate it.

The example (which includes a Radasm project) can be downloaded via the ModernUI repository or downloaded directly from this link: https://github.com/mrfearless/ModernUI/blob/master/Release/MUISpinner1.zip?raw=true

(https://i.postimg.cc/RCs3kBNf/MUISpinner1.gif)

There are a number of ways of adding image frames to the ModernUI_Spinner control.
The most basic level is to add individual images to construct the spinner animation. This can be done with the MUISpinnerAddFrame or MUISpinnerLoadFrame - using an image handle that is already loaded or using a resource id of an image.

For example, the first spinner it is comprised of 8 separate bitmap images:
(https://i.postimg.cc/L4jBSGBs/squares-circle-grey-1.png) (https://i.postimg.cc/Znz83LZZ/squares-circle-grey-2.png) (https://i.postimg.cc/1X0pKN5F/squares-circle-grey-3.png) (https://i.postimg.cc/GpBG5fmd/squares-circle-grey-4.png) (https://i.postimg.cc/bwwQQrXG/squares-circle-grey-5.png) (https://i.postimg.cc/hGHTW0Xx/squares-circle-grey-6.png) (https://i.postimg.cc/dVNGnFv5/squares-circle-grey-7.png) (https://i.postimg.cc/dtB2kdfP/squares-circle-grey-8.png)

For images that are circular, it can be more convenient to use the MUISpinnerAddImage or MUISpinnerLoadImage functions, as these only require one image. The image is copied a number of times into frame images - as specified by the dwNoFramesToCreate parameter. Each new frame image is incrementally rotated - based on the angle calculated for each new frame image. The bReverse parameter if set to TRUE will set the spinner animation to counter-clockwise. Note: the MUISpinnerAddImage or MUISpinnerLoadImage functions only work with png images or png's stored as RCDATA resources.

The far right spinner on the top row is created via loading a single png image:
(https://i.postimg.cc/MG9xnWkm/771-1.png)
Once loaded it is rotated and new frames are created to enable it to look like this:
(https://i.postimg.cc/7YsNt0n1/771.gif)

For more complicated spinners, or spinners that are not circular in nature, the MUISpinnerAddSpriteSheet and MUISpinnerLoadSpriteSheet functions are provided. These allow you to provide a long (wide) image (bitmap, icon or png) handle (or resource id) that contains all the spinner frames in the one image. The image frames are extracted out of this image. The amount of frame images in the spritesheet is passed via the dwSpriteCount parameter.

The clock spinner is a good example of this, as it can't be rotated due to the buttons around its edge:
(https://i.postimg.cc/kXp5pg6R/832-01.png)
So either it can be constructed by manually adding each frame or by using a spritesheet like so:
(https://i.postimg.cc/dQn3GBJB/832trans.png)
Which looks like this once all the individual frames are extracted:
(https://i.postimg.cc/CxRs35c3/832.gif)

I put some compile time conditions to allow for using of TimerQueue, Multimedia Timer or WM_TIMER for the animation of the spinner.

The Icons8 website is a good source for spinners, and they can be adjusted for size and color etc before downloading - including under the additional download options button as a spritesheet (using apng format). Take note of the frames value, as you will need to use this so that the spritesheet can be divided up into the correct individual frames.

https://icons8.com/preloaders/en/search/spinner (https://icons8.com/preloaders/en/search/spinner)
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 28, 2019, 04:02:45 PM
Hi fearless
This is a very good job  :thumbsup:
Recently I needed something similar, but due to time constraints I used a different solution. I will try your control.
There are two things that need improvement:
- Under Win10 64, your application triggers a virus warning (Trojan).
- On some spinners there is a graphics error (see picture).

Keep this cool work going! The complete MUI is a good stuff  :thumbsup:

Biterider
Title: Re: ModernUI_Spinner Control
Post by: jj2007 on June 28, 2019, 05:19:03 PM
It's beautiful, my compliments :thumbsup:
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 28, 2019, 07:51:36 PM
Thanks JJ and Biterider.
Its always work in progress ;-) but hopefully I can add to it all over time and build up a collection of useful UI controls.
Thats odd about the win10 x64 graphics issues - makes me think its dpi scaling related perhaps, as only a quarter of the image is shown for the spinners that are handled with the single image that is rotated - the manually added frames and spritesheet ones appear to look ok. Maybe its in using the GdipDrawRect in those single rotated images vs GdipDrawRectRect in the spritesheet functions. Something to look into though.

Also still have to do the x64 version at some point. But generally I'm behind with syncing my x64 version of the ModernUI controls and library vs the x86 version.
Thought about doing a ModernUI_Animation control which would likely be similar code, with additional code etc to handle a frame speed for each frame.
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 28, 2019, 09:35:11 PM
I updated the ModernUI_Spinner control to use the GdipDrawRectRectI instead of GdipDrawRect, hoping that this overrides any possible scaling issue - if that was the issue in win10 x64.
I uploaded MUISpinner1.exe to virustotal: https://www.virustotal.com/gui/file/d8c76960a7653fb3d688047101d662d0aa5c82fd0dfe33062f9ec888d7b6a7ae/detection
Only 4 false positives - so unsure how to combat that issue.
Attached is MUISpinner1.zip with just the updated exe to hopefully see if its fixed the issue on win10 x64
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 28, 2019, 09:38:38 PM
Hi fearless
Unfortunately, it behaves like the first version  :undecided:


Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 28, 2019, 10:20:09 PM
Well thats a strange one for sure. :D have to think on that for a bit, maybe I can create a dc and bitmap, then handle the original image with that as the backing and get that graphics context, instead of getting the graphics context straight from the image.

Do you have a high dpi monitor? I think it's a scaling issue, but don't know for sure - maybe its an issue with the actual png image somehow?
Title: Re: ModernUI_Spinner Control
Post by: LiaoMi on June 28, 2019, 10:46:54 PM
Hi fearless,

try so ..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>True/PM</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </requestedPrivileges>
    </security>
  </trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates app support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates app support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates app support for Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates app support for Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!--The ID below indicates app support for Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 28, 2019, 10:51:58 PM
Hi fearless
Im using a ASUS MX299Q wide screen. The resolution is set at 2560x1080 pixel running at 60Hz.
I hope this helps  :biggrin:

Biterider
Title: Re: ModernUI_Spinner Control
Post by: LiaoMi on June 28, 2019, 11:57:59 PM
Quote from: Biterider on June 28, 2019, 10:51:58 PM
Hi fearless
Im using a ASUS MX299Q wide screen. The resolution is set at 2560x1080 pixel running at 60Hz.
I hope this helps  :biggrin:

Biterider

I have a similar monitor, and I have the same effect, there must be another reason, not the screen resolution ...
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 29, 2019, 12:34:30 AM
I noticed that the png's from Icons8 are apng - which it turns out is an animated png - only seen this when using XnView and seen that the png contained x frames.
I opened those png's in IcoFx and exported out the single image which resulted in smaller png file sizes.
I'm hoping that maybe it was due to this. So I recompiled the MUISpinner.exe in the attached zip, hoping it was this, before I go off looking for other possible solutions.
Fingers crossed.
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 29, 2019, 12:49:45 AM
Hi fearless
Sorry, still the same effect...


Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 29, 2019, 01:08:25 AM
Ok thanks for testing for me.
I updated the rotation function to use the dc of the control and then use that for the graphics context, similar to how the spritesheets are loaded and handled.
Updated the sample MUISpinner1.exe again. If its still the same, then I'm currently out of ideas.
Does it show the correct image size for any of those affected spinners - specifically the first image as its just cloned if angle is 0/360, and the 180deg of the image is flipped rather than rotated, so just wondering if any of those appear as quick flashes in those spinners?
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 29, 2019, 01:31:19 AM
Hi fearless
One thought: It seems that the spinner image has sometimes and sometimes not an offset, like the hotspot of a cursor.
Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 29, 2019, 01:46:45 AM
Are they still animating but only showing a quarter of the image?
Title: Re: ModernUI_Spinner Control
Post by: FORTRANS on June 29, 2019, 04:09:24 AM
Hi,

   Tried the version from Reply # 12 on my 8.1 laptop.  The six
spinners shown are working well.

Steve
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 29, 2019, 06:24:42 AM
I changed the transform and rotation using info from http://www.jose.it-berater.org/smfforum/index.php?topic=1906.0, instead of creating a matrix and rotating and transforming that matrix.
I attach two versions, both use the new transform and rotation, the 1st one scales the width and height based on dpi and uses that measurement for the transform (movement) call. 2nd one uses the width and height as it was before, just from the image size. Not sure if either will work or not but worth a shot.
Only other thought i had was in relation to GdipSetPageScale, on my pc of 1920x1080 GdipGetPageScale returns 1.0, I would imagine on higher dpi it would be a different value, but if its already set (guessing its detected automatically) im unsure if setting this would have any purposeful effect.
Anyhow, hopefully one of those examples works.
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 29, 2019, 07:17:34 AM
Hi fearless
both EXEs produce the same result.

QuoteDoes it show the correct image size for any of those affected spinners - specifically the first image as its just cloned if angle is 0/360, and the 180deg of the image is flipped rather than rotated, so just wondering if any of those appear as quick flashes in those spinners?

On the executable file before the new transformation, those spinners that show completely also rotate. Those who show only a quarter sometimes flicker.

Biterider
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 29, 2019, 08:15:14 PM
Hi fearless
I've tested the last 2 EXEs on Win7 64bit and they work as expected.
Without knowing what your code looks like, it's hard to say what went wrong and why.
What is for sure, it has something to do with the operating system. Maybe a missing return value, an unpreserved register or something like that.

Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 29, 2019, 10:42:13 PM
Thanks for checking that Biterider. Its a head scratcher for sure.

The source for the libraries is available on the github repo: https://github.com/mrfearless/ModernUI/tree/master/Controls/ModernUI_Spinner (https://github.com/mrfearless/ModernUI/tree/master/Controls/ModernUI_Spinner) - I didnt upload the most recent changes, but don't think much changed except trying to use hdc and the other transform calls instead of using a matrix

The main function that is used to create the rotated gdi+ images is _MUI_SpinnerRotateCenterImage, which takes the hImage loaded, and the angle, and returns a pBitmap object (gdi+).

The main call chain is

- MUISpinnerLoadImage: https://github.com/mrfearless/ModernUI/blob/master/Controls/ModernUI_Spinner/ModernUI_Spinner.asm#L1381 (https://github.com/mrfearless/ModernUI/blob/master/Controls/ModernUI_Spinner/ModernUI_Spinner.asm#L1381)
- MUISpinnerAddImage: https://github.com/mrfearless/ModernUI/blob/master/Controls/ModernUI_Spinner/ModernUI_Spinner.asm#L1310 (https://github.com/mrfearless/ModernUI/blob/master/Controls/ModernUI_Spinner/ModernUI_Spinner.asm#L1310)
- _MUI_SpinnerRotateCenterImage: https://github.com/mrfearless/ModernUI/blob/master/Controls/ModernUI_Spinner/ModernUI_Spinner.asm#L1753

If a png is already loaded by user (using some other mechanism), then user can call MUISpinnerAddImage, which internally calls _MUI_SpinnerRotateCenterImage
If using MUISpinnerLoadImage to load a png, it loads it, then calls MUISpinnerAddImage, which internally calls _MUI_SpinnerRotateCenterImage

Returned pBitmap (gdi+ object) is stored in the internal array for frames (which is set to 60 frames max)

I've attached the ModernUI_Spinner source and the source of the MUISpinner1 demo for easier access - the attached ModernUI_Spinner source does have some changes from trying the various things - but should be similar-ish - I commented out some stuff, but can always reference the github version to see what anything was previously - the only function that changed in all the attempts was the _MUI_SpinnerRotateCenterImage function.
Title: Re: ModernUI_Spinner Control
Post by: Biterider on June 30, 2019, 06:35:48 PM
Hi fearless
It took me some time to put all in place. I had to download the complete framework to get the missing files.
Unfortunately, my RadASM setup is different than yours, so I had to setup the build chain from scratch.
I got it running to debug, but to look into the compiled libraries I had to include the corresponding source files. Now I got the problem that the linker can not resolve the _WinMainCRTStarup symbol. In case you ask, I changed the name of the entry point to check if this is the problem, but no.
Any clue?  :undecided:
Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on June 30, 2019, 10:54:26 PM
I put the WinMainCRTStartup proc in just as a test to see if it helped with virustotal - it didn't, so you can eliminate that and change it back to the start: and end start normally seen:
start:
    Invoke GetModuleHandle,NULL
    mov hInstance, eax
    Invoke GetCommandLine
    mov CommandLine, eax
    Invoke InitCommonControls
    mov icc.dwSize, sizeof INITCOMMONCONTROLSEX
    mov icc.dwICC, ICC_COOL_CLASSES or ICC_STANDARD_CLASSES or ICC_WIN95_CLASSES
    Invoke InitCommonControlsEx, offset icc
   
    Invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
    Invoke ExitProcess, eax

Could be the linker perhaps? I'm currently using v12 of the linker from a visual studio installation and not the default version that comes with masm32 sdk - this is to support pdb if compiling for debugging so that the symbols can be seen in x64dbg - found the older link didn't work for that.

Title: Re: ModernUI_Spinner Control
Post by: TimoVJL on June 30, 2019, 11:30:09 PM
WinMainCRTStartup and wWinMainCRTStartup are known entry names for MS linker, for GUI application.
Title: Re: ModernUI_Spinner Control
Post by: Biterider on July 01, 2019, 02:36:15 AM
Hi fearless
after hours and hours of debugging, I think I got it  :biggrin: .
It is the GdipRotateMatrix call in the _MUI_SpinnerRotateCenterImage procedure. It requires a fresh FPU, otherwise if fails (at least on Win10).
Check the FPU content anyway. There is a leftover at the beginning of the procedure.

Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 01, 2019, 02:49:22 AM
Thanks for looking this, much appreciated.

So I take it if i issue a finit call after finishing with my calcs and before the GdiRotateMatrix it should be ok?
edit: i placed finit during the MUISpinnerAddImage call after the _MUI_SpinnerRotateCenterImage and MUISpinnerAddFrame calls that add or sub the angle just in case it should be reinitialized there as well.

Attached is the recompiled demo after adding in those finit calls to the ModernUI_Spinner library, hopefully its working now
Title: Re: ModernUI_Spinner Control
Post by: Biterider on July 01, 2019, 04:27:51 AM
Hi fearless
Good news and bad news  :biggrin:
The good new is that it seems to work,  :thumbsup:
the bad one is that some spinners (#2, #5, #6 & #7) always flicker at the same position. It seems as if a frame is missing.

Biterider

PS: check the beginning of _MUI_SpinnerRotateCenterImage, it looks like, that after the range, you dont unload a value from the FPU.
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 01, 2019, 05:31:45 AM
Ok thanks.

I took out the code for cloning frames that are at angle 0 and 360. Only does 1 check now for the 180deg -as this throws the image off slightly for some reason - and gives a speed wobble to the spinner, so instead i do the flip image. I slowed down the far right spinner to see if you can see all frames drawn.

I ended up using fstp st(0) to free the fpu from the loaded fAngle now instead. Hopefully that is enough, or maybe the ffree st(0) would be more appropriate here. I spotted an issue in MUISpinnerAddImage where I had commented out the initial store of the angle to begin with (if 0, or 360 for reversed animation) - it was just loading a value into the fpu and not storing it.


So this is the 180 deg fpu code check now:

    finit           ; init fpu
    fld fAngle
    fcom FP4(180.0) ; compare ST(0) with the value of the real4_var variable: 180.0
    fstsw ax        ; copy the Status Word containing the result to AX
    fwait           ; insure the previous instruction is completed
    sahf            ; transfer the condition codes to the CPU's flag register
    fstp st(0)
    ;ffree st(0)
    jz angle_is_180
    jmp other_angle
   
angle_is_180:
    ;Invoke GdipDrawImageRectRectI, pGraphicsBuffer, hImage, 0, 0, dwImageWidth, dwImageHeight, 0, 0, dwImageWidth, dwImageHeight, UnitPixel, NULL, NULL, NULL
    Invoke GdipDrawImage, pGraphicsBuffer, hImage, 0, 0
    Invoke GdipImageRotateFlip, pBitmap, Rotate180FlipNone
    jmp tidyup

other_angle:


All other fpu instructions after that load and store into a variable. Let me know if there is any noticeable frames missing still - the 180deg frame for example.
Title: Re: ModernUI_Spinner Control
Post by: Biterider on July 01, 2019, 05:52:18 AM
Hi fearless
All is fine now  :thumbsup:  Good job  :eusa_dance:

Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 01, 2019, 06:29:09 AM
Ah brilliant! Thanks for your help
Title: Re: ModernUI_Spinner Control
Post by: HSE on July 01, 2019, 09:36:50 AM
Hi fearless:
If You use "fcomp" don't need fstp.
Title: Re: ModernUI_Spinner Control
Post by: jj2007 on July 01, 2019, 11:28:33 AM
Quote from: HSE on July 01, 2019, 09:36:50 AM
Hi fearless:
If You use "fcomp" don't need fstp.

You mean fcomip, I suppose?

include \masm32\MasmBasic\MasmBasic.inc
  Init
  fld FP10(179.9)      ; current value
  fld FP10(180.0)      ; compare with 180
  fcomip ST, ST(1)     ; compare and pop
  .if Carry?
        PrintLine Str$("%f is above 180", ST(0))
  .elseif Zero?
        PrintLine Str$("%f equals 180", ST(0))
  .else
        PrintLine Str$("%f is below 180", ST(0))
  .endif
  fld FP10(0.1)
  fadd
  fld FP10(180.0)
  fcomip ST, ST(1)
  .if Carry?
        PrintLine Str$("%f is above 180", ST(0))
  .elseif Zero?
        PrintLine Str$("%f equals 180", ST(0))
  .else
        PrintLine Str$("%f is below 180", ST(0))
  .endif
  fld FP10(0.1)
  fadd
  fld FP10(180.0)
  fcomip ST, ST(1)
  .if Carry?
        PrintLine Str$("%f is above 180", ST(0))
  .elseif Zero?
        PrintLine Str$("%f equals 180", ST(0))
  .else
        PrintLine Str$("%f is below 180", ST(0))
  .endif
  Inkey
EndOfCode


179.9000 is below 180
180.0000 equals 180
180.1000 is above 180
Title: Re: ModernUI_Spinner Control
Post by: Biterider on July 01, 2019, 03:32:49 PM
Hi fearless
Just a minor optimization; if the divisor (the get the number of rotated images) is a multiple of 2, you can flip vertically the rotated images up to 180° in reverse order to get the remaining 180°.
The same way, if the divisor is a multiple of 4, you can first apply an horizontally flip in reverse order of images you previously get from the first quadrant.
The idea is to get a better performance than simply rotating all the images.  :icon_idea:

Just my 2 cents.

Biterider
Title: Re: ModernUI_Spinner Control
Post by: LiaoMi on July 01, 2019, 11:52:41 PM
Hi fearless,

I still have flickering on the problem pictures, i.e. When switching to a repeated circle, the picture completely disappears and reappears, this causes flicker.
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 02, 2019, 02:10:17 AM
Hi LiaoMi,

On the far right spinner (which is now slowed down) can you tell which frame is disappearing? The far right faded wheel spinner has 12 segments - so should have 12 images.
Title: Re: ModernUI_Spinner Control
Post by: LiaoMi on July 02, 2019, 02:23:56 AM
Quote from: fearless on July 02, 2019, 02:10:17 AM
Hi LiaoMi,

On the far right spinner (which is now slowed down) can you tell which frame is disappearing? The far right faded wheel spinner has 12 segments - so should have 12 images.

I downloaded the last example again, now the animation works everywhere as it should, maybe I'm wrong, but I downloaded the same archive, very strange  :biggrin: Now everything is great! Thanks for the cool example!
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 02, 2019, 02:48:27 AM
Great news. I thought I had missed something.
Title: Re: ModernUI_Spinner Control
Post by: HSE on July 02, 2019, 10:03:08 PM
Quote from: jj2007 on July 01, 2019, 11:28:33 AM
You mean fcomip, I suppose?

NO, I mean fcomp  :biggrin:

For sure your program have problems because iisn't tranfering conditions from FPU to CPU and fcomp pop st(0). If you want to show st(0), you have to store it in a real8 variable before fcomp operation.

Just a note: I never transfer conditions but test ah. Perhaps and old recommendation, I don't remember.
Title: Re: ModernUI_Spinner Control
Post by: jj2007 on July 02, 2019, 11:53:54 PM
So you are using fcomp + fstsw + sahf? Can you post a short example? I'd like to make a benchmark, out of curiosity.
Title: Re: ModernUI_Spinner Control
Post by: HSE on July 03, 2019, 12:18:07 AM
macro and equ:compvalR macro a1,a2
Fld a1
fcomp a2
fstsw ax
endm

FP_LESSTHAN equ 01h
FP_EQUALTO equ 40h


use:compvalR x, minimox
.if ( ah & FP_LESSTHAN)
fld x
fstp minimox
.endif
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 22, 2019, 07:42:05 AM
I updated the x64 version of the ModernUI_Spinner and started making an x64 demo version MUISpinner1

I found some odd issues with GDI+ in x64 that I can't explain and haven't found anything online specifically about the issue. Appears to make the loaded png images slightly misshapen and attempting to create a spinner from a single png and rotate it works, but the image is ever so slightly out in each frame so the whole image appears to wobble. png spritesheets also appear to exhibit parts of the image being cutoff by a pixel or so in width and/or height from what i can estimate. the bmp frames and spritesheet spinners appear to work fine.

I did try adding a dependency in the xml manifest relating to gdiplus, but didnt seem to make much of a difference.

I could be GDI+ on win7 x64 that is the issue, so I wonder if others could test it out and see if it does show any odd wobbles and misshapen images

The x64 library is here: https://github.com/mrfearless/ModernUI64/blob/master/Release/ModernUI_Spinner.zip?raw=true
The entire RadASM project is here: https://github.com/mrfearless/ModernUI64/blob/master/Release/MUISpinner1.zip?raw=true

Attached is the example exe in a zip (without RadASM project)
Title: Re: ModernUI_Spinner Control
Post by: jj2007 on July 22, 2019, 12:27:33 PM
Looks cute on my Win7-64, and I don't see problems other than slightly rough edges :thumbsup:
Title: Re: ModernUI_Spinner Control
Post by: Biterider on July 22, 2019, 03:49:42 PM
Hi Fearless
Same result as above here (Win10/64). The 10th spinner has a dramatic offset. Maybe it is the place to start looking for.

Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 22, 2019, 07:38:29 PM
And its like the anti-aliasing, smoothing and other stuff isn't being applied by the GDI+, which you can see in the image JJ posted, which is what I see as well. Might have to look at the include files to see if there is something not set correctly, maybe that's where the problem is. Normally with the code below it should apply all those:

    Invoke GdipSetPixelOffsetMode, pGraphicsBuffer, PixelOffsetModeHighQuality
    Invoke GdipSetPageUnit, pGraphicsBuffer, UnitPixel
    Invoke GdipSetSmoothingMode, pGraphicsBuffer, SmoothingModeAntiAlias
    Invoke GdipSetInterpolationMode, pGraphicsBuffer, InterpolationModeHighQualityBicubic
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 22, 2019, 09:17:49 PM
Turns out my gdiplus definition files did have some incorrect values for those equates listed above - I copied the values from those defined in the windows.inc and the image quality looks better now, but still getting a small drift in the image position as it rotates, which I can't seem to resolve at the moment. Still noticing some tiny clipping or offset placement is out by a pixel or so on the spritesheet images, and the 10th spinner image is still in the upper left quadrant of the control for some reason. Slight progress, but still some mysteries left to solve.
Title: Re: ModernUI_Spinner Control
Post by: jj2007 on July 22, 2019, 10:44:11 PM
It's in Windows.inc, and the values are correct afaik. There is little difference between 2 and 4, though.
if 0
SmoothingModeDefault = 0 ; Gdi+ version is always 6.1.7601.24440 on Win7-64
SmoothingModeHighSpeed = 1 ; on Win7-64, Gdi+ 1.1.0.0 gets loaded independently of the manifest
SmoothingModeHighQuality = 2
SmoothingModeNone = 3
SmoothingModeAntiAlias = 4
SmoothingModeAntiAlias8x4= SmoothingModeAntiAlias= 4
SmoothingModeAntiAlias8x8= 5
endif
gdi+ GdipSetSmoothingMode, GraphObj, gdiSmoothing  ; a global variable for playing ;-)
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 23, 2019, 01:22:25 AM
For some reason in my gdiplus includes for uasm, based on the WinInc includes some of those values where no higher than 2, so SmoothingModeAntiAlias was 2 instead of 4, the InterpolationModeHighQualityBicubic was 4 (or 2 i think) instead of 7 - anyways once i changed them it all appeared more crisp and smoother, so I clearly had some wrong values in them.

I managed to fix the other issues - turns out i was using:
Invoke GdipDrawImage, pGraphicsBuffer, hImage, 0, 0
And not supplying reals, just 0 for the last two parameters. When I changed it over to use I version it solved most of those weird drifting problems

Invoke GdipDrawImageI, pGraphicsBuffer, hImage, 0, 0

The other spinner problem, no 10 in the demo, which was only showing quarter of its image was down to not zeroing registers I think and maybe shifting on eax/ebx instead of rax/rbx before doing some calculations from rectangle values and image width and height, so now it works with:

    xor rax, rax
    xor rbx, rbx
    mov eax, rect.right
    shr rax, 1
    mov rbx, qwImageWidth
    shr rbx, 1
    sub rax, rbx
    .IF sqword ptr rax < 0
        mov rax, 0
    .ENDIF
    mov pt.x, eax
   
    xor rax, rax
    xor rbx, rbx
    mov eax, rect.bottom
    shr rax, 1
    mov rbx, qwImageHeight
    shr rbx, 1
    sub rax, rbx
    .IF sqword ptr rax < 0
        mov rax, 0
    .ENDIF
    mov pt.y, eax


Beforehand it was doing something like

    mov eax, rect.right
    shr eax, 1
    mov rbx, qwImageWidth
    shr ebx, 1
    sub eax, ebx
    .IF sqword ptr rax < 0
        mov eax, 0
    .ENDIF
    mov pt.x, eax


Attached is the updated exe in the zip, which i hope is working now
Title: Re: ModernUI_Spinner Control
Post by: Biterider on July 23, 2019, 02:13:49 AM
Hi fearless
It looks OK now  :thumbsup:


Biterider
Title: Re: ModernUI_Spinner Control
Post by: fearless on July 23, 2019, 02:17:40 AM
Thanks Biterider
Title: Re: ModernUI_Spinner Control
Post by: jj2007 on July 23, 2019, 06:11:29 AM
Much better, compliments :thup:
Title: Re: ModernUI_Spinner Control
Post by: LiaoMi on July 23, 2019, 07:00:46 AM
Quote from: fearless on July 23, 2019, 01:22:25 AM
For some reason in my gdiplus includes for uasm, based on the WinInc includes some of those values where no higher than 2, so SmoothingModeAntiAlias was 2 instead of 4, the InterpolationModeHighQualityBicubic was 4 (or 2 i think) instead of 7 - anyways once i changed them it all appeared more crisp and smoother, so I clearly had some wrong values in them.

I managed to fix the other issues - turns out i was using:
Invoke GdipDrawImage, pGraphicsBuffer, hImage, 0, 0
And not supplying reals, just 0 for the last two parameters. When I changed it over to use I version it solved most of those weird drifting problems

Invoke GdipDrawImageI, pGraphicsBuffer, hImage, 0, 0

The other spinner problem, no 10 in the demo, which was only showing quarter of its image was down to not zeroing registers I think and maybe shifting on eax/ebx instead of rax/rbx before doing some calculations from rectangle values and image width and height, so now it works with:

    xor rax, rax
    xor rbx, rbx
    mov eax, rect.right
    shr rax, 1
    mov rbx, qwImageWidth
    shr rbx, 1
    sub rax, rbx
    .IF sqword ptr rax < 0
        mov rax, 0
    .ENDIF
    mov pt.x, eax
   
    xor rax, rax
    xor rbx, rbx
    mov eax, rect.bottom
    shr rax, 1
    mov rbx, qwImageHeight
    shr rbx, 1
    sub rax, rbx
    .IF sqword ptr rax < 0
        mov rax, 0
    .ENDIF
    mov pt.y, eax


Beforehand it was doing something like

    mov eax, rect.right
    shr eax, 1
    mov rbx, qwImageWidth
    shr ebx, 1
    sub eax, ebx
    .IF sqword ptr rax < 0
        mov eax, 0
    .ENDIF
    mov pt.x, eax


Attached is the updated exe in the zip, which i hope is working now

Hi fearless,

as before, I have problems with drawing, grains are visible in the pictures, they appear as noise, then disappear and the picture is clearly visible, so an infinite number of times.