He asked me to make a tool to create autoboot adf files to launch automatically these files, from his large collection of demos and intros.
I found the nice ADFLib from Laurent Clevy, but had some problems with the adflib.dll I found on the internet, so I downloaded the source and built the needed static lib thanks to the great Dev-C++ by BloodSheedSoftware. I converted some headers to use it directly from PureBASIC.
The result is a little example on using the ADFLib in PureBASIC.
The static library is included so anybody should be able to use it directly in PureBASIC. Just inspire yourself with the included source.
I've not converted all headers and functions, but it wouldn't be too difficult.
Here you can found the whole zip package : http://www.pbfrance.com/?url=source&cmd=viewer&val=29
Below the example source.
Code: Select all
;*****************************************************************************
;
; ADFLib for PureBASIC example
; Creates ADF files from a master and copy exe files from a source directory.
;
; (C)opyright J. Benoist (djes) on 2014
;
; ADFLib documentation is in the main ADFlib-master directory.
;
; Notes :
; Beware of non-checked headers !
; C sources modified strdup->_strdup to avoid msvcrt dependancy
; Static library .a created, no dll needed.
;
;*****************************************************************************
IncludeFile "incpb\adf_str.pbi"
IncludeFile "incpb\adf_blk.pbi"
EnableExplicit
Import "adflib.a"
adfEnvInitDefault()
adfEnvCleanUp()
adfInstallBootBlock(*vol,*code) ;PREFIX RETCODE adfInstallBootBlock(struct Volume *vol,uint8_t*);
adfMount(*dev, nPart.i, readOnly.i) ;PREFIX struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly );
adfUnMount(*vol) ;PREFIX void adfUnMount(struct Volume *vol);
adfVolumeInfo(*vol) ;PREFIX void adfVolumeInfo(struct Volume *vol);
adfMountDev(filename$, readOnly.i) ;PREFIX struct Device* adfMountDev( char* filename,BOOL ro);
adfUnMountDev(*dev) ;PREFIX void adfUnMountDev( struct Device* dev);
adfCreateFlop(*dev, volName$, volType.l);PREFIX RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType );
adfDeviceInfo(*dev) ;PREFIX void adfDeviceInfo(struct Device *dev);
adfCreateDumpDevice(filename$, cylinders.l, heads.l, sectors.l);PREFIX struct Device* adfCreateDumpDevice(char* filename, int32_t cyl, int32_t heads, int32_t sec);
adfToRootDir(*vol) ;PREFIX RETCODE adfToRootDir(struct Volume *vol);
adfCreateDir(*vol, parent.l, name$) ;PREFIX RETCODE adfCreateDir(struct Volume* vol, SECTNUM parent, char* name);
adfChangeDir(*vol, name$) ;PREFIX RETCODE adfChangeDir(struct Volume* vol, char *name);
adfParentDir(*vol) ;PREFIX RETCODE adfParentDir(struct Volume* vol);
adfRemoveEntry(*vol, parent.l, name$) ;PREFIX RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM pSect, char *name);
adfGetDirEnt(*vol, parent.l ) ;PREFIX struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect );
adfGetRDirEnt(*vol, parSect.l, recurs.l ); PREFIX struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM nSect, BOOL recurs );
printEntry(*entry) ;PREFIX void printEntry(struct Entry* entry);
adfFreeDirList(*list) ;PREFIX void adfFreeDirList(struct List* List);
adfFreeEntry(*Entry) ;PREFIX void adfFreeEntry(struct Entry *);
adfRenameEntry(*vol, oldDir.l, old$, newDir.l, new$) ;PREFIX RETCODE adfRenameEntry(struct Volume *vol, SECTNUM, char *old,SECTNUM,char *pNew);
adfSetEntryAccess(*Volume, parent.l, name$, newAcc.l) ;PREFIX RETCODE adfSetEntryAccess(struct Volume*, SECTNUM, char*, int32_t);
adfSetEntryComment(*vol, parSect.l, name$, newCmt$) ;PREFIX RETCODE adfSetEntryComment(struct Volume*, SECTNUM, char*, char*);
adfOpenFile(*vol, name$, mode$) ;PREFIX struct File* adfOpenFile(struct Volume *vol, char* name, char *mode);
adfFlushFile(*file) ;PREFIX void adfFlushFile(struct File *file);
adfCloseFile(*file) ;PREFIX void adfCloseFile(struct File *file);
adfFileRealSize(size.l, blockSize.l, *dataN, *extN);PREFIX int32_t adfFileRealSize(uint32_t size, int blockSize, int32_t *dataN, int32_t *extN);
adfReadFile(*file, n.l, *buffer) ;PREFIX int32_t adfReadFile(struct File* file, int32_t n, uint8_t *buffer);
adfEndOfFile(*file) ;PREFIX BOOL adfEndOfFile(struct File* file);
adfWriteFile(*file, n.l, *buffer) ;PREFIX int32_t adfWriteFile(struct File *file, int32_t n, uint8_t *buffer);
adfFileSeek(*file, pos.l) ;PREFIX void adfFileSeek(struct File *file, uint32_t pos);
EndImport
;*****************************************************************************
Procedure TheEnd(Msg$)
MessageRequester("Error", Msg$, #PB_MessageRequester_Ok)
End
EndProcedure
;*****************************************************************************
Define ExeFilename$, Dest$
ExeFilename$ = OpenFileRequester("Please choose some exe files","","Exe files|*.exe|All files|*.*", 0, #PB_Requester_MultiSelection)
If ExeFilename$ = ""
TheEnd("No file selected...")
EndIf
Dest$ = PathRequester("Please select ADFs destination directory", GetPathPart(ProgramFilename()))
If Dest$ = ""
TheEnd("No destination choosen...")
EndIf
While ExeFilename$
Debug "---------------------------------------"
Debug "Processing file " + ExeFilename$
Debug " to dir " + Dest$
Define *dev.Device, *vol.Volume
Define NewADFFilename$
Define *file.File, Length.l, *MemoryID, bytes.l, written.l
NewADFFilename$ = Dest$ + GetFilePart(ExeFilename$) + ".adf" : Debug "New ADF file to create : " + NewADFFilename$
If CopyFile("MasterA500-1200.adf", NewADFFilename$)
;Master could also be created with things like this, but it wouldn't be so easily customisable by user.
;*dev = adfCreateDumpDevice("newfloppy.adf", 80, 2, 11)
;adfCreateFlop(*dev, "empty", #FSMASK_DIRCACHE )
Debug "Copying master file"
adfEnvInitDefault()
*dev.Device = adfMountDev(NewADFFilename$ , #False);
*vol.Volume = adfMount(*dev, 0, #False);
adfRemoveEntry(*vol, *vol\curDirPtr, "Intro.exe") : Debug "Removing original intro.exe file"
*file = adfOpenFile(*vol, "Intro.exe", "w") : Debug "Creating new intro.exe"
If *file <> 0
If ReadFile(0, ExeFilename$) : Debug "Opening original exe file"
Length = Lof(0) ; Lit la taille en octets du fichier
If Length <> 0
*MemoryID = AllocateMemory(Length) : Debug "Allocating exe memory : " + Str(Length) + " bytes"
If *MemoryID
bytes = ReadData(0, *MemoryID, Length) : Debug "Copying exe from original path"
If bytes <> 0
written = adfWriteFile(*file, Length, *MemoryID) : Debug "... to ADF."
If written <> bytes
MessageRequester("Error", "Something wrong occured while writing " + ExeFilename$ + " in the ADF", #PB_MessageRequester_Ok)
EndIf
Else
MessageRequester("Error", "Can't read " + ExeFilename$ + " content", #PB_MessageRequester_Ok)
EndIf
Else
MessageRequester("Error", "Can't allocate " + Str(Length) + " bytes for " + ExeFilename$, #PB_MessageRequester_Ok)
EndIf
Else
MessageRequester("Error", ExeFilename$ + " is empty...", #PB_MessageRequester_Ok)
EndIf
Else
MessageRequester("Error", "Can't open " + ExeFilename$, #PB_MessageRequester_Ok)
EndIf
adfCloseFile(*file)
Else
MessageRequester("Error", "Can't create Intro.exe in the " + GetFilePart(ExeFilename$) + " adf file", #PB_MessageRequester_Ok)
EndIf
adfUnMount(*vol)
adfUnMountDev(*dev)
Else
TheEnd("Can't copy master file 'MasterA500-1200.adf' to '" + ExeFilename$ + ".ADF'")
EndIf
adfEnvCleanUp()
ExeFilename$ = NextSelectedFileName()
Wend
Debug "--- END"
MessageRequester("Information", "Done.", #PB_MessageRequester_Ok)
End
;--- Feel free to try these others functions
; *cell.List = adfGetDirEnt(*vol, *vol\curDirPtr);
; *List = *cell
; While *cell
; *Entry.Entry = *cell\content
; If *Entry\type = #ST_DIR
; Debug *Entry\name$ + "/"
; Else
; Debug *Entry\name$
; If *Entry\name$ = "Intro.exe"
; adfRemoveEntry(*vol, *vol\curDirPtr, *Entry\name$)
; adfRenameEntry(*vol, *vol\curDirPtr, *Entry\name$, *vol\curDirPtr, "Test")
; *file.File = adfOpenFile(*vol, *Entry\Name$, "rw");
; adfFlushFile(*file)
; adfCloseFile(*file)
; EndIf
; EndIf
; *cell = *cell\Next;
; Wend
;
; adfFreeDirList(*List);
;