TASEmulators / BizHawk

BizHawk is a multi-system emulator written in C#. BizHawk provides nice features for casual gamers such as full screen, and joypad support in addition to full rerecording and debugging tools for all system cores.
http://tasvideos.org/BizHawk.html
Other
2.21k stars 385 forks source link

2.10-rc1 Lua gui drawLine and drawRectangle not behaving as expected #4040

Closed UTDZac closed 2 months ago

UTDZac commented 2 months ago

Summary

We have a few Lua scripts to run alongside Pokémon games for GBA (mGBA core) and NDS (melonDS core).

The new 2.10-rc1 build has changed the visual output of some core gui Lua functions that we use to create a tracker UI. We utilize drawLine and drawRectangle for some custom created UI elements, such as an on-screen checkbox or selection indicator.

These functions appear to behave differently on 2.10-rc1, such that the thickness of lines for rectangle are 1px thicker than we expect. In addition, the line draw function has some unusual conditions such that the line is 1px thicker.

Repro

  1. Setup by drawing a black filled rectangle
  2. Draw a yellow rectangle of any width but height 0
  3. Draw a yellow rectangle of any height but width 0
  4. Draw a "back slash" red line at a perfect 45 degree angle of any length: (0, 0) to (8, 8)
  5. Draw a "forward slash" red line at a perfect 45 degree angle of any length: (8, 0) to (0, 8)
gui.drawRectangle(0, 0, 100, 100, 0xFF000000, 0xFF000000) -- BLACK
-- Test 1: Horizontal rectangle, height of 1px
gui.drawRectangle(20, 20, 5, 0, 0xFFFFFF00, 0xFFFFFFFF) -- YELLOW, WHITE
-- Test 2: Vertical rectangle, width of 1px
gui.drawRectangle(40, 20, 0, 5, 0xFFFFFF00, 0xFFFFFFFF) -- YELLOW, WHITE
-- Test 3: Diagonal line (45deg angle), width of 1px
gui.drawLine(20, 40, 28, 48, 0xFFFF0000) -- RED
-- Test 4: Diagonal line (45deg angle), width of 1px
gui.drawLine(48, 40, 40, 48, 0xFFFF0000) -- RED

Output

The lines generated for Test 1, 2 and 4 are thicker on 2.10-rc1. Not sure why Test 3 is exempt from this issue. (Note: The green dots are simply there to show the size of a single 1x1 pixel, to help compare sizes between versions.)

image

The left-half of the image shows the output of the above sample repro Lua code. The right-half is an example of how the drawRectangle of width/height 0 is used to create our custom selection indicator UI element.

Host env.

Display Configuration

This is what my configuration showed. I don't recall changing any of this after the initial download. I did notice, however, these are not the defaults. Changing to the defaults and restarting client yielded the same outcome.

CasualPokePlayer commented 2 months ago

such that the thickness of lines for rectangle are 1px thicker than we expect

This seems more just to be an edge case with "0" width/height. The width/height themselves already have an off by one (present in 2.9). Logicially, you would assume "0" width/height would just result in a nonexistent rectangle, then a width/height of "1" is the smallest rectangle, etc. Except GDI+ for some reason does not do this. For compatibility with this behavior, we try to mimic this off by one, although I assume our handling doesn't handle "0" correctly here.

the line draw function has some unusual conditions such that the line is 1px thicker.

This seems to be another annoying edge-case due to some 0.5 subpixel jitter with how ImGui handles rectangles, I'll see if handling it with lower level functions works better here.