PDA

View Full Version : [TuT]Let's paint on SMART! (Easy)



Flight
12-08-2011, 04:14 AM
Painting on SMART
By Flight


I've seen quite a few posts on the forum for people wanting to know how some scripts are able to paint on SMART, so I'm gonna show you how I do it.

Things may or may not be 100% accurate, and I'm sure there's better ways of doing so, but this is simple enough to understand.

Requirements:

The newest Simba of course! (http://villavu.com/forum/forumdisplay.php?f=308)
The newest SMART (http://villavu.com/forum/forumdisplay.php?f=179)
Positive attitude to push forward


What we'll cover:

Writing text on SMART
Painting an image on SMART




Step One: Getting our procedures

Starting off we're gonna need to import 'PaintSmart.scar' from the SRL Include so we can use it within our script. Let's do that by adding this line up with the rest of the includes: (near the top of your script)

{$i SRL/SRL/misc/paintsmart.scar}

Note that this is not my procedure, I believe it was BobboHobbo. This is the procedure we'll use to draw an array of text on SMART at a specific point we define using a specific color we define. For those of you who don't know an array of text (TStringArray) is really simple to make. Here's an example:

PrintTexts := ['Hello', 'there', 'my name', 'is Flight'];

You can see how anything in the array is defined within the "[]" and separated with commas. And because it's text (strings) each text will have (''). Alright, so let's get our procedure.

Procedure PrintOnSmart(TP: TStringArray; Placement: TPoint; Colour: integer);
var
mx, my, Pic, I, B, H, TPH, Numb: Integer;
TTP: TPointArray;
Canvas: TCanvas;
begin
SmartSetDebug(True);
GetClientDimensions(mx, my);
Pic := BitmapFromString(mx, my, '');
TPH := High(TP);
for I := 0 to TPH do
begin
TTP := LoadTextTPA(TP[i], SmallChars, H);
for B := 0 to High(TTP) do
begin
Numb := ((I + 1) * 13);
FastSetPixel(Pic, TTP[b].x + 1, TTP[b].y + Numb + 1,131072);
FastSetPixel(Pic, TTP[b].x, TTP[b].y + Numb, Colour);
end;
end;
Canvas := TCANVAS.Create;
Canvas.Handle := SmartGetDebugDC;
DrawBitmap(Pic, Canvas, Placement.x, Placement.y);
FreeBitmap(Pic);
end;

The parameters for this procedure is (TStringArray, Placement, Color), very simple, ya? We already know what to put in place for "TP", but what about the other two? Easy peasy. Placement is where the top-left corner of first text will appear. So, to get an accurate coordinate of where you'll want to place your text, what I always do is load up SMART and drag the "Select a client" button (near the top of Simba, looks like a green scope with a target in the middle) over to SMART.

Now when you hover your mouse over SMART the coords displayed in Simba (bottom left-hand corner) are now accurate. :) So, move your mouse over SMART where you want to place your text. I chose the point (40, 50):
http://i42.tinypic.com/295705t.png

Now we just need a color for our text. I simply use Simba's Colour-Picker tool (just left of the 'Select a client' tool) and get a color that way. I picked 255, which is a pure red. So it looks like we have everything we need to start using the procedure, let's do it!



Step Two: Printing text

Hopefully you've already thought of what you're gonna print on your SMART canvas. For this tutorial I'm gonna use ['A painted canvas', 'by Flight'], with my placement being Point(40, 50) and my color being 255. So where ever you want your on-screen painting go ahead an use it as such. So here's what my test script is looking like so far:

program PaintStuff;
{$define SMART}
{$i srl/srl.scar}
{$i SRL/SRL/misc/paintsmart.scar}

Procedure PrintOnSmart(TP: TStringArray; Placement: TPoint; Colour: integer);
var
mx, my, Pic, I, B, H, TPH, Numb: Integer;
TTP: TPointArray;
Canvas: TCanvas;
begin
SmartSetDebug(True);
GetClientDimensions(mx, my);
Pic := BitmapFromString(mx, my, '');
TPH := High(TP);
for I := 0 to TPH do
begin
TTP := LoadTextTPA(TP[i], SmallChars, H);
for B := 0 to High(TTP) do
begin
Numb := ((I + 1) * 13);
FastSetPixel(Pic, TTP[b].x + 1, TTP[b].y + Numb + 1,8388736);
FastSetPixel(Pic, TTP[b].x, TTP[b].y + Numb, Colour);
end;
end;
Canvas := TCANVAS.Create;
Canvas.Handle := SmartGetDebugDC;
DrawBitmap(Pic, Canvas, Placement.x, Placement.y);
FreeBitmap(Pic);
end;

Procedure DoThePainting;
begin
PrintOnSmart(['A painted canvas', 'by Flight'], Point(40, 50), 255);
end;

begin
Smart_Server := 86;
Smart_Members := True;
Smart_Signed := True;
Smart_SuperDetail := False;
SetupSRL; //This must be called before any canvas painting

DoThePainting;

end.

Alright, let's run it and see how she turned out.
http://i42.tinypic.com/2lchhg.png

Wonderful! Also you're probably asking why the text was written from top to bottom. Well that's how the procedure works, for each independent string (text) you paint, it will appear below the last text. Because I had two strings ("A painted canvas" and "By Flight") I had two lines of text painted on SMART.

There's no limit to what all you can print on SMART with text. If you've used some of my scripts before you've noticed I use this for the on-screen printing of progress reports and such. But for now, this is a good place to begin and experiment. :)



Step Three: Printing images

Ok this... I'm sure there's a much simpler way of doing so, but this is the way I do it. It's a cheap hack pretty much. :p What we're gonna do here is modify (butcher) the "PrintOnSmart" procedure. If you've read over the procedure you'll see what it does is draw your text on the screen in the form of a Bitmap. So what we'll do is create our own bitmap (image) to be drawn in the procedure.

Go ahead and make the image you want to draw in paint, photoshop, whatever, just make sure you save it as Bitmap (.bmp, 24-bit). I'll be using this:
http://i40.tinypic.com/nltyeh.jpg

Alright, let's modify the procedure to make two "Pic"s. I'll make the new modified procedure, assuming we'll be placing our image at (40, 100) (slightly below where our text ends).

Procedure PrintOnSmart(TP: TStringArray; Placement: TPoint; Colour: integer);
var
mx, my, Pic, Pic2, I, B, H, TPH, Numb: Integer; //Add another Pic here (I used Pic2)
TTP: TPointArray;
Canvas: TCanvas;
begin
SmartSetDebug(True);
GetClientDimensions(mx, my);
Pic := BitmapFromString(mx, my, '');
Pic2 := //Here is where we'll put the BMP info from our image
TPH := High(TP);
for I := 0 to TPH do
begin
TTP := LoadTextTPA(TP[i], SmallChars, H);
for B := 0 to High(TTP) do
begin
Numb := ((I + 1) * 13);
FastSetPixel(Pic, TTP[b].x + 1, TTP[b].y + Numb + 1,8388736);
FastSetPixel(Pic, TTP[b].x, TTP[b].y + Numb, Colour);
end;
end;
Canvas := TCANVAS.Create;
Canvas.Handle := SmartGetDebugDC;
DrawBitmap(Pic, Canvas, Placement.x, Placement.y);
DrawBitmap(Pic2, Canvas, 40, 100); //The 40 & 100 is the X/Y of where the image will be printed
FreeBitmap(Pic);
FreeBitmap(Pic2);
end;

Luckily Simba has a tool for converting a Bitmap to a string, which we can use within this procedure. So let's go up to 'Tools > Bitmap conversion' and open the image we want to use. Now just hit the 'To string' button and your image's BMP info will be printed in Simba. Here's mine:

Bmp := BitmapFromString(22, 19, 'meJytk7ENAjEMRVNSsgprsApr3A' +
'iU11KySsoraRnDZ/Glr499CS6wopPPsV9sx2ntn3K+3ny5cnlasJy' +
'WrUhwTzgDopYKhP50DpYKRMODvV4LSkAVUFgX9bks/Ss8Q9DbSjj0' +
'QHCFF5QzzwRClABIJYFDQsjqZwKBoJBDwlweb/Ol3chb9hEq1Hvv6' +
'pabqQRYTITh+LKE0Ez/hU/fbF1jRZr/aK5AgBtDdDUZp9E8MA0NvL' +
'+MreYrm8ykb+VLYdTo6Cx8zuGlj2QHxKVFOg==');

Alright, let's plug that into the procedure:

Procedure PrintOnSmart(TP: TStringArray; Placement: TPoint; Colour: integer);
var
mx, my, Pic, Pic2, I, B, H, TPH, Numb: Integer;
TTP: TPointArray;
Canvas: TCanvas;
begin
SmartSetDebug(True);
GetClientDimensions(mx, my);
Pic := BitmapFromString(mx, my, '');
Pic2 := BitmapFromString(22, 19, 'meJytk7ENAjEMRVNSsgprsApr3A' +
'iU11KySsoraRnDZ/Glr499CS6wopPPsV9sx2ntn3K+3ny5cnlasJy' +
'WrUhwTzgDopYKhP50DpYKRMODvV4LSkAVUFgX9bks/Ss8Q9DbSjj0' +
'QHCFF5QzzwRClABIJYFDQsjqZwKBoJBDwlweb/Ol3chb9hEq1Hvv6' +
'pabqQRYTITh+LKE0Ez/hU/fbF1jRZr/aK5AgBtDdDUZp9E8MA0NvL' +
'+MreYrm8ykb+VLYdTo6Cx8zuGlj2QHxKVFOg==');
TPH := High(TP);
for I := 0 to TPH do
begin
TTP := LoadTextTPA(TP[i], SmallChars, H);
for B := 0 to High(TTP) do
begin
Numb := ((I + 1) * 13);
FastSetPixel(Pic, TTP[b].x + 1, TTP[b].y + Numb + 1,8388736);
FastSetPixel(Pic, TTP[b].x, TTP[b].y + Numb, Colour);
end;
end;
Canvas := TCANVAS.Create;
Canvas.Handle := SmartGetDebugDC;
DrawBitmap(Pic, Canvas, Placement.x, Placement.y);
DrawBitmap(Pic2, Canvas, 40, 100);
FreeBitmap(Pic);
FreeBitmap(Pic2);
end;

Now let's run it and see what happens.
http://i44.tinypic.com/vzeg07.png

Yaya, success! :spot:

So this concludes the super simple SMART painting tutorial. Like I mentioned before this is just how I do it personally, you're in no way limited to using my methods. So be creative, play around with this and see what you can come up with.:) If you've any questions ask away.

~Cheerz

YoHoJo
12-08-2011, 04:21 AM
:D Wonderful.
Plan on adding an option for this for all of my scripts in the future and was going to look at yours as an example, a tutorial is even better! Awesome job Flight!

You ever look through this thread?
http://villavu.com/forum/showthread.php?t=56774
Any idea how to make more complex looking stuff like that?
(Not the mouseover portion, but just how the painting is not just text but a pretty looking thing, is that the same as how you did the Garfield bitmap?)

Flight
12-08-2011, 04:26 AM
:D Wonderful.
Plan on adding an option for this for all of my scripts in the future and was going to look at yours as an example, a tutorial is even better! Awesome job Flight!

You ever look through this thread?
http://villavu.com/forum/showthread.php?t=56774
Any idea how to make more complex looking stuff like that?
(Not the mouseover portion, but just how the painting is not just text but a pretty looking thing, is that the same as how you did the Garfield bitmap?)

I would image so. I'm quite new to canvases and what not. I think if anyone would have a good idea on that it's Mormonman. I'd love to play around with them in the future, no doubt!

mika
12-08-2011, 04:52 AM
awesome great tut

[XoL]
12-08-2011, 04:52 AM
Thank you so much for releasing this :D I just really liked the paints on your scripts so I thought id learn from the best :P

Kyle Undefined
12-08-2011, 06:42 AM
Awesome tut, bookmarked for later :D

Zyt3x
12-08-2011, 07:03 AM
Nice tutorial Flight :)

I committed some functions to smart.simba yesterday making one able to get the real mouse position, You could incorporate that in this tutorial making a section like "When the user hovers this, paint this"

I Am Legend
12-08-2011, 07:46 AM
Kewl man ..

tls
12-08-2011, 07:47 AM
A big issue with creating an interactive paint is that we can't use multi-threading(or a mouseListener). The only thing I can think of where it is readily-applicable is an onscreen gui, which would take more work than its worth and a form is smarter anyways. You could weave the paint in with the script but it would take speed away from the script and make the script a jumbled mess. I was playing with it earlier and I just hated the limitations that scripts have, speed/power/etc.
On a less annoyed note, I might develop some sort of paint-gui include but I'm completely undecided at this point.

Flight
12-08-2011, 07:53 AM
A big issue with creating an interactive paint is that we can't use multi-threading(or a mouseListener). The only thing I can think of where it is readily-applicable is an onscreen gui, which would take more work than its worth and a form is smarter anyways. You could weave the paint in with the script but it would take speed away from the script and make the script a jumbled mess. I was playing with it earlier and I just hated the limitations that scripts have, speed/power/etc.
On a less annoyed note, I might develop some sort of paint-gui include but I'm completely undecided at this point.

That's exactly what I was thinking before. Multi-threading was the term I was looking for. :p I might have been able to just wing everything else, but having a constant mouselistener is something I have no idea how to do.

Forms, I've tried those before and failed...

@Zyt3x:
Thank you :) Yeah I think that would be fairly simple to accomplish but like what Mormonman was talking about is using multi-threading or a mouselistener is what's needed for such results, and my knowledge doesn't extend that far. I was hoping between you and Mormonman something might emerge. :p

Coh3n
12-08-2011, 07:09 PM
Looks nice, Flight, although there is a function in paintsmart.scar that draws text to the SMART canvas (SMART_DrawText/Ex). I'm going to edit it so it adds a shadow, and I think I'll add a SMART_DrawTextArray to paintsmart.scar so it'll work just like the function in the OP.

Main
12-08-2011, 07:27 PM
Yayayay i love pyou!!@#!@#@!

tls
12-08-2011, 09:13 PM
Looks nice, Flight, although there is a function in paintsmart.scar that draws text to the SMART canvas (SMART_DrawText/Ex). I'm going to edit it so it adds a shadow, and I think I'll add a SMART_DrawTextArray to paintsmart.scar so it'll work just like the function in the OP.

Go ahead and add all the functions in my other thread please. :) thanks.

Coh3n
12-08-2011, 10:47 PM
Go ahead and add all the functions in my other thread please. :) thanks.I planned on it, don't worry. :)

tls
12-08-2011, 10:50 PM
I planned on it, don't worry. :)

We might need to redo some of the functions...I'm gonna run some tests to find the fastest methods.

putonajonny
12-09-2011, 10:51 PM
We should get PrintOnSmart included in the paintsmart.simba file so nooby scripters could use it with very little effort

Aegis
12-10-2011, 12:04 AM
Awesome, I'll come back to this when I get around to creating a paint for my script :)

Thanks!

drop parti
12-10-2011, 05:18 PM
thanks for this great tutorial. This is gonna help me on my way to becoming a great scripter :)

logical
12-12-2011, 04:28 PM
it is possible to make simba run two seperate loops?

eg one for the paint to provide real time stats and the other to run the script.

or is that what multi-threading is?

brilliant TUT by the way :) ....what does TUT stand for anyway >.<

'Toxin
12-12-2011, 04:33 PM
it is possible to make simba run two seperate loops?

eg one for the paint to provide real time stats and the other to run the script.

or is that what multi-threading is?

brilliant TUT by the way :) ....what does TUT stand for anyway >.<

TUT -> Tutorial.

Yes it is possible for simba to run two loops, may start hogging your memory though(not really sure). You can design a script to have a procedure of a mainloop, and a function which is looping to fix up the paint on the smart canvas.

logical
12-12-2011, 04:41 PM
Oo...thx Toxin

But could i have an example?...I'm just a bit curious. :)

euphemism
12-12-2011, 04:43 PM
I planned on it, don't worry. :)

Coh3n, when I stumbled upon the procedure used in this tutorial a few months ago, I noticed that it doesn't flicker when you redraw, unlike the text painting in paintsmart. Not to mention, you can use any color you want with this. Is there a particular reason why working on a bitmap and then drawing that to SMART is faster?

tls
12-12-2011, 06:56 PM
Coh3n, when I stumbled upon the procedure used in this tutorial a few months ago, I noticed that it doesn't flicker when you redraw, unlike the text painting in paintsmart. Not to mention, you can use any color you want with this. Is there a particular reason why working on a bitmap and then drawing that to SMART is faster?

The flickering is caused by each point being drawn to the canvas during the function, with un-precompiled code. Drawing a bitmap to a canvas is faster because it is precompiled. :)

Coh3n
12-12-2011, 10:17 PM
Coh3n, when I stumbled upon the procedure used in this tutorial a few months ago, I noticed that it doesn't flicker when you redraw, unlike the text painting in paintsmart. Not to mention, you can use any color you want with this. Is there a particular reason why working on a bitmap and then drawing that to SMART is faster?I didn't know there was any kind of flickering with paintsmart.scar. I've only ever used it with MSI for debugging, never for progress reports.


The flickering is caused by each point being drawn to the canvas during the function, with un-precompiled code. Drawing a bitmap to a canvas is faster because it is precompiled. :)If the method in the first post is faster and doesn't flicker, maybe it's better to rewrite paintsmart.scar to use that method? I'm not sure how much I like creating/freeing a bitmap each time the function is called. Seems inefficient if it's called often.

Swatarianess
12-17-2011, 04:30 PM
Would it Paint progress reports? :P cuz that'd be cool ^^

Flight
12-18-2011, 02:12 AM
Would it Paint progress reports? :P cuz that'd be cool ^^

If you've ever used any one of my scripts you'd see this is possible.

RISK
12-18-2011, 07:21 AM
Great tutorial. But may I suggest that you go thru each line of your examples and say what each part does? For someone that might not be able to figure it out, that is.
So that they aren't just copy pasting it in to their own scripts and if something goes wrong or they want to modify something, they know how to fix it or modify it.

Swatarianess
12-18-2011, 07:29 AM
If you've ever used any one of my scripts you'd see this is possible.

Actually no I haven't :( but i will next time I open simba I thought painting on simba could make it slow :/ well in my case it might because of slow laptop but I'll try on your scripts anyways ;) just hadn't seen it on some scripts I tried...

Flight
12-18-2011, 09:06 AM
http://i.imgur.com/1Xi9t.png

The possibilities are endless. ;)

Swatarianess
12-24-2011, 01:40 PM
http://i.imgur.com/1Xi9t.png

The possibilities are endless. ;)

thats pretty sexyy aswell as that 99hp u got :spot:

hmm imma try a simple Timer + 2 strings and see how far i get :/ hopefully it can withsand and/or surpass the capabilites of the reflect bot painting ways


reserve for awesome paint ;)

P1nky
12-24-2011, 05:29 PM
Thank you mate, just made my report print on SMART.

iCURiP
12-30-2011, 04:28 PM
Might be because I'm using SRL 5, but it flashes instead of staying there (It only preforms once per loop instead of staying), when i used it with SLR 4 yesterday it was fine.

Just pointing it out :p.

Ketan
12-30-2011, 05:49 PM
http://i.imgur.com/1Xi9t.png

The possibilities are endless. ;)

I used it for your fletcher and when it runs the loop-checker, it just flashes. Where should I put it so that it doesn't, blink/flash?

Coh3n
01-11-2012, 02:50 AM
Flight, you may want to check out this thread (http://villavu.com/forum/showthread.php?t=71762). Will make painting on SMART much easier. ;)

Flight
01-11-2012, 03:06 AM
Flight, you may want to check out this thread (http://villavu.com/forum/showthread.php?t=71762). Will make painting on SMART much easier. ;)

Will do! I'll test things out myself and update the tutorial.

Sin
02-01-2012, 02:55 AM
Okay, if I paint a FULL paint progress (like on a reflection bot), it'll take up a bit of RAM amirite?

Drax
02-01-2012, 03:08 AM
Okay, if I paint a FULL paint progress (like on a reflection bot), it'll take up a bit of RAM amirite?

I do it on my woodcutting script and it doesn't take up much ram. The way i run it, it does. It's in my report procedure and to keep it updated i repeat it.
But you can't do this for the whole script as simba doesn't have true multithreading. But you can do it with timers to get a constant update as well as running the main script.

heres the link.
http://villavu.com/forum/showthread.php?t=51578&highlight=multithreading
I could never get it to work out though, maybe you can.

Sin
02-01-2012, 02:48 PM
Shit goes down whenever I try to do it.
[Error] C:\Simba\Includes\SRL/SRL/misc/paintsmart.simba(281:14): Unknown identifier 'LoadTextTPA' at line 280

Sir Ducksworthy
03-18-2012, 06:39 AM
Everytime I try and paint a BMP it gives me this error wtf
Error: Exception: You are accessing an invalid point, (5,19) at bitmap[4] at line 73