Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
BASFILE - Converts small files to BAS code.
#1

ATTENTION: This program is now out of date and no longer needed to include files in compiled programs.  QB64PE now has a a built-in $EMBED command that does this.  I will leave the program posted here up for archival purposes and for those who have yet to update to the latest QB64PE, but I won’t be updating it anymore.



BASFILE is a utility I use often when wanting to put small files INSIDE my EXE programs.  It does this by converting the file to BAS code that, when run, will recreate the file.  This tool is helpful when wanting to distribute/post just BAS code instead of extra files with your program.  The BASFILE program will ask you for a file to convert and then for an BAS output filename to create.  The source is below. 

- Dav

Code: (Select All)
'=================
'BASFILE.BAS v0.25
'=================
'Coded by Dav for QB64PE 3.8, SEP/2023

'v0.25  - More friendly and purely dialog handled app now, no window.
'       - Added DIM line to output FUNCTION for OPTION _EXPLICIT users.
'       - Saves the encoded filename in output FUNCTION for information.

'======
'ABOUT :
'======

'BASFILE helps you include binary files INSIDE your QB64 compiled programs.
'It does this by converting file to BAS code that you add to your program
'that will recreate the file when you wish to use it.

'BASFILE will ask you for a file to convert, and will output the BAS code.

'=========================================================================

_ScreenMove _Middle: _ScreenHide

length& = 160 '<-- Length of data lines in output code. !! MUST BE DIV BY 4!!
'             Smaller number means shorter lines, but bigger output code.
'
'Make sure length& is divisble by 4.  If not, then adjust it so it is.
If length& Mod 4 <> 0 Then length& = length& - (length& Mod 4)
If length& < 4 Then length& = 4

cr$ = Chr$(13)
m$ = "BASFILE v.25 - Binary file to .BAS converter." + cr$ + cr$
m$ = m$ + "Converts a file to .BAS code to include in QB64 programs." + cr$
m$ = m$ + "BASFILE will first ask you for a file to convert, then it will" + cr$
m$ = m$ + "will ask you for a .BAS filename to create." + cr$ + cr$
m$ = m$ + "Proceed?"

If _MessageBox("BASFILE v.25", m$, "yesno", "question") = 0 Then System

IN$ = _OpenFileDialog$("Open File to encode...", "", "", "All files", -1)
If IN$ = "" Then
    _MessageBox "BASFILE v.25", "No file selected.  BASFILE will close.", "info"
    System
End If

m$ = "You selected: " + IN$ + cr$ + cr$
m$ = m$ + "Now select a .BAS filename to create."
_MessageBox "BASFILE v.25", m$, "info"

OUT$ = _SaveFileDialog$("Save Encoded file as ", "", "*.bas", "BAS files")
If OUT$ = "" Then
    _MessageBox "BASFILE v.25", "No filename given.  BASFILE will close.", "info"
    System
End If

m$ = "You have selected..." + cr$ + cr$
m$ = m$ + "Input file: " + IN$ + cr$
m$ = m$ + "Output file: " + OUT$ + cr$ + cr$
m$ = m$ + "Proceed?"

If _MessageBox("BASFILE v.25", m$, "yesno", "question") = 0 Then
    _MessageBox "BASFILE v.25", "Ok.  BASFILE will close.", "info"
    System
End If

'Grab whole file as a string
Open IN$ For Binary As 1
INDATA$ = (Input$(LOF(1), 1))

'Original size
OrigSize& = Len(INDATA$)

'Compress it
INDATA$ = _Deflate$(INDATA$)
CompSize& = Len(INDATA$)

Open OUT$ For Output As 2

INDATA$ = E$(INDATA$)

Q$ = Chr$(34) 'quotation mark
Print #2, "'==================================="
Print #2, "'EXAMPLE: SAVING BASFILE$ TO DISK"
Print #2, "'==================================="
Print #2, "'OPEN "; Q$; IN$; Q$; " FOR OUTPUT AS #1"
Print #2, "'PRINT #1, BASFILE$;"
Print #2, "'CLOSE #1"
Print #2, ""
Print #2, "Function BASFILE$()"
Print #2, "    'Returns decoded file as BASFILE$"
Print #2, "    'Encoded file: "; IN$
Print #2, "    DIM A$, c$, o$, btemp$, a&, j&, p&, oc&, i, i&, a, c&"
Print #2, "    A$ = SPACE$("; LTrim$(RTrim$(Str$(Len(INDATA$)))); "): a& = 1"
Print #2, "    Mid$(A$, a&, "; LTrim$(RTrim$(Str$(length&))); ") = "; Q$;

BC& = 1
Do
    a$ = Mid$(INDATA$, BC&, 4)
    BC& = BC& + 4: LL& = LL& + 4
    If LL& >= length& Then
        LL& = 0
        Print #2, a$;: Print #2, Q$; ": a& = a& + "; LTrim$(RTrim$(Str$(length&)))
        Print #2, "    Mid$(A$, a&, "; LTrim$(RTrim$(Str$(length&))); ") = "; Q$;
    Else
        Print #2, a$;
    End If
    If Len(INDATA$) - BC& < 4 Then
        a$ = Mid$(INDATA$, Len(INDATA$) - BC&, 1)
        a$ = a$ + Q$
        Print #2, a$;: Exit Do
    End If
Loop

Print #2, ""
Print #2, "    o$ = Space$("; LTrim$(RTrim$(Str$(CompSize&))); "): oc& = 1"
Print #2, "    For i = 39 To 125"
Print #2, "        If i <> 64 And i <> 96 Then c$ = c$ + Chr$(i)"
Print #2, "    Next: Dim v As _Unsigned Long"
Print #2, "    a = Val(Mid$(a$, 1, 1))"
Print #2, "    For i& = 2 To Len(a$) Step 5: v = 0"
Print #2, "        For j& = 0 To 4: p& = 85 ^ (4 - j&)"
Print #2, "            c& = InStr(c$, Mid$(a$, i& + j&, 1)) - 1"
Print #2, "        v = v + c& * p&: Next: Mid$(o$, oc&, 4) = MKL$(v)"
Print #2, "        oc& = oc& + 4"
Print #2, "    Next: btemp$ = Mid$(o$, 1, Len(o$) - a + 1)"
Print #2, "    BASFILE$ = _INFLATE$(btemp$, "; LTrim$(RTrim$(Str$(OrigSize&))); ")"
Print #2, "End Function"

_MessageBox "BASFILE v.25", OUT$ + " created!", "info"
System

Function E$ (in$)
    For i = 39 To 125 'Make 85 character set to use
        If i <> 64 And i <> 96 Then c$ = c$ + Chr$(i)
    Next
    Dim v As _Unsigned Long
    t$ = in$ 'make a working copy so in$ isn't changed
    If Len(t$) Mod 4 > 0 Then 'pad needed bytes on end
        a = 5 - Len(t$) Mod 4
        t$ = t$ + Space$(a - 1)
    End If
    out$ = Space$(Len(t$) * 1.25): outb& = 1
    For i& = 1 To Len(t$) Step 4
        v = CVL(Mid$(t$, i&, 4))
        For j& = 4 To 0 Step -1
            p& = 85 ^ j&
            r& = v \ p&
            v = v Mod p&
            Mid$(out$, outb&, 1) = Mid$(c$, r& + 1, 1)
            outb& = outb& + 1
        Next
    Next
    E$ = LTrim$(RTrim$(Str$(a))) + out$
End Function

Find my programs here in Dav's QB64 Corner
Reply
#2
Hi Dav,

I am a little confused by BASFILE.

Can I use it to do library .BI and .BM so I have only one source file to distribute?
Which seems practical, if possible.
b = b + ...
Reply
#3
This is great. looking forward to the related programs. I wanted to use a method like this for using sounds files to embed them in a program, extract them to a temporary directory and play them from there, but hadn't gotten to there yet. 

Using the created (converted)  files is very simple. Here's an program I made reading a small text file made with notepad and just reworking the file created in  BASFILE.

Code: (Select All)
'an example program that uses Dav's Basfile


Print unpackstring$

thestring:
Data ""
Data "hailDQbC\H5:9e::AQ<cCQ4E8]<c9E5B>aLb9eDD8h4c]PLBE_BZX4mhU[lb"
Data "_L5lDQ4cEQlb74G##0PH%%L2"
Data "/END"
' i added /END as a flag, I use it a lot for reading string data of variable length with the read statment

Print BASFILE$

Function unpackstring$
    a$ = ""
    Restore thestring
    Do
        Read in$
        a$ = a$ + in$
    Loop Until InStr(in$, "/END") 'stop at the endflag for the flag
    a$ = Left$(a$, (Len(a$) - 4)) 'take the endflag out of the string
    btemp$ = ""
    For i& = 1 To Len(a$) Step 4: B$ = Mid$(a$, i&, 4)
        If InStr(1, B$, "%") Then
            For C% = 1 To Len(B$): F$ = Mid$(B$, C%, 1)
                If F$ <> "%" Then C$ = C$ + F$
            Next: B$ = C$: End If: For j = 1 To Len(B$)
            If Mid$(B$, j, 1) = "#" Then
        Mid$(B$, j) = "@": End If: Next
        For t% = Len(B$) To 1 Step -1
            B& = B& * 64 + Asc(Mid$(B$, t%)) - 48
            Next: X$ = "": For t% = 1 To Len(B$) - 1
            X$ = X$ + Chr$(B& And 255): B& = B& \ 256
    Next: btemp$ = btemp$ + X$: Next
    unpackstring$ = _Inflate$(btemp$): btemp$ = ""

End Function
Reply
#4
bplus,

It lets you put a file in the program so the program can create the file onto disk.  You can stick a converted BM/BI file in the code and save it out while the program runs, but I'm pretty sure the program can't use it as a BM/BI file that way - those need to be accessible during the compiling process. 

James D Jarvis,

Yep that looks good.  Several members have made tools like this which are better than mine (SMcNeil & RhoSigma come to mind..).  I'll go ahead and post the BASIMAGE progam next.

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#5
I updated BASFILE in keep up with recent _INFLATE$ changes QB64-PE 3.8.  BASFILE now adds the extra _INFLATE$ parameter of the original file size to the output code.  Also BASFILE now uses the OPEN & SAVE file dialogs.  I recommend not using the older BASFILE versions and use this new one instead.

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#6
Thank you Dav, for the heads up. This routine will be useful.
Reply
#7
Thanks @Dav.

I wonder if I found a bug with the MacOS version of QB64pe.

I have compiled your program @Dav, but when it presents the dialog to pick a file to encode, I cannot choose anything.

I see you allow everything, so not sure...

@a740g any ideas?

[Image: Screen-Shot-2023-09-16-at-7.50.07-PM.png...gayo&raw=1]
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#8
Ahh maybe it is a bug because using no arguments besides the title, it allows me to choose files.

[Image: Screen-Shot-2023-09-16-at-7.53.13-PM.png...khhc&raw=1]

Changed to : `IN$ = _OpenFileDialog$("Open File to encode...")` and it works... odd.
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#9
OK I think there might be a bug in MacOS for this, for sure. Does passing "" work in Windows too @dav? Might want to do that way instead to make work everywhere if you like.

This works:
`IN$ = _OpenFileDialog$("Open File to encode...", "", "", "All files", -1)`

Note: passing `""` instead of `"*.*"`

@a740g FYI
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#10
(09-17-2023, 12:04 AM)grymmjack Wrote: OK I think there might be a bug in MacOS for this, for sure. Does passing "" work in Windows too @dav? Might want to do that way instead to make work everywhere if you like.

This works:
`IN$ = _OpenFileDialog$("Open File to encode...", "", "", "All files", -1)`

Note: passing `""` instead of `"*.*"`

@a740g FYI

Hmm, thats odd.  Well..Yes, your new way does work in Windows. too, so I will edit the source and put that way in instead.  Thanks for your report, @grymmjack, and coming up with a fix.

- Dav

Find my programs here in Dav's QB64 Corner
Reply




Users browsing this thread: 2 Guest(s)