BBC BASIC for Windows
IDE and Compiler >> Tools and Utilities >> Turtle drawing tool ( improved version added))
http://bb4w.conforums.com/index.cgi?board=addins&action=display&num=1471816900

Turtle drawing tool ( improved version added))
Post by michael on Aug 21st, 2016, 10:01pm

Look down the posts to the modified version of DDRMS turtle program

You may ask me why I don't make all those draws in one line and have it interpret all the info..

Well, its because you can take the command and use READ and DATA statements and send the draw info to the tool.

So the tool is just that, a tool, and the colour scheme is up to you. I didn't modify the palettes.

I am working on an improved version so you can curve your draws and get more angles, but that may require using degrees and other statements.
Code:
      VDU 23,22,1024;600;8,15,16,1 :REM max width is 1920 and 1440 height
      GCOL 6
      REM PEN UP
      PROCgo("up",0)
      REM go north east (45 degrees) 500 points
      PROCgo("ne",500)
      PROCgo("down",100)
      PROCgo("n",100)
      PROCgo("ne",100)
      PROCgo("e",100)
      PROCgo("se",100)
      PROCgo("s",100)
      PROCgo("sw",100)
      PROCgo("w",100)
      PROCgo("nw",100)
      REM Pen up
      PROCgo("up",0)
      REM move east 10 pixels
      PROCgo("e",10)
      REM in this case, fill flood fills the chosen area with color 12 and it works with pen up
      PROCgo("fill",12)
      END
      DEFPROCgo(cmd$,coun%)
      PRIVATE x%,y%,pen%
      LOCAL c%
      IF cmd$="up" THEN pen%=1
      IF cmd$="down" THEN pen%=0
      IF cmd$="fill" THEN GCOL coun%:FILL x%,y%
      IF cmd$="n" THEN
        REPEAT
          y%=y%+1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="s" THEN
        REPEAT
          y%=y%-1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="e" THEN
        REPEAT
          x%+=1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="w" THEN
        REPEAT
          x%-=1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="ne" THEN
        REPEAT
          x%+=1:y%+=1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="nw" THEN
        REPEAT
          x%-=1:y%+=1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="sw" THEN
        REPEAT
          x%-=1:y%-=1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      IF cmd$="se" THEN
        REPEAT
          x%+=1:y%-=1:IF pen%=0 THEN MOVE x%,y%:DRAW x%,y%
          c%+=1
        UNTIL c%=coun%
      ENDIF
      ENDPROC
 

Re: Turtle drawing tool ( with flood fill ability)
Post by DDRM on Aug 22nd, 2016, 09:30am

Hi Michael,

Would it make sense to replace all the IF...THENs in PROCgo with a CASE statement?

A lot of the statements in each block are the same: could they be moved out so they are only there once?

Do you update x% and y% correctly if the pen is up?

Your routine means that diagonal moves move coun% steps in the x and/or y directions, rather than drawing a line of the specified length, which is the way turtle graphics normally work. That's not to say it's wrong, and I can see the advantage in terms of getting things to line up, but it might confuse the unwary user!

If your CASE statement decoded the direction into an angle, you could simply calculate the new x,y directions as
MOVE x%,y% :REM Redundant? Only if something else may move the cursor in the meantime
x%+=coun%*COS(angle)
y%+=coun%*SIN(angle)
IF pen%=0 THEN DRAW x%,y% ELSE MOVE x%,y%

I think I'd use reals (variants) for x and y, though, since otherwise rounding errors for small moves would accumulate rapidly, and alignments would get missed. Alternatively, you might consider adding 1/2 and then rounding, so you'd plot to the nearest pixel each time.

Best wishes,

D

Re: Turtle drawing tool ( with flood fill ability)
Post by michael on Aug 22nd, 2016, 1:05pm

I don't know a lot about sin and cos. Although I have seen them in code over the years. I must study this and see if I can find a proper solution.
thanks
Re: Turtle drawing tool ( with flood fill ability)
Post by DDRM on Aug 23rd, 2016, 08:30am

Hi Michael,

If you have a line of length 1 running at an angle a to the horizontal, then

COS(a) gives you the distance you will get along the horizontal axis
SIN(a) gives you the distance you will go up vertically.

Note that in BB4W the angles that COS and SIN expect are in radians (of which there are 2*PI in a full circle). There is a function RAD which will convert degrees to radians, and it will work as a composite function (i.e. COSRAD(a), SINRAD(a) ). Alternatively, you can multiply your angles in degrees by PI/180.

Best wishes,

D
Re: Turtle drawing tool ( with flood fill ability)
Post by DDRM on Aug 25th, 2016, 3:44pm

I was tempted to have a little go. Michael, I hope you don't feel I'm treading on your toes.

I've started with the basic turtle graphics commands, but then added a few more, partly inspired by Michael's version, such as absolute moves and angles. I've also provided support for "macros", in the form of repeatable sequences, and embedded strings.

I've chosen to make all positions integers, which makes it easier to get things to line up (all moves etc are calculated to the nearest integer position). Arguably doing it to the nearest even number would be better (since there are two BB4W graphics units per pixel), but I couldn't be bothered left it as an exercise for the student.

Conversely I've made the angle be a real, since it's quite likely you will want fractional numbers of degrees (for example my 16-sided "circles"!).

Because I wanted to be able to include macros, which are implemented as recursive calls, I can't (simply) use PRIVATE variables to hold the turtle parameters( EDIT: this turns out to be wrong - see later post.). There's a cunning trick shown on the wiki that I think would work, but I thought it would be a bit complicated to understand, so I've gone for an initialisation routine, and global variables with hopefully distinctive names.

All commands are single letters, to ease parsing, and I've chosen to make it case-insensitive.

Hope that's interesting. If anyone works out a nice (set of) command string(s), or adds nice functions, do share it!

:-)

D

Code:
      REM David's Turtle Graphics Programme.

      REM Possible instructions
      REM u: Pen Up (don't draw, just move)
      REM d: Pen Down (start drawing as you move)
      REM r: Turn right (some number of degrees - 90 degrees if number omitted - or 0!)
      REM l: Turn right (some number of degrees - 90 degrees if number omitted - or 0!)
      REM f: Move/draw forward (some distance)
      REM b: Move/draw backward (some distance)
      REM h: Move to the home position (0,0 unless changed?)
      REM n: Reset heading to north (positive y, =90 degrees)
      REM a: Set an absolute heading angle in degrees (anticlockwise, from right=0)
      REM x: Set an absolute position horizontally (move, don't draw)
      REM y: Set an absolute position vertically (move, don't draw)
      REM c: Set drawing colour (BB4W palette, from 0 - 15 - but you could redefine them as required)
      REM t: Set pen thickness
      REM i: Flood f(I)ll with a solid colour (specified)
      REM w: Wipe screen (and send turtle to home position)
      REM [: Start a string to repeat several times (macro)
      REM ]: Indicate the end of a repeated string - followed by the number of repeats
      REM .: Indicates that up to the next . represents an embedded string name

      PROCTurtleInit

      MODE 21
      REM Example using simple direct turns and moves to draw a square. Note that parameterless L and R give 90 degree turns
      REM Note that x and y changes will result in draws, unless the pen is up.
      command$="ux100y100df50lf50lf50lf50l"
      PROCTurtle(command$)
      REM Example using a macro to draw the octagon
      command$="ux400y400d[f100l45]8nuf50i4b50a0"
      PROCTurtle(command$)
      REM Two macros can follow each other, but you can't nest them, as things stand.
      command$="c1t3[f100l45]3a0d[df100l45]8nuf50i3"
      PROCTurtle(command$)
      REM You can define a "function" as a single command string, and then embed that
      REM within the string passed to PROCTurtle, using full stops
      circ$="d[f20l22.5]16"
      command$="b50a0[f100l45]3a0f200.circ$.uf200.circ$."
      PROCTurtle(command$)
      REM Here's an example where the command string is generated programmatically:
      REM you could set sizes/positions/colours etc this way at run time
      FOR x%=200 TO 20 STEP -20
        command$="ux800y250a0uf"+STR$(x%)+"c"+STR$(x%/20)+"nb"+STR$(INT(x%*PI/36))+"d[f"+STR$(INT(x%*2*PI/36))+"l10]36"
        PROCTurtle(command$)
      NEXT x%
      END
      :
      DEFPROCTurtleInit
      REM Turtle parameters made global to allow recursive calls to PROCTurtle for macros
      Turtle_px%=0   :REM X position of turtle
      Turtle_py%=0   :REM Y position of turtle
      Turtle_angle=0 :REM initial heading of turtle in degrees (anticlockwise from right=0)
      Turtle_pen%=0  :REM i.e. pen up
      Turtle_col%=15
      ENDPROC
      :
      DEFPROCTurtle(c$)
      LOCAL dx%,dy%,t$,n
      WHILE c$<>""
        t$=LEFT$(c$,1)
        c$=MID$(c$,2)
        n=VAL(c$)
        dx%=0
        dy%=0
        IF n>0 THEN c$=MID$(c$,LEN(STR$(n))+1)
        REM There's a fault here: if a parameter is 0 then it'll get left on the string
        REM But it's not a serious one, since it will get stripped off the next time round, without doing anything in the CASE.
        CASE t$ OF
          WHEN "u","U":Turtle_pen%=0
          WHEN "d","D":Turtle_pen%=1
          WHEN "h","H":Turtle_px%=0:Turtle_py%=0:Turtle_angle=0
          WHEN "n","N":Turtle_angle=90
          WHEN "w","W":CLS:Turtle_px%=0:Turtle_py%=0:Turtle_angle=0
          WHEN "l","L":IF n=0 THEN Turtle_angle+=90 ELSE Turtle_angle+=n
          WHEN "r","R":IF n=0 THEN Turtle_angle-=90 ELSE Turtle_angle-=n
          WHEN "f","F":dx%=INT (n*COSRAD(Turtle_angle)+0.5):dy%=INT(n*SINRAD(Turtle_angle)+0.5)
          WHEN "b","B":dx%=-INT((n*COSRAD(Turtle_angle)+0.5)):dy%=-INT((n*SINRAD(Turtle_angle)+0.5))
          WHEN "a","A":Turtle_angle=n
          WHEN "x","X":Turtle_px%=n
          WHEN "y","Y":Turtle_py%=n
          WHEN "c","C":GCOL n MOD 16
          WHEN "t","T":VDU 23,23,n;0;0;0;
          WHEN "i","I":GCOL n:FILL Turtle_px%,Turtle_py%
          WHEN "[":
            REM You could modify this to allow nested macros - you'd need to count and balance the left and right brackets
            REM In the meantime, you could include a macro in an embedded string inside your macro - that would work OK, I think.
            n=INSTR(c$,"]")
            t$=LEFT$(c$,n-1)
            c$=MID$(c$,n+1)
            n=VAL(c$)
            IF n>0 THEN c$=MID$(c$,LEN(STR$(n))+1)
            FOR dx%=1 TO n
              PROCTurtle(t$)
            NEXT dx%
            dx%=0
          WHEN ".":
            n=INSTR(c$,".")
            t$=LEFT$(c$,n-1)
            c$=MID$(c$,n+1)
            PROCTurtle(EVAL(t$))
        ENDCASE
        Turtle_px%+=dx%
        Turtle_py%+=dy%
        IF Turtle_pen% THEN DRAW Turtle_px%,Turtle_py% ELSE MOVE Turtle_px%,Turtle_py%
      ENDWHILE
      ENDPROC
 

Re: Turtle drawing tool ( with flood fill ability)
Post by michael on Aug 26th, 2016, 07:11am

Very nice layout. Every little bit of help counts. I do appreciate any help you offer, as well as with any one else.

I also ordered a book on assembly (16 and 32 bit) and it should be here by September 14. Its over 700 pages long so it should have all the crucial info I need and I previewed some of it online. It seems to be the best book out there.

Assembly Language For X86 Processors
It has step by step instructions and I already found multi conditional statements for one compare.
Also Richard said it would be a good book to use.

I must mention that Richard did set up the core graphics on OPENGL in SDLIDE version of BBC (made with BBC)..
This probably needs a second look since it is blazingly fast.

I want to work with a team. Eventually we can perhaps put all the works together into a nice package and promote it on YouTube and maybe when its done Ill put BBC Basic on one of our Mud Bog trucks to help bring curious visitors.

Or perhaps on my rust bucket van in a crash up derby.
When things are perfect, that's when I will do so.



Re: Turtle drawing tool ( with flood fill ability)
Post by DDRM on Aug 26th, 2016, 10:39am

It turns out that my comment about PRIVATE variables not working in recursive calls was wrong, due to my misunderstanding of the manual. In fact it will work fine. So instead of PROCTurtleInit, you could include the following:
Code:
      PRIVATE Turtle_px%,Turtle_py%,Turtle_angle,Turtle_pen%,Turtle_col%,flag%
      IF NOT flag% THEN
        Turtle_px%=0   :REM X position of turtle
        Turtle_py%=0   :REM Y position of turtle
        Turtle_angle=0 :REM initial heading of turtle in degrees (anticlockwise from right=0)
        Turtle_pen%=0  :REM i.e. pen up
        Turtle_col%=15
        flag%=TRUE
      ENDIF
 

at the beginning of PROCTurtle().

That has the merit of making the procedure a self-contained unit which is "ready to go", but the very slight disadvantage that the runtime engine has to wade through those instructions every time, even though they are only used on the first call.

Best wishes,

D
Re: Turtle drawing tool ( with flood fill ability)
Post by michael on Aug 26th, 2016, 11:35am

It has interesting results on SDLIDE version of BBC Basic. On BBC Basic the draws are smoother and on SDLIDE it is jagged.
Re: Turtle drawing tool ( with flood fill ability)
Post by michael on Aug 27th, 2016, 4:15pm

I think I will modify your tool to make resizable true 3D templates.
Also I think I just came up with an idea to make a true 3D dimension tool that should be effective.(3D layers with closest values being seen. I am designing the arrays for holding the images.

or.... perhaps I should research D3D.... this sounds like a plan.. Or Open GL since Richard used it for SDLIDE core graphics.

Re: Turtle drawing tool (DDRMs version with input)
Post by michael on Oct 3rd, 2016, 05:36am

So this works with the text input utility
It took a bit to adapt this, but now you can keep track of the turtle position
BUT you must always on a new line command a color
Aside from that it retains your position.
I still need to change the palettes so they return to original values.
Some lines are left in for view for others
I am thinking of making BMPtoTURTLECODE (like BMPtoCODE)
Code:
      REM preserve turtle coordinates for the text box so it doesnt draw unwanted lines.
      presx%=0:presy%=0
      REM David's Turtle Graphics Programme.
      REM modified by michael to add possibilities.  needs to preserve the color settings for
      REM draws. I am working on figuring that out
      REM Possible instructions
      REM u: Pen Up (don't draw, just move)
      REM d: Pen Down (start drawing as you move)
      REM r: Turn right (some number of degrees - 90 degrees if number omitted - or 0!)
      REM l: Turn right (some number of degrees - 90 degrees if number omitted - or 0!)
      REM f: Move/draw forward (some distance)
      REM b: Move/draw backward (some distance)
      REM h: Move to the home position (0,0 unless changed?)
      REM n: Reset heading to north (positive y, =90 degrees)
      REM a: Set an absolute heading angle in degrees (anticlockwise, from right=0)
      REM x: Set an absolute position horizontally (move, don't draw)
      REM y: Set an absolute position vertically (move, don't draw)
      REM c: Set drawing colour (BB4W palette, from 0 - 15 - but you could redefine them as required)
      REM t: Set pen thickness
      REM i: Flood f(I)ll with a solid colour (specified)
      REM w: Wipe screen (and send turtle to home position)
      REM [: Start a string to repeat several times (macro)
      REM ]: Indicate the end of a repeated string - followed by the number of repeats
      REM .: Indicates that up to the next . represents an embedded string name
      MODE 22
      PROCTurtleInit
      REM gbx% and gby% NEED to be whole numbers and need to be global ( they hold shared text input location )
      gbx%=0:gby%=0:split%=0:cursor%=0 :REM GLOBAL VARIABLES
      REM split% holds the divide location of the string so edits can be made. ( this is where it gets technical)
      tempstr$=""
      lx=0:ly=0:lh=0:lv=0
      REM define my line position
      li=0
      COLOUR 1,225,225,225 REM Set background color to windows common color gray (my custom RGB text background color)
      GCOL 0 : REM Set graphics foreground to palette color 0  (BLACK)
      GCOL 128+1 : REM Set graphics background to palette color 1
      VDU 5 : REM Treat text as graphics (transparent background)
      OFF:CLG:PROC_color("F",255,255,255)
      REM H,V,TEXTLIMIT (getting simpler?)
      REPEAT
        MOVE Turtle_px%,Turtle_py%
        PROC_input(200,610,50)
        MOVE presx%,presy%
        command$=MESSAGE$
        PROCTurtle(command$)
        *REFRESH
      UNTIL FALSE
      END
      REM Example using simple direct turns and moves to draw a square. Note that parameterless L and R give 90 degree turns
      command$="ux100y100df50lf50lf50lf50l"
      PROCTurtle(command$)

      REM Note that x and y changes will result in draws, unless the pen is up.
      REM Example using a macro to draw the octagon
      command$="ux400y400d[f100l45]8nuf50i4b50a0"
      PROCTurtle(command$)
      REM Two macros can follow each other, but you can't nest them, as things stand.
      command$="c1t3[f100l45]3a0d[df100l45]8nuf50i3"
      PROCTurtle(command$)
      REM You can define a "function" as a single command string, and then embed that
      REM within the string passed to PROCTurtle, using full stops
      circ$="d[f20l22.5]16"
      command$="b50a0[f100l45]3a0f200.circ$.uf200.circ$."
      PROCTurtle(command$)
      REM Here's an example where the command string is generated programmatically:
      REM you could set sizes/positions/colours etc this way at run time
      FOR x%=200 TO 20 STEP -20
        command$="ux800y250a0uf"+STR$(x%)+"c"+STR$(x%/20)+"nb"+STR$(INT(x%*PI/36))+"d[f"+STR$(INT(x%*2*PI/36))+"l10]36"
        PROCTurtle(command$)
      NEXT x%
      END
      :
      DEFPROCTurtleInit
      REM Turtle parameters made global to allow recursive calls to PROCTurtle for macros
      Turtle_px%=0   :REM X position of turtle
      Turtle_py%=0   :REM Y position of turtle
      Turtle_angle=0 :REM initial heading of turtle in degrees (anticlockwise from right=0)
      Turtle_pen%=0  :REM i.e. pen up
      Turtle_col%=15
      ENDPROC
      :
      DEFPROCTurtle(c$)
      PRIVATE Turtle_px%,Turtle_py%,Turtle_angle,Turtle_pen%,Turtle_col%,flag%
      IF NOT flag% THEN
        Turtle_px%=0   :REM X position of turtle
        Turtle_py%=0   :REM Y position of turtle
        Turtle_angle=0 :REM initial heading of turtle in degrees (anticlockwise from right=0)
        Turtle_pen%=0  :REM i.e. pen up
        Turtle_col%=15
        flag%=TRUE
      ENDIF
      LOCAL dx%,dy%,t$,n
      WHILE c$<>""
        t$=LEFT$(c$,1)
        c$=MID$(c$,2)
        n=VAL(c$)
        dx%=0
        dy%=0
        IF n>0 THEN c$=MID$(c$,LEN(STR$(n))+1)
        REM There's a fault here: if a parameter is 0 then it'll get left on the string
        REM But it's not a serious one, since it will get stripped off the next time round, without doing anything in the CASE.
        CASE t$ OF
          WHEN "u","U":Turtle_pen%=0
          WHEN "d","D":Turtle_pen%=1
          WHEN "h","H":Turtle_px%=0:Turtle_py%=0:Turtle_angle=0
          WHEN "n","N":Turtle_angle=90
          WHEN "w","W":CLS:Turtle_px%=0:Turtle_py%=0:Turtle_angle=0
          WHEN "l","L":IF n=0 THEN Turtle_angle+=90 ELSE Turtle_angle+=n
          WHEN "r","R":IF n=0 THEN Turtle_angle-=90 ELSE Turtle_angle-=n
          WHEN "f","F":dx%=INT (n*COSRAD(Turtle_angle)+0.5):dy%=INT(n*SINRAD(Turtle_angle)+0.5)
          WHEN "b","B":dx%=-INT((n*COSRAD(Turtle_angle)+0.5)):dy%=-INT((n*SINRAD(Turtle_angle)+0.5))
          WHEN "a","A":Turtle_angle=n
          WHEN "x","X":Turtle_px%=n
          WHEN "y","Y":Turtle_py%=n
          WHEN "c","C":GCOL n MOD 16
          WHEN "t","T":VDU 23,23,n;0;0;0;
          WHEN "i","I":GCOL n:FILL Turtle_px%,Turtle_py%
          WHEN "[":
            REM You could modify this to allow nested macros - you'd need to count and balance the left and right brackets
            REM In the meantime, you could include a macro in an embedded string inside your macro - that would work OK, I think.
            n=INSTR(c$,"]")
            t$=LEFT$(c$,n-1)
            c$=MID$(c$,n+1)
            n=VAL(c$)
            IF n>0 THEN c$=MID$(c$,LEN(STR$(n))+1)
            FOR dx%=1 TO n
              PROCTurtle(t$)
            NEXT dx%
            dx%=0
          WHEN ".":
            n=INSTR(c$,".")
            t$=LEFT$(c$,n-1)
            c$=MID$(c$,n+1)
            PROCTurtle(EVAL(t$))
        ENDCASE
        Turtle_px%+=dx%
        Turtle_py%+=dy%
        IF Turtle_pen% THEN DRAW Turtle_px%,Turtle_py% ELSE MOVE Turtle_px%,Turtle_py%
      ENDWHILE
      presx%=Turtle_px%:presy%=Turtle_py%
      ENDPROC
      REM H,V,TEXTLIMIT (simpler?)
      DEF PROC_input(bx,by,textlimit)
      LOCAL rback%,gback%,bback%
      rback%=255:gback%=255:bback%=255
      LOCAL rfore%,gfore%,bfore%,fill
      rfore%=0:gfore=0:bfore=0
      gbx%=bx:gby%=by:initialx%=0:sl%=0:key$="":MESSAGE$="":MES$=""
      initialx%=textlimit*16.2
      FOR fill=1 TO 58
        PROC_color("f",255,255,255):LINE bx+3,by+20-fill,bx+initialx%,by+20-fill
      NEXT fill
      PROC_color("f",0,0,0):LINE bx+3,by+20,bx+initialx%,by+20:LINE bx+3,by+20-fill,bx+initialx%,by+20-fill:
      REPEAT
        REPEAT
          key$ =INKEY$(1)
          PROC_color("F",rfore%,gfore%,bfore%)
          MOVE bx,by:PRINT MESSAGE$;"_" :* REFRESH
          sl%=LEN(MESSAGE$)
          remains%=sl%-cursor%
          lstring$=LEFT$(MESSAGE$,cursor%):rstring$=RIGHT$(MESSAGE$,remains%)
        UNTIL key$ <>""
        sl%=LEN(MESSAGE$)
        IF INKEY(-48) sl%=LEN(MESSAGE$)-1:key$=""
        REPEAT UNTIL INKEY(0)=-1
        IF MESSAGE$<> MESSAGE$ OR sl%<LEN(MESSAGE$) THEN
          PROC_color("F",rback%,gback%,bback%)
          MOVE bx,by
          PRINT MESSAGE$;"_"
        ENDIF
        MES$=MID$(MESSAGE$,0,sl%)
        MESSAGE$=MES$
        PROC_color("F",rback%,gback%,bback%):MOVE bx,by:PRINT MESSAGE$;"_"
        IF LEN(key$) = 1 THEN
          IF LEN(MESSAGE$)<textlimit THEN PROC_color("F",rback%,gback%,bback%):MOVE bx,by:PRINT MESSAGE$;"_": MESSAGE$=MESSAGE$+key$:* REFRESH OFF
          REM (jump)
        ENDIF
      UNTIL INKEY(-74)
      * REFRESH ON
      ENDPROC
      REM ***********************this is my super custom text box tool ***********************
      REM X,Y,text color,boarder color,message,r,g,b
      REM ************************************************************************
      DEF PROC_pr(X,Y,C,CT,msg$,r,g,b)
      initialx%=LEN(msg$)
      COLOUR 0,r,g,b
      GCOL 0
      LET tx= X+initialx%+25
      LET ty= Y:reduction%=0
      reduction%=initialx%/2
      reduction%=reduction%*6
      IF initialx%<20 THEN reduction%=reduction%/2
      initialx%=initialx%*22-reduction%
      FOR fill=1 TO 58
        LINE X+3,Y+20-fill,X+initialx%,Y+20-fill
      NEXT fill
      GCOL CT
      MOVE tx,ty
      PRINT msg$
      GCOL C
      LINE X,Y+20,X+initialx%,Y+20
      LINE X,Y+20,X,Y-40
      LINE X,Y-40,X+initialx%,Y-40
      LINE X+initialx%,Y-40,X+initialx%,Y+20
      LINE X-5,Y+25,X+initialx%+5,Y+25
      LINE X-5,Y+25, X-5,Y-45
      LINE X+initialx%+5,Y+25,X+initialx%+5,Y-45
      LINE X-5,Y-45,X+initialx%+5,Y-45
      MOVE 0,0 REM hide that thing
      ENDPROC
      REM ******************this is a custom Foreground and Background control tool (too much?) *****************
      REM color "F"or"B", r,g,b
      DEF PROC_color(fb$,r,g,b)
      IF fb$="f" OR fb$="F" THEN COLOUR 0,r,g,b : GCOL 0
      IF fb$="b" OR fb$="B" THEN COLOUR 1,r,g,b : GCOL 128+1
      ENDPROC
 

Re: Turtle drawing tool ( New mod down posts)
Post by DDRM on Oct 3rd, 2016, 3:02pm

Hi Michael,

I don't think you need another set of variables to hold the position of the turtle - you've already got Turtle_px% and Turtle_py%! Similarly, there is Turtle_col% holding the existing colour of the turtle's pen (although if you've re-programmed it in your text input there's a problem...)

If you add:
Code:
MOVE Turtle_px%,Turtle_py%
GCOL Turtle_col% 

at the beginning of the ProcTurtle (I've put them just after the LOCAL declarations), and modify my sloppy line in that routine setting the colour to:
Code:
WHEN "c","C":Turtle_col%= n MOD 16:GCOL Turtle_col% 

It should work just fine.

Incidentally, I see your version includes BOTH PROCTurtleInit (which sets up the turtle control parameters as globals) AND the flag-controlled setup of PRIVATE variables with the same names within PROCTurtle. That's confusing, and risks you not being sure which one is active at any given place in the programme. The PRIVATE ones will be active within the drawing routine itself, but the global ones will be in force outside it - for example in your box-drawing routine... You need to ditch one or the other (if you really need access to them outside the Turtle routine itself, you'll need to keep the global versions, and ditch the PRIVATE ones - otherwise you could just ditch PROCTurtleInit).

At the moment your PROC_input doesn't preserve and restore the background behind the input box, which is a bit limiting... Given that we worked out several ways to do this a few months ago, why not incorporate that code? Alternatively, you could set aside part of the screen (maybe the very top or bottom lines) for your commands, and exclude them from the turtle drawing area. If you set the text and graphics areas carefully, BB4W will even deal with all the clipping issues for you!

If you restricted the programmer to the 16 colours available for the mouse drawing, you could simplify your textbox routine significantly, and avoid problems with modified colours 0 and 1...

At the moment, PROC_Input is a procedure which sets a global variable (MESSAGE$) , which you then assign to command$ before passing it to the turtle routine. Why not make PROC_Input into a function which could return the string direct to command$ (or simply pass MESSAGE$ to PROCTurtle)?

Best wishes,

D

Re: Turtle drawing tool ( New mod down posts)
Post by michael on Oct 3rd, 2016, 5:49pm

input tool is now a FN
color tool is now just standard colors
graphics text tool is also standard colors.
So its basic.
I modified the program with your suggestions except for my invented variables.
It now seems to function well.
Code:
      MODE 22
      presx%=0:presy%=0
      PROCTurtleInit
      REM gbx% and gby% NEED to be whole numbers and need to be global ( they hold shared text input location )
      gbx%=0:gby%=0:split%=0:cursor%=0 :REM GLOBAL VARIABLES
      REM split% holds the divide location of the string so edits can be made. ( this is where it gets technical)
      tempstr$=""
      lx=0:ly=0:lh=0:lv=0
      REM define my line position
      li=0
      REM Set background color to windows common color gray (my custom RGB text background color)
      GCOL 0 : REM Set graphics foreground to palette color 0  (BLACK)
      GCOL 128+8 : REM Set graphics background to palette color 1
      VDU 5 : REM Treat text as graphics (transparent background)
      OFF:CLG:PROC_pr(10,900,"DDRMS turtle program",13)
      PROC_color("F",15)
      REM H,V,TEXTLIMIT (getting simpler?)
      REPEAT
        command$= FN_input(200,610,50)
        MOVE presx%,presy%
        PROCTurtle(command$)
        *REFRESH
      UNTIL FALSE
      END
      DEFPROCTurtleInit
      REM Turtle parameters made global to allow recursive calls to PROCTurtle for macros
      Turtle_px%=0   :REM X position of turtle
      Turtle_py%=0   :REM Y position of turtle
      Turtle_angle=0 :REM initial heading of turtle in degrees (anticlockwise from right=0)
      Turtle_pen%=0  :REM i.e. pen up
      Turtle_col%=15
      ENDPROC
      REM ***********************this is my super custom text box tool ***********************
      REM X,Y,message,backgroundcolor
      REM ************************************************************************
      DEF PROC_pr(X,Y,msg$,c%)
      initialx%=LEN(msg$)
      GCOL c%
      LET tx= X+initialx%+25
      LET ty= Y:reduction%=0
      reduction%=initialx%/2
      reduction%=reduction%*6
      IF initialx%<20 THEN reduction%=reduction%/2
      initialx%=initialx%*22-reduction%
      FOR fill=1 TO 58
        LINE X+3,Y+20-fill,X+initialx%,Y+20-fill
      NEXT fill
      GCOL 0
      MOVE tx,ty
      PRINT msg$
      GCOL 0
      LINE X,Y+20,X+initialx%,Y+20
      LINE X,Y+20,X,Y-40
      LINE X,Y-40,X+initialx%,Y-40
      LINE X+initialx%,Y-40,X+initialx%,Y+20
      LINE X-5,Y+25,X+initialx%+5,Y+25
      LINE X-5,Y+25, X-5,Y-45
      LINE X+initialx%+5,Y+25,X+initialx%+5,Y-45
      LINE X-5,Y-45,X+initialx%+5,Y-45
      MOVE 0,0 REM hide that thing
      ENDPROC
      :
      DEFPROCTurtle(c$)
      GCOL Turtle_col%
      PRIVATE Turtle_pen%,flag%
      IF NOT flag% THEN
        Turtle_px%=0   :REM X position of turtle
        Turtle_py%=0   :REM Y position of turtle
        Turtle_angle=0 :REM initial heading of turtle in degrees (anticlockwise from right=0)
        Turtle_pen%=0  :REM i.e. pen up
        REM Turtle_col%=15
        flag%=TRUE
      ENDIF
      LOCAL dx%,dy%,t$,n
      WHILE c$<>""
        t$=LEFT$(c$,1)
        c$=MID$(c$,2)
        n=VAL(c$)
        dx%=0
        dy%=0
        IF n>0 THEN c$=MID$(c$,LEN(STR$(n))+1)
        REM There's a fault here: if a parameter is 0 then it'll get left on the string
        REM But it's not a serious one, since it will get stripped off the next time round, without doing anything in the CASE.
        CASE t$ OF
          WHEN "u","U":Turtle_pen%=0
          WHEN "d","D":Turtle_pen%=1
          WHEN "h","H":Turtle_px%=0:Turtle_py%=0:Turtle_angle=0
          WHEN "n","N":Turtle_angle=90
          WHEN "w","W":CLS:Turtle_px%=0:Turtle_py%=0:Turtle_angle=0
          WHEN "l","L":IF n=0 THEN Turtle_angle+=90 ELSE Turtle_angle+=n
          WHEN "r","R":IF n=0 THEN Turtle_angle-=90 ELSE Turtle_angle-=n
          WHEN "f","F":dx%=INT (n*COSRAD(Turtle_angle)+0.5):dy%=INT(n*SINRAD(Turtle_angle)+0.5)
          WHEN "b","B":dx%=-INT((n*COSRAD(Turtle_angle)+0.5)):dy%=-INT((n*SINRAD(Turtle_angle)+0.5))
          WHEN "a","A":Turtle_angle=n
          WHEN "x","X":Turtle_px%=n
          WHEN "y","Y":Turtle_py%=n
          WHEN "c","C":Turtle_col%= n MOD 16:GCOL Turtle_col%
          WHEN "t","T":VDU 23,23,n;0;0;0;
          WHEN "i","I":GCOL n:FILL Turtle_px%,Turtle_py%
          WHEN "[":
            REM You could modify this to allow nested macros - you'd need to count and balance the left and right brackets
            REM In the meantime, you could include a macro in an embedded string inside your macro - that would work OK, I think.
            n=INSTR(c$,"]")
            t$=LEFT$(c$,n-1)
            c$=MID$(c$,n+1)
            n=VAL(c$)
            IF n>0 THEN c$=MID$(c$,LEN(STR$(n))+1)
            FOR dx%=1 TO n
              PROCTurtle(t$)
            NEXT dx%
            dx%=0
          WHEN ".":
            n=INSTR(c$,".")
            t$=LEFT$(c$,n-1)
            c$=MID$(c$,n+1)
            PROCTurtle(EVAL(t$))
        ENDCASE
        Turtle_px%+=dx%
        Turtle_py%+=dy%
        IF Turtle_pen% THEN DRAW Turtle_px%,Turtle_py% ELSE MOVE Turtle_px%,Turtle_py%
      ENDWHILE
      presx%=Turtle_px%:presy%=Turtle_py%
      ENDPROC
      REM H,V,TEXTLIMIT (simpler?)
      DEF FN_input(bx,by,textlimit)
      LOCAL fill,MESSAGE$
      gbx%=bx:gby%=by:initialx%=0:sl%=0:key$="":MESSAGE$="":MES$=""
      initialx%=textlimit*16.2
      FOR fill=1 TO 58
        PROC_color("f",15):LINE bx+3,by+20-fill,bx+initialx%,by+20-fill
      NEXT fill
      PROC_color("f",0):LINE bx+3,by+20,bx+initialx%,by+20:LINE bx+3,by+20-fill,bx+initialx%,by+20-fill:
      REPEAT
        REPEAT
          key$ =INKEY$(1)
          PROC_color("F",0)
          MOVE bx,by:PRINT MESSAGE$;"_" :* REFRESH
          sl%=LEN(MESSAGE$)
          remains%=sl%-cursor%
          lstring$=LEFT$(MESSAGE$,cursor%):rstring$=RIGHT$(MESSAGE$,remains%)
        UNTIL key$ <>""
        sl%=LEN(MESSAGE$)
        IF INKEY(-48) sl%=LEN(MESSAGE$)-1:key$=""
        REPEAT UNTIL INKEY(0)=-1
        IF sl%<LEN(MESSAGE$) THEN
          PROC_color("F",15)
          MOVE bx,by
          PRINT MESSAGE$;"_"
        ENDIF
        MES$=MID$(MESSAGE$,0,sl%)
        MESSAGE$=MES$
        PROC_color("F",15):MOVE bx,by:PRINT MESSAGE$;"_"
        IF LEN(key$) = 1 THEN
          IF LEN(MESSAGE$)<textlimit THEN PROC_color("F",15):MOVE bx,by:PRINT MESSAGE$;"_": MESSAGE$=MESSAGE$+key$:* REFRESH OFF
          REM (jump)
        ENDIF
      UNTIL INKEY(-74)
      * REFRESH ON
      =MESSAGE$
      REM ******************this is a custom Foreground and Background control tool (too much?) *****************
      REM color "F"or"B", r,g,b
      DEF PROC_color(fb$,c%)
      IF fb$="f" OR fb$="F" THEN COLOUR c%: GCOL c%
      IF fb$="b" OR fb$="B" THEN COLOUR c% : GCOL 128+c%
      ENDPROC