GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2008-05-12 18:50:37

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

draw_line_width_color - confirmed BUG in GM7

Wow. This is a duesy. I was moderating the Tutorials and Examples forum at GMC and came across a huge bug thanks to a submission from Fede-lasse. He submitted a painting example using surfaces and mentioned a bug that caused lag when drawing a line while not moving the mouse. That didn't make sense to me, and looking at the code there was no obvious reason for it. But it was true. The CPU would spike to 100% in that case, otherwise usage was be closer to 2%. I switched off various things in the code and narrowed it down to draw_line_width_color().

I made a new project and tested the relative speeds of draw_line(), draw_line_color(), draw_line_width(), and draw_line_width_color() depending on the length of the line, including zero-length lines. There was no significant difference until I got to draw_line_width_color() ... and what a difference indeed. Not only did drawing a zero-length line completely lock-up the test, ending the process caused a BSOD! This machine never BSODs. This is the line of code:

draw_line_width_color(0,0,0,0,30,0,0);

I used 0 (black) for the color, but the color doesn't matter. The width doesn't matter. But the length? Yeah, that matters. If you are ready to reset your computer, please try to confirm this bug. Putting that code in the Draw Event of an instance in the first room causes a tame-by-comparison "Unexpected error" upon startup and the close of the game. Putting that in another event triggered after the game has started causes a catastrophic crash.


Abusing forum power since 1986.

Offline

#2 2008-05-13 01:38:36

EyeGuy
Member
Registered: 2007-10-18
Posts: 19

Re: draw_line_width_color - confirmed BUG in GM7

Ah, yea, I remember when I was debugging someone else's example, this came up.  Mighty hard to debug something that completely crashes your computer.  I didn't know how he was doing it.

Offline

#3 2008-05-15 16:47:38

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: draw_line_width_color - confirmed BUG in GM7

OK, that's one apparent confirmation. Anyone else will to try this?


Abusing forum power since 1986.

Offline

#4 2008-05-21 02:07:29

RoboBOT
Member
Registered: 2008-02-23
Posts: 6
Website

Re: draw_line_width_color - confirmed BUG in GM7

So I got the "unexpected error" thing when in the draw event, like you said. I then tried it in a keyboard event, and it locked up the program. Task Manager said I was using about 52% of CPU power, but that's likely due to having a dual core processor. I was able to close the program without a reboot, but there is definitely issues with that function.

(Intel Core 2 CPU, 1.6 GHz, Windows Vista Home Premium, 2 GB RAM)

Offline

#5 2008-05-21 02:33:42

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: draw_line_width_color - confirmed BUG in GM7

RoboBOT wrote:

Task Manager said I was using about 52% of CPU power, but that's likely due to having a dual core processor.

Right. When I said my CPU spiked to 100%, it was only the one CPU. Overall I was seeing only 25% usage because I have a dual dual-core setup. GM is single-threaded so that makes perfect sense. I haven't confirmed this, but I think it is highly likely that the BSOD is caused by a graphics driver. I should have paid more attention.

Thanks for the confirmation.


Abusing forum power since 1986.

Offline

#6 2009-05-17 20:46:20

flexaplex
Member
Registered: 2008-12-11
Posts: 72

Re: draw_line_width_color - confirmed BUG in GM7

Brief Description:            draw_line_width_color - locks up / gives 'unexpected error message' when length equivalent to 0
GM Versions:                   GM7
References:                     [1] [2]
Example File:                   draw_line_width_color bug.gmk
Bug Confirmed:                Yes
Hardware Dependent:     No

Main Info:

When using draw_line_width_color there is a bug if the length of the line drawn is equal to 0. ie when using the function:
draw_line_width_color(x1,y1,x2,y2,w,col1,col2)

if point_distance(x1,y1,x2,y2) == 0 then the bug will occur. If the function is called in the draw event and also on the very 1st step of the game the bug will give an 'unexpected error has occurred' message otherwise it will make the game will completely lock up.

Workaround:

Simply check to make sure you're not drawing a line of length 0, ie use this when calling:

if (point_distance(x1,y1,x2,y2) != 0)
{
  draw_line_width_color(x1,y1,x2,y2,w,col1,col2);
}

Or creating a separate function:

// draw_line_width_color2(x1,y1,x2,y2,w,col1,col2)
{
    if (point_distance(argument0,argument1,argument2,argument3) == 0) {exit;}
    draw_line_width_color(argument0,argument1,argument2,argument3,argument4,argument5,argument6);
}

Last edited by flexaplex (2009-06-16 08:30:29)

Offline

#7 2009-05-19 06:12:57

paul23
Member
Registered: 2007-10-17
Posts: 110

Re: draw_line_width_color - confirmed BUG in GM7

Maybe a better way to solve this would be by using draw_rectangle_color()?

(a minor guess, don't have GM on this comp):

var dir, dis, x1, y1, x2, y2,w,c1,c2;
x1 = argument0;
y1 = argument1;
x2 = argument2;
y2 = argument3;
w = argument4;
c1 = argument5;
c2 = argument6;
dir = point_direction(x1,y1,x2,y2);
dis = point_distance(x1,y1,x2,y2);
d3d_transform_add_rotation_z(dir);
d3d_transform_add_translation(x1,y1,0);
draw_rectangle_color(0,-w/2,dis,w/2,c1,c2,c2,c1,false);
d3d_transform_add_translation(-x1,-y1,0);
d3d_transform_add_rotation_z(-dir);

Should work I think?

Offline

#8 2009-05-19 09:37:57

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: draw_line_width_color - confirmed BUG in GM7

Is there ever a reason to actually draw a zero length line, though? Seems like checking the length first is the faster solution. On the other hand, your method would allow you to completely replace the draw_line_width_color function with a version that works. Assuming it works and doesn't have the same problem (edit: it does work correctly). That's an obvious advantage, especially for its minimal impact on existing code. This is how I did it with a similar function, the only real difference is I replaced an extra divide with an extra translation, for probably nil difference in execution time. That duplicate divide was just bugging me. laugh

// draw_line_width_color(x1,y1,x2,y2,w,col1,col2)
{
    d3d_transform_stack_push();
    d3d_transform_add_translation(0,-argument4/2,0);
    d3d_transform_add_rotation_z(point_direction(argument0,argument1,argument2,argument3));
    d3d_transform_add_translation(argument0,argument1,0);
    draw_rectangle_color(0,0,point_distance(argument0,argument1,argument2,argument3),argument4,argument5,argument6,argument6,argument5,false);
    d3d_transform_stack_pop();
}

(yet another weird problem with the automatic code formatting, hmmmm)

Hardware Dependent:     No

I think this is probably hardware dependent, it seems like a driver issue to me. Reproducibility is also in question. I never did figure out why it sometimes crashes (eg. in my tests) and other times doesn't (eg. in Fede-lasse's paint example).


Abusing forum power since 1986.

Offline

#9 2009-05-20 17:09:05

flexaplex
Member
Registered: 2008-12-11
Posts: 72

Re: draw_line_width_color - confirmed BUG in GM7

If you want to write it as a new function, why not just:

// draw_line_width_color(x1,y1,x2,y2,w,col1,col2)
{
  if (point_distance(argument0,argument1,argument2,argument3) == 0) {exit;}
  draw_line_width_color(argument0,argument1,argument2,argument3,argument4,argument5,argument6);
}

As for whether it is hardware dependant, I presumed it was not because everyone seems to be having the same problems and the problem does not occur on other functions.

After doing some testing I found splash screens interfered with the bug. For example if you use:

if (show_question("Execute Code?"))
{
  draw_line_width_color(0,0,0,0,30,0,0);
  game_end();
}

When answering 'yes' it treats it as 'bad gml' and ignores the code instead of crashing the game, I don't know why this is. So perhaps there is also some other scenarios that cause the bug to not occur. What was the exact code used in Fede-lasse's paint example?

Also about that unexpected error message that occurs in the draw event instead of crashing the game, the error message only occurs if you execute the function on the very first step of the game, you can test this by putting a timer check before executing the function, creating an instance that uses the function mid-game or even using the code in an instance not in the 1st room. When doing this it crashes GM like when used in any other event.

Last edited by flexaplex (2009-05-20 17:25:55)

Offline

#10 2009-06-16 01:19:26

xDanielx
Member
Registered: 2009-01-02
Posts: 38

Re: draw_line_width_color - confirmed BUG in GM7

Can't test at the moment, but I agree that it's likely a graphics driver issue. I look forward to the era when drivers transition into managed code...!

Offline

#11 2009-06-16 06:33:16

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: draw_line_width_color - confirmed BUG in GM7

flexaplex wrote:

If you want to write it as a new function, why not just:

// draw_line_width_color(x1,y1,x2,y2,w,col1,col2)
{
  if (point_distance(argument0,argument1,argument2,argument3) == 0) {exit;}
  draw_line_width_color(argument0,argument1,argument2,argument3,argument4,argument5,argument6);
}

As long as you give it a different name so it's not recursive, otherwise you'll overflow the stack and crash the game. That's why it's not such a convenient drop replacement.


flexaplex wrote:

What was the exact code used in Fede-lasse's paint example?

Step Event:

//Update the previous mouse position first, so it becomes old when xx,yy is updated
prex = xx
prey = yy;
//Update the new position (Now prex,prey will be the old mouse position)
xx = mouse_x;
yy = mouse_y;

//Draws a line at the surface if the left mouse button was pressed
if (mouse_check_button(mb_left)) {
  surface_set_target(surf); //Start drawing on the surface
    draw_line_width_color(prex,prey,xx,yy,width,col,col); //Draw the actual line
    //Draw circles at the points to reduce the "edge look"
    draw_circle_color(prex,prey,width/2,col,col,0);
    draw_circle_color(xx,yy,width/2,col,col,0);
  surface_reset_target(); //Reset the surface target
}

I haven't tried it again since my original post. I don't intend to anytime soon. I've been having trouble getting my computer to reliably start. BSODs are out of the question right now.


Abusing forum power since 1986.

Offline

#12 2009-06-16 08:39:24

flexaplex
Member
Registered: 2008-12-11
Posts: 72

Re: draw_line_width_color - confirmed BUG in GM7

xot wrote:

Step Event:

//Update the previous mouse position first, so it becomes old when xx,yy is updated
prex = xx
prey = yy;
//Update the new position (Now prex,prey will be the old mouse position)
xx = mouse_x;
yy = mouse_y;

//Draws a line at the surface if the left mouse button was pressed
if (mouse_check_button(mb_left)) {
  surface_set_target(surf); //Start drawing on the surface
    draw_line_width_color(prex,prey,xx,yy,width,col,col); //Draw the actual line
    //Draw circles at the points to reduce the "edge look"
    draw_circle_color(prex,prey,width/2,col,col,0);
    draw_circle_color(xx,yy,width/2,col,col,0);
  surface_reset_target(); //Reset the surface target
}

I haven't tried it again since my original post. I don't intend to anytime soon. I've been having trouble getting my computer to reliably start. BSODs are out of the question right now.

I just tested it on its own, it's crashing normally for me.

Last edited by flexaplex (2009-06-16 08:54:10)

Offline

Board footer

Powered by FluxBB