Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 308
» Latest member: Donaldvem
» Forum threads: 1,741
» Forum posts: 17,901

Full Statistics

Latest Threads
The QB64 IDE shell
Forum: Utilities
Last Post: JasonPag
09-16-2024, 05:37 PM
» Replies: 9
» Views: 762
Importance regarding Ches...
Forum: Utilities
Last Post: JasonPag
09-01-2024, 06:34 PM
» Replies: 0
» Views: 31
Chess and Analysis and En...
Forum: Utilities
Last Post: JasonPag
08-28-2024, 02:37 PM
» Replies: 0
» Views: 32
DAY 009:_PutImage
Forum: Keyword of the Day!
Last Post: grymmjack
09-02-2023, 02:57 PM
» Replies: 54
» Views: 2,033
Fall Banner Contest?
Forum: Site Suggestions
Last Post: grymmjack
08-31-2023, 11:50 PM
» Replies: 36
» Views: 1,261
ColorPicker - Function th...
Forum: Dav
Last Post: Dav
08-31-2023, 11:04 PM
» Replies: 3
» Views: 315
Goals(1) = New Tile()
Forum: Works in Progress
Last Post: RhoSigma
08-31-2023, 09:45 PM
» Replies: 3
» Views: 127
micro(A)v11
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:14 PM
» Replies: 90
» Views: 3,589
Updating The Single Most ...
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:13 PM
» Replies: 7
» Views: 254
QBJS Image Question
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 05:49 PM
» Replies: 5
» Views: 155

 
  Data Type Conversion Help
Posted by: TarotRedhand - 05-02-2022, 08:26 PM - Forum: Help Me! - Replies (4)

Simply put how do I convert the type of the result of the operation in the () from LONG to DOUBLE in the snippet below?

Code: (Select All)
Answer# = 1.0 + (ARowEnd& - ARowStart&)

Thanks

TR

Print this item

  QB64 on ARM/Raspberry Pi
Posted by: David Irish - 05-02-2022, 05:31 PM - Forum: General Discussion - Replies (2)

Just curious about the support for ARM and Raspberry Pi that QB64 has. 

Does it work already on the Raspberry Pi, and if so, are there special setup instructions? Do we need to recompile the source code, or does it already work?

Also -- let's say I'm not using Raspberry Pi's official OS. If I am using Ubuntu, Manjaro, Linux Mint, or other Linux variants, do I pay closer attention to the Raspberry Pi, or to the version of Linux. In other words, is there one version of QB64 that works on multiple Linux distros, regardless of CPU, or do I need to stick to a Raspberry Pi/ARm version?

THanks in advance

Print this item

  School themes from USSR and EurAsia
Posted by: DANILIN - 05-02-2022, 12:31 PM - Forum: Programs - Replies (22)

School themes from USSR and EurAsia

Some topics have been preserved for eternity
web.archive.org/save/
plus I saved 5500 pages of previous forum qb64

School themes from USSR

Relief 3d multivariate parametric
https://qb64forum.alephc.xyz/index.php?topic=4398

Russian Circle Diagram
https://qb64forum.alephc.xyz/index.php?topic=4367

Shuffling Letters
https://qb64forum.alephc.xyz/index.php?topic=3982

Guess Number
https://qb64forum.alephc.xyz/index.php?topic=3999

Integral of letters: all combinations of letters of all words
https://qb64forum.alephc.xyz/index.php?topic=3106

Rebus of Letters
https://qb64forum.alephc.xyz/index.php?topic=2961

Running strings
https://qb64forum.alephc.xyz/index.php?topic=1724

Russian Sorting Halves Danilin
https://qb64forum.alephc.xyz/index.php?topic=702

Nobel Prize will not receive itself
Nobelevskaya premiya sama sebya ne poluchit
Нобелевская премия сама себя не получит
Le prix Nobel ne se recevra pas
Nobelpreis wird sich nicht erhalten
Il Premio Nobel non ricevera se stesso

Print this item

  Codebox Select All
Posted by: SMcNeill - 05-02-2022, 12:22 PM - Forum: General Discussion - Replies (5)

Code inside the code boxes can now be selected by clicking anywhere within the title bar.

Code: (Select All)
Test me out! 

Print this item

  why the qb64 editor is slow under linux
Posted by: Coolman - 05-02-2022, 11:50 AM - Forum: General Discussion - Replies (15)

after my switch to linux, i notice that the qb64 editor is slow under linux...

Print this item

  Linking Lists
Posted by: SMcNeill - 05-02-2022, 05:41 AM - Forum: SMcNeill - No Replies

Code: (Select All)
$COLOR:32

CONST True = -1, False = 0
CONST Left = 1, Right = 2, Middle = 3, Center = 3
CONST None = 0, Alpha = 1, Numeric = 2, NoCase = 4, Reverse = 8
CONST LeftClick = 1, RightClick = 2, LeftDown = 4, RightDown = 8, Hover = 16

TYPE MenuType
    Valid AS _BYTE
    Visible AS _BYTE
    ScrollBarHidden AS _BYTE
    Top AS INTEGER
    Left AS INTEGER
    Width AS INTEGER
    Height AS INTEGER
    Frame AS _BYTE
    BorderColor AS _UNSIGNED LONG
    BackgroundColor AS _UNSIGNED LONG
    Header AS _BYTE
    Caption AS STRING * 255
    CC AS _UNSIGNED LONG 'caption color
    CBG AS _UNSIGNED LONG 'caption background color
    HighLightColor AS _UNSIGNED LONG
    Exit AS _BYTE
    Entries AS INTEGER
    TopEntry AS INTEGER
    ListColor AS _UNSIGNED LONG
    ListBackground AS _UNSIGNED LONG
    ListJustify AS _BYTE
END TYPE

DIM SHARED MenusActive AS LONG
REDIM SHARED Menu(10) AS MenuType
REDIM SHARED MenuList(32767, 10) AS STRING 'Up to 32,767 items max in our list.
REDIM SHARED MenuListDisabled(32767, 10) AS _BYTE
REDIM SHARED MenuDisplayOrder(32767, 10) AS INTEGER
TYPE LinkType
    one AS LONG
    another AS LONG
END TYPE
REDIM SHARED LinkedTo(1000) AS LinkType
DIM SHARED ScrollDelay AS _FLOAT
DIM SHARED MouseScroll AS INTEGER

'Before here goes BI file content
'After here goes working program

DEFLNG A-Z
SCREEN _NEWIMAGE(800, 600, 32)
_SCREENMOVE _MIDDLE

MainMenu = GetMenuHandle
SetMenuSize MainMenu, 200, 150
SetMenuPosition MainMenu, 100, 100
SetMenuFrame MainMenu, True, Red, Yellow
SetMenuVisible MainMenu, True
SetMenuCaption MainMenu, True, "Name", Black, White, True
SetMenuListProperties MainMenu, Black, 0, Center 'Right 'Left
SetMenuHighLightColor MainMenu, Red
FOR i = 1 TO 23
    READ n$
    AddMenuItem MainMenu, n$
NEXT

DATA Steve,Pete,Bob,Joe,Fred
DATA Sam,One,Two,Three,Four
DATA Five,Six,Seven,Eight,Nine
DATA These,are,all,my,names
DATA "Aren't",they,grand

SecondMenu = GetMenuHandle
SetMenuSize SecondMenu, 100, 150
SetMenuPosition SecondMenu, 300, 100
SetMenuFrame SecondMenu, True, Red, Yellow
SetMenuVisible SecondMenu, True
SetMenuCaption SecondMenu, True, "Age", Black, White, True
SetMenuListProperties SecondMenu, Black, 0, Left
SetMenuHighLightColor SecondMenu, Red

FOR i = 1 TO 23
    READ n$
    AddMenuItem SecondMenu, n$
NEXT

DATA 12,23,34,45,56
DATA 67,78,89,90,1
DATA 9,98,87,76,65
DATA 54,43,32,21,10
DATA 42,55,12

sortmode = 0: linked = -1: menuon = 1

HideMenuScrollBar MainMenu
LinkMenus MainMenu, SecondMenu

DisableItem MainMenu, 5
ScrollDelay = .25
DO
    CLS
    LOCATE 20, 1: PRINT "Press <H> to hide the menu."
    PRINT "Press <S> to show the menu."
    PRINT "Press <N> for No Sort order."
    PRINT "Press <A> for Alphabetic Sort order."
    PRINT "Press <#> for Numeric Sort order."
    PRINT "Press <C> to toggle case sorting."
    PRINT "Press <R> to toggle reverse sorting."
    PRINT "Press <L> to link the menus."
    PRINT "Press <U> to unlink the menus."
    PRINT "Press <TAB> to swap between menus."
    PRINT "<ESC> to quit"
    PRINT
    PRINT "Currently: ";
    IF sortmode AND 1 THEN
        PRINT "ALPHA SORT";
        IF kase THEN PRINT ", CASE-SENSITIVE";
        IF reversed THEN PRINT ", REVERSE-ORDER" ELSE PRINT
    ELSEIF sortmode AND 2 THEN
        PRINT "NUMERIC SORT";
        IF reversed THEN PRINT ", REVERSE-ORDER" ELSE PRINT
    ELSE
        PRINT "NOT SORTING"
    END IF
    LOCATE 5, 25
    IF linked THEN PRINT "LINKED LISTS" ELSE PRINT "UNLINKED LISTS"
    LOCATE 6, 15: PRINT "MENU ASSOCIATED WITH KEYBOARD: "; menuon

    MouseScroll = 0
    WHILE _MOUSEINPUT
        MouseScroll = MouseScroll + _MOUSEWHEEL
    WEND

    k = _KEYHIT
    SELECT CASE k
        CASE ASC("L"), ASC("l"): LinkMenus MainMenu, SecondMenu: linked = -1
        CASE ASC("U"), ASC("u"): UnLinkMenus MainMenu, SecondMenu: linked = 0
        CASE ASC("H"), ASC("h"): HideMenu menuon
        CASE ASC("S"), ASC("s"): ShowMenu menuon
        CASE ASC("N"), ASC("n"): sortmode = None: changed = -1: reversed = 0: kase = 0
        CASE ASC("A"), ASC("a"): sortmode = Alpha: changed = -1
        CASE ASC("#"), ASC("3"): sortmode = Numeric: changed = -1
        CASE ASC("C"), ASC("c"): kase = NOT kase: changed = -1
        CASE ASC("R"), ASC("r"): reversed = NOT reversed: changed = -1
        CASE 9: menuon = menuon + 1: IF menuon = 3 THEN menuon = 1
        CASE 27: SYSTEM
    END SELECT
    IF changed THEN
        IF sortmode <> 0 THEN
            IF kase THEN sortmode = sortmode OR NoCase ELSE sortmode = sortmode AND NOT NoCase
            IF reversed THEN sortmode = sortmode OR Reverse ELSE sortmode = sortmode AND NOT Reverse
        END IF
        MenuDisplaySort menuon, sortmode
        changed = 0
    END IF
    DisplayMenus
    CheckMenus MouseStatus, MenuSelected, OptionSelected
    IF MouseStatus <> 0 AND MenuSelected <> 0 THEN
        IF MouseStatus AND LeftClick THEN
            LOCATE 1, 1
            PRINT "You LEFT CLICKED Option #"; OptionSelected; " in Menu #"; MenuSelected
            PRINT "Which was: "; GetListItem(MenuSelected, OptionSelected)
            PRINT
            IF linked THEN
                PRINT "Since our lists are linked, we get the following items:"; GetListItem(1, OptionSelected), GetListItem(2, OptionSelected)
            ELSE
                PRINT "Since our lists are unlinked, we get the following items:"; GetListItem(MenuSelected, OptionSelected)
            END IF
            _DISPLAY
            _DELAY 2 'give it time to pop up
        ELSEIF MouseStatus AND RightClick THEN
            LOCATE 1, 1
            PRINT "You RIGHT CLICKED Option #"; OptionSelected; " in Menu #"; MenuSelected
            PRINT "Which was: "; GetListItem(MenuSelected, OptionSelected)
            PRINT
            IF linked THEN
                PRINT "Since our lists are linked, we get the following items:"; GetListItem(1, OptionSelected), GetListItem(2, OptionSelected)
            ELSE
                PRINT "Since our lists are unlinked, we get the following items:"; GetListItem(MenuSelected, OptionSelected)
            END IF
            _DISPLAY
            _DELAY 2 'give it time to pop up
        END IF
        COLOR Yellow
        IF MouseStatus AND LeftDown THEN LOCATE 35, 1: PRINT "LEFT MOUSE DOWN over Option #"; OptionSelected; " in Menu #"; MenuSelected
        IF MouseStatus AND RightDown THEN LOCATE 35, 1: PRINT "RIGHT MOUSE DOWN over Option #"; OptionSelected; " in Menu #"; MenuSelected
        COLOR Purple
        IF MouseStatus AND Hover THEN LOCATE 36, 1: PRINT "HOVERING over Option #"; OptionSelected; " in Menu #"; MenuSelected;
        COLOR White

    END IF
    _LIMIT 30
    _DISPLAY
LOOP



'And here goes the BM routines



SUB LinkMenus (handle1, handle2)
    IF handle1 = 0 OR handle2 = 0 THEN ERROR 5: EXIT SUB
    IF handle1 = handle2 THEN EXIT SUB 'Why the heck are we linking one list to itself?!
    IF Menu(handle1).Valid AND Menu(handle2).Valid THEN
        LinkMax = LinkedTo(0).one 'I'm using the very first entry into my array to store the number of link entries I have
        'First check to see if the two menus are already linked
        FOR i = 1 TO LinkMax
            found = 0
            IF handle1 = LinkedTo(i).one OR handle1 = LinkedTo(i).another THEN found = found + 1
            IF handle2 = LinkedTo(i).one OR handle2 = LinkedTo(i).another THEN found = found + 1
            IF found = 2 THEN EXIT SUB 'the two lists are already linked
            IF handle1 = 0 AND handle2 = 0 AND openspot = 0 THEN openspot = i 'we found a spot where a link was freed before; let's use it
        NEXT
        MenuDisplaySort handle1, None: MenuDisplaySort handle2, None 'unsort the lists to begin with.
        Menu(handle1).TopEntry = 1: Menu(handle2).TopEntry = 1 'and then reset them to their topmost position

        IF openspot THEN
            LinkedTo(openspot).one = handle1
            LinkedTo(openspot).another = handle2
        ELSE
            LinkMax = LinkMax + 1: LinkedTo(0).one = LinkMax
            LinkedTo(LinkMax).one = handle1
            LinkedTo(LinkMax).another = handle2
        END IF
    ELSE
        ERROR 5
    END IF
END SUB

SUB UnLinkMenus (handle1, handle2)
    IF handle1 = 0 OR handle2 = 0 THEN ERROR 5: EXIT SUB 'no list should be linked to 0.  0 is nothing...  Can't free a link to nothing.
    IF handle1 = handle2 THEN EXIT SUB 'We can't unlink a list from itself!
    IF Menu(handle1).Valid AND Menu(handle2).Valid THEN
        FOR i = 1 TO LinkedTo(0).one
            IF handle1 = LinkedTo(i).one OR handle1 = LinkedTo(i).another THEN found = found + 1
            IF handle2 = LinkedTo(i).one OR handle2 = LinkedTo(i).another THEN found = found + 1
            IF found = 2 THEN LinkedTo(i).one = 0: LinkedTo(i).another = 0 'unlink them!
        NEXT
    ELSE
        ERROR 5
    END IF
END SUB

SUB DisableItem (handle, item)
    IF Menu(handle).Valid THEN MenuListDisabled(item, handle) = -1 ELSE ERROR 5
END SUB

SUB EnableItem (handle, item)
    IF Menu(handle).Valid THEN MenuListDisabled(item, handle) = 0 ELSE ERROR 5
END SUB

SUB ShowMenu (Handle)
    IF Menu(Handle).Valid THEN Menu(Handle).Visible = -1 ELSE ERROR 5
END SUB

SUB HideMenu (Handle)
    IF Menu(Handle).Valid THEN Menu(Handle).Visible = 0 ELSE ERROR 5
END SUB

SUB ShowMenuScrollBar (Handle)
    IF Menu(Handle).Valid THEN Menu(Handle).ScrollBarHidden = 0 ELSE ERROR 5
END SUB

SUB HideMenuScrollBar (Handle)
    IF Menu(Handle).Valid THEN Menu(Handle).ScrollBarHidden = -1 ELSE ERROR 5
END SUB



FUNCTION GetListItem$ (Handle, Item)
    IF Menu(Handle).Valid THEN
        IF Item < 0 OR Item > Menu(Handle).Entries THEN ERROR 5: EXIT FUNCTION
        GetListItem$ = LTRIM$(RTRIM$(MenuList(Item, Handle)))
    ELSE
        ERROR 5
    END IF
END FUNCTION



SUB AddMenuItem (Handle, Item$)
    IF Menu(Handle).Valid THEN
        Menu(Handle).Entries = Menu(Handle).Entries + 1
        MenuList(Menu(Handle).Entries, Handle) = Item$
        MenuDisplayOrder(Menu(Handle).Entries, Handle) = Menu(Handle).Entries
    ELSE
        ERROR 5
    END IF
END SUB


SUB SetMenuListProperties (Handle, ListColor AS _UNSIGNED LONG, ListBackground AS _UNSIGNED LONG, ListJustify AS _BYTE)
    IF Menu(Handle).Valid THEN
        Menu(Handle).ListColor = ListColor
        Menu(Handle).ListBackground = ListBackground
        Menu(Handle).ListJustify = ListJustify
    ELSE
        ERROR 5
    END IF
END SUB

SUB SetMenuHighLightColor (Handle, HighLightColor AS _UNSIGNED LONG)
    IF Menu(Handle).Valid THEN
        Menu(Handle).HighLightColor = HighLightColor
    ELSE
        ERROR 5
    END IF
END SUB


SUB SetMenuCaption (Handle, Header, Caption AS STRING * 255, CaptionColor AS _UNSIGNED LONG, CaptionBackground AS _UNSIGNED LONG, Xit)
    IF Menu(Handle).Valid THEN
        Menu(Handle).Header = Header
        Menu(Handle).Caption = Caption
        Menu(Handle).CC = CaptionColor
        Menu(Handle).CBG = CaptionBackground
        Menu(Handle).Exit = Xit
    ELSE
        ERROR 5
    END IF
END SUB


SUB SetMenuFrame (Handle, HaveFrame, FrameColor AS _UNSIGNED LONG, FrameBackGround AS _UNSIGNED LONG)
    IF Menu(Handle).Valid THEN
        Menu(Handle).Frame = HaveFrame
        Menu(Handle).BorderColor = FrameColor
        Menu(Handle).BackgroundColor = FrameBackGround
    ELSE
        ERROR 5
    END IF
END SUB



SUB SetMenuPosition (Handle, Left, Top)
    IF Menu(Handle).Valid THEN
        'some basic error checking
        IF Top < 0 THEN ERROR 5: EXIT SUB 'Let's try and keep the menu on the screen, why don't we
        IF Left < 0 THEN ERROR 5: EXIT SUB
        IF Left > _WIDTH THEN ERROR 5: EXIT SUB
        IF Top > _HEIGHT THEN ERROR 5: EXIT SUB
        Menu(Handle).Left = Left
        Menu(Handle).Top = Top
    ELSE
        ERROR 5 'toss a generic error if the handle is bad
        'I can add a custom error pop up routine later with appropiate messages
    END IF
END SUB


SUB SetMenuVisible (Handle, Visible)
    IF Menu(Handle).Valid THEN Menu(Handle).Visible = Visible ELSE ERROR 5
END SUB

SUB SetMenuSize (Handle, Width, Height)
    IF Menu(Handle).Valid THEN
        'some basic error checking
        IF Width < _FONTWIDTH THEN ERROR 5: EXIT SUB 'Can't we at least make a menu which will hold a single character?!
        IF Height < _FONTHEIGHT THEN ERROR 5: EXIT SUB
        IF Width > _WIDTH THEN ERROR 5: EXIT SUB 'And let's not make it generally larger than our screen, why don't we?!
        IF Height > _HEIGHT THEN ERROR 5: EXIT SUB
        Menu(Handle).Width = Width
        Menu(Handle).Height = Height
    ELSE
        ERROR 5 'toss a generic error if the handle is bad
        'I can add a custom error pop up routine later with appropiate messages
    END IF
END SUB

FUNCTION GetMenuHandle&
    FOR i = 1 TO MenusActive
        IF Menu(i).Valid = 0 THEN found = i: EXIT FOR
    NEXT
    IF NOT found THEN
        MenusActive = MenusActive + 1
        found = MenusActive
        u = UBOUND(Menu)
        DO UNTIL MenusActive < u
            REDIM _PRESERVE Menu(u + 10) AS MenuType
            REDIM _PRESERVE MenuList(32767, u + 10) AS STRING
            REDIM _PRESERVE MenuDisplayOrder(32767, u + 10) AS INTEGER
            REDIM _PRESERVE MenuListDisabled(32767, u + 10) AS _BYTE
            u = UBOUND(Menu)
        LOOP
    END IF
    GetMenuHandle& = found
    Menu(found).Valid = -1 'and let's make this a valid handle
END FUNCTION


SUB CheckMenus (MouseStatus AS LONG, MenuSelected AS LONG, OptionSelected AS LONG)

    MenuSelected = 0: OptionSelected = 0
    FOR i = 1 TO MenusActive
        IF Menu(i).Visible AND Menu(i).Valid THEN
            IF startnum = 0 THEN startnum = i
            ProcessMenu i, startnum, MouseStatus, MenuSelected, OptionSelected
            IF MenuSelected THEN EXIT SUB
        END IF
    NEXT
END SUB


SUB DisplayMenus
    FC = _DEFAULTCOLOR: BG = _BACKGROUNDCOLOR
    FOR Whichone = 1 TO MenusActive
        IF Menu(Whichone).Visible THEN
            'Get the starting limits of where menu/list text can appear
            x1 = Menu(Whichone).Left: x2 = x1 + Menu(Whichone).Width
            y1 = Menu(Whichone).Top: y2 = Menu(Whichone).Top + Menu(Whichone).Height
            caption$ = LTRIM$(RTRIM$(Menu(Whichone).Caption)) 'strip unneeded spaces from the caption (WhichOnef any)

            'clear the background
            LINE (Menu(Whichone).Left, Menu(Whichone).Top)-STEP(Menu(Whichone).Width, Menu(Whichone).Height), Menu(Whichone).BackgroundColor, BF
            'draw the frame; adjust text limits
            IF Menu(Whichone).Frame THEN
                LINE (Menu(Whichone).Left, Menu(Whichone).Top)-STEP(Menu(Whichone).Width, Menu(Whichone).Height), Menu(Whichone).BorderColor, B
                x1 = x1 + 1: y1 = y1 + 1
                x2 = x2 - 1: y2 = y2 - 1
            END IF
            IF Menu(Whichone).Header THEN
                temp = x2 - x1 + 1
                LINE (x1, y1)-(x2, y1 + _FONTHEIGHT), Menu(Whichone).CBG, BF
                IF Menu(Whichone).Exit THEN
                    temp = temp - _FONTWIDTH * 2
                    ex1 = x2 - 1 - _FONTWIDTH: ex2 = ex1 + _FONTWIDTH
                    ey1 = y1 + 1: ey2 = ey1 + _FONTHEIGHT - 3
                    LINE (ex1, ey1)-(ex2, ey2), Red, BF
                    LINE (ex1, ey1)-(ex2, ey2), Black
                    LINE (ex1, ey2)-(ex2, ey1), Black
                END IF
                DO UNTIL _PRINTWIDTH(caption$) <= temp
                    caption$ = LEFT$(caption$, LEN(caption$) - 1)
                LOOP
                COLOR Menu(Whichone).CC, Menu(Whichone).CBG
                _PRINTSTRING (x1 + (temp - _PRINTWIDTH(caption$)) \ 2, y1), caption$
                y1 = y1 + _FONTHEIGHT
                IF Menu(Whichone).Frame THEN
                    LINE (x1, y1)-(x2, y1), Menu(Whichone).BorderColor
                    y1 = y1 + 2
                END IF
            END IF 'end header creation

            IF Menu(Whichone).Entries > 0 THEN 'We have items in our list to display!
                IF Menu(Whichone).TopEntry < 1 THEN Menu(Whichone).TopEntry = 1 'check to make certain we're displaying from the first entry on at least
                IF Menu(Whichone).TopEntry > Menu(Whichone).Entries THEN Menu(Whichone).TopEntry = Menu(Whichone).Entries
                printlimit = (x2 - x1 + 1) \ _FONTWIDTH
                limitfound = 1 + (y2 - y1 + 1) \ _FONTHEIGHT - 1
                IF limitfound > Menu(Whichone).Entries THEN
                    limitfound = Menu(Whichone).Entries
                ELSE
                    scrollneeded = -1
                    printlimit = printlimit - 1
                END IF
                COLOR Menu(Whichone).ListColor, Menu(Whichone).ListBackground
                IF Menu(Whichone).ScrollBarHidden = -1 THEN scrollneeded = 0
                DIM r AS _UNSIGNED _BYTE, g AS _UNSIGNED _BYTE, b AS _UNSIGNED _BYTE
                DIM CC AS INTEGER

                r = _RED32(Menu(Whichone).BackgroundColor)
                g = _GREEN32(Menu(Whichone).BackgroundColor)
                b = _BLUE32(Menu(Whichone).BackgroundColor)
                Fade& = _RGBA32(r, g, b, 180)

                SELECT CASE Menu(Whichone).ListJustify
                    CASE Left
                        FOR j = 1 TO limitfound
                            CC = MenuDisplayOrder(Menu(Whichone).TopEntry + j - 1, Whichone) 'currentchoice
                            graybox = 0
                            t$ = RTRIM$(LTRIM$(MenuList(CC, Whichone)))
                            IF MenuListDisabled(CC, Whichone) THEN graybox = -1
                            FOR ii = 1 TO LinkedTo(0).one
                                IF Whichone = LinkedTo(ii).one AND MenuListDisabled(CC, LinkedTo(ii).another) THEN graybox = -1
                                IF Whichone = LinkedTo(ii).another AND MenuListDisabled(CC, LinkedTo(ii).one) THEN graybox = -1
                            NEXT
                            t$ = LEFT$(t$, printlimit)
                            _PRINTSTRING (x1, y1 + (j - 1) * _FONTHEIGHT), t$
                            IF graybox THEN LINE (x1, y1 + (j - 1) * _FONTHEIGHT)-(x2, y1 + (j) * _FONTHEIGHT), Fade&, BF
                        NEXT
                    CASE Right
                        FOR j = 1 TO limitfound
                            CC = MenuDisplayOrder(Menu(Whichone).TopEntry + j - 1, Whichone) 'currentchoice
                            graybox = 0
                            t$ = RTRIM$(LTRIM$(MenuList(MenuDisplayOrder(Menu(Whichone).TopEntry + j - 1, Whichone), Whichone)))
                            IF MenuListDisabled(CC, Whichone) THEN graybox = -1
                            FOR ii = 1 TO LinkedTo(0).one
                                IF Whichone = LinkedTo(ii).one AND MenuListDisabled(CC, LinkedTo(ii).another) THEN graybox = -1
                                IF Whichone = LinkedTo(ii).another AND MenuListDisabled(CC, LinkedTo(ii).one) THEN graybox = -1
                            NEXT

                            t$ = LTRIM$(LEFT$(t$, printlimit))
                            p = _PRINTWIDTH(t$)
                            IF scrollneeded THEN
                                _PRINTSTRING (x2 - p - _FONTWIDTH, y1 + (j - 1) * _FONTHEIGHT), t$
                            ELSE
                                _PRINTSTRING (x2 - p, y1 + (j - 1) * _FONTHEIGHT), t$
                            END IF
                            IF graybox THEN LINE (x1, y1 + (j - 1) * _FONTHEIGHT)-(x2, y1 + (j) * _FONTHEIGHT), Fade&, BF
                        NEXT
                    CASE Center
                        FOR j = 1 TO limitfound
                            CC = MenuDisplayOrder(Menu(Whichone).TopEntry + j - 1, Whichone) 'currentchoice
                            graybox = 0
                            t$ = LTRIM$(MenuList(MenuDisplayOrder(Menu(Whichone).TopEntry + j - 1, Whichone), Whichone))
                            IF MenuListDisabled(CC, Whichone) THEN graybox = -1
                            FOR ii = 1 TO LinkedTo(0).one
                                IF Whichone = LinkedTo(ii).one AND MenuListDisabled(CC, LinkedTo(ii).another) THEN graybox = -1
                                IF Whichone = LinkedTo(ii).another AND MenuListDisabled(CC, LinkedTo(ii).one) THEN graybox = -1
                            NEXT
                            t$ = LTRIM$(RTRIM$(LEFT$(t$, printlimit)))
                            p = _PRINTWIDTH(t$)
                            _PRINTSTRING ((x2 - x1 + 1) - p \ 2, y1 + (j - 1) * _FONTHEIGHT), t$
                            IF graybox THEN LINE (x1, y1 + (j - 1) * _FONTHEIGHT)-(x2, y1 + (j) * _FONTHEIGHT), Fade&, BF
                        NEXT
                    CASE ELSE
                        FOR j = 1 TO limitfound
                            CC = MenuDisplayOrder(Menu(Whichone).TopEntry + j - 1, Whichone) 'currentchoice
                            graybox = 0
                            t$ = RTRIM$(LTRIM$(MenuList(CC, Whichone)))
                            IF MenuListDisabled(CC, Whichone) THEN graybox = -1
                            FOR ii = 1 TO LinkedTo(0).one
                                IF Whichone = LinkedTo(ii).one AND MenuListDisabled(CC, LinkedTo(ii).another) THEN graybox = -1
                                IF Whichone = LinkedTo(ii).another AND MenuListDisabled(CC, LinkedTo(ii).one) THEN graybox = -1
                            NEXT
                            t$ = LEFT$(t$, printlimit)
                            _PRINTSTRING (x1, y1 + (j - 1) * _FONTHEIGHT), t$
                            IF graybox THEN LINE (x1, y1 + (j - 1) * _FONTHEIGHT)-(x2, y1 + (j) * _FONTHEIGHT), Fade&, BF
                        NEXT
                        Menu(Whichone).ListJustify = Left 'If it's not specified for some reason, let's make it left justified as default
                END SELECT
            END IF 'end of displaying items
            IF scrollneeded THEN 'then we need a vertical scroll bar
                barx1 = x2 - _FONTWIDTH - 1
                barx2 = barx1 + _FONTWIDTH
                LINE (barx1, y1)-(barx2, y2), LightGray, BF
                COLOR Black, DarkGray
                _PRINTSTRING (barx1, y1), ""
                _PRINTSTRING (barx1, y2 - _FONTHEIGHT), ""
            END IF
        END IF
    NEXT
    COLOR FC, BG
END SUB



SUB ProcessMenu (WhichOne AS LONG, StartNum AS LONG, MouseStatus AS LONG, MenuSelected AS LONG, OptionSelected AS LONG)
    STATIC OldMouse AS _BYTE, ElapsedTimer AS _FLOAT, Click AS _BYTE
    STATIC ScrollAble AS _BYTE, OldMouse2 AS _BYTE, Click2 AS _BYTE
    MX = _MOUSEX: MY = _MOUSEY: MB = _MOUSEBUTTON(1): MB2 = _MOUSEBUTTON(2)
    IF ScrollDelay < 0 THEN ScrollDelay = 0

    'Get the starting limits of where menu/list text can appear
    x1 = Menu(WhichOne).Left: x2 = x1 + Menu(WhichOne).Width
    y1 = Menu(WhichOne).Top: y2 = Menu(WhichOne).Top + Menu(WhichOne).Height
    IF WhichOne = StartNum THEN
        IF OldMouse = 0 AND MB = -1 THEN Click = -1 ELSE Click = 0
        IF OldMouse2 = 0 AND MB2 = -1 THEN Click2 = -1 ELSE Click2 = 0
        OldMouse = MB: OldMouse2 = MB2
        IF ElapsedTimer + ScrollDelay < TIMER(0.01) THEN
            ElapsedTimer = TIMER(0.01)
            ScrollAble = -1
        ELSE
            ScrollAble = 0
        END IF
    END IF




    IF Menu(WhichOne).Frame THEN
        LINE (Menu(WhichOne).Left, Menu(WhichOne).Top)-STEP(Menu(WhichOne).Width, Menu(WhichOne).Height), Menu(WhichOne).BorderColor, B
        x1 = x1 + 1: y1 = y1 + 1
        x2 = x2 - 1: y2 = y2 - 1
    END IF
    IF Menu(WhichOne).Header THEN
        temp = x2 - x1 + 1
        IF Menu(WhichOne).Exit THEN
            temp = temp - _FONTWIDTH * 2
            ex1 = x2 - 1 - _FONTWIDTH: ex2 = ex1 + _FONTWIDTH
            ey1 = y1 + 1: ey2 = ey1 + _FONTHEIGHT - 3
        END IF
        y1 = y1 + _FONTHEIGHT
        IF Menu(WhichOne).Frame THEN y1 = y1 + 2
    END IF 'end header creation

    IF Menu(WhichOne).Entries > 0 THEN 'We have items in our list to display!
        IF Menu(WhichOne).TopEntry < 1 THEN Menu(WhichOne).TopEntry = 1 'check to make certain we're displaying from the first entry on at least
        IF Menu(WhichOne).TopEntry > Menu(WhichOne).Entries THEN Menu(WhichOne).TopEntry = Menu(WhichOne).Entries
        printlimit = (x2 - x1 + 1) \ _FONTWIDTH
        limitfound = 1 + (y2 - y1 + 1) \ _FONTHEIGHT - 1
        IF limitfound > Menu(WhichOne).Entries THEN
            limitfound = Menu(WhichOne).Entries
        ELSE
            scrollneeded = -1
            printlimit = printlimit - 1
        END IF
    END IF 'end of displaying items

    IF Menu(WhichOne).ScrollBarHidden = -1 THEN scrollneeded = 0

    IF scrollneeded THEN 'then we need a vertical scroll bar
        barx1 = x2 - _FONTWIDTH - 1
        barx2 = barx1 + _FONTWIDTH
    END IF


    SELECT CASE MY 'let's determine which line we clicked the mouse on
        CASE IS < ey1 'do nothing as it's too far up the screen to be a click in this box
        CASE IS > y2 'do nothing again as it's too far down the screen to be a click in this box
        CASE ey1 TO ey2 'we've clicked on the line where the EXIT button might exist
        CASE y1 TO y2
    END SELECT



    SELECT CASE MY 'let's determine which line we clicked the mouse on
        CASE IS < ey1 'do nothing as it's too far up the screen to be a click in this box
        CASE IS > y2 'do nothing again as it's too far down the screen to be a click in this box
        CASE ey1 TO ey2 'we've clicked on the line where the EXIT button might exist
            IF Click AND Menu(WhichOne).Exit THEN
                IF MX >= ex1 AND MX <= ex2 THEN Menu(WhichOne).Visible = False 'If the exit button is available, and we click it, it closes the menu/list
            END IF
        CASE y1 TO y2
            done = 0
            IF barx1 > 0 THEN p2 = barx1 - 1 ELSE p2 = x2
            IF MX >= x1 AND MX <= p2 THEN 'highlight the choice the user is over
                yPOS = ((MY - y1 + 1) \ _FONTHEIGHT) * _FONTHEIGHT + y1
                IF yPOS + _FONTHEIGHT <= y2 THEN LINE (x1, yPOS)-(p2, yPOS + _FONTHEIGHT), Menu(WhichOne).HighLightColor, B
            END IF

            IF MouseScroll THEN
                IF MX >= x1 AND MX <= x2 THEN
                    Menu(WhichOne).TopEntry = Menu(WhichOne).TopEntry + MouseScroll
                    IF Menu(WhichOne).TopEntry < 1 THEN Menu(WhichOne).TopEntry = 1
                    IF Menu(WhichOne).TopEntry > Menu(WhichOne).Entries - limitfound + 1 THEN Menu(WhichOne).TopEntry = Menu(WhichOne).Entries - limitfound + 1
                    FOR i = 1 TO LinkedTo(0).one
                        IF WhichOne = LinkedTo(i).one THEN Menu(LinkedTo(i).another).TopEntry = Menu(WhichOne).TopEntry
                        IF WhichOne = LinkedTo(i).another THEN Menu(LinkedTo(i).one).TopEntry = Menu(WhichOne).TopEntry
                    NEXT
                END IF
            END IF

            IF scrollneeded THEN
                IF MY >= y1 AND MY <= y1 + _FONTHEIGHT AND MX >= barx1 AND MX <= barx2 AND MB <> 0 THEN 'it's the top scroll bar
                    IF ScrollAble THEN Menu(WhichOne).TopEntry = Menu(WhichOne).TopEntry - 1
                    IF Menu(WhichOne).TopEntry < 1 THEN Menu(WhichOne).TopEntry = 1
                    done = -1
                    FOR i = 1 TO LinkedTo(0).one
                        IF WhichOne = LinkedTo(i).one THEN Menu(LinkedTo(i).another).TopEntry = Menu(WhichOne).TopEntry
                        IF WhichOne = LinkedTo(i).another THEN Menu(LinkedTo(i).one).TopEntry = Menu(WhichOne).TopEntry
                    NEXT
                ELSEIF MY >= y2 - _FONTHEIGHT AND MY <= y2 AND MX >= barx1 AND MX <= barx2 AND MB <> 0 THEN 'it's the bottom scroll bar
                    IF ScrollAble THEN Menu(WhichOne).TopEntry = Menu(WhichOne).TopEntry + 1
                    IF Menu(WhichOne).TopEntry > Menu(WhichOne).Entries - limitfound + 1 THEN Menu(WhichOne).TopEntry = Menu(WhichOne).Entries - limitfound + 1
                    done = -1
                    FOR i = 1 TO LinkedTo(0).one
                        IF WhichOne = LinkedTo(i).one THEN Menu(LinkedTo(i).another).TopEntry = Menu(WhichOne).TopEntry
                        IF WhichOne = LinkedTo(i).another THEN Menu(LinkedTo(i).one).TopEntry = Menu(WhichOne).TopEntry
                    NEXT
                ELSEIF MX >= barx1 AND MX <= barx2 AND MB <> 0 THEN
                    MenuLimit = Menu(WhichOne).Entries - limitfound + 2
                    ylimit = y2 - y1 - _FONTHEIGHT * 2 + 1
                    yPOS = MY - y1 - _FONTHEIGHT + 1
                    Menu(WhichOne).TopEntry = (MenuLimit - (ylimit - yPOS) / ylimit * MenuLimit)
                    IF Menu(WhichOne).TopEntry >= MenuLimit THEN Menu(WhichOne).TopEntry = MenuLimit - 1
                    done = -1
                    FOR i = 1 TO LinkedTo(0).one
                        IF WhichOne = LinkedTo(i).one THEN Menu(LinkedTo(i).another).TopEntry = Menu(WhichOne).TopEntry
                        IF WhichOne = LinkedTo(i).another THEN Menu(LinkedTo(i).one).TopEntry = Menu(WhichOne).TopEntry
                    NEXT
                END IF
            END IF

            IF NOT done THEN 'if we've processed a scrollbar event, we're finished
                IF MX >= x1 AND MX <= x2 THEN
                    MenuSelected = WhichOne
                    OptionSelected = MenuDisplayOrder((MY - y1 + 1) \ _FONTHEIGHT + Menu(WhichOne).TopEntry, WhichOne)
                    invalidate = 0
                    IF MenuListDisabled(OptionSelected, WhichOne) THEN invalidate = -1
                    FOR ii = 1 TO LinkedTo(0).one
                        IF WhichOne = LinkedTo(ii).one AND MenuListDisabled(OptionSelected, LinkedTo(ii).another) THEN invalidate = -1
                        IF WhichOne = LinkedTo(ii).another AND MenuListDisabled(OptionSelected, LinkedTo(ii).one) THEN invalidate = -1
                    NEXT
                    IF barx1 <> 0 AND MX > barx1 THEN invalidate = -1
                    IF invalidate THEN MenuSelected = 0: OptionSelected = 0
                END IF
            END IF
    END SELECT


    MouseStatus = 0
    MouseStatus = MouseStatus OR -Click 'leftclick
    MouseStatus = MouseStatus OR Click2 * -2 'rightclick
    MouseStatus = MouseStatus OR _MOUSEBUTTON(1) * -4 'leftdown
    MouseStatus = MouseStatus OR _MOUSEBUTTON(2) * -8 'rightdown
    MouseStatus = MouseStatus OR (MenuSelected <> 0) * 16 'If we're over the menu, we're hovering

END SUB


SUB MenuDisplaySort (handle AS LONG, sortmethod AS _BYTE)
    gap = Menu(handle).Entries

    IF sortmethod AND Alpha THEN
        IF sortmethod AND NoCase THEN
            DO
                gap = 10 * gap \ 13
                IF gap < 1 THEN gap = 1
                i = 0
                swapped = 0
                DO
                    t$ = UCASE$(LTRIM$(RTRIM$(MenuList(MenuDisplayOrder(i, handle), handle))))
                    t1$ = UCASE$(LTRIM$(RTRIM$(MenuList(MenuDisplayOrder(i + gap, handle), handle))))
                    IF t$ > t1$ THEN
                        SWAP MenuDisplayOrder(i, handle), MenuDisplayOrder(i + gap, handle)
                        FOR ii = 1 TO LinkedTo(0).one
                            IF handle = LinkedTo(ii).one THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).another), MenuDisplayOrder(i + gap, LinkedTo(ii).another)
                            IF handle = LinkedTo(ii).another THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).one), MenuDisplayOrder(i + gap, LinkedTo(ii).one)
                        NEXT
                        swapped = -1
                    END IF
                    i = i + 1
                LOOP UNTIL i + gap > Menu(handle).Entries
            LOOP UNTIL gap = 1 AND swapped = 0
        ELSE
            DO
                gap = 10 * gap \ 13
                IF gap < 1 THEN gap = 1
                i = 0
                swapped = 0
                DO
                    t$ = LTRIM$(RTRIM$(MenuList(MenuDisplayOrder(i, handle), handle)))
                    t1$ = LTRIM$(RTRIM$(MenuList(MenuDisplayOrder(i + gap, handle), handle)))
                    IF t$ > t1$ THEN
                        SWAP MenuDisplayOrder(i, handle), MenuDisplayOrder(i + gap, handle)
                        FOR ii = 1 TO LinkedTo(0).one
                            IF handle = LinkedTo(ii).one THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).another), MenuDisplayOrder(i + gap, LinkedTo(ii).another)
                            IF handle = LinkedTo(ii).another THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).one), MenuDisplayOrder(i + gap, LinkedTo(ii).one)
                        NEXT
                        swapped = -1
                    END IF
                    i = i + 1
                LOOP UNTIL i + gap > Menu(handle).Entries
            LOOP UNTIL gap = 1 AND swapped = 0
        END IF
        IF sortmethod AND Reverse THEN
            FOR i = 1 TO Menu(handle).Entries \ 2
                SWAP MenuDisplayOrder(i, handle), MenuDisplayOrder(Menu(handle).Entries - i + 1, handle)
                FOR ii = 1 TO LinkedTo(0).one
                    IF handle = LinkedTo(ii).one THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).another), MenuDisplayOrder(Menu(handle).Entries - i + 1, LinkedTo(ii).another)
                    IF handle = LinkedTo(ii).another THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).one), MenuDisplayOrder(Menu(handle).Entries - i + 1, LinkedTo(ii).one)
                NEXT
            NEXT
        END IF
    ELSEIF sortmethod AND Numeric THEN
        DO
            gap = 10 * gap \ 13
            IF gap < 1 THEN gap = 1
            i = 0
            swapped = 0
            DO
                IF VAL(MenuList(MenuDisplayOrder(i, handle), handle)) > VAL(MenuList(MenuDisplayOrder(i + gap, handle), handle)) THEN
                    SWAP MenuDisplayOrder(i, handle), MenuDisplayOrder(i + gap, handle)
                    FOR ii = 1 TO LinkedTo(0).one
                        IF handle = LinkedTo(ii).one THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).another), MenuDisplayOrder(i + gap, LinkedTo(ii).another)
                        IF handle = LinkedTo(ii).another THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).one), MenuDisplayOrder(i + gap, LinkedTo(ii).one)
                    NEXT
                    swapped = -1
                END IF
                i = i + 1
            LOOP UNTIL i + gap > Menu(handle).Entries
        LOOP UNTIL gap = 1 AND swapped = 0
        IF sortmethod AND Reverse THEN
            FOR i = 1 TO Menu(handle).Entries \ 2
                SWAP MenuDisplayOrder(i, handle), MenuDisplayOrder(Menu(handle).Entries - i + 1, handle)
                FOR ii = 1 TO LinkedTo(0).one
                    IF handle = LinkedTo(ii).one THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).another), MenuDisplayOrder(Menu(handle).Entries - i + 1, LinkedTo(ii).another)
                    IF handle = LinkedTo(ii).another THEN SWAP MenuDisplayOrder(i, LinkedTo(ii).one), MenuDisplayOrder(Menu(handle).Entries - i + 1, LinkedTo(ii).one)
                NEXT
            NEXT
        END IF
    ELSE
        FOR i = 1 TO Menu(handle).Entries
            MenuDisplayOrder(i, handle) = i
            FOR ii = 1 TO LinkedTo(0).one
                IF handle = LinkedTo(ii).one THEN MenuDisplayOrder(i, LinkedTo(ii).another) = i
                IF handle = LinkedTo(ii).another THEN MenuDisplayOrder(i, LinkedTo(ii).one) = i
            NEXT
        NEXT
    END IF

END SUB


Here we can easily create a multiple lists of things.  Link one list to another, if we want...  Sort them.  Select them.  Hide them...  Invalidate choices...  It's a very powerful little library, and one which I plug into a lot of little things for when I need a menu of choices. 

Sorting.  Linking lists.  Unlinking lists.  Selecting things.  Hiding lists.  Restoring lists.  Scrolling via the mouse wheel or in-built sliders.  Hiding/showing sliders.  Making selections unavailable, and restoring availability...

Print this item

  Mouse Help Needed
Posted by: SierraKen - 05-02-2022, 01:30 AM - Forum: Help Me! - Replies (27)

I'm doing another update for Ken's Artillery 2 using sliders for the power and angle. I got the sliders themselves working OK, but for some reason the computer keeps thinking the mouse button is pressed on each turn and after one turn, and then the computer, the computer takes over and shoots from your guy thinking you have pressed the mouse already. For a long time I've had some issues with the mouse commands and I'm not sure how to fix this. Any help is appreciated, thank you. I put comment lines where the code is at to help you. Also, I spent over 2 hours trying to fix this trying many different ways and loops, etc. No success, this is as best as I can get it so far. Is there a command to reset the _mousebutton (1) command? Because that's all I really need. 

Code: (Select All)
'I've always wanted to make this game ever since I started programming in the 80's.
'This was created by Ken G. with much help from others below.
'Thank you to B+ for much of the math code.
'It takes the computer a little time to learn how to hit your base.
'Created on June 26, 2019.
'Version 2 made on April 30, 2022.
'Added: Levels, random colored mountains, and better looking cannons.

_Title "Ken's Artillery 2"
_Limit 200
Cls
Screen _NewImage(1200, 700, 32)
Print "                                              Ken's Artillery 2"
Print: Print: Print
Print "                                      By SierraKen with math help from B+."
Print: Print: Print
Print "                         Instructions: You play against the computer by shooting a cannonball"
Print "                         from your cannon at your base on the left side of the screen"
Print "                         to the computer's base on the right side of the screen."
Print "                         To do this, you type a power number between 0 and 80 and press Enter."
Print "                         Then you type an angle that the cannonball will travel at,"
Print "                         between 0 and 90 and press Enter."
Print "                         You get a point every time you hit the other base."
Print "                         If you hit the enemy 5 times you advance to the next mountain."
Print "                         If the enemy hits you 5 times in one mountain, you lose."
Print "                         Watch the wind speed indicator up on top to see the direction and"
Print "                         speed of the wind, which makes a big difference on where your"
Print "                         cannonball will land. Also, there will be a random sized mountain"
Print "                         and color for every level and game."
Print: Print: Print
Input "                         Press Enter to begin.", start$
Cls
level = 1

start:
c = 0
mountain = 0
win = 0
compoints = 0
points = 0
ground = 590 'up is negative in direction

'Your Cannon

cbx = 10 '              cannon butt end x, y
cby = ground - 20
cmx = 50 '              cannon mouth end
cmy = ground - 70

'Computer's Cannon

cbx2 = 1190
cby2 = cby
cmx2 = 1150
cmy2 = cmy


g = .15 '       with air resistance
Randomize Timer
air = Int(Rnd * 20)
air2 = air / 1000
Randomize Timer
air3 = Int(Rnd * 100)
If air3 > 50 Then air2 = -air2
airX = air2
Color , _RGB32(156, 210, 237)
Cls
'Bases
Line (cbx, ground)-(cbx + 100, ground - 20), _RGB32(4, 4, 4), BF
Line (cbx2, ground)-(cbx2 - 100, ground - 20), _RGB32(4, 4, 4), BF
'Mountain
Randomize Timer
sz = Int(Rnd * 300) + 100
circx = 595
cl1 = Int(Rnd * 55) + 50
cl2 = Int(Rnd * 55) + 50
cl3 = Int(Rnd * 55) + 50
Line (0, ground)-(1200, 700), _RGB32(cl1, cl2, cl3), BF 'ground
Circle (circx, ground), sz, _RGB32(cl1, cl2, cl3)
Paint (circx, ground - 2), _RGB32(cl1, cl2, cl3)
again:
Color _RGB(0, 0, 0)
Locate 10, 136: Print "              "
Locate 10, 2: Print "Your Turn     "
Randomize Timer
air = Int(Rnd * 20)
air2 = air / 1000
Randomize Timer
air3 = Int(Rnd * 100)
If air3 > 50 Then air2 = -air2
airX = air2
airx2 = airX * 1000
If airx2 < -1 Then winddir$ = "West"
If airx2 > 1 Then winddir$ = "East"
If airx2 > -1 And airx2 < 1 Then winddir$ = "Sunny"
If airx2 < 0 Then airx2 = airx2 * -1

GoSub Wind:
_PrintString (5, 50), "Power"
_PrintString (5, 80), "Angle"
Line (60, 40)-(260, 70), _RGB32(255, 255, 255), B
Line (60, 70)-(260, 100), _RGB32(255, 255, 255), B
Line (60, 100)-(120, 130), _RGB32(255, 0, 5), BF
Color _RGB32(0, 0, 0), _RGB32(255, 0, 5)
_PrintString (70, 110), "Fire!"
vel = 40
vel2 = 100
a = 45
a2 = 100
Line (61, 41)-(vel2, 69), _RGB32(255, 0, 1), BF
Line (61, 71)-(a2, 99), _RGB32(0, 255, 1), BF


'This is the part that I can't fix --------------------------------------------------------

go:
Do While _MouseInput
    If Point(_MouseX, _MouseY) = _RGB32(255, 0, 1) And _MouseButton(1) = -1 Then
        vel2 = _MouseX + 5
        If vel2 > 259 Then vel2 = 259
        Line (61, 41)-(259, 69), _RGB32(156, 210, 237), BF
        Line (61, 41)-(vel2, 69), _RGB32(255, 0, 1), BF
        vel = Int(vel2 / 4)
        vel$ = Str$(vel)
        Color _RGB32(0, 0, 0), _RGB32(255, 0, 0)
        _PrintString (265, 50), vel$
        _Display
    End If
    If Point(_MouseX, _MouseY) = _RGB32(0, 255, 1) And _MouseButton(1) = -1 Then
        a2 = _MouseX + 5
        If a2 > 259 Then a2 = 259
        Line (61, 71)-(259, 99), _RGB32(156, 210, 237), BF
        Line (61, 71)-(a2, 99), _RGB32(0, 255, 1), BF
        a = Int(a2 / 3)
        aaa$ = Str$(a)
        Color _RGB32(0, 0, 0), _RGB32(0, 255, 0)
        _PrintString (265, 80), aaa$
        _Display
    End If
    If Point(_MouseX, _MouseY) = _RGB32(255, 0, 5) And _MouseButton(1) = -1 Then
        GoTo going:
    Else
        GoTo go:
    End If
Loop
Line (61, 41)-(vel2, 69), _RGB32(255, 0, 1), BF
Line (61, 71)-(a2, 99), _RGB32(0, 255, 1), BF

GoTo go:

'--------------------------------------------------------------------------------------------
going:
Color _RGB32(0, 0, 0), _RGB32(156, 210, 237)
If a > 90 Then a = 90
If a < 0 Then a = 0
If vel < 0 Then vel = 0
If vel > 80 Then vel = 80
vel = Int(vel / 4)
a = 360 - a
ca = _D2R(a)
cmx = cbx + (100 * Cos(_D2R(a)))
cmy = cby + (100 * Sin(_D2R(a)))

'initialize
bx = cmx 'ball x, y same as cannon mouth at start of shot
by = cmy


dx = vel * Cos(ca) 'start at cannon mouth
dy = vel * Sin(ca)

'shot

Do
    _Limit 200
    GoSub Wind:

    a$ = InKey$
    If a$ = Chr$(27) Then End
    Circle (bx, by), 5, _RGB32(0, 0, 0)
    Paint (bx, by), _RGB32(0, 0, 0), _RGB32(0, 0, 0)
    For ccc = 0 To 7 Step .1
        Line (cbx, cby)-(cmx + ccc, cmy), _RGB32(150, 50, 0) 'cannon line
    Next ccc
    oldbx = bx: oldby = by
    dx = dx + airX
    dy = dy + g
    bx = bx + dx
    by = by + dy
    _Display
    _Limit 30
    Circle (oldbx, oldby), 5, _RGB(156, 210, 237)
    Paint (oldbx, oldby), _RGB(156, 210, 237)
    If Point(bx, by) = _RGB32(cl1, cl2, cl3) Then
        mountain = 1
        For explosion = 0 To 20 Step .5
            Circle (bx, by), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
    End If
    If bx > cbx2 - 120 And bx < cbx2 + 20 And by >= ground - 2 Then
        points = points + 1
        win = 0
        Locate 3, 64: Print "You: "; points; " Computer: "; compoints
        For explosion = 0 To 20 Step .5
            Circle (bx, by), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
        For sndd = 500 To 700 Step 50
            Sound sndd, 1
        Next sndd
        mountain = 1
        If points = 5 And win = 0 Then win = 1: level = level + 1: GoTo start:
    End If
Loop Until mountain = 1 Or by > 700
For ccc = 0 To 7 Step .1
    Line (cbx, cby)-(cmx + ccc, cmy), _RGB32(156, 210, 237) 'delete cannon line
Next ccc
mountain = 0
'The Computer's Turn

comp:

Color _RGB(0, 0, 0)
Locate 10, 2: Print "                      "
Locate 10, 137: Print "Computer Turn"
GoSub Wind:

'Computer learns as it goes but is not perfect, like a human.  ;-)
If c = 0 Then GoTo compstuff:
oldvel2 = vel2

compstuff:
Randomize Timer
vel2 = Int(Rnd * 35) + 30

a2 = a

vel2 = Int(vel2 / 4)

If c = 0 Then GoTo nex:
'Last shot was too far away.
If oldbx2 < cbx Then
    vel2 = oldvel2 - 1
    If vel2 < 8 Then vel2 = 8
End If
'Last shot wasn't far enough.
If oldbx2 > cbx Then
    vel2 = oldvel2 + 1
    If vel2 > 15 Then vel2 = 15
End If
nex:
c = 1
ca2 = _D2R(a2)
cmx2 = cbx2 - (100 * Cos(_D2R(a2)))
cmy2 = cby2 + (100 * Sin(_D2R(a2)))

'initialize
bx2 = cmx2 'ball x, y same as cannon mouth at start of shot
by2 = cmy2
dx2 = vel2 * Cos(ca2) 'start at cannon mouth
dy2 = vel2 * Sin(ca2)

'shot

Do
    _Limit 200
    a$ = InKey$
    If a$ = Chr$(27) Then End
    Circle (bx2, by2), 5, _RGB32(0, 0, 0)
    Paint (bx2, by2), _RGB32(0, 0, 0), _RGB32(0, 0, 0)
    For ccc = 0 To 7 Step .1
        Line (cbx2, cby2)-(cmx2 - ccc, cmy2), _RGB32(150, 50, 0) 'cannon line
    Next ccc
    oldbx2 = bx2: oldby2 = by2
    dx2 = dx2 + airX
    dy2 = dy2 + g
    bx2 = bx2 - dx2
    by2 = by2 + dy2
    _Display
    _Limit 30
    Circle (oldbx2, oldby2), 5, _RGB(156, 210, 237)
    Paint (oldbx2, oldby2), _RGB(156, 210, 237)
    If Point(bx2, by2) = _RGB32(cl1, cl2, cl3) Then
        mountain = 1
        For explosion = 0 To 20 Step .5
            Circle (bx2, by2), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
    End If
    If bx2 > cbx - 20 And bx2 < cbx + 120 And by2 >= ground Then
        compoints = compoints + 1
        Locate 3, 64: Print "You: "; points; " Computer: "; compoints
        For explosion = 0 To 20 Step .5
            Circle (bx2, by2), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
        For sndd = 500 To 700 Step 50
            Sound sndd, 1
        Next sndd
        mountain = 1
        If compoints = 5 Then Color _RGB(0, 0, 0): Locate 20, 65: Print "COMPUTER WINS!": GoTo asking:
    End If
Loop Until mountain = 1 Or by2 > 700

For ccc = 0 To 7 Step .1
    Line (cbx2, cby2)-(cmx2 - ccc, cmy2), _RGB32(156, 210, 237) 'delete cannon line
Next ccc
mountain = 0
GoTo again:

'This code is used in a few different places in the program.
Wind:
Color _RGB(0, 0, 0)
Locate 1, 73: Print "Wind"
If winddir$ = "West" Then
    Locate 2, 82: Print "                               "
    Locate 2, 59: Print airx2; " mph   "
End If
If winddir$ = "East" Then
    Locate 2, 59: Print "               "
    Locate 2, 82: Print airx2; " mph   "
End If
Locate 2, 68: Print "West <-> East"
Locate 3, 64: Print "You: "; points; " Computer: "; compoints
Locate 4, 71: Print "Level: "; level
Return

asking:
Locate 22, 65: Input "Again? (Yes/No):", ag$
If ag$ = "y" Or ag$ = "Y" Or ag$ = "yes" Or ag$ = "Yes" Or ag$ = "YES" Or ag$ = "yES" Or ag$ = "yeS" Then points = 0: level = 1: GoTo start:
End

Print this item

  A quick lesson on: What is IMP?
Posted by: SMcNeill - 05-02-2022, 12:35 AM - Forum: Learning Resources and Archives - Replies (21)

One way to break down the logic of IMP is to remember with A IMP B:

Your result is *always* going to have all the bits of B set…

For example, let’s assume A and B are both _UNSIGNED _BYTEs.

Now if B =3, the result of A IMP B will be = ??????11, depending on A to fill in the ?
And if B = 5, the result of A IMP B will be = ?????1?1, depending on A to fill in the ?

*Whatever* the final result is, it’s going to have every bit set that B already has set.




And, with that half of the process solved, it’s *also* going to set any bits that A *DOES NOT* have set.

A = 2.  B = 3.

In binary, those are:
A = 00000010
B = 00000011

A IMP B is solved by first setting all the bits in the answer to match B:   ??????11
Then we toggle all the bits in A: 11111101.
And we set the ones that are on, for our answer: 11111111

2 IMP 3 = 255




(NOT A) OR B

That’s the breakdown of what IMP is doing.

(NOT A) says the result is going to have all the bits set that A does NOT have.
OR B says our result is *also* going to have all the bits set that B does.

A IMP B = (NOT A) OR B

Really, that’s all there is to it.  It’s convoluted, and not really something I think most folks ever really need, but that’s all the does in a nutshell.

Print this item

  DBF conversion/use programs
Posted by: SMcNeill - 05-02-2022, 12:11 AM - Forum: SMcNeill - Replies (1)

Two programs here which might be useful for someone who needs to access data from a DBF file for use inside a QB64 program.

First, we have a simple program to change DBF files to CSV (Comma Separated Value) Text files:



Code: (Select All)
'DBF to CSV text converter

'Program written by Steve McNeill @ 9/19/2012

'Code is free to use, abuse, modify, destroy, steal, copy, share, and alter in any way anyone wishes.
'Just be aware, I'm not responsible if it melts your computer, fries your brain, or makes you sing like a drunken sailor.
'Use is purely at your own risk, but it seems safe enough to me!

'All this does is convert old dbf files into a simple CSV text file, which can then be read into any program which you wish to use the data with.
'Your old files stay as they are, and it does nothing to them except read them and then give you a new, converted file to work with.

'change file$ and file1$ to the name of your DBF and new converted filename, respectively.

'No credit, cash, check, or money order needed for this.  Enjoy!!

REM $DYNAMIC

TYPE DBF_Header
    FileType AS _UNSIGNED _BYTE
    Year AS _UNSIGNED _BYTE
    Month AS _UNSIGNED _BYTE
    Day AS _UNSIGNED _BYTE
    RecordNumber AS _UNSIGNED LONG
    FirstRecord AS _UNSIGNED INTEGER
    RecordLength AS _UNSIGNED INTEGER
    ReservedJunk AS STRING * 16
    TableFlag AS _UNSIGNED _BYTE
    CodePageMark AS _UNSIGNED _BYTE
    ReservedJunk1 AS STRING * 2
END TYPE

TYPE Field_Subrecord
    FieldName AS STRING * 11
    FieldType AS STRING * 1
    Displacement AS _UNSIGNED LONG
    FieldLength AS _UNSIGNED _BYTE
    FieldDecimal AS _UNSIGNED _BYTE
    FieldFlags AS _UNSIGNED _BYTE
    AutoNext AS _UNSIGNED LONG
    AutoStep AS _UNSIGNED _BYTE
    ReservedJunk AS STRING * 8
END TYPE

TYPE DBF_HeaderTerminator
    EndCode AS _UNSIGNED _BYTE 'Our End of Field Code is a CHR$(13), or 13 if we read it as a byte
END TYPE

TYPE DBF_VFPInfo
    Info AS STRING * 263
END TYPE

DIM DataH AS DBF_Header
DIM DataFS(1) AS Field_Subrecord
DIM DataHT AS DBF_HeaderTerminator
DIM DataVFP AS DBF_VFPInfo

file$ = ".\tempdata.dbf"
file2$ = ".\converted.txt"

Get_Header file$, DataH
'Display_Header DataH
Get_Fields file$, DataFS()
'Display_Fields DataFS()
Print_Data file$, DataH, DataFS(), file2$
PRINT "Your file has been converted."
PRINT "The original file was: "; file$
PRINT "The converted file is: "; file2$

END


SUB Display_Header (DataH AS DBF_Header)
PRINT "Data File Type: ";
SELECT CASE DataH.FileType
    CASE 2: PRINT "FoxBASE"
    CASE 3: PRINT "FoxBASE+/Dbase III plus, no memo"
    CASE 48: PRINT "Visual FoxPro"
    CASE 49: PRINT "Visual FoxPro, autoincrement enabled"
    CASE 50: PRINT "Visual FoxPro with field type Varchar or Varbinary"
    CASE 67: PRINT "dBASE IV SQL table files, no memo"
    CASE 99: PRINT "dBASE IV SQL system files, no memo"
    CASE 131: PRINT "FoxBASE+/dBASE III PLUS, with memo"
    CASE 139: PRINT "dBASE IV with memo"
    CASE 203: PRINT "dBASE IV SQL table files, with memo"
    CASE 229: PRINT "HiPer-Six format with SMT memo file"
    CASE 245: PRINT "FoxPro 2.x (or earlier) with memo"
    CASE 251: PRINT "FoxBASE"
    CASE ELSE: PRINT "Unknown File Type"
END SELECT
PRINT "Date: "; DataH.Month; "/"; DataH.Day; "/"; DataH.Year
PRINT "Number of Records: "; DataH.RecordNumber
PRINT "First Record: "; DataH.FirstRecord
PRINT "Record Length: "; DataH.RecordLength
PRINT "Reserved Junk: "; DataH.ReservedJunk
PRINT "Table Flags: ";
none = 0
IF DataH.TableFlag AND 1 THEN PRINT "file has a structural .cdx ";: none = -1
IF DataH.TableFlag AND 2 THEN PRINT "file has a Memo field ";: none = -1
IF DataH.TableFlag AND 4 THEN PRINT "file is a database (.dbc) ";: none = -1
IF none THEN PRINT ELSE PRINT "None"
PRINT "Code Page Mark: "; DataH.CodePageMark
PRINT "Reserved Junk: "; DataH.ReservedJunk1
END SUB

SUB Display_Fields (DataH() AS Field_Subrecord)
FOR r = 1 TO UBOUND(DataH)
    PRINT "Field Name :"; DataH(r).FieldName
    PRINT "Field Type :"; DataH(r).FieldType
    PRINT "Field Displacement :"; DataH(r).Displacement
    PRINT "Field Length :"; DataH(r).FieldLength
    PRINT "Field Decimal :"; DataH(r).FieldDecimal
    PRINT "Field Flags :"; DataH(r).FieldFlags
    PRINT "Field AutoNext :"; DataH(r).AutoNext
    PRINT "Field SutoStep :"; DataH(r).AutoStep
    PRINT "Field Reserved Junk :"; DataH(r).ReservedJunk
    SLEEP
    PRINT "**************************"
NEXT
END SUB

SUB Get_Header (file$, DataH AS DBF_Header)
OPEN file$ FOR BINARY AS #1 LEN = LEN(DataH)
GET #1, 1, DataH
CLOSE
END SUB

SUB Get_Fields (file$, DataH() AS Field_Subrecord)
DIM databyte AS _UNSIGNED _BYTE
DIM temp AS Field_Subrecord
OPEN file$ FOR BINARY AS #1 LEN = 1
counter = -1: s = 33
DO
    counter = counter + 1
    GET #1, s, databyte
    s = s + 32
LOOP UNTIL databyte = 13
REDIM DataH(counter) AS Field_Subrecord
IF counter < 1 THEN BEEP: BEEP: PRINT "Database has no file records.": END
CLOSE
OPEN file$ FOR BINARY AS #1 LEN = 32
FOR r = 1 TO counter
    GET #1, 32 * r + 1, DataH(r) 'record 1 is our header info, so we need to start our field info at record 2
NEXT

CLOSE
END SUB

SUB Print_Data (file$, DataH AS DBF_Header, DataFS() AS Field_Subrecord, file2$)
DIM databyte AS _UNSIGNED _BYTE
OPEN file$ FOR BINARY AS #1
OPEN file2$ FOR OUTPUT AS #2
SEEK #1, DataH.FirstRecord + 1
DO
    GET #1, , databyte 'This is the first byte which tells us if the record is good, or has been deleted.
    IF databyte = 32 THEN WRITE #2, "Good Record", ELSE WRITE #2, "Deleted Record",
    FOR i = 1 TO UBOUND(DataFS)
        SELECT CASE DataFS(i).FieldType
            CASE "C", "0"
                'C is for Characters, or basically STRING characters.
                '0 is for Null Flags, which I have no clue what they're for.  I'm basically reading them here as worthless characters until I learn otherwise.
                temp$ = ""
                FOR j = 1 TO DataFS(i).FieldLength
                    GET #1, , databyte
                    temp$ = temp$ + CHR$(databyte)
                NEXT
            CASE "Y"
                'Y is for currency, which is an _INTEGER 64, with an implied 4 spaces for decimal built in.
                REDIM temp AS _INTEGER64
                GET #1, , temp
                temp$ = STR$(temp)
                l = LEN(temp$)
                temp$ = LEFT$(temp$, l - 4) + "." + RIGHT$(temp$, 4)
            CASE "N", "F", "M", "G"
                'N is for numberic, F is for Floating numbers, and both seem to work in the same manner.
                'M is for Memo's, which are stored in a different  DBT file.  What we have here is the block number of the memo location in that file, stored as a simple set of characters.
                'G is for OLE files.  We store the info for it just the same as we do for a Memo.
                'we read the whole thing as a string, which is an odd way for dBase to write it, but I don't make the rules.  I just convert them!
                temp$ = ""
                FOR j = 1 TO DataFS(i).FieldLength
                    GET #1, , databyte
                    temp$ = temp$ + CHR$(databyte)
                NEXT
            CASE "D"
                'D is for Date fields.
                'Dates are stored as a string, in the format YYYYMMDD
                temp$ = ""
                FOR j = 1 TO DataFS(i).FieldLength
                    GET #1, , databyte
                    temp$ = temp$ + CHR$(databyte)
                NEXT
                year$ = LEFT$(temp$, 4)
                month$ = MID$(temp$, 5, 2)
                day$ = RIGHT$(temp$, 2)
                temp$ = day$ + "/" + month$ + "/" + year$
            CASE "L"
                'L is our logical operator.  Basically, it's simply True or False Boolean logic
                GET #1, , databyte
                IF databyte = 32 THEN temp$ = "True" ELSE temp$ = "false"
            CASE "@", "O"
                '@ are Timestamps, which I'm too lazy to fully support at the moment.
                'They are 8 bytes - two longs, first for date, second for time.
                'The date is the number of days since  01/01/4713 BC.
                'Time is hours * 3600000L + minutes * 60000L + Seconds * 1000L
                'All I'm going to do is read both longs as a single _Integer64 and then write that data to the disk.
                'Be certain to convert it as needed to make use of the Timestamp.
                'I'm just lazy and don't wanna convert anything right now!  :P

                'O are double long integers -- basically Integer 64s.  Since I'm reading a timestamp as an Int64, this routine works for them as well.
                REDIM temp1 AS _INTEGER64
                GET #1, , temp1
                temp$ = STR$(temp1)
            CASE "I", "+"
                'Long Integers.  Basically 4 byte numbers
                '+ are auto-increments.  Stored the same way as a Long.
                REDIM temp2 AS LONG
                GET #1, , temp2
                temp$ = STR$(temp2)
        END SELECT
        IF i = UBOUND(datafs) THEN WRITE #2, temp$ ELSE WRITE #2, temp$,
    NEXT
LOOP UNTIL EOF(1)
CLOSE
END SUB


Useage here is simple:
1) Download the file below and put it in your QB64 folder (and extract it)

2) copy and paste the code above into your QB64 IDE.

3) compile and run
4) Enjoy looking at the "converted.txt" file which we created in that same folder, which now has all the DATA in that DBF file converted over to CSV TXT for ease of use in QB64 (or any other program which you might need it for).



Attached Files
.zip   tempdata.zip (Size: 315 bytes / Downloads: 32)
Print this item

  Is Discord part of the Phoenix edition,?
Posted by: PhilOfPerth - 05-02-2022, 12:09 AM - Forum: General Discussion - Replies (6)

I looked at the QB64 Discord link, and it still carries QB64 as its identity. Is this where we still go, or is there a new PE edition somewhere?  Confused

Print this item