Is the canvas the only way to draw?

Just starting out? Need help? Post your questions and find answers here.
munfraid
Posts: 104
Joined: Sat Mar 24, 2018 1:33 pm

Re: Is the canvas the only way to draw?

Post by munfraid »

Random Terrain wrote: Fri Jul 16, 2021 5:04 pmSo there is code in there that switches the color to BGR
Yes, you find it in the procedure ColorCellClicked().

It's simply done like that:

Code: Select all

bgrColor = Blue(rgbColor) + Green(rgbColor)*256 + Red(rgbColor)*65536
User avatar
Random Terrain
Posts: 63
Joined: Fri Jul 09, 2021 9:48 pm
Location: USA
Contact:

Re: Is the canvas the only way to draw?

Post by Random Terrain »

When you have time, I have a few more questions.

Question 1: Row Mode Clear

How do I clear the editor when the user selects a different Row Mode (as if they clicked on the Clear button)? In other words, where would the code below go?

Code: Select all

 
      Dim playfieldData(cols, rows)
      Dim playfieldFG(rows)
      Dim playfieldBG(rows)
      StartDrawing(CanvasOutput(#Canvas_Playfield))
      Box(0, 0, cols*colScale, rows*rowHeight, #White)
      StopDrawing()

Question 2: Arrays

I see you already keep track of things using arrays, but I probably need to create two more FG and BG arrays just to remember the smaller Atari 2600 color data numbers. For example, if the user paints a row with #EDEDED, the secondary array would store $0E for that row.

I probably also need to have a special playfield array that is separate from the one used for the canvas.

Then when the user clicks on the "Output Code" or "Display Code" button or whatever it will be called, it will display the correct data for the user.

So I'm guessing I'd start with something like this:

Code: Select all

Global Dim bB_playfieldData(32, 11)
Global Dim bB_playfieldFG(11)
Global Dim bB_playfieldBG(11)
(bB stands for batari Basic.)

When a Row Mode is selected, the canvas would be cleared, playfieldData(cols, rows), playfieldFG(rows), playfieldBG(rows) would be Dim-ed, and the secondary bB arrays would be Dim-ed.

Selecting 176 Rows would clear the canvas and do this:
Dim bB_playfieldData(32, 176)
Dim bB_playfieldFG(176)
Dim bB_playfieldBG(176)

Selecting 88 Rows would clear the canvas and do this:
Dim bB_playfieldData(32, 88)
Dim bB_playfieldFG(88)
Dim bB_playfieldBG(88)

Selecting 44 Rows would clear the canvas and do this:
Dim bB_playfieldData(32, 44)
Dim bB_playfieldFG(44)
Dim bB_playfieldBG(44)

Selecting 22 Rows would clear the canvas and do this:
Dim bB_playfieldData(32, 22)
Dim bB_playfieldFG(22)
Dim bB_playfieldBG(22)

Selecting 11 Rows would clear the canvas and do this:
Dim bB_playfieldData(32, 11)
Dim bB_playfieldFG(11)
Dim bB_playfieldBG(11)

When the player draws or erases, the bB_playfieldData array would keep track based on the Row Mode that was selected.

When the user clicks on the "Output Code" or "Display Code" button or whatever it will be called, the program will display the string " playfield:" (3 leading spaces), start the next row with 3 spaces, and read bB_playfieldData and put a dot for 0 (off) and an uppercase X for 1 (on) 32 times, repeat until the end of the rows, then end it with the string "end" with no leading spaces. A blank line would be placed after "end." Example:

Code: Select all

   playfield:
   .XXXXX.XXXX.XX...XXXX.XXXX.XXXX.
   .XX....XX...XX...XX...XX....XX..
   .XXXXX.XXXX.XX...XXXX.XX....XX..
   ....XX.XX...XX...XX...XX....XX..
   .XXXXX.XXXX.XXXX.XXXX.XXXX..XX..
   ................................
   XXXXX.XXXX.XXXX.XXXXX....XX.XX..
   XX....XX...XX...XX..XX..XXXXXXX.
   XXXXX.XXXX.XXXX.XX..XX...XX.XX..
   ...XX.XX...XX...XX..XX..XXXXXXX.
   XXXXX.XXXX.XXXX.XXXXX....XX.XX..
end
The foreground color data would start with the string " pfcolors:" (3 leading spaces), start the next row with 3 spaces, read bB_playfieldFG and put one color for that row including the dollar sign, repeat, then end it with the string "end" with no leading spaces. A blank line would be placed after "end." Example:

Code: Select all

   pfcolors:
   $0E
   $0C
   $0A
   $08
   $06
   $00
   $00
   $0E
   $0C
   $0A
   $08
end

The background color data would start with the string " bkcolors:" (3 leading spaces), start the next row with 3 spaces, read bB_playfieldBG and put one color for that row including the dollar sign, repeat, then end it with the string "end" with no leading spaces. Two blank lines would be placed after "end." Example:

Code: Select all

   bkcolors:
   $8C
   $8E
   $8E
   $00
   $F0
   $F2
   $F2
   $F4
   $F4
   $F4
   $F6
end


The string "__Main_Loop" with no leading spaces would be next, followed by two blank lines, then code based on the Row Mode would be placed.

If 176 Rows, this would be next:

Code: Select all

   ;***************************************************************
   ;
   ;  176 rows that are 1 scanline high except the top and bottom
   ;  rows (which seem to be 2 scanlines high). All of the colors
   ;  seem to be 2 scanlines high.
   ;
   DF6FRACINC = 255 ; Background colors.
   DF4FRACINC = 255 ; Playfield colors.

   DF0FRACINC = 255 ; Column 0.
   DF1FRACINC = 255 ; Column 1.
   DF2FRACINC = 255 ; Column 2.
   DF3FRACINC = 255 ; Column 3.
If 88 Rows, this would be next:

Code: Select all

 
   ;***************************************************************
   ;
   ;  88 rows that are 2 scanlines high.
   ;
   DF6FRACINC = 255 ; Background colors.
   DF4FRACINC = 255 ; Playfield colors.

   DF0FRACINC = 128 ; Column 0.
   DF1FRACINC = 128 ; Column 1.
   DF2FRACINC = 128 ; Column 2.
   DF3FRACINC = 128 ; Column 3.
If 44 Rows, this would be next:

Code: Select all

   ;***************************************************************
   ;
   ;  44 rows that are 4 scanlines high.
   ;
   DF6FRACINC = 128 ; Background colors.
   DF4FRACINC = 128 ; Playfield colors.

   DF0FRACINC = 64 ; Column 0.
   DF1FRACINC = 64 ; Column 1.
   DF2FRACINC = 64 ; Column 2.
   DF3FRACINC = 64 ; Column 3.
If 22 Rows, this would be next:

Code: Select all

   ;***************************************************************
   ;
   ;  22 rows that are 8 scanlines high.
   ;
   DF6FRACINC = 64 ; Background colors.
   DF4FRACINC = 64 ; Playfield colors.

   DF0FRACINC = 32 ; Column 0.
   DF1FRACINC = 32 ; Column 1.
   DF2FRACINC = 32 ; Column 2.
   DF3FRACINC = 32 ; Column 3.
If 11 Rows, this would be next:

Code: Select all

   ;***************************************************************
   ;
   ;  11 rows that are 16 scanlines high.
   ;
   DF6FRACINC = 32 ; Background colors.
   DF4FRACINC = 32 ; Playfield colors.

   DF0FRACINC = 16 ; Column 0.
   DF1FRACINC = 16 ; Column 1.
   DF2FRACINC = 16 ; Column 2.
   DF3FRACINC = 16 ; Column 3.
After that two blank lines would be placed, then this would be placed:

Code: Select all

 
   ;***************************************************************
   ;
   ;  Displays the screen.
   ;
   drawscreen
Two blank lines would be placed after that, then this would be placed:

Code: Select all

   goto __Main_Loop

Here's an example of what it might look like all together:

Code: Select all

   playfield:
   .XXXXX.XXXX.XX...XXXX.XXXX.XXXX.
   .XX....XX...XX...XX...XX....XX..
   .XXXXX.XXXX.XX...XXXX.XX....XX..
   ....XX.XX...XX...XX...XX....XX..
   .XXXXX.XXXX.XXXX.XXXX.XXXX..XX..
   ................................
   XXXXX.XXXX.XXXX.XXXXX....XX.XX..
   XX....XX...XX...XX..XX..XXXXXXX.
   XXXXX.XXXX.XXXX.XX..XX...XX.XX..
   ...XX.XX...XX...XX..XX..XXXXXXX.
   XXXXX.XXXX.XXXX.XXXXX....XX.XX..
end

   pfcolors:
   $0E
   $0C
   $0A
   $08
   $06
   $00
   $00
   $0E
   $0C
   $0A
   $08
end

   bkcolors:
   $8C
   $8E
   $8E
   $00
   $F0
   $F2
   $F2
   $F4
   $F4
   $F4
   $F6
end


__Main_Loop


   ;***************************************************************
   ;
   ;  11 rows that are 16 scanlines high.
   ;
   DF6FRACINC = 32 ; Background colors.
   DF4FRACINC = 32 ; Playfield colors.

   DF0FRACINC = 16 ; Column 0.
   DF1FRACINC = 16 ; Column 1.
   DF2FRACINC = 16 ; Column 2.
   DF3FRACINC = 16 ; Column 3.


   ;***************************************************************
   ;
   ;  Displays the screen.
   ;
   drawscreen


   goto __Main_Loop
Then the user can copy the entire code and run it to see what it looks like on a real Atari 2600 or they can choose to just copy the data and put in a program they're already working on.



Question 3: Draw/Erase/Toggle

How hard would it be to add a draw button, an erase button, and a toggle button? One editor I used had toggle as the default and it let the user hold the CTRL key to erase and hold down the Alt key to draw without toggling. In this case with SpiderBasic, maybe the user could have the choice of using buttons and/or using keyboard shortcuts (whichever the user prefers).


Thanks.
munfraid
Posts: 104
Joined: Sat Mar 24, 2018 1:33 pm

Re: Is the canvas the only way to draw?

Post by munfraid »

Random Terrain wrote: Fri Jul 16, 2021 9:04 pmQuestion 1: Row Mode Clear

How do I clear the editor when the user selects a different Row Mode (as if they clicked on the Clear button)? In other words, where would the code below go?
This goes to the GadgetEvents() procedure where the events of the #Combo_Rows are handled.

Question 2: Arrays

There are various ways to handle your data. Of course you can use more arrays ore extend the existing ones whith another dimension. Another possibility would be a Structured List. It's a matter of taste.

Then you give a long description of the specs for the code you want to output. What is the question about this?

Random Terrain wrote: Fri Jul 16, 2021 9:04 pmQuestion 3: Draw/Erase/Toggle

How hard would it be to add a draw button, an erase button, and a toggle button?
Not hard at all. You can see in the code how gadgets (like buttons) are declared, put in place and how their events are handled. The Draw button is yet there. Just add two new buttons for Toggle and Erase. Inside GadgetEvents() where you perform the drawing add the new modes. For Toggle it's:

Code: Select all

playfieldData(x, y*rowHeight) = 1-playfieldData(x, y*rowHeight)
For Erase it's:

Code: Select all

playfieldData(x, y*rowHeight) = 0
Each one followed by the box command as it is done with the draw mode.
User avatar
Random Terrain
Posts: 63
Joined: Fri Jul 09, 2021 9:48 pm
Location: USA
Contact:

Re: Is the canvas the only way to draw?

Post by Random Terrain »

munfraid wrote: Sat Jul 17, 2021 8:25 am
Random Terrain wrote: Fri Jul 16, 2021 9:04 pmQuestion 1: Row Mode Clear

How do I clear the editor when the user selects a different Row Mode (as if they clicked on the Clear button)? In other words, where would the code below go?
This goes to the GadgetEvents() procedure where the events of the #Combo_Rows are handled.
Thanks. I'm going to make a new thread about "Case" for others who might be new to SpiderBasic.


munfraid wrote: Sat Jul 17, 2021 8:25 am
Random Terrain wrote: Fri Jul 16, 2021 9:04 pmQuestion 1: Row Mode Clear
Question 2: Arrays
There are various ways to handle your data. Of course you can use more arrays ore extend the existing ones whith another dimension. Another possibility would be a Structured List. It's a matter of taste.

Then you give a long description of the specs for the code you want to output. What is the question about this?
I wanted to put it all out in detail before I forget it and to let you see it at the same time in case you have any ideas on the best way to do it. For example, if the user has selected 44 rows, the output will be different than if the user selected 88 rows.

In other BASIC-like languages, most everything is done with if-then. (If this was selected, then do this.) There's also a main loop where everything happens. In SpiderBasic, it seems like everything is separate from everything else. Like little countries doing their own thing and not really having anything to do with each other.


munfraid wrote: Sat Jul 17, 2021 8:25 am
Random Terrain wrote: Fri Jul 16, 2021 9:04 pmQuestion 3: Draw/Erase/Toggle

How hard would it be to add a draw button, an erase button, and a toggle button?
Not hard at all. You can see in the code how gadgets (like buttons) are declared, put in place and how their events are handled. The Draw button is yet there. Just add two new buttons for Toggle and Erase. Inside GadgetEvents() where you perform the drawing add the new modes. For Toggle it's:

Code: Select all

playfieldData(x, y*rowHeight) = 1-playfieldData(x, y*rowHeight)
For Erase it's:

Code: Select all

playfieldData(x, y*rowHeight) = 0
Each one followed by the box command as it is done with the draw mode.
That does look pretty easy. Thanks.
munfraid
Posts: 104
Joined: Sat Mar 24, 2018 1:33 pm

Re: Is the canvas the only way to draw?

Post by munfraid »

Random Terrain wrote: Sat Jul 17, 2021 3:14 pmThanks. I'm going to make a new thread about "Case" for others who might be new to SpiderBasic.
Don't know if you yet know it: When you click in your code on a keyword such as 'case' and then hit F1, the manual will pop up showing the help page for this command or keyword. Also pay attention to the footer. Whenever you edit the code, a short help for the command you're editing is displayed there, which I find very helpful.
Random Terrain wrote: Sat Jul 17, 2021 3:14 pmThere's also a main loop where everything happens. In SpiderBasic, it seems like everything is separate from everything else. Like little countries doing their own thing and not really having anything to do with each other.
That was very confusing for me too in the beginning. The reason that there is no main loop is javascript. SB code is transpiled into javascript and this runs asynchronously. That's why a linear programm execution is not possible, and because of that also no event loop. But the difference is not too big. With BindEvent() you assign a procedure to your window, which handles all the events. This is pretty much like a main loop.

By the way, I had a look in your website today and really like it. Was like a trip to the past with nice memories! As a kid I owned a VC 2600 by myself and truly loved it. Spent hours to play Pitfall and River Raid and some others all day... Even took my first approach to code with this machine.

I also added some code to the editor. The playfield is now cleared when select a new row mode, and there are new buttons for toggle and erase. Maybe you'd like have a look:

Code: Select all

;- META
EnableExplicit

#AppName = "Playfield Editor"
#Version = "0.0.3"

;- DECLARATIONS

; defining named constants for all objects
; important for much better code readability

Enumeration windows
  #Window_Main  
  #Window_Color
  #Window_Code
EndEnumeration

Enumeration gadgets
  #Button_Clear
  #Button_FrontColor
  #Button_BackColor
  #Button_Draw
  #Button_Toggle
  #Button_Erase
  #Button_EditBG  
  #Button_EditFG
  #Canvas_Playfield
  #Combo_Rows  
  #Container_ColorTable
  #Text_EditingMode
  #Text_FrontColor
  #Text_BackColor
  #Text_Footer
  #Text_Mode
  #Text_Title
EndEnumeration

Enumeration fonts
  #Font_UiBig
  #Font_UiNormal
  #Font_UiSmall
EndEnumeration

;- SETTINGS

; defines several settings for the appearance
; change as you wish

; ui
Global colorWindowBG = RGB(64,64,64)   ; colors for the editor
Global colorText = RGB(255,255,255)     
Global fontUiBig.s = "Arial"           ; fonts for text in editor ui 
Global fontUiBigSize = 30
Global fontUiNormal.s = "Arial"
Global fontUiNormalSize = 16
Global fontUiSmall.s = "Arial"
Global fontUiSmallSize = 10
Global spacer = 10                     ; space between ui elements; change as you like
Global textFooter.s = #AppName + " v." + #Version + " by randomterrain.com"

; playyfield
Global mode = #Button_Draw            ; default mode 
Global colorFG = #Black               ; default foreground color
Global colorBG = #White               ; default background color
Global cols = 32                      ; fixed value for number of columns
Global colScale = 15                  ; currently set to 15, which results in 15*32 columns = 480 pixel width; change as you wish
Global rows = 176                     ; same as for columns
Global rowScale = 2                   ; same as for columns
Global rowHeight = 16                 ; set to 16 by default because I put 11 rows as default in the initUI() procedure
Global x, y, GID, whichColor
Global Dim playfieldData(cols, rows)
Global Dim playfieldFG(rows)
Global Dim playfieldBG(rows)
Define i
For i = 0 To rows-1
  playfieldFG(i) = colorFG
  playfieldBG(i) = colorBG
Next

;- PROCEDURES

Procedure ClearPlayfield()
  
  Dim playfieldData(cols, rows)
  Dim playfieldFG(rows)
  Dim playfieldBG(rows)
  StartDrawing(CanvasOutput(#Canvas_Playfield))
  Box(0, 0, cols*colScale, rows*rowHeight, #White)
  StopDrawing()
  
EndProcedure

Procedure TimerEvents()
  Select EventTimer()
    Case 0
      If WindowMouseX(#Window_Color) = -1
        CloseWindow(#Window_Color)  
      EndIf
  EndSelect
EndProcedure

Procedure WindowEvents()
  Select EventWindow()
    Case #Window_Color
      CloseWindow(#Window_Color)
  EndSelect  
EndProcedure

Procedure ColorCellClicked(Title.s, Color.s)
  
  Protected selectedColor = Val(ReplaceString(Color.s, "#", "$"))
  selectedColor = Blue(selectedColor) + Green(selectedColor)*256 + Red(selectedColor)*65536 
  
  Select whichColor
      
    Case #Button_FrontColor
      colorFG = selectedColor      
      GID=GadgetID(#Button_FrontColor)
      ! $(v_gid.div).find(".dijitButtonContents").css("background-color", spider_helper_ColorToHtml(v_colorfg));
      
    Case #Button_BackColor
      colorBG = selectedColor      
      GID=GadgetID(#Button_BackColor)
      ! $(v_gid.div).find(".dijitButtonContents").css("background-color", spider_helper_ColorToHtml(v_colorbg));
      
  EndSelect
  
  CloseWindow(#Window_Color)
  
EndProcedure

Procedure.s Get_NTSC_ColorTable()
  
  Protected Table.s
  Protected Title.s, Color.s
  Protected RowCounter, ColCounter
  
  Restore NTSC
  
  Table + "<table id='colorTable' style='width:100%;height:100%'>"
  
  For RowCounter = 0 To 15
    Table + "<tr>"
    For ColCounter = 0 To 7
      Read.s Title
      Read.s Color
      Table + "<td title='" + Title + "' color='" + Color + "' style='background-color:" + Color + "'></td>"
    Next ; ColCounter
    Table + "</tr>"
  Next ; RowCounter
  
  Table + "</table>"
  
  ProcedureReturn Table
  
EndProcedure

Procedure GadgetEvents()
  
  ; handle all that happens during runtime 
  
  Protected gadget = EventGadget()
  Protected type = EventType()
  Protected i

  Select gadget
      
    Case #Canvas_Playfield
      If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(#Canvas_Playfield, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
        If StartDrawing(CanvasOutput(#Canvas_Playfield))
          
          ; find out which column and row was clicked
          x = (GetGadgetAttribute(#Canvas_Playfield, #PB_Canvas_MouseX)/colScale)
          y = (GetGadgetAttribute(#Canvas_Playfield, #PB_Canvas_MouseY)/(rowHeight*rowScale))
          
          ; perform drawing depending on current mode
          If mode = #Button_Draw
            playfieldData(x, y*rowHeight) = 1 
            Box(x*colScale, y*rowScale*rowHeight, colScale, rowHeight*rowScale, playfieldFG(y*rowheight))
            
          ElseIf mode = #Button_Toggle
            Select playfieldData(x, y*rowHeight)
              Case 1
                playfieldData(x, y*rowHeight) = 0 
                Box(x*colScale, y*rowScale*rowHeight, colScale, rowHeight*rowScale, playfieldBG(y*rowheight))
              Case 0
                playfieldData(x, y*rowHeight) = 1 
                Box(x*colScale, y*rowScale*rowHeight, colScale, rowHeight*rowScale, playfieldFG(y*rowheight))
            EndSelect
                    
          ElseIf mode = #Button_Erase
            playfieldData(x, y*rowHeight) = 0
            Box(x*colScale, y*rowScale*rowHeight, colScale, rowHeight*rowScale, playfieldBG(y*rowheight))
            
          ElseIf mode = #Button_EditBG
            playfieldBG(y*rowHeight) = colorBG
            Box(0, y*rowHeight*rowScale, cols*colScale, rowHeight*rowScale, colorBG)
            For i = 0 To cols-1
              If playfieldData(i,y*rowHeight) = 1
                Box(i*colScale, y*rowScale*rowHeight, colScale, rowHeight*rowScale, playfieldFG(y*rowheight))
              EndIf
            Next
            
          ElseIf mode = #Button_EditFG
            playfieldFG(y*rowHeight) = colorFG
            For i = 0 To cols-1
              If playfieldData(i,y*rowHeight) = 1
                Box(i*colScale, y*rowScale*rowHeight, colScale, rowHeight*rowScale, colorFG)
              EndIf
            Next
          EndIf
          
          StopDrawing()
          
        EndIf
      EndIf
      
    Case #Combo_Rows 
      rowHeight = Pow(2, GetGadgetState(#Combo_Rows))
      If type = #PB_EventType_Change
        ClearPlayfield()
      EndIf
      
    Case #Button_Draw To #Button_EditFG
      ; set drawing mode
      For i = #Button_Draw To #Button_EditFG
        SetGadgetState(i, 0)
      Next
      SetGadgetState(gadget, 1)
      mode = gadget
      
    Case #Button_FrontColor, #Button_BackColor
      whichColor = gadget
      OpenWindow(#Window_Color, WindowMouseX(#Window_Main)-10, WindowMouseY(#Window_Main)-50, 
                 200, 400, "Color NTSC");, #PB_Window_BorderLess)
      ContainerGadget(#Container_ColorTable, 0, 0, WindowWidth(#Window_Color), WindowHeight(#Window_Color)  )
      GID = GadgetID(#Container_ColorTable)
      ! $(v_gid.div).empty();
      ! $(v_gid.div).append($(v_ntsc_colortable));
      ! $('#colorTable').on('click','td', function() {
      !   f_colorcellclicked($(this).attr("title"), $(this).attr("color"));
      ! });
      AddWindowTimer(#Window_Color, 0, 100)
      
    Case #Button_Clear
      ClearPlayfield()

  EndSelect
  
EndProcedure


Procedure initUI()
  
  ; create main window and user interface
  
  LoadFont(#Font_UiBig, fontUiBig, fontUiBigSize)
  LoadFont(#Font_UiNormal, fontUiNormal, fontUiNormalSize)
  LoadFont(#Font_UiSmall, fontUiSmall, fontUiSmallSize)
     
  If OpenWindow(#Window_Main, 0, 0, 0, 0, #AppName, #PB_Window_Background)
    
    SetWindowColor(#Window_Main, colorWindowBG)
    
    ; title
    TextGadget(#Text_Title, 5*spacer, 5*spacer, cols*colScale*3, fontUiBigSize, #AppName)
    SetGadgetFont(#Text_Title, FontID(#Font_UiBig))
    SetGadgetColor(#Text_Title, #PB_Gadget_FrontColor, colorText)
    
    ; playfield
    CanvasGadget(#Canvas_Playfield, GadgetX(#Text_Title), GadgetY(#Text_Title)+GadgetHeight(#Text_Title)+4*spacer,
                 cols*colScale, rows*rowScale, #PB_Canvas_Border)
    
    ; clear button
    ButtonGadget(#Button_Clear, GadgetX(#Text_Title), GadgetY(#Canvas_Playfield)+GadgetHeight(#Canvas_Playfield)+3*spacer,
                 80, 30, "Clear")
    
    ; row modes
    TextGadget(#Text_Mode, GadgetX(#Canvas_Playfield)+GadgetWidth(#Canvas_Playfield)+3*spacer, GadgetY(#Canvas_Playfield), 
               200, fontUiNormalSize, "Row Mode")
    SetGadgetFont(#Text_Mode, FontID(#Font_UiNormal))
    SetGadgetColor(#Text_Mode, #PB_Gadget_FrontColor, colorText)
    
    ComboBoxGadget(#Combo_Rows, GadgetX(#Text_Mode), GadgetY(#Text_Mode)+fontUiNormalSize+spacer, 240, 30)
    AddGadgetItem(#Combo_Rows, -1, " 32 columns with 176 rows")
    AddGadgetItem(#Combo_Rows, -1, " 32 columns with 88 rows")
    AddGadgetItem(#Combo_Rows, -1, " 32 columns with 44 rows")
    AddGadgetItem(#Combo_Rows, -1, " 32 columns with 22 rows")
    AddGadgetItem(#Combo_Rows, -1, " 32 columns with 11 rows")
    SetGadgetState(#Combo_Rows, 4)
    
    ; editing mode
    TextGadget(#Text_EditingMode, GadgetX(#Text_Mode), GadgetY(#Combo_Rows)+30+3*spacer, 240, fontUiNormalSize, "Editing Mode")
    SetGadgetFont(#Text_EditingMode, FontID(#Font_UiNormal))
    SetGadgetColor(#Text_EditingMode, #PB_Gadget_FrontColor, colorText)
        
    ButtonGadget(#Button_Draw, GadgetX(#Text_Mode), GadgetY(#Text_EditingMode)+fontUiNormalSize+spacer, 80, 30,
                 "Draw", #PB_Button_Toggle )
    ButtonGadget(#Button_Toggle, GadgetX(#Text_Mode)+80, GadgetY(#Text_EditingMode)+fontUiNormalSize+spacer, 80, 30,
                 "Toggle", #PB_Button_Toggle )
    ButtonGadget(#Button_Erase, GadgetX(#Text_Mode)+160, GadgetY(#Text_EditingMode)+fontUiNormalSize+spacer, 80, 30,
                 "Erase", #PB_Button_Toggle)
    ButtonGadget(#Button_EditFG, GadgetX(#Text_Mode), GadgetY(#Text_EditingMode)+fontUiNormalSize+spacer+30, 80, 30,
                 "Color FG", #PB_Button_Toggle )
    ButtonGadget(#Button_EditBG, GadgetX(#Text_Mode)+80, GadgetY(#Text_EditingMode)+fontUiNormalSize+spacer+30, 80, 30,
                 "Color BG", #PB_Button_Toggle)
    SetGadgetState(mode, 1)
    
    ; color selection
    TextGadget(#Text_FrontColor, GadgetX(#Text_Mode), GadgetY(#Button_EditFG)+35+3*spacer, 160, fontUiNormalSize, "Foreground Color")
    SetGadgetFont(#Text_FrontColor, FontID(#Font_UiNormal))
    SetGadgetColor(#Text_FrontColor, #PB_Gadget_FrontColor, colorText)
    ButtonGadget(#Button_FrontColor, GadgetX(#Text_FrontColor)+GadgetWidth(#Text_FrontColor), GadgetY(#Text_FrontColor)-5, 60, 30, "")
    GID=GadgetID(#Button_FrontColor)
    ! $(v_gid.div).find(".dijitButtonContents").css("background-color", spider_helper_ColorToHtml(v_colorfg));
    
    TextGadget(#Text_BackColor, GadgetX(#Text_Mode), GadgetY(#Button_EditFG)+75+3*spacer, 160, fontUiNormalSize, "Background Color")
    SetGadgetFont(#Text_BackColor, FontID(#Font_UiNormal))
    SetGadgetColor(#Text_BackColor, #PB_Gadget_FrontColor, colorText)
    ButtonGadget(#Button_BackColor, GadgetX(#Text_BackColor)+GadgetWidth(#Text_BackColor), GadgetY(#Text_BackColor)-5, 60, 30, "")
    GID=GadgetID(#Button_BackColor)
    ! $(v_gid.div).find(".dijitButtonContents").css("background-color", spider_helper_ColorToHtml(v_colorbg));
    
    ; footer
    TextGadget(#Text_Footer, GadgetX(#Text_Title), GadgetY(#Button_Clear)+GadgetHeight(#Button_Clear)+3*spacer,
               cols*colScale*3, fontUiSmallSize, textFooter)
    SetGadgetFont(#Text_Footer, FontID(#Font_UiSmall))
    SetGadgetColor(#Text_Footer, #PB_Gadget_FrontColor, colorText)
    
  EndIf

EndProcedure

;- POINT OF ENTRY
; programm starts here

Global NTSC_ColorTable.s = Get_NTSC_ColorTable()
initUI()
BindEvent(#PB_Event_Gadget, @GadgetEvents())
BindEvent(#PB_Event_CloseWindow, @WindowEvents())
BindEvent(#PB_Event_Timer, @TimerEvents())

;- DATA SECTION
DataSection
  
  NTSC:
  Data.s "$00", "#000000", "$02", "#1A1A1A", "$04", "#393939", "$06", "#5B5B5B", "$08", "#7E7E7E", "$0A", "#A2A2A2", "$0C", "#C7C7C7", "$0E", "#EDEDED"
  Data.s "$10", "#190200", "$12", "#3A1F00", "$14", "#5D4100", "$16", "#826400", "$18", "#A78800", "$1A", "#CCAD00", "$1C", "#F2D219", "$1E", "#FEFA40"
  Data.s "$20", "#370000", "$22", "#5E0800", "$24", "#832700", "$26", "#A94900", "$28", "#CF6C00", "$2A", "#F58F17", "$2C", "#FEB438", "$2E", "#FEDF6F"
  Data.s "$30", "#470000", "$32", "#730000", "$34", "#981300", "$36", "#BE3216", "$38", "#E45335", "$3A", "#FE7657", "$3C", "#FE9C81", "$3E", "#FEC6BB"
  Data.s "$40", "#440008", "$42", "#6F001F", "$44", "#960640", "$46", "#BB2462", "$48", "#E14585", "$4A", "#FE67AA", "$4C", "#FE8CD6", "$4E", "#FEB7F6"
  Data.s "$50", "#2D004A", "$52", "#570067", "$54", "#7D058C", "$56", "#A122B1", "$58", "#C743D7", "$5A", "#ED65FE", "$5C", "#FE8AF6", "$5E", "#FEB5F7"
  Data.s "$60", "#0D0082", "$62", "#3300A2", "$64", "#550FC9", "$66", "#782DF0", "$68", "#9C4EFE", "$6A", "#C372FE", "$6C", "#EB98FE", "$6E", "#FEC0F9"
  Data.s "$70", "#000091", "$72", "#0A05BD", "$74", "#2822E4", "$76", "#4842FE", "$78", "#6B64FE", "$7A", "#908AFE", "$7C", "#B7B0FE", "$7E", "#DFD8FE"
  Data.s "$80", "#000072", "$82", "#001CAB", "$84", "#033CD6", "$86", "#205EFD", "$88", "#4081FE", "$8A", "#64A6FE", "$8C", "#89CEFE", "$8E", "#B0F6FE"
  Data.s "$90", "#00103A", "$92", "#00316E", "$94", "#0055A2", "$96", "#0579C8", "$98", "#239DEE", "$9A", "#44C2FE", "$9C", "#68E9FE", "$9E", "#8FFEFE"
  Data.s "$A0", "#001F02", "$A2", "#004326", "$A4", "#006957", "$A6", "#008D7A", "$A8", "#1BB19E", "$AA", "#3BD7C3", "$AC", "#5DFEE9", "$AE", "#86FEFE"
  Data.s "$B0", "#002403", "$B2", "#004A05", "$B4", "#00700C", "$B6", "#09952B", "$B8", "#28BA4C", "$BA", "#49E06E", "$BC", "#6CFE92", "$BE", "#97FEB5"
  Data.s "$C0", "#002102", "$C2", "#004604", "$C4", "#086B00", "$C6", "#289000", "$C8", "#49B509", "$CA", "#6BDB28", "$CC", "#8FFE49", "$CE", "#BBFE69"
  Data.s "$D0", "#001501", "$D2", "#103600", "$D4", "#305900", "$D6", "#537E00", "$D8", "#76A300", "$DA", "#9AC800", "$DC", "#BFEE1E", "$DE", "#E8FE3E"
  Data.s "$E0", "#1A0200", "$E2", "#3B1F00", "$E4", "#5E4100", "$E6", "#836400", "$E8", "#A88800", "$EA", "#CEAD00", "$EC", "#F4D218", "$EE", "#FEFA40"
  Data.s "$F0", "#380000", "$F2", "#5F0800", "$F4", "#842700", "$F6", "#AA4900", "$F8", "#D06B00", "$FA", "#F68F18", "$FC", "#FEB439", "$FE", "#FEDF70"
  
EndDataSection
User avatar
Random Terrain
Posts: 63
Joined: Fri Jul 09, 2021 9:48 pm
Location: USA
Contact:

Re: Is the canvas the only way to draw?

Post by Random Terrain »

munfraid wrote: Sat Jul 17, 2021 4:26 pm
Random Terrain wrote: Sat Jul 17, 2021 3:14 pmThanks. I'm going to make a new thread about "Case" for others who might be new to SpiderBasic.
Don't know if you yet know it: When you click in your code on a keyword such as 'case' and then hit F1, the manual will pop up showing the help page for this command or keyword. Also pay attention to the footer. Whenever you edit the code, a short help for the command you're editing is displayed there, which I find very helpful.
Thanks. I didn't know that. From now on I'll copy example code I see on SpiderBasic.com and paste it into the editor so I can do that.


munfraid wrote: Sat Jul 17, 2021 4:26 pm
Random Terrain wrote: Sat Jul 17, 2021 3:14 pmThere's also a main loop where everything happens. In SpiderBasic, it seems like everything is separate from everything else. Like little countries doing their own thing and not really having anything to do with each other.
That was very confusing for me too in the beginning. The reason that there is no main loop is javascript. SB code is transpiled into javascript and this runs asynchronously. That's why a linear programm execution is not possible, and because of that also no event loop. But the difference is not too big. With BindEvent() you assign a procedure to your window, which handles all the events. This is pretty much like a main loop.
I hope it doesn't take me too long to get used to it since I'd like to have other online tools for people to use, such as a sprite editor/animator.


munfraid wrote: Sat Jul 17, 2021 4:26 pm
Random Terrain wrote: Sat Jul 17, 2021 3:14 pmThere's also a main loop where everything happens. In SpiderBasic, it seems like everything is separate from everything else. Like little countries doing their own thing and not really having anything to do with each other.
By the way, I had a look in your website today and really like it. Was like a trip to the past with nice memories! As a kid I owned a VC 2600 by myself and truly loved it. Spent hours to play Pitfall and River Raid and some others all day... Even took my first approach to code with this machine.
Thanks. I can only make Atari 2600 games using batari Basic. Assembly language is too hard for me. I use an IDE for bB called Visual batari Basic, but the creator of it stopped working on it years ago, so it's getting buggier as time goes on. It also only works on Windows computers, so many people can't even use it

I hope to have at least a few free online tools that all batari Basic programmers can use no matter what kind of computer they have.


munfraid wrote: Sat Jul 17, 2021 4:26 pm I also added some code to the editor. The playfield is now cleared when select a new row mode, and there are new buttons for toggle and erase.
Thanks. Since Toggle is extra-sensitive, I might just have Draw and Erase. If SpiderBasic allows it, I'll add the Ctrl key as a keyboard shortcut that lets the user erase instead of draw when that key is held down.
User avatar
Random Terrain
Posts: 63
Joined: Fri Jul 09, 2021 9:48 pm
Location: USA
Contact:

Re: Is the canvas the only way to draw?

Post by Random Terrain »

I'm going through the program, trying to learn more about the language before I make any changes.

In the section below, why is Define used? Couldn't i just be a Global variable instead? What is Define doing in this situation? Doesn't seem to match up with what is on the Define page.

Code: Select all

Define i
For i = 0 To rows-1
  playfieldFG(i) = colorFG
  playfieldBG(i) = colorBG
Next

Thanks.
munfraid
Posts: 104
Joined: Sat Mar 24, 2018 1:33 pm

Re: Is the canvas the only way to draw?

Post by munfraid »

There's no special reason for using Define instead of Global or Protected here, those would work too. Using EnableExplicit in the code all variables have to be declared or the compiler will complain. This is good programming practice and highly recommended. Without EnableExplicit you will end up searching strange bugs because of a simple typo. It's explained in the Compiler Directives.
Remove the line "Define i" and run the code. Then you can see the compiler error.
User avatar
Random Terrain
Posts: 63
Joined: Fri Jul 09, 2021 9:48 pm
Location: USA
Contact:

Re: Is the canvas the only way to draw?

Post by Random Terrain »

munfraid wrote: Tue Jul 20, 2021 9:18 am There's no special reason for using Define instead of Global or Protected here, those would work too. Using EnableExplicit in the code all variables have to be declared or the compiler will complain. This is good programming practice and highly recommended. Without EnableExplicit you will end up searching strange bugs because of a simple typo. It's explained in the Compiler Directives.
Remove the line "Define i" and run the code. Then you can see the compiler error.
Thanks. I changed it to this:

Code: Select all

Global _Loop

Code: Select all

For _Loop = 0 To rows-1
  playfieldFG(_Loop) = colorFG
  playfieldBG(_Loop) = colorBG
Next
I also added a note above EnableExplicit so I'll remember what it does.

Code: Select all

;***********************************************************************
;***********************************************************************
;
;- BUG CATCHER
;
;  When explicit mode is enabled, all the variables which are not
;  explicitly declared with Define, Global, Protected or Static are
;  not accepted and the compiler will raise an error. It can help to
;  catch typo bugs.
;
EnableExplicit
User avatar
Random Terrain
Posts: 63
Joined: Fri Jul 09, 2021 9:48 pm
Location: USA
Contact:

Re: Is the canvas the only way to draw?

Post by Random Terrain »

After reading the page for it, I'm still not clear about Protected. The page says:

Protected allows a variable to be accessed only in a Procedure even if the same variable has been declared as Global in the main program.

In the case of this program, why would I want a variable value to only change inside of a Procedure, then go back to its original value when done?


Thanks.
Post Reply