Hobby Basic, ένας μικρός διερμηνευτής για την κονσόλα των Windows

Προβολή συνημμένου 245146


Ο διερμηνευτής ξεπέρασε τα 1000 downloads στο φόρουμ του flat assembler. Συγκίνηση on.

Προβολή συνημμένου 245148


To coffee project της ημέρας.
Ένας ANSI viewer γραμμένος στην Hobby BASIC 1.4.3.

Εισαγωγή.

To 16color.rs φιλοξενεί χιλιάδες εικόνες ANSI σε φακέλους χρονολογικά, παράδειγμα ο φάκελος 1990.
Σκοπός μου να γράψω έναν viewer που θα μπορεί να φορτώσει απευθείας τις ANSI εικόνες που βρίσκονται ανεβασμένες στην εν λόγω ιστοσελίδα. Θα μπορεί όμως να λειτουργήσει και offline, φορτώνοντας εικόνες από τον φάκελο ART της Hobby BASIC.

Δοκιμές.

To screenshot είναι από τον κώδικα της σελίδας 1990. Βλέπω πως η σελίδα για την εικόνα AKO.ANS είναι η /PACK/1990/AKO.ANS

Προβολή συνημμένου 245124


Επισκέφτηκα την σελίδα και είδα πως ο απευθείας σύνδεσμος (direct link) της εικόνας είναι ελαφρά διαφορετικός pack/1990/raw/AKO.ANS
Δοκιμάζω τον σύνδεσμο, φορτώνω την εικόνα στην κονσόλα.

Κώδικας:
    screen 80,30,300
    color 0,7
    cls
    ansi "https://16colo.rs/pack/1990/raw/AKO.ANS"
    inkey
    end

Προβολή συνημμένου 245128


Δοκιμάζω τώρα να "κλέψω" όλους τους συνδέσμους τύπου .ANS από την σελίδα 1990 και να τους σώσω σε ένα αρχείο κειμένου. Η σελίδα περιέχει περίπου 440 διπλούς συνδέσμους, άρα κοντά 220 αρχεία .ANS.

Κώδικας:
    src$ = GETSRC("https://16colo.rs/pack/1990/")
    links$ = EXTRACT(src$,".ans")
    if LEN(TRIM(0,links$) > 0)
        save "links.txt",links$
    endif

Προβολή συνημμένου 245130


Το πρόγραμμα.

O Viewer φορτώνει εικόνες από 6 διαφορετικούς φακέλους του 16color.rs. Μπορούν φυσικά να προστεθούν και άλλοι. Μπορεί να τις αναπαράγει τυχαία ή σε σειρά. Περιλαμβάνει μερικό έλεγχο λαθών και κάνει skip στα διπλά ονόματα. Παίζει αυτόματα σαν slideshow ή manual κάνοντας skip στην επόμενη πατώντας κάποιο πλήκτρο (ή το Esc και στις 2 περιτπώσεις). Αποθηκεύει αντίγραφο κάθε εικόνας που φορτώνει στον φάκελο ART της Hobby BASIC. Πριν φορτώσει κάθε εικόνα, πρώτα ελέγχει αν υπάρχει ήδη κατεβασμένη και την φορτώνει από τον σκληρό δίσκο κάνοντας την εναλλαγή αυτόματα από online σε offline. Μπορεί ακόμα να δουλέψει μόνο offline φορτώνοντας τις εικόνες που θα βρει μέσα στον φάκελο ART.

Άφησα το πρόγραμμα να τρέξει κάμποση ώρα σε Windows 10 αλλάζοντας που και που τις παραμέτρους του. Δεν είδα κάποιο πρόβλημα, χωρίς όμως αυτό να αποκλείεται. Θα το ενσωματώσω στα παραδείγματα σε μια επόμενη έκδοση του διερμηνευτή.

Κώδικας:
    rem  AVIEW.BAS
    rem  Hobby Basic Interpreter
    rem  ANSI Text File Viewer (requires an internet connection)

    AUTO_PLAY = 1
    RANDOM_ORDER = 1
    TEXT_SPEED = 2
    OFFLINE = 0

    url$ = "https://16colo.rs/pack/"

    numOfFolders = 6
    dim folder$[numOfFolders] = "1990", "ansipics", "eansis", "1991", "aaa-8991", "ensiart"

    if RANDOM_ORDER then folder$[].SHUFFLE

    view 11
    screen 80,50
    cursor 0,0
    color 0,7
    cls

    ? "ANSI Text File Viewer for Hobby Basic"

    art_path$ = PATH("ART\")

    if CHDIR(art_path$,0) = -1
        ? "Can''t find ART folder"
        pause
        end
    endif

    if OFFLINE
        ? "AVIEW is running offline"
        exec "dir /b *.ans",tmp$
        tmp$ = TRIM(0,tmp$)
        goto split_links
    endif

    index = -1

    next_folder#

    index = (index+1) % numOfFolders
    folder_path$ = url$ + folder$[index] + "/"
    raw_path$ = folder_path$ + "raw/"

    ? "Loading source from ",folder_path$

    src$ = GETSRC(folder_path$)
    if V0 <> 1
        ? "Can''t open URL"
        wait 2000
        goto next_folder
    endif

    tmp$ = TRIM(0,EXTRACT(src$,".ans"))
    if LEN(tmp$) = 0
        ? "Can''t find any .ANS links in folder ",folder$[index]
        wait 2000
        goto next_folder
    endif

    split_links#

    numOfLinks = SPLIT(tmp$,CHR(13),-1)
    if numOfLinks = 0
        ? "Splitting links to array failed"
        wait 2000
        if ~OFFLINE then goto next_folder else pause : end
    endif

    ? numOfLinks," links found with extension .ANS" : wait 500

    dim list$[numOfLinks+1]
    SPLIT(tmp$,CHR(13),list$[])
    if RANDOM_ORDER then list$[].SHUFFLE

    x = 0

    ansi_viewer#

    filename$ = RIGHT(TRIM(0,list$[x]),-1)
    path$ = art_path$ + filename$
    if SIZE(path$) = -1
        if OFFLINE then goto @f
        path$ = raw_path$ + filename$
    endif

    if prev_path$ = path$ then goto @f
    prev_path$ = path$

    color 0,7
    cls
    title path$
    ansi path$,TEXT_SPEED
    if KEY(27) then wait 100 : goto @f
    if AUTO_PLAY then wait 3000 else inkey
    @@# x = x + 1 : if x < numOfLinks then goto ansi_viewer
    if ~OFFLINE then goto next_folder else goto ansi_viewer

Προβολή συνημμένου 245151


Κλείνοντας.

Η Hobby BASIC είναι εξ'ολοκλήρου γραμμένη σε 32-bit assembly και Win32 API. Η εντολή ANSI έχει backend έναν handmade loader γραμμένο σε assembly για να μπορεί να φορτώνει γραφικά ANSI στην κονσόλα, η εντολή EXTRACT που ανακτά τους συνδέσμους από μια ιστοσελίδα το ίδιο.

Αν τρέξετε το πρόγραμμα θα σας προσφέρει πολύ όμορφες και νοσταλγικές στιγμές, οι εικόνες ANSI είναι κομμάτι της ιστορίας και εξέλιξης των υπολογιστών.
Το 16colo.rs, εχει προσβαση και μεσω ftp, οπου έχει τα αρχεια και συμπιεσμενα σε packs, αλλα και ασυμπιεστα (raw). Το λεω πληροφοριακα, για πιθανό επόμενο project :)

Εχω φτιάξει κατι αντίστοιχο σε python για την Mystic BBS. :)

Φοβερη η hobby basic. Μήπως υπάρχει ενδεχόμενο να υπάρξει και σε εκδοση για Linux ;
 
Γεια σου xqtr,

Μου έδωσες ωραία ιδέα (και ενδιαφέρον task), θα δοκιμάσω μέσω wininet api που το έχω δουλέψει παλιότερα.

Φοβάμαι πως δεν μπορεί να γίνει recompile για Linux, ο κώδικας της είναι γραμμένος από την αρχή σε 32-bit assembly και win32 api χωρίς cross platform βιβλιοθήκες όπως SDL. Ίσως τρέχει στο WINE, δεν το έχω δοκιμάσει
 
Εχω φτιάξει κατι αντίστοιχο σε python για την Mystic BBS.
Είχα εγκαταστήσει κάποτε δοκιμαστικά την Synchronet BBS από το σπίτι. Ήμουν Administrator και ταυτόχρονα το μοναδικό μέλος. Φανταστικό υπέροχο software. Με έμαθε πολλά πράγματα.

Το 16colo.rs, εχει προσβαση και μεσω ftp, οπου έχει τα αρχεια και συμπιεσμενα σε packs, αλλα και ασυμπιεστα (raw). Το λεω πληροφοριακα, για πιθανό επόμενο project.
Με έβαλες σε σκέψεις φίλε xqtr, έψαξα και βρήκα ένα παλιό παράδειγμα που έχω γράψει σε win32 assembly. Είναι ένα πρόγραμμα που συνδέεται μέσω ftp στον server και κατεβάζει ένα αρχείο. Οπότε σε πρώτη φάση θα δω πως μπορώ να διαβάσω το ftp directory του server με συναρτήσεις WinINet και βλέπω μετά. Έχω μια βάση.

Κώδικας:
        ; WinInet functions example.
        ; The following sample code establish a connection to an FTP server.
        ; It controls how long to wait while connecting to the FTP server in WinInet.
        ; It downloads a file from FTP server to local disk and displays the download progress on Console title.
        ; FTP account username and password required.
    
        ; Written by Picnic
        ; Fasm v1.69.02
        ; Tested on Windows XP

        format PE CONSOLE 4.0
        entry main

        include 'include\win32ax.inc'

        INFINITE = -1
        INTERNET_SERVICE_FTP = 1
        INTERNET_DEFAULT_FTP_PORT = 21
        INTERNET_OPEN_TYPE_DIRECT = 1
        FTP_TRANSFER_TYPE_BINARY = 2
        INTERNET_FLAG_TRANSFER_BINARY = 2
        INTERNET_FLAG_RELOAD = 0x80000000
        INTERNET_FLAG_DONT_CACHE = 0x4000000
        CONTENT_LENGTH = 4096

.data
        szHost TCHAR '',0                   ; xxx.xxx.xxx.xxx
        szUser TCHAR '',0                   ; username
        szPass TCHAR '',0                   ; password
        szRemoteFile TCHAR '',0             ; /music/test.mp3
        szLocalFile TCHAR '',0              ; c:\test.mp3

        lpExitCode dd 0
        lpBytesRead dd 0
        lpCharsWritten dd 0

        dwTimeout dd 0
        dwThreadID dd 0
        dwTotalBytes dd 0

        hStdOut dd 0
        hConnect dd 0
        hOpen dd 0
        hThread dd 0
        hFile dd 0
        hHeap dd 0
        hMem dd 0
        hRequest dd 0

        Buffer db 256 dup ?

.code
main:
        ; ///Returns a handle for the standard output
        invoke GetStdHandle, STD_OUTPUT_HANDLE
        .if eax = -1
            stdcall LastError, <'GetStdHandle() failed. Error code %d'>
            jmp Exit
        .endif

        mov [hStdOut], eax
    

        ;  ///Obtains a handle to the heap of the calling process
        invoke GetProcessHeap
        .if ~eax
            stdcall LastError, <'GetProcessHeap() failed. Error code %d'>
            jmp Exit
        .endif

        mov [hHeap], eax
    

        ; ///Allocates a block of memory from a heap
        invoke HeapAlloc, [hHeap], HEAP_ZERO_MEMORY, CONTENT_LENGTH+1
        .if ~eax
            stdcall LastError, <'HeapAlloc() failed. Error code %d'>
            jmp Exit
        .endif

        mov [hMem], eax
    

        ; ///Initializes use of the WinINet functions
        invoke InternetOpen, NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, 0, 0
        .if ~eax
            stdcall LastError, <'InternetOpen() failed. Error code %d'>
            jmp Exit
        .endif

        mov [hOpen], eax
    

        ; ///Create a connection thread
        invoke CreateThread, NULL, 0, Thread, 0, 0, 0
        mov [hThread], eax

        ; ///Wait for the call to InternetConnect in thread function to complete
        mov [dwTimeout], 10000
        invoke WaitForSingleObject, [hThread], [dwTimeout]
        .if eax = WAIT_TIMEOUT
            stdcall Print, <'Can not connect to FTP server.',13,10>
            .if [hOpen]
                invoke InternetCloseHandle, [hOpen]
                mov [hOpen], 0
            .endif
            ; Wait until the thread exits
            invoke WaitForSingleObject, [hThread], INFINITE
            stdcall Print, <'Thread has exited.',13,10>
            jmp Exit
        .endif

        ; ///The state of the specified thread is signaled
        invoke GetExitCodeThread, [hThread], lpExitCode
        .if ~eax
            stdcall LastError, <'GetExitCodeThread() failed. Error code %d'>
            jmp Exit
        .endif

        invoke CloseHandle, [hThread]

        .if [lpExitCode]
            ; ///Thread function failed
            jmp Exit
        .endif

    
        ; ///Initiates access to a remote file on an FTP server for reading or writing
         invoke FtpOpenFile, [hConnect], szRemoteFile, GENERIC_READ,\
                   INTERNET_FLAG_TRANSFER_BINARY+INTERNET_FLAG_DONT_CACHE+INTERNET_FLAG_RELOAD, 0
        .if ~eax
            stdcall LastError, <'FtpOpenFile() failed. Error code %d'>
            jmp Exit
        .endif

        mov [hRequest], eax
    

        ; ///Creates a new file on disk. The function overwrites the file if it exists
        invoke CreateFile, szLocalFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
        .if eax = -1
            stdcall LastError, <'CreateFile() failed. Error code %d'>
            jmp Exit
        .endif

        mov [hFile], eax
    

        stdcall Print, <'Downloading file from FTP server...',13,10>

        ; ///Read from file on the server in a loop chunks of 4Kb each
        .repeat
            invoke InternetReadFile, [hRequest], [hMem], CONTENT_LENGTH, lpBytesRead
            .if eax
                ; ///Write the memory buffer to file on disk
                invoke WriteFile, [hFile], [hMem], [lpBytesRead], lpCharsWritten, 0
                mov ecx, [lpCharsWritten]
                add [dwTotalBytes], ecx
                ; /// Sets the title bar string for the current Console
                invoke wsprintf, Buffer, <'Downloaded %d bytes so far..'>, [dwTotalBytes]
                invoke SetConsoleTitle, Buffer
            .endif
        .until ~[lpBytesRead]

    
        ; /// File download completed
        cinvoke wsprintf, Buffer, <'Download completed. Total %d bytes.',13,10>, [dwTotalBytes]
        stdcall Print, Buffer


    
; ///Release allocated memory, close open handles and exit program
Exit:
        .if [hFile]
            invoke CloseHandle, [hFile]
        .endif
        .if [hMem]
            invoke HeapFree, [hHeap], 0, [hMem]
        .endif
        .if [hRequest]
             invoke InternetCloseHandle, [hRequest]
        .endif
        .if [hOpen]
            invoke InternetCloseHandle, [hOpen]
        .endif
        .if [hConnect]
            invoke InternetCloseHandle, [hConnect]
        .endif

        invoke ExitProcess, 0



proc  Thread
        stdcall Print, <'Trying to establish connection...',13,10>

        ; ///Call InternetConnect to establish a FTP session
        invoke InternetConnect, [hOpen], szHost, INTERNET_DEFAULT_FTP_PORT,\
                  szUser, szPass, INTERNET_SERVICE_FTP, 0, 0
        .if ~eax
            stdcall LastError, <'InternetConnect() failed. Error code %d'>
            mov eax, 1
        .else
            mov [hConnect], eax
            stdcall Print, <'Connection established to FTP server.',13,10>
            xor eax, eax
        .endif
        ret
endp



; ///Prints a character string to Console
proc  Print lpBuffer
        cinvoke wsprintf, Buffer, [lpBuffer]
        invoke WriteConsole, [hStdOut], Buffer, eax, lpCharsWritten, 0
        .if ~eax
            stdcall LastError, <'WriteConsole() failed. Error code %d'>
            jmp Exit
        .endif
        ret
endp



; ///Displays last-error info & code value
proc  LastError lpBuffer
        invoke GetLastError
        cinvoke wsprintf, Buffer, [lpBuffer], eax
        invoke MessageBox, HWND_DESKTOP, Buffer, 0, MB_OK+MB_ICONERROR
        ret
endp



data import

        library kernel32,'KERNEL32.DLL',\
                 user32,'USER32.DLL',\
                 wininet,'WININET.DLL'

        include 'include\api\kernel32.inc'
        include 'include\api\user32.inc'
        include 'include\api\wininet.inc'

end data
1658920065153.png



1658921903768.png

Hobby Basic 1.4.5

Ο διερμηνευτής αναπτύσσεται σε περιβάλλον Windows 7 και 10. Είχα καιρό να τρέξω την Hobby Basic σε Windows XP και δεν πρόσεξα πως ορισμένες αλλαγές που έκανα έχουν σπάσει την συμβατότητα προς τα πίσω.

Συγκεκριμένα, χρησιμοποίησα κάποιες κλήσεις του λειτουργικού που υποστηρίζονται από τα Vista και έπειτα. Δεν το είχα πάρει χαμπάρι και όταν δοκίμασα να τρέξω την Hobby Basic σε Windows XP πήρα μήνυμα λάθους. Το πρόβλημα αφορούσε την εντολή VIEW που στα Windows 7/10 δίνει (μεταξύ άλλων) την δυνατότητα αλλαγής μεγέθους της γραμματοσειράς σε μέγεθος 5x5 pixel στην κονσόλα. Το πρόβλημα διορθώθηκε και πλέον ο διερμηνευτής τρέχει σε Windows 7/10 αλλά και στα XP, που απλά παραβλέπουν αυτό το mode.

Δείτε τι εννοώ τρέχοντας το παράδειγμα CELL που χρησιμοποιεί το mode 5x5. (Ακόμα δύο παραδείγματα χρησιμοποιούν αυτό το mode, το Snake και το 15).

Στα Windows 10 εμφανίζεται σωστά με μέγεθος κελιών 5x5. Τα σχήματα είναι τετράγωνα.
1658923106299.png

Στα Windows XP μένει το default 8x12 και τα σχήματα είναι παραλληλόγραμμα. Οπότε θα χρειαστούν αλλαγές στον κώδικα του παραδείγματος ώστε να υποστηρίζονται και τα 2 λειτουργικά και να φαίνεται σωστά.
1658924482763.png
 
Είχα εγκαταστήσει κάποτε δοκιμαστικά την Synchronet BBS από το σπίτι. Ήμουν Administrator και ταυτόχρονα το μοναδικό μέλος. Φανταστικό υπέροχο software. Με έμαθε πολλά πράγματα.
Εγω εχω ακομα μια, με mystic bbs. Εννοειτε οτι η κινηση είναι χαλαρή εως ανύπαρκτη, αλλά τουλάχιστον κανω το κεφι μου. Το χω ρίξει και στο modding, οπότε, οποιαδηποτε κινηση προέρχεται απο εκεί ,μιας και έρχονται να δουν, να παρουν ιδεες και να κατεβασουν τα mods.

Αν θες ριξε μάτι ,θα δεις και το mod για το 16colo.rs. Η διευθυνση είναι :

telnet://andr01d.zapto.org:9999


Με έβαλες σε σκέψεις φίλε xqtr, έψαξα και βρήκα ένα παλιό παράδειγμα που έχω γράψει σε win32 assembly. Είναι ένα πρόγραμμα που συνδέεται μέσω ftp στον server και κατεβάζει ένα αρχείο. Οπότε σε πρώτη φάση θα δω πως μπορώ να διαβάσω το ftp directory του server με συναρτήσεις WinINet και βλέπω μετά. Έχω μια βάση.

Δεν το ειχα ποτέ με assembly και windows :)
 
Εγω εχω ακομα μια, με mystic bbs. Εννοειτε οτι η κινηση είναι χαλαρή εως ανύπαρκτη, αλλά τουλάχιστον κανω το κεφι μου. Το χω ρίξει και στο modding, οπότε, οποιαδηποτε κινηση προέρχεται απο εκεί ,μιας και έρχονται να δουν, να παρουν ιδεες και να κατεβασουν τα mods. Αν θες ριξε μάτι ,θα δεις και το mod για το 16colo.rs. Η διευθυνση είναι : telnet://andr01d.zapto.org:9999 Δεν το ειχα ποτέ με assembly και windows :)

Είμαι μέσα, τέλειο που διατηρείς BBS !

Θα μπω αργά το βραδάκι με την ησυχία μου να την εξερευνήσω. Και βέβαια να κάνω εγγραφή. Είναι 24/7 open?
 
Τελευταία επεξεργασία:
Είμαι μέσα, τέλειο που διατηρείς BBS !

Θα μπω αργά το βραδάκι με την ησυχία μου να την εξερευνήσω. Και βέβαια να κάνω εγγραφή. Είναι 24/7 open?
Παντα, εκτος και αν εχει φαει κανα κολλημα το rpi, γιατι τα κάνει κατι τετοια. Αλλα γενικά, ειναι 24/7.
 
Hobby-BASIC.png

Hobby Basic 1.4.8

Ένα νέο update στον διερμηνευτή.
Η Hobby BASIC μπορεί τώρα να σώσει αρχεία σε μορφή ANSI.
Αυτό γίνεται μέσω του Text Draw, του σχεδιαστικού προγράμματος της Hobby BASIC.
Ήθελα εδώ και καιρό να προσθέσω αυτήν την δυνατότητα στο Text Draw, βρήκα χρόνο στις καλοκαιρινές διακοπές.

Ας δούμε ένα παράδειγμα στα γρήγορα.
Τρέχω το Text Draw και ανοίγω μια ANSI εικόνα.

1660818241472.png


Πειράζω λίγο τα χρώματα (ας με συγχωρέσει ο Cleaner).

1660818409594.png


Την αποθηκεύω με όνομα αρχείου TEST.ANS.

1660818429302.png


Ο ANSI κώδικας του TEST.ANS που σώνει το Text Draw.

1660818724181.png


Ανοίγω την εικόνα στο PabloDraw για να βεβαιωθώ πως είναι οκ.

1660818812752.png
 
Τελευταία επεξεργασία:
1662379272854.png

Hobby BASIC 1.4.9

Μια νέα εντολή προστέθηκε, η DEF.

Η εντολή DEF χρησιμοποιείται για τον ορισμό συναρτήσεων μιας γραμμής.
Είναι κάτι ανάλογο με την DEF FN που υπάρχει στην GW-BASIC και στην QBASIC.
Για την ώρα είναι σε δοκιμαστικό στάδιο, εμπεριέχεται στον διερμηνευτή αλλά στο README δεν αναφέρω ακόμα τίποτα

Σύνταξη: DEF fname([arg,...]) = expression

Παράδειγμα.
Κώδικας:
    DEF perim(X,Y)=2*X+2*Y
    DEF mydef(X)=POW(X,2)+3*X+5

    print perim(2,2)
    print mydef(4)
 
1664358827612.png
Exceeded 100000 views in Flat Assembler forum.

Μια συλλογή από μκρά και πολύ απλά προγράμματα για την Hobby BASIC, όπως το 99 bottles of beer και παρόμοια τέτοια.
Τα είχα ξεχασμένα στον σκληρό δίσκο, οπότε και τα έβαλα σε ένα zip. Δεν συμπεριλαμβάνονται στο download της Hobby BASIC.
Είναι προγράμματα της Gillespie BASIC που τρέχουν με μικρές αλλαγές και στην Hobby BASIC.

Κώδικας:
 rem ********************************************
 rem             The Fibonacci Series
 rem ********************************************
 A=1
 B=1
 FOR Z=0 TO 40
    C=A+B
    PRINT A
    A=B
    B=C
NEXT Z

1664195509776.png
 

Συνημμένα

Τελευταία επεξεργασία:
1670757772470.png

1662379272854.png

Hobby BASIC 1.5.2

Ένα νέο update στον διερμηνευτή.

Κατά την διάρκεια κατασκευής του ZNAX διαπίστωσα κάποια minor bug στον διερμηνευτή όπως για παράδειγμα, η συνάρτηση GetVerion που δίνει λάθος πληροφορίες έκδοσης σε περιβάλλον Windows 10 και χρειάστηκε αντικατάσταση με άλλο API. Παρόμοιας δυναμικής ήταν και τα υπόλοιπα bug. Ασφαλώς bug θα συνεχίσουν να υπάρχουν, είναι λογικό σε οποιοδήποτε σχετικά μεγάλο project να αποτελούν μέρος του. Κάποια που ήδη γνωρίζω αλλά δεν έχω αποφασίσει την επίλυση τους και άλλα που περιμένουν να τα ανακαλύψω.

Διορθώθηκε και ένα bug της εντολής PROMPT που "έτρωγε" έναν χαρακτήρα.

Κώδικας:
    view 11
    screen 80,30,300
    color 0,7
    cls

    a$ = PROMPT('Hello','Please enter your name')
    if LEN(a$) > 0
        print 'Χαίρε ',a$
        pause
    endif
    end

1670760637078.png

1670760649397.png
 
Τελευταία επεξεργασία:
Ο Ledix είναι ένα παζλ τύπου Sokoban που έγραψα το 2005 και μετέφερα πρόσφατα στην Hobby BASIC χρησιμοποιώντας ANSI γραφικά στην κονσόλα των Windows. θα βρείτε τον κώδικα του παιχνιδιού στα συνοδευτικά προγράμματα του διερμηνευτή.

Σκοπός σας είναι να τοποθετήσετε τις μπλε σφαίρες στις σημειωμένες θέσεις στο πάτωμα.
Μικρά επίπεδα που μπορεί να γίνουν απολαυστικά δύσκολα να λυθούν.
Χρησιμοποιήστε τα βέλη του πληκτρολογίου για να μετακινηθείτε, κάθε δωμάτιο έχει λύση, θυμηθείτε το!
Πατήστε το πλήκτρο 1 για μετάβαση στο επόμενο δωμάτιο, 2 για προηγούμενο δωμάτιο.
Πατήστε Space για επαναφορά του τρέχοντος δωματίου.
Περισσότερα για το Ledix στο MobyGames.

1672139951735.png
 
Τελευταία επεξεργασία:
Φοβερα τα ansi γραφικα και η ολη υλοποιηση της hobby basic. Σε παλαιότερη εποχη, θα εκανε θραυση.

Respect, που λενε :)
 
Ναι ναι κάπως έτσι, ευχαριστώ xqtr :thumbup:

Mπορώ και τα δουλεύω ευκολότερα με το Draw, το σχεδιαστικό που έγραψα για αυτόν τον λόγο. Οι βασικές λειτουργίες του μου φτάνουν για να επεξεργάζομαι ANSI γραφικά. Θέλω να μεταφέρω και άλλα παζλ μου στην κονσόλα των Windows.
 
Τελευταία επεξεργασία:
Hobby BASIC.png

Hobby BASIC 1.5.3

Ένα νέο update στον διερμηνευτή, μεταξύ άλλων περιλαμβάνει και ένα νέο παζλ.

To Colorsok είναι ένα παζλ τύπου Sokoban που έγραψα το 2005 (υπάρχει online εδώ) και μετέφερα στην Hobby BASIC. θα βρείτε τον κώδικα του παιχνιδιού στα συνοδευτικά προγράμματα του διερμηνευτή.

Colorsok is a clone of an old Sokoban-style java game called 'Socolor'
Blocks of the same color need to be pushed all together.

Use keyboard arrows to move.
Press spacebar to reset current room.
Press 1 to skip to next room.
Press 2 for previous room.
Press 4 to undo a move.


HOBBY_BASIC_COLORSOK_PUZZLE.png
 
Έκλεψα λίγο χρόνο το Σαββατόβραδο που πέρασε και έγραψα το D-Star με την Hobby BASIC χρησιμοποιώντας ANSI γραφικά στην κονσόλα των Windows. Χαρακτήρες δηλαδή του extended ASCII σετ. Θα βρείτε τον κώδικα στα συνοδευτικά προγράμματα του διερμηνευτή, μέσα στον φάκελο GAMES. Καλά πήγε για τις λίγες ώρες που ασχολήθηκα. Η version που έγραψα το 2005 υπάρχει ακόμα online.

D-Star is a clone of an old puzzle game originally written for TI-83/84 calculator
The object of the game is to collect the yellow diamonds
You move all the way to the next wall with every move
You may use spacebar to switch your place with the red block
Try to clear the board in the least number of moves
You have 1024 moves limit to complete 10 mazes
Use keyboard arrows to move
Press spacebar to switch
Press 1 to restart room


HOBBY-BASIC-DSTAR.png
 
Τα γραφικα, δικα σου; Δεν δηλωνεις να γίνεις μελος των Blocktronics, Lazarus, Fire η άλλου ansi artists group; :)
 
Ναι στο συγκεκριμένο εγώ τα σχεδίασα, είναι απλά πραγματάκια, τουβλάκια, τοίχος, κτλ. Αυτοί είναι καλλιτέχνες και group που θαυμάζω και παρακολουθώ χρόνια, αλλά δεν μπαίνω στα χωράφια τους. Μένω σε αυτό που κάπως ξέρω και μου αρέσει περισσότερο να κάνω, να γράφω κώδικα. Με τα ANSI γραφικά έχω πάντως κόλλημα, είναι και ένας από τους λόγους που ξεκίνησα να γράφω την Hobby BASIC.
 
Hobby-BASIC.png

Hobby BASIC 1.5.4

Ένα νέο update στον διερμηνευτή.

Προστέθηκε μια νέα δυνατότητα, η ενολή SWAP με έξι παραμέτρους.

Κώδικας:
        swap x,y                              ! swap two variables
        swap a$,b$                            ! swap two strings
        swap a[x],b[y]                        ! swap twο array elements

        swap x,y,cols,rows,x1,y1              ! swap two rectangular areas of the screen   NEW

Με την πρoσθήκη της νέας μορφής της SWAP, η Hobby BASIC παρέχει 4 διαφορετικούς τρόπους για να ανταλλάξει 2 περιοχές της οθόνης. Είτε με τον λίγο πολύπλοκο (αλλά και πιο ευέλικτο) τρόπο της GRAB, είτε με τις εντολές BLOAD/BSAVE, είτε με την LIFO στοίβα οθόνης, και τέλος με την SWAP, τα παρακάτω κομμάτια κώδικα δίνουν το ίδιο αποτέλεσμα.


using GRAB method
Κώδικας:
        SCREEN_TO_ARRAY = 0
        dim array[80,r]
        grab 0,0,80,r,array[],SCREEN_TO_ARRAY
        grab c,0,c,r,array[],0,0
        grab 0,0,c,r,array[],c,0

using BLOAD/BSAVE
Κώδικας:
        A = 701
        B = 702
        bsave 0,0,c,r,A
        bsave c,0,c,r,B
        bload 0,0,B
        bload c,0,A

using the screen LIFO stack
Κώδικας:
        store 0,0,c,r
        store c,0,c,r
        restore 0,0
        restore c,0

using SWAP command
Κώδικας:
        swap 0,0,c,r,c,0

1676380957079.png

Τα προηγούμενα κομμάτια κώδικα δίνουν το ίδιο αποτέλεσμα.

1676380998249.png
 
Hobby-BASIC.png

Hobby BASIC 1.5.5

Ένα νέο update στον διερμηνευτή.
Μουσική και εφέ ταυτόχρονα στην Hobby BASIC.
Οι δυνατότητες ήχου επεκτάθηκαν και πλέον υποστηρίζονται και τα αρχεία mp3.
Οι ήχοι WAV φορτώνουν γρήγορα από την μνήμη (προτείνονται για τα εφέ ενός παιχνιδιού).
Τα αρχεία MP3 φορτώνουν απευθείας από τον δίσκο (προτείνονται για την μουσική ενός παιχνιδιού).

Μία εντολή πολλές λειτουργίες, ένα χαρακτηριστικό της Hobby BASIC.

Ας δούμε πως λειτουργεί η εντολή SOUND με ένα αρχείο ήχου WAV.

Αρχικά εκχωρούμε ένα αναγνωριστικό ID στον ήχο (το 700 είναι μια τυχαία τιμή).
Κώδικας:
    SFX1=700
    path$='ART\FX\SFX1.WAV'

Φορτώνουμε τον ήχο (στην μνήμη) και τον συσχετίζουμε με το ID. Αυτό συμβαίνει μία φορά μόνο.
Κώδικας:
    sound path$,SFX1

Για να παίξουμε τον ήχο μέσα από το πρόγραμμά μας οποιαδήποτε στιγμή.
Κώδικας:
    sound SFX1,1

η πιο απλά
Κώδικας:
    sound SFX1

Τα παραπάνω ισχύουν και για τα αρχεία mp3.
Στα mp3 (μόνο) υπάρχει διαθέσιμο το ακόλουθο σετ εντολών: 0 STOP, 1 PLAY, 2 REPEAT, 3 PAUSE, 4 RESUME

Το πρόγραμμα SOUND.BAS θα το βρείτε στον φάκελο EXAMPLES/MISC

Κώδικας:
    rem  SOUND.BAS
    rem  Hobby BASIC Interpreter
    rem
    rem  The audio features have recently been expanded and mp3 files are now supported
    rem  Short WAV files are loaded into memory fast (recommended for game sound effects)
    rem  Larger MP3 files are played directly from disk (recommended for game music)
    rem  In both cases, an ID value must be assigned first to the sound
    rem  MP3 only commands: 0 STOP, 1 PLAY, 2 REPEAT, 3 PAUSE, 4 RESUME

    THEME = 700
    SFX1 = 701

    rem  load and assign ID value to sfx and sound loop

    path$ = PATH("ART\FX\SFX1.WAV")
    sound path$,SFX1

    url$ = "https://dl.dropboxusercontent.com/s/swn8lepi6bhootw/loop5.mp3"

    get_file("loop5.mp3",url$)

    sound PATH("ART\FX\MP3\loop5.mp3"),THEME

    view 11
    screen 80,30,300
    cursor 0,0
    color 0,7
    cls

    print "Hobby BASIC Sound Programming"
    print
    print "MP3 Commands:"
    print "Press 0 to stop"
    print "Press 1 to play"
    print "Press 2 to play repeat"
    print "Press 3 to pause"
    print "Press 4 to resume"
    print
    print "Press Spacebar to play SFX"
    print "Press Esc to exit"

    main#

    inkey : k = V0

    if k = 27    rem  key Esc
        sound -1 : end
    elseif k = 32     rem  key Spacebar
        pen 14 : erase 6,9,8,-1,1
        sound SFX1
        wait 50
        pen 7 : erase 6,9,8,-1,1
    else
        k = k - 48     rem  convert keypress to integer
        if (k >= 0 and k < 5)      rem  check number range
            pen 7 : paint 0,0,30,10,-1,1
            pen 14 : erase 10,k+3,20,-1,1
            sound THEME,k
        endif
    endif

    goto main


sub get_file(name$,url$)
    local path$,temp$

    path$ = PATH("ART/FX/MP3/")+name$

    if SIZE(path$) = -1
        temp$ = PATH(1)
        if CHDIR(PATH("ART/FX/MP3/"),0)
            load url$,1
            CHDIR(temp$,0)
        endif
    endif
ends

1677979229260.png

Have fun with Hobby BASIC.
 
To coffee project της ημέρας (μάλλον το red bull project της νύχτας αλλά οκ).
Ένα Same Game γραμμένο στην Hobby BASIC για την κονσόλα των Windows.
Θα το βρείτε μέσα στον φάκελο EXAMPLES/GAMES

Κινηθείτε γρήγορα και φτιάξτε ματσάκια από ίδια χρώματα.
Κάντε αριστερό κλικ για να αντικαταστήσετε ένα πλακίδιο με το διπλανό του.
Πατήστε Spacebar για να συλλέξετε τα ματσάκια.
Πατήστε 1 οποιαδήποτε στιγμή για νέο πίνακα.

Move fast and make bunches of same colors
Left click to replace a position with its neighbor
Right spacebar to collect colored bunches
Press 1 to reset the board

1678535366604.png
1678535392778.png

Have fun with Hobby BASIC.
 
Πίσω
Μπλουζα