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
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.
- 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