SRL Archive - OSR Help

How to clear a canvas?


Coh3n

2011-04-01 01:47:36

So after posting this, I thought I'd try to fix it. I've managed to reduce the problem by having a global TBitmap rather than repeatedly creating bitmaps that don't get freed.

So first of all, the current paintsmart.scar calls FreeBitmap() on a TBitmap, which doesn't work. It needs to call TBitmap.free(). So I did that originally, but that doesn't make sense because the bitmap is freed right after it's used, and therefore nothing is displayed on SMART (well, there is, but it's cleared so fast you can't see it). That's when I made a global TBitmap to be drawn to. This stopped new bitmaps from being created and not freed, thus reducing the memory increase.

Now the issue is with clearing the TBitmap's canvas. Right now, there's a procedure (ClearCanvas) that creates and draws a blank bitmap on a canvas. Sure, it looks like it's cleared, but my logic is that yeah, visually it's cleared, but it's just adding a blank layer on top of the already existing bitmap, thus increasing the size. This builds up pretty quickly and before you know it you're using more memory than your computer can handle.

I've tried freeing the TBitmap instead of clearing, then simply creating a new one to be drawn to, but that only worked for one run through. I then had to restart Simba in order for anything to be drawn to SMART again. I've tried the TCanvas.Refresh procedure, and nothing was displayed. I'm honestly shocked there's no a TCanvas.Clear method, otherwise this would be very easy.

So anyway, does anyone have any suggestions? Here's my version of paintsmart.scar:

//-----------------------------------------------------------------//
//-- Scar Standard Resource Library --//
//-- � Smart Painting routines --//
//-----------------------------------------------------------------//
// Procedure ClearCanvas(canvas: TCanvas; w, h: integer); //
// Procedure ClearRSCanvas(canvas: TCanvas); //
// Procedure SMART_DrawDotsEx(Clear: boolean; pixels: TPointArray; color: TColor);
// Procedure SMART_DrawDots(Dots: TPointArray); //
// Procedure SMART_DrawBoxEx(Clear: boolean; Box: TBox; color: TColor);
// procedure SMART_DrawBox(Box: TBox); //
// procedure SMART_DrawText(x, y: Integer; font, Text: string; Color:TColor);
//-----------------------------------------------------------------//

var
SMART_Canvas: TBitmap;
SMART_DebugSetup: Boolean;

procedure SMART_SetupDebug();
begin
//SmartSetDebug(True);
SMART_Canvas := TBitmap.Create;
SMART_Canvas.canvas.handle := SmartGetDebugDC;
SMART_DebugSetup := true;
end;

{*******************************************************************************
Procedure ClearCanvas(canvas: TCanvas; w, h: integer);
Contributors: Sir R. Magician, mastaraymond
Description: Clears a canvas of dimensions (w, h)
*******************************************************************************}
Procedure ClearCanvas(canvas: TCanvas; w, h: integer);
var
CleanBMP: integer;
begin

CleanBMP := BitmapFromString(w, h, '');

{$ifdef Simba}
DrawBitmap(CleanBMP,Canvas,0,0);
{$else}
SafeDrawBitmap(CleanBMP, canvas, 0, 0);
{$endif}

try
FreeBitmap(CleanBMP);
except
writeln('SMART BITMAP NOT FREED');
end;

end;

{*******************************************************************************
Procedure ClearRSCanvas(canvas: TCanvas);
Contributors: Sir R. Magician
Description: Clears a canvas of RS dimensions
*******************************************************************************}
Procedure ClearRSCanvas(canvas: TCanvas);
begin
ClearCanvas(canvas, MIX2 + 100, MIY2 + 100);
end;

{*******************************************************************************
Procedure SMART_DrawDotsEx(Clear: boolean; pixels: TPointArray; color: TColor);
Contributors: Sir R. Magician
Description: Draws an ATPA onto the SMART Debug canvas
*******************************************************************************}
procedure DrawDotsMulti(Clear: boolean; pixels : T2DPointArray);
{$IFDEF SMART}
var
i, h, color : integer;
begin
if (not SMART_DebugSetup) then
SMART_SetupDebug();

if Clear then ClearRSCanvas(SMART_Canvas.canvas);

for h := 0 to High(pixels) do
begin

color := h div 5 + h mod 5;
case color of
0 : SMART_Canvas.canvas.Pen.Color := clWhite;
1 : SMART_Canvas.canvas.Pen.Color := clYellow;
2 : SMART_Canvas.canvas.Pen.Color := clBlue;
3 : SMART_Canvas.canvas.Pen.Color := clLime;
4 : SMART_Canvas.canvas.Pen.Color := clGreen;
end;

for i:= 0 to High(pixels[h]) do
begin
SMART_Canvas.canvas.moveto(pixels[h][i].x-1, pixels[h][i].y);
SMART_Canvas.canvas.LineTo(pixels[h][i].x, pixels[h][i].y);
end;
end;

{$ELSE}
begin
{$ENDIF}
end;

{*******************************************************************************
Procedure SMART_DrawDotsEx(Clear: boolean; pixels: TPointArray; color: TColor);
Contributors: Sir R. Magician, caused, mastaraymond
Description: Draws a TPA onto the SMART Debug canvas
*******************************************************************************}
procedure SMART_DrawDotsEx(Clear: boolean; pixels: TPointArray; color: TColor);
{$IFDEF SMART}
var
i : integer;
begin
if (not SMART_DebugSetup) then
SMART_SetupDebug();

SMART_Canvas.canvas.Pen.Color := color;
if Clear then ClearRSCanvas(SMART_Canvas.canvas);

for i:= 0 to high(pixels) do
begin
SMART_Canvas.canvas.moveto(pixels[i].x-1,pixels[i].y);
SMART_Canvas.canvas.LineTo(pixels[i].x,pixels[i].y);
end;

{$ELSE}
begin
{$ENDIF}

end;

{*******************************************************************************
Procedure SMART_DrawDots(Dots: TPointArray);
Contributors: Sir R. Magician
Description: Draws a TPA onto the SMART Debug canvas
*******************************************************************************}
procedure SMART_DrawDots(Dots: TPointArray);
begin
SMART_DrawDotsEx(True, Dots, clRed);
end;


{*******************************************************************************
procedure SMART_DrawBoxEx(Clear: boolean; Box: TBox; color: TColor);
Contributors: Sir R. Magician, caused, mastaraymond
Description: Draws a TBox onto the SMART Debug canvas
*******************************************************************************}
procedure SMART_DrawBoxEx(Clear: boolean; Box: TBox; color: TColor);
{$IFDEF SMART}
begin
if (not SMART_DebugSetup) then
SMART_SetupDebug();

SMART_Canvas.canvas.Pen.Color := color;
if Clear then ClearRSCanvas(SMART_Canvas.canvas);

SMART_Canvas.canvas.moveto(Box.x1,Box.y1);
SMART_Canvas.canvas.LineTo(Box.x2,Box.y1);
SMART_Canvas.canvas.LineTo(Box.x2,Box.y2);
SMART_Canvas.canvas.LineTo(Box.x1,Box.y2);
SMART_Canvas.canvas.LineTo(Box.x1,Box.y1);

{$ELSE}
begin
{$ENDIF}

end;

{*******************************************************************************
Procedure SMART_DrawBox(Box: TBox);
Contributors: Sir R. Magician
Description: Draws a TBox onto the SMART Debug canvas
*******************************************************************************}
procedure SMART_DrawBox(Box: TBox);
begin
SMART_DrawBoxEx(True, Box, clRed);
end;

{*******************************************************************************
procedure SMART_DrawTextEx(Clear: Boolean; x, y: Integer; font, Text: string; Color: TColor);
Contributors: Jukka, Shuttleu
Description: Draws text onto the SMART Debug canvas at position x, y
*******************************************************************************}
procedure SMART_DrawTextEx(Clear: Boolean; x, y: Integer; font, Text: string; Color:TColor);
var
i, height: integer;
tpa: tpointarray;
begin
tpa := LoadTextTPA(text,font,height);
for i:= 0 to high(tpa) do
begin
tpa[i].x := tpa[i].x + x;
tpa[i].y := tpa[i].y + y;
end;
SMART_DrawDotsEx(Clear, tpa, Color);
end;

{*******************************************************************************
procedure SMART_DrawText(x, y: Integer; font, Text: string; Color: TColor);
Contributors: Shuttleu
Description: Draws text onto the SMART Debug canvas at position x, y
*******************************************************************************}
procedure SMART_DrawText(x, y: Integer; font, Text: string; Color:TColor);
begin
SMART_DrawTextEx(False, x, y, font, Text, Color);
end;

procedure SMART_FreeDebug();
begin
try
SMART_Canvas.Free;
except
Writeln('Failed to free SMART_Canvas bitmap: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;
Thanks in advance. :)

Flight

2011-04-01 01:55:19

I don't know what to donate in as far as input, but if you find a way to correctly clear them and it's commited to SRL, then I applaud you!

Coh3n

2011-04-01 01:56:44

From: Flight
I don't know what to donate in as far as input, but if you find a way to correctly clear them and it's commited to SRL, then I applaud you!

This is already in SRL. ;)

I'm just fixing it because there were HUGE memory leaks. This was the reason so many people were getting code:8 errors with MSI (I'm 90% sure anyway).

P.S. I really like your signature picture, especially the phoenixes. ;)

Flight

2011-04-01 02:36:21

This would effect all scripts that use Smart though, would it not?

And thanks for the compliment, it's taken from the official symbol of my 'Flight Project' I started in 2007. It was private-server related so I'm sure you wouldn't be interested in that. ;)


Coh3n

2011-04-01 02:38:49

It's cool. It looks like something off the front of a Journey album.

And this wouldn't affect any scripts, even the ones that include paintsmart.scar. Nothing about how the procedure are used is changed, it's just going to hopefully be leak-free.

Wizzup?

2011-04-01 03:20:16

From: Coh3n
This is already in SRL. ;)

I'm just fixing it because there were HUGE memory leaks. This was the reason so many people were getting code:8 errors with MSI (I'm 90% sure anyway).


It would be really awesome if that is true. :)
I think clearing a canvas is really just painting it with a specific colour, no? (probably black)

Your ClearCanvas looks OK. You could probably also use some draw procedure from a canvas, eg: rectangle(0, 0, w-1,h-1)

Coh3n

2011-04-01 12:02:33

From: Wizzup?
Your ClearCanvas looks OK. You could probably also use some draw procedure from a canvas, eg: rectangle(0, 0, w-1,h-1)

But wouldn't drawing a blank bitmap over the existing bitmap just build up the size?

And Dgby posted a different version on this thread, and for some reason I have a feeling that version will work perfectly. :rolleyes:

I'll be trying it out later.

Wizzup?

2011-04-01 12:12:18

From: Coh3n
But wouldn't drawing a blank bitmap over the existing bitmap just build up the size?

And Dgby posted a different version on this thread, and for some reason I have a feeling that version will work perfectly. :rolleyes:

I'll be trying it out later.


No. ``Drawing'' a bitmap to it is essentially the same as doing
for x := 0 to w do for y := 0 to h do setpixel(x, y, getpixel(bitmap, x, y,));

Coh3n

2011-04-01 12:23:16

From: Wizzup?
No. ``Drawing'' a bitmap to it is essentially the same as doing
for x := 0 to w do for y := 0 to h do setpixel(x, y, getpixel(bitmap, x, y,));

Hm, okay then there shouldn't be anything wrong with what I have in the first post. I'll do some more testing and see what happens. Thanks.

E: Everything seems to be fine. I'll update SRL when I get the chance. :)

**BANNED The Man

2011-04-01 12:33:34

From: Coh3n
I'm just fixing it because there were HUGE memory leaks. This was the reason so many people were getting code:8 errors with MSI (I'm 90% sure anyway).


I have never used MSI and didn't realise that it used paint.
If I had known, I would have told you earlier.
Yes, you are correct that the old paint.scar has/had huge memory leaks.

-Boom

Dgby714

2011-04-01 12:43:53

Would this work?
procedure ClearCanvasEx(iCanvas: TCanvas);
begin
with TBitmap.Create do
try
Canvas := iCanvas;
Width := 0;
Height := 0;
finally
Free;
end;
end;

Wizzup?

2011-04-01 14:52:30

That doesn't clear it, that makes it 0, 0.

Coh3n

2011-04-01 14:54:05

Dgby, did you test your paintsmart version a bunch of times? I'm running into the problem I had earlier. It paints to SMART the first time one of the functions is called, but never again after that until I restart Simba.

From: Dynamite
I have never used MSI and didn't realise that it used paint.
If I had known, I would have told you earlier.
Yes, you are correct that the old paint.scar has/had huge memory leaks.

-Boom

And you never thought to report that to anyone?

Dgby714

2011-04-01 15:05:01

Didn't really test mine a lot but I'm guessing the Clearing doesn't work….

Coh3n

2011-04-01 19:18:12

Well anyway, I ran a lot of tests today and none really proved to help any. Sometimes I would use smart debugging, object tracking and wait while chopping and the memory wouldn't budge, other times it would increase 30k in 10 minutes. I tried with just each of them enabled, and there wasn't a significant amount of change to say there was a leak in each.

So I honestly don't know anymore. I know the memory leak has been fixed in paintsmart.scar, so I'll commit that now, but I'm puzzled about the MSI procedures.