Openrct2: Right-Click Scrolling at Smallest Zoom Level May Cause Game to Freeze

Created on 10 Feb 2017  路  18Comments  路  Source: OpenRCT2/OpenRCT2

OS: Windows 10
Version: 0.0.7
Commit/Build: e717c36

The game has a moderate chance of becoming unresponsive if the player uses the right mouse button and scrolls around the map a lot when zoom is set to the smallest level. The chance of the game becoming unresponsive appears to be higher if there are more objects on the map, if the map is large, or both.

It is possible that this problem also existed in vanilla RCT2, but the lower maximum resolution in RCT2 meant that the player would be unable to cover as much ground as they can in OpenRCT2, so if this problem existed in RCT2, the likelihood of it happening there was probably a lot lower.

  • [ ] Reproducible in RCT2 (vanilla)?
  • [ ] Multiplayer?

Steps to reproduce

  1. Load any map, preferably a larger map with more objects
  2. Zoom out to the smallest level
  3. With the right mouse button pressed down, move your mouse in broad, sweeping strokes at a moderate speed (try a Mobius loop, circle or cross)

Screenshots / Video:

In the Scenario Editor with the default landscape (148x148 flat land with grass terrain):
https://www.youtube.com/watch?v=uDI7Mm3gJ_4
In the Scenario Editor on a randomly generated 254x254 map with grass terrain and trees:
https://www.youtube.com/watch?v=bMXJaPDamVQ
In a completed run of the Time Twister scenario, Future World:
https://www.youtube.com/watch?v=2N_XQuClGE8

bug

Most helpful comment

@janisozaur
Dump from Androgeos

Commit df0e45e

Error message:
Unhandled exception thrown: write access violation.
copyDest was 0x1F5BB18527E.

Call stack:

>   openrct2.dll!DrawRLESprite2<0,3>(const unsigned char * source_bits_pointer=0x000001f5b5a18f5c, unsigned char * dest_bits_pointer=0x000001f5bb184384, const unsigned char * dpi, const rct_drawpixelinfo * source_y_start=-1, int height=31, int source_x_start=0, int width=32, int) Line 146   C++
    openrct2.dll!gfx_rle_sprite_to_buffer(const unsigned char * source_bits_pointer, unsigned char * dest_bits_pointer, const unsigned char * palette_pointer, const rct_drawpixelinfo * dpi, int image_type=0, int source_y_start=-1, int height=31, int source_x_start=0, int width=32) Line 215  C++
    openrct2.dll!gfx_draw_sprite_palette_set_software(rct_drawpixelinfo * dpi=0x0000000727eff500, int image_id, int x=28313, int y, unsigned char * palette_pointer=0x0000000000000000, unsigned char * unknown_pointer=0x0000000000000000) Line 604    C++
    openrct2.dll!OpenRCT2::Drawing::X8DrawingContext::DrawSprite(unsigned int image=3123, int x=28320, int y=5376, unsigned int tertiaryColour=0) Line 733  C++
    openrct2.dll!paint_ps_image(rct_drawpixelinfo * dpi, paint_struct * ps, unsigned int imageId=3123, short x, short y=5376) Line 985  C
    openrct2.dll!paint_draw_structs(rct_drawpixelinfo * dpi=0x0000000727eff500, paint_struct * ps=0x00007fffd03545e8, unsigned int viewFlags=1152) Line 898 C
    openrct2.dll!viewport_paint_column(rct_drawpixelinfo * dpi=0x0000000727eff500, unsigned int viewFlags=1152) Line 754    C
    openrct2.dll!viewport_paint(rct_viewport * viewport, rct_drawpixelinfo * dpi, short left=28264, short top, short right=4496, short bottom=5406) Line 733    C
    openrct2.dll!viewport_render(rct_drawpixelinfo * dpi=0x0000000727eff610, rct_viewport * viewport, int left=0, int top=0, int right=32760, int bottom=5406) Line 659 C
    openrct2.dll!window_editor_main_paint(rct_window * w, rct_drawpixelinfo * dpi) Line 98  C
    openrct2.dll!window_draw_single(rct_drawpixelinfo * dpi, rct_window * w=0x00007fffd062f500, int left, int top, int right=807, int bottom=976) Line 1728 C
    openrct2.dll!window_draw(rct_drawpixelinfo * dpi=0x0000000727eff6d0, rct_window * w=0x00007fffd062f500, int left=245, int top=28, int right=807, int bottom=976) Line 1623  C
    openrct2.dll!window_draw_all(rct_drawpixelinfo * dpi, short left, short top, short right, short bottom) Line 584    C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi, rct_window * window, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 373    C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd0630880, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 320  C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd06303a0, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 316  C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd062fec0, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 320  C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd062f9e0, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 280  C
    openrct2.dll!viewport_move(short x, short y, rct_window * w=0x00007fffd062f500, rct_viewport * viewport=0x00007fffd05c1060) Line 487    C
    openrct2.dll!viewport_update_position(rct_window * window=0x00007fffd062f500) Line 603  C
    openrct2.dll!window_update_all_viewports(...) Line 157  C
    openrct2.dll!OpenRCT2::Drawing::X8DrawingEngine::Draw() Line 229    C++
    openrct2.dll!SoftwareDrawingEngine::Draw() Line 110 C++
    openrct2.dll!OpenRCT2::Context::RunVariableFrame() Line 439 C++
    openrct2.dll!OpenRCT2::Context::RunGameLoop() Line 361  C++
    openrct2.dll!OpenRCT2::Context::RunOpenRCT2(int argc=-1360930560, char * * argv=0x0000000004100800) Line 136    C++
    openrct2.dll!NormalisedMain(int argc=1, char * * argv=0x000001f5aee0ed20) Line 65   C++
    openrct2.dll!LaunchOpenRCT2(int argc, wchar_t * * argvW) Line 55    C++
    [External Code] 

Autos on breakpoint:
```麓

  • dest_bits_pointer 0x000001f5bb184384 height 31 int
  • source_bits_pointer 0x000001f5b5a18f5c source_x_start 0 int
    source_y_start -1 int
    width 32 int
Locals on break;
  • copyDest 0x000001f5bb18527e
  • copySrc 0x000001f5b5a19342 dataSize Variable is optimized away and not available.
  • dest_bits_pointer 0x000001f5bb184384 dpi Variable is optimized away and not available.
    firstPixelX Variable is optimized away and not available.
    height 31 int
    i 16 int
    line_width 1916 int
  • lineData 0x000001f5b5a1935a
  • loop_dest_pointer 0x000001f5bb18527c mod Variable is optimized away and not available.
    numPixels 32 int
    offset Variable is optimized away and not available.
    offset Variable is optimized away and not available.
  • source_bits_pointer 0x000001f5b5a18f5c source_x_start 0 int
    source_y_start -1 int
    width 32 int
    x_start Variable is optimized away and not available.
    ```

All 18 comments

I've had this before, I thought it was caused by going too far outside the bounds of the map.

https://github.com/OpenRCT2/OpenRCT2/blob/develop/src/openrct2/interface/viewport.c#L711
becomes an inifiniteloop because of signed integer overflow of dpi1.x + dpi1.width

I'm on it

@Androgeos Would you be able to test Chaosmeister's pull request? I can help provide a build if you can't build it yourself.

@Gymnasiast Thanks. I can help to test, but I've never done a build myself. Would be great if you can provide one.

@Androgeos This build should work (hopefully): https://ci.appveyor.com/api/buildjobs/jbhidit9frq006hy/artifacts/artifacts%2Fopenrct2-portable-release-x64-df0e45e.zip

You'll need to unzip it somewhere and run from there (just double-click the .EXE).

Thanks. Not sure why Firefox decided to stall once it downloaded 100%, so I used Edge and it downloaded just fine.

I loaded four saved games with developed parks (one of which is the same Gemini City save I used in creating this ticket), the default 148x148 scenario editor map and a 254x254 scenario editor landscape generated randomly. In all 6 maps, I held down the right mouse button and scrolled as furiously as I could (in the same way I triggered the original freezes), but it was only on the 254x254 map where the game actually crashed while I was scrolling. I encountered only significant frame drops on the other 5 maps, but the game just kept running.

Here's my dump of the crash on the 254x254 map:
23d39334-8e54-4740-91f7-913ca125d4a6(df0e45e_x86-64).zip

The game seems very difficult to freeze via right-click scrolling at high speeds now - you need to scroll like crazy for an extended period of time on the largest maps before something goes wrong. I daresay it's nearly impossible under normal conditions if you don't consider the crash to be a freeze.

@Chaosmeister Would you be able to address that crash as well?

I will have a look at it.
I did not experience any crashes in my own previous tests.

@Androgeos are you able to reproduce it yourself? I'm not experiencing any crash, neither on parks nor in the editor

I just found another infiniteloop...
but that would be another freeze, not a crash.

Well, it's still worth fixing, right?

definitely! I already opened a new ticket for it

5795

There is still the crash left. Could you open a new issue for that?

I'm still unable to reproduce the crash. It might have been something unrelated

Has anyone looked into the provided dump?

no

Pinging @Nubbie in case he's around

@janisozaur
Dump from Androgeos

Commit df0e45e

Error message:
Unhandled exception thrown: write access violation.
copyDest was 0x1F5BB18527E.

Call stack:

>   openrct2.dll!DrawRLESprite2<0,3>(const unsigned char * source_bits_pointer=0x000001f5b5a18f5c, unsigned char * dest_bits_pointer=0x000001f5bb184384, const unsigned char * dpi, const rct_drawpixelinfo * source_y_start=-1, int height=31, int source_x_start=0, int width=32, int) Line 146   C++
    openrct2.dll!gfx_rle_sprite_to_buffer(const unsigned char * source_bits_pointer, unsigned char * dest_bits_pointer, const unsigned char * palette_pointer, const rct_drawpixelinfo * dpi, int image_type=0, int source_y_start=-1, int height=31, int source_x_start=0, int width=32) Line 215  C++
    openrct2.dll!gfx_draw_sprite_palette_set_software(rct_drawpixelinfo * dpi=0x0000000727eff500, int image_id, int x=28313, int y, unsigned char * palette_pointer=0x0000000000000000, unsigned char * unknown_pointer=0x0000000000000000) Line 604    C++
    openrct2.dll!OpenRCT2::Drawing::X8DrawingContext::DrawSprite(unsigned int image=3123, int x=28320, int y=5376, unsigned int tertiaryColour=0) Line 733  C++
    openrct2.dll!paint_ps_image(rct_drawpixelinfo * dpi, paint_struct * ps, unsigned int imageId=3123, short x, short y=5376) Line 985  C
    openrct2.dll!paint_draw_structs(rct_drawpixelinfo * dpi=0x0000000727eff500, paint_struct * ps=0x00007fffd03545e8, unsigned int viewFlags=1152) Line 898 C
    openrct2.dll!viewport_paint_column(rct_drawpixelinfo * dpi=0x0000000727eff500, unsigned int viewFlags=1152) Line 754    C
    openrct2.dll!viewport_paint(rct_viewport * viewport, rct_drawpixelinfo * dpi, short left=28264, short top, short right=4496, short bottom=5406) Line 733    C
    openrct2.dll!viewport_render(rct_drawpixelinfo * dpi=0x0000000727eff610, rct_viewport * viewport, int left=0, int top=0, int right=32760, int bottom=5406) Line 659 C
    openrct2.dll!window_editor_main_paint(rct_window * w, rct_drawpixelinfo * dpi) Line 98  C
    openrct2.dll!window_draw_single(rct_drawpixelinfo * dpi, rct_window * w=0x00007fffd062f500, int left, int top, int right=807, int bottom=976) Line 1728 C
    openrct2.dll!window_draw(rct_drawpixelinfo * dpi=0x0000000727eff6d0, rct_window * w=0x00007fffd062f500, int left=245, int top=28, int right=807, int bottom=976) Line 1623  C
    openrct2.dll!window_draw_all(rct_drawpixelinfo * dpi, short left, short top, short right, short bottom) Line 584    C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi, rct_window * window, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 373    C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd0630880, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 320  C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd06303a0, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 316  C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd062fec0, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 320  C
    openrct2.dll!viewport_redraw_after_shift(rct_drawpixelinfo * dpi=0x000001f5aedf54b8, rct_window * window=0x00007fffd062f9e0, rct_viewport * viewport=0x00007fffd05c1060, int x=-4104, int y=-615) Line 280  C
    openrct2.dll!viewport_move(short x, short y, rct_window * w=0x00007fffd062f500, rct_viewport * viewport=0x00007fffd05c1060) Line 487    C
    openrct2.dll!viewport_update_position(rct_window * window=0x00007fffd062f500) Line 603  C
    openrct2.dll!window_update_all_viewports(...) Line 157  C
    openrct2.dll!OpenRCT2::Drawing::X8DrawingEngine::Draw() Line 229    C++
    openrct2.dll!SoftwareDrawingEngine::Draw() Line 110 C++
    openrct2.dll!OpenRCT2::Context::RunVariableFrame() Line 439 C++
    openrct2.dll!OpenRCT2::Context::RunGameLoop() Line 361  C++
    openrct2.dll!OpenRCT2::Context::RunOpenRCT2(int argc=-1360930560, char * * argv=0x0000000004100800) Line 136    C++
    openrct2.dll!NormalisedMain(int argc=1, char * * argv=0x000001f5aee0ed20) Line 65   C++
    openrct2.dll!LaunchOpenRCT2(int argc, wchar_t * * argvW) Line 55    C++
    [External Code] 

Autos on breakpoint:
```麓

  • dest_bits_pointer 0x000001f5bb184384 height 31 int
  • source_bits_pointer 0x000001f5b5a18f5c source_x_start 0 int
    source_y_start -1 int
    width 32 int
Locals on break;
  • copyDest 0x000001f5bb18527e
  • copySrc 0x000001f5b5a19342 dataSize Variable is optimized away and not available.
  • dest_bits_pointer 0x000001f5bb184384 dpi Variable is optimized away and not available.
    firstPixelX Variable is optimized away and not available.
    height 31 int
    i 16 int
    line_width 1916 int
  • lineData 0x000001f5b5a1935a
  • loop_dest_pointer 0x000001f5bb18527c mod Variable is optimized away and not available.
    numPixels 32 int
    offset Variable is optimized away and not available.
    offset Variable is optimized away and not available.
  • source_bits_pointer 0x000001f5b5a18f5c source_x_start 0 int
    source_y_start -1 int
    width 32 int
    x_start Variable is optimized away and not available.
    ```
Was this page helpful?
0 / 5 - 0 ratings