BASFILE - Converts small files to BAS code. - Dav - 04-26-2022
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. I've also posted a modified program that displays my avatar image as an example of what you can do with BASFILE output.
- Dav
Code: (Select All) '==================
' BASFILE.BAS v0.21
'==================
'Coded by Dav for QB64GL 1.4, MAY/2020
'Fixed in v0.21: Replaced the @ symbol in encoded BAS output to a forum
' friendly character so code can be pasted in the QB64 forum
' without breaking it.
'Added in v0.20: Now uses _DEFLATE/INFLATE to make smaler output
'======
'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.
'=========================================================================
DEFINT A-Z
DECLARE FUNCTION E$ (B$)
PRINT
PRINT "============="
PRINT "BASFILE v0.21"
PRINT "============="
PRINT
INPUT "INPUT File --> ", IN$: IF IN$ = "" THEN END
INPUT "OUTPUT File -> ", OUT$: IF OUT$ = "" THEN END
OPEN IN$ FOR BINARY AS 1
IF LOF(1) = 0 THEN
CLOSE: KILL IN$
PRINT UCASE$(IN$); " not found!": END
END IF
'Grab whole file as a string
INDATA$ = (INPUT$(LOF(1), 1))
'Compress it
INDATA$ = _DEFLATE$(INDATA$)
OPEN OUT$ FOR OUTPUT AS 2
PRINT: PRINT "Encoding file...";
Q$ = CHR$(34) 'quotation mark
PRINT #2, "A$ = "; Q$; Q$
PRINT #2, "A$ = A$ + "; Q$;
BC& = 1
DO
a$ = MID$(INDATA$, BC&, 3)
BC& = BC& + 3: LL& = LL& + 4
IF LL& = 60 THEN
LL& = 0
PRINT #2, E$(a$);: PRINT #2, Q$
PRINT #2, "A$ = A$ + "; Q$;
ELSE
PRINT #2, E$(a$);
END IF
IF LEN(INDATA$) - BC& < 3 THEN
a$ = MID$(INDATA$, LEN(INDATA$) - BC&, 1): B$ = E$(a$)
SELECT CASE LEN(B$)
CASE 0: a$ = Q$
CASE 1: a$ = "%%%" + B$ + Q$
CASE 2: a$ = "%%" + B$ + Q$
CASE 3: a$ = "%" + B$ + Q$
END SELECT: PRINT #2, a$;: EXIT DO
END IF
LOOP: PRINT #2, ""
PRINT #2, "btemp$="; Q$; Q$
PRINT #2, "FOR i&=1TO LEN(A$) STEP 4:B$=MID$(A$,i&,4)"
PRINT #2, "IF INSTR(1,B$,"; Q$; "%"; Q$; ") THEN"
PRINT #2, "FOR C%=1 TO LEN(B$):F$=MID$(B$,C%,1)"
PRINT #2, "IF F$<>"; Q$; "%"; Q$; "THEN C$=C$+F$"
PRINT #2, "NEXT:B$=C$:END IF:FOR j=1 TO LEN(B$)"
PRINT #2, "IF MID$(B$,j,1)="; Q$; "#"; Q$; " THEN"
PRINT #2, "MID$(B$,j)="; Q$; "@"; Q$; ":END IF:NEXT"
PRINT #2, "FOR t%=LEN(B$) TO 1 STEP-1"
PRINT #2, "B&=B&*64+ASC(MID$(B$,t%))-48"
PRINT #2, "NEXT:X$="; Q$; Q$; ":FOR t%=1 TO LEN(B$)-1"
PRINT #2, "X$=X$+CHR$(B& AND 255):B&=B&\256"
PRINT #2, "NEXT:btemp$=btemp$+X$:NEXT"
PRINT #2, "BASFILE$=_INFLATE$(btemp$):btemp$="; Q$; Q$
PRINT #2, "'==================================="
PRINT #2, "'EXAMPLE: SAVE 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 "Done!"
PRINT UCASE$(OUT$); " saved."
END
FUNCTION E$ (B$)
FOR T% = LEN(B$) TO 1 STEP -1
B& = B& * 256 + ASC(MID$(B$, T%))
NEXT
a$ = ""
FOR T% = 1 TO LEN(B$) + 1
g$ = CHR$(48 + (B& AND 63)): B& = B& \ 64
'If @ is here, replace it with # to fix the
'problem posting code with @ in the QB64 forum.
'It wil be restored during the decoding process.
IF g$ = "@" THEN g$ = "#"
a$ = a$ + g$
NEXT: E$ = a$
END FUNCTION
Here is an example of using some BASFILE output. The code below decodes/loads an image to screen without extracting it to disk first to use, so the image data stays in the EXE. The companion program BASIMAGE makes this kind of image loader code automatically.
Code: (Select All) SCREEN _NEWIMAGE(150, 150, 32)
DIM m AS _MEM: m = _MEMIMAGE(0)
'decode screen memory...
A$ = ""
A$ = A$ + "haIkMf2NDld4479BTHAR49FT8AR59BTaR4ITHA69B\AR49FT8o;OOc\I[iZ]"
A$ = A$ + "fJV\Kb]g7QBDll`Mk]O<c_=m<MgC??i9?iomToaeKNe;6dkNm;gKje_l53ji"
A$ = A$ + "?kY32GSR>f?_AQ[R>o4jWOe;NnPn`KOEEGmU?nPdWNg[7TbG<SM\OnS2G5MJ"
A$ = A$ + ";fN4dWo`K7dg_lCEmkOnS1mgonW1mOogOW[bWOSnc_oEEolkOK#Gmi?<X?N3"
A$ = A$ + "KmAR_:j5?oI3:leS75^:J;hYgoVGEeGodk64HYol[OF5HWKnWkDP_H6kGohZ"
A$ = A$ + "1Qc=\;bf6En:<fiW2G55^:jDG:?1FZXOle??8UUF:?II\aOoOoc_7TbG5QaL"
A$ = A$ + "Qk]<Gac?5^:J;iY_lag>8`B<?Qil]FfI9LUbG51OL1njE_likdX_d2OMJZ`E"
A$ = A$ + "AkKFRSe7h9e_D3nVJ\?_>^KSM#`L<SPaVScc?onG[2O6kC[K?f[[27;la5kW"
A$ = A$ + "O<VNU_2S5^:LeS;5^:J[h98h[8`Cojj_?8f7EEF1\39`GEfiZ_FeeGMiDm]M"
A$ = A$ + "273c_gZ[9=mLbcA5lU6Cl<V[`EQ[>_5JWOk=fk:RmYM?N2ZjKYKVKFA8nc5Q"
A$ = A$ + "nGH7Uo^;_YooBR1`e_8fVFAhg`c7D_?HV]5OEDRGMhZ`EWGRKWAOY;?GVaC8"
A$ = A$ + "^MSONAJ>\`nm6OfG_hM3RIF8HORoM#?KD_l6>X8<6mRV=fNVa67C?la6cc]h"
A$ = A$ + "[`HQ[2GMJZ`EQ[f2NR7;36WCUULSQAle4O<>N#So;^6<?YS13mc5m\Wnd1YW"
A$ = A$ + "?V?`eogojj1YnjRiO>^C]h[<V[`EQ[>=d<oWOCk:Tj3M^O1nV2Og?nfG64WW"
A$ = A$ + "ijeRkkA\Qal1Mf1aa0KU5QhLScYJGM`fZV?Qlm]hOOf7HhI`Ucl9?K2G5^jh"
A$ = A$ + "bB\#Kig_lRZZS=gH71m5`?h`N6\CETN^In0<Sj[:fWDhnPmg>l56j_Oi=S[_"
A$ = A$ + "8fn=4HFff\6OB>VU]h;Ua::lEhZ`EQ[2GMn9dF`]?khYkN>O^lc4n<2mUleC"
A$ = A$ + "W?YKm`kRSc5_o=32SCRi:dWc7OAlj0Jfk:S\HAmh:T??8nehJeJ<G<Om_<S5"
A$ = A$ + "^:LeF`CJ>^`cib5cfMcIjjI2mcPWPo_inJhG8L=HK\P7EOFETnI>kW87J`iS"
A$ = A$ + "c56=gmH>H9i>_bG3<fhcB;njOAKSQ[2G]5\4N^EFbaCjjLQma3KS4L5\mX\T"
A$ = A$ + "CC\1>bEmlOEUE^H^HKS5aa7\>VnaH7bi^gJFoRLN8Rf0H?EGSR>M\IP`EQ[>"
A$ = A$ + "eUkiC[UIL>7h6CN[e_`TeXgHO8h9]ONX_F6S^S?LSK72OWc>84HFf>84jkal"
A$ = A$ + "0:BmknBG3fk\=>U_Li3aSA6;LEhZ`EQ[>eE;FJPW6I0`B<kX[;MW?eA^`acW"
A$ = A$ + "Ci9dob7SZNLE?inMcHFRWZafNliV_7`l8achB6WE?nZGNflHXNS4^:LeF`CH"
A$ = A$ + "n>8OGhi7QJb9J;MebCGNSDS1hHO1O>QDKOLkLG^JT1P?iMl4^6;Q[Le:IU_^"
A$ = A$ + "]]HL]C?^nLL]5;R_TH:b<Vc^hiFn16^:LeFHc3nXAiY9ai3lTY>9\4^bEW3F"
A$ = A$ + "ToZ46da7:Wan[bI73BIGnjZSOW_7#K2NGKBmTHUeCYFnhZgJb0mGWRSY?LEh"
A$ = A$ + "Z`EQ[>ei:mN[8d?3oYhb5_FS=H:?MKlEIN4S5AI9N<;:;=9fbM63TjC[NcO\"
A$ = A$ + "gHfLLU^61Mbi_=d6h6WejlaedHEk6c5g7N\i[`EQ[fBNR]71NZngb5oBibQ]"
A$ = A$ + "NaF6f7:2]ghJ=afRT_:]\m=83?EI2:WkZJ<?0A>ein^F7KAeLF^^n\9oG1>J"
A$ = A$ + "lnfmNdmM>Rggi:N\ZCBQ[2G]_I9njZ\d4NZgnG4hYaSIBMlAfo6hJ^X>nIGn"
A$ = A$ + "0[n3b=^oNZGl9M_SDS;`hm_kLf:nV\Z[9JcWe;WQLe8>]]_f>gImEco]QFle"
A$ = A$ + "F`HQ[2G5^:LeY>Ge=?GThbDD[W9FefgajPQ;_?aHAnf5__:egBL<Fdj;<?o6"
A$ = A$ + "84cEgcYN<\dS5i>?[Fe]8^f5ilETV;>lcKMm3=n>k\jL:9gkAcGSUkb?N`E^"
A$ = A$ + "HRY]UKA>c7^:LenT[FDN^dI=c0^Bok^3o]gAKF8Gdic=F?=mZQImh3Emnm;E"
A$ = A$ + "hLQHeRed<;UWjMOjh_NGOgk8J^bSf=NM;b[?jR0WFDM^ZVJl<jOMi<o3U_2G"
A$ = A$ + "5^JOaE>KN^mK=gH<[n5Iln5gohifI?J=laBUN>i[SngdMe#1^OAkOP]:]oRU"
A$ = A$ + "^6Win2\G;ee6;E?907kn>XedF`2WKlnl4KZSSY1nHcEG8FS?^2G5^:LEhZCM"
A$ = A$ + "^BmG1kK:`BL]\Gm_2cL:kdKl3K1?]TaKDG?ldmmUMdRbWV6iMZCLoTbN;U;f"
A$ = A$ + "G2l5?WDMNTL<YdhnPfk`EQ[fJ^Bo>gJ67\4?O^Z_`7o^]d?omH8nc0?36bEo"
A$ = A$ + ">D>aa>;9GJJ^FlGH>h`nM3l5N?NY_gMOH^NWKnm_FcY_8<WAdVjNO8LEhZm5"
A$ = A$ + "GiRcG]nKHFW8mRU5>g7:fAI8N<hcbMV5`9flaSnKnZLiNG;ekgg;G3IOim#H"
A$ = A$ + "Xe:^]4LU;_;1OQkGT_iQ[2G]5L5[IkaJDLj#LTZaYO<FN51kOJ];o#9ln0og"
A$ = A$ + "^eh[i\CYmmL^B<GO[SL7g]oO^=DGC4hHV>WnYO6Gk6ZcmI1nD#I`kb76jnTa"
A$ = A$ + "4kPMF_6hk2G5^:LEhZ73L5n>GlSgUWJcGG<J]ll#aCX=#gKC;Z6?e>[iUiSW"
A$ = A$ + "Jgn<WVWi^mWImM]YiaglJNJ[O_K\ZJKKAZ?0GBKdBm5_:NLgmbQNlMQ[2GM\"
A$ = A$ + "h:=7PMi2fTmWm>LeQ`Wj`W?CZ97`NghlIQm#VS`WiZIJEoeIFgamTV_dmbWH"
A$ = A$ + "ggYfOI^BcEXmEkWkLaLeBFK?Q[2GMdh:3?=[FVALUFGcfJkOJkB]n:#agCcM"
A$ = A$ + "fNiZPVORlJ:4f<kaB^eoG;oW[[cA]n<dc?Q?di5Y<Tc69>6^oM9[Aa`EQ[2G"
A$ = A$ + "5^ja4GiF?kjlMji[W3ELW1chR1B]NM<^fELgWJ^L?Y^K8Ogdl2b_WYhl5Vco"
A$ = A$ + "E:_dcWHlkdH\O^L<J=aVFm36kg:TOn^eMHhZ`EWbLeTh;:n_RkODO]`c[jHa"
A$ = A$ + "EEkHbjNVm]M_lMA[G#<GEk[7KC\<K7OhgK=AgjH;2nTcaCJnB^F^27SjcZkZ"
A$ = A$ + "fR\Vi36^:LeF`Efego\J:`e4S9akR\7\4O`g[]0?g8GHh_[VSoM\3eJ?RHX^"
A$ = A$ + "[;SKfi;NLnhnN=NI>OY[nbW_7de_WSSLmUXMfa5]lYnB]ARkKG=Y^Wm?=?I`"
A$ = A$ + "cHhZ`EQ[2GMFcE^JNSD?LhH]f;f3#^lYo^h\RdmiI>?61OhReRFCodl#aYNn"
A$ = A$ + "XRONefKgHALeEYMjfk=MM1DD_n#LlH<#LnhSfTNnXB5cj[I^OCb_mafE7?5^"
A$ = A$ + ":LeQP[LkoA]ZgWgZYcAdaE86_^ehL;OnbL5H87G];GFVc1jl\hi3ZnCJbk=R"
A$ = A$ + "mNGMD[glSj=^1MnT]ZAKZ`m9j3ifGegF;InPLKQF7YL?CjJ`Q_^JmI9LEhZ]"
A$ = A$ + "V[dhT=YOB6?gD6KjHFmiX;FSogVgLleMFM7Pl7SjS:G=J7laBkkGSL_CY]g?"
A$ = A$ + "d[Q[?\WM#W=mFc?R[36`VIUU`nkQ97SM[i6eV7cCJ=R;LEhZ`EQ[>Gh:GM^d"
A$ = A$ + "Ug8^aPd<VdVLXYeh]haLi670n>7GQ?cM_iJO^?<PkmX7:WLO_Gj5coFcgV7?"
A$ = A$ + "j^im>Mo#a=gfNciSceXFke9Q[2G]5LUKn2hHhjW3H0e^HAmm5oDkP>>3a6fE"
A$ = A$ + "kRef4ng1KZcVW5I_N]miZdWaebE?Dan#4m_hnPW?W>gJ]nicmIfJknXFB]8J"
A$ = A$ + "]k9CQ[2G]5LE;nR]=jZ[J;9_UW_VOKWK9ljhCGke>OZkRYeJhZMn7RlaT\VT"
A$ = A$ + "h_K9lenJ<mlH[e[kTj_>JO`j#gl^F_mR2llZ\Tc7jgglf<LEhZ]P[j=VNL^i"
A$ = A$ + "ln_7OY?O^eOh<nRnkkhi\G\kLnZ^5kh4nmm^WLiAL_mPVm6GeiM5G<?Vi3o>"
A$ = A$ + "ahU[a6]\iamik[L;?LEhZ`EQ[>Gh:FjiV]g>S_<kcK]6gUO\GcmG_6[Hf_cF"
A$ = A$ + "O4QaUHlodlh4d^fLhZKO:[a_7POWNmg7Le\L\dd>?kM63GQkaNcic=NZm9?5"
A$ = A$ + "^:LeQH=kaomAEfi:fH?HdaJcmeUFcbV^7^S?[W]]NB]WblA[lJVWg:no;a_I"
A$ = A$ + "[ef8>FgNHUe6GSlbcmNTK>O]\iMXZYeQ[2GMXi;gHjKUSPCHZ>[=aFl5;GoU"
A$ = A$ + "NMjaE>NF]oi_fccoiFcKH]foL\o\WU5<_1ff^^G5ibIhS1;5^:LEhZ`EWSL5"
A$ = A$ + ";\OWQk9No?ASoiBjWW6[VYmQ^aldMlEBk=ccJmnHbn1P\>jMiW^SedL#I]lD"
A$ = A$ + "_a7^4OaYS;SK_>GhY`EQ[>Ff61OYeW\Uj?YInRg\FOLf5JIcPIf9eA=EcZK8"
A$ = A$ + "6OZ9[=A>gPEOc_di3ZnVbaEmnmjk<KIlS3G5^jLV[F2OY[eQQj4_`0^adk6o"
A$ = A$ + ">Jk\eKnk`OBFK>6OCk\a<kgKhIM?oL]LeJ^n\mmSELn2G5^:LEhZ`ENYkOV^"
A$ = A$ + "J2L=_?=aZFWGhTaF9kGjCleCSHOd[?eaL^iXRk=GokB?ogeeME_?lWMijna>"
A$ = A$ + "naQ[2GmH#hI2i9X[NV_K>DccG5Gnf]c?Fc]AfZVN`i;NCONamGVh>3]6F]7["
A$ = A$ + "dcFWC`V;?FR7;ci;LEhZC9Yl5cH:OaLQOMl<e7l^nNml`fHenEKOXh?9f>M_"
A$ = A$ + "JjC?VYga\6NR7;aiToc3G5^jLAQ[2GM8h[R#=Nc=GaFl5W7l^hYXnfb]^FGc"
A$ = A$ + "HPNXbaE^acY7?kK<LOgRUnGVW2G5^j#cH8OKhi:Rl\YbBlndjEGfD]b1`NiP"
A$ = A$ + "gF:;Ge8Glh_S_Oem0?lnHAQW2G5^jh`GHoK\8=^Rm6K^M<m;PgLn=CG[#^nl"
A$ = A$ + "U`A>KMch9bWJm6K^^GMn_R_Y2G5^jDF^lP0R[OTml_`lH8fnH\O7nML=K#T;"
A$ = A$ + "W3jUGN]h:nkDNRO7CiYSModiV2G5^:LEhZcAeR_:2kS9XVnibmmk[de?XkHL"
A$ = A$ + "caD[YOjoWi:<f=foJ:?aech`CQ[2GMN8=_0IYlEA]Z?JmZY8>oPYeHTNaNTU"
A$ = A$ + "enWTWemRcWF?k2?5^:LeiWL[93dGlUbn\kXjUcO]I]i<SCJN?g]F2ITbCLlm"
A$ = A$ + "^?e5mX`EQ[>=EhZX35SifS>em4]:G<FgT:JF^g#O76OV;6AJ^gkZG#]H97?M"
A$ = A$ + "OgG#R2G5^jlCX_PgobJ5_JgJ<dE[CGRZn=gXMn_JJ>^`a?f]6o>f]UAQ[R>\"
A$ = A$ + "l5gGQmi^eFG8j>fkE`C`N<k_=MN77kf]X`EAQ[2GmhCJOG]NWbkYQ=ZEcJ^_"
A$ = A$ + "dDB>NjFc<J>NF4n\SMKDDhZXC;eR_6V[hH=4M;T;?GJ]Wa7MnY`EA72nb]6Q"
A$ = A$ + "gWZ5?M\OnS2G5MnX`E7FmoAY%%L2"
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
BASFILE$ = _INFLATE$(btemp$,m.SIZE): btemp$ = ""
'Load to screen memory
_MEMPUT m, m.OFFSET, BASFILE$
_MEMFREE m
SLEEP
RE: BASFILE - Converts small files to BAS code. - bplus - 04-26-2022
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.
RE: BASFILE - Converts small files to BAS code. - James D Jarvis - 04-26-2022
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
RE: BASFILE - Converts small files to BAS code. - Dav - 04-26-2022
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
|