ADFLib et PureBASIC

Vous avez développé un logiciel en PureBasic et vous souhaitez le faire connaitre ?
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

ADFLib et PureBASIC

Message par djes »

Un ami vient d'acheter un lecteur USB Gotek pour remplacer son lecteur de disquettes Amiga. Seul problème, le lecteur ne lit que les ADF et les DMS, et les démos et intros nécessitent un environnement genre Workbench pour démarrer, ou de taper leur nom dans un shell/CLI.

Il m'a demandé de faire un petit convertisseur, pour créer automatiquement des ADF autoboot à partir de fichiers Amiga exe.

J'ai regardé du côté de l'excellente bibliothèque de fonctions ADFLib, mais je n'ai pas trouvé de DLL facile à utiliser en PureBASIC. Du coup j'ai légérement modifié les sources et le projet pour créer une bibliothèque statique directement utilisable en PureBASIC, grâce à Dev-C++.

Le résultat est donc la bibliothèque statique compilée adflib.a, et un exemple qui crée des ADF grâce à un modèle de fichier ADF en y copiant les programmes Amiga sélectionnés. J'ai aussi joint les fichiers projets pour Dev-C++.

Vous trouverez l'archive complète sur PBFrance (merci à GallyHC) :

http://www.pbfrance.com/?url=source&cmd=viewer&val=29

Voici le code d'exemple :

Code : Tout sélectionner

;*****************************************************************************
;
; 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);
; 
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: ADFLib et PureBASIC

Message par Backup »

il me semble qu'avec Total Commander , il existe un Pluggin qui peut creer/extraire de l'ADF

ici :
http://www.ghisler.com/plugins.htm
AmigaDX
3.6
2012/06/03 32+64 bit With this plugin you can extract/view ADF, DMS, ADZ, HDF, HDZ, DMP file types for Amiga Emulators (WinUAE, U*AE). You can also create/modify ADF files. If you are an old Amiga user who have installed WinUAE or other Amiga emulator then this plugin is for you. Source available.
mais , bon boulot quand meme
bien que ça risque d’intéresser peut de monde non ?
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: ADFLib et PureBASIC

Message par Micoute »

le principal est d'y prendre du plaisir ! non ?
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: ADFLib et PureBASIC

Message par djes »

Dobro a écrit :il me semble qu'avec Total Commander , il existe un Pluggin qui peut creer/extraire de l'ADF

ici :
http://www.ghisler.com/plugins.htm
AmigaDX
3.6
2012/06/03 32+64 bit With this plugin you can extract/view ADF, DMS, ADZ, HDF, HDZ, DMP file types for Amiga Emulators (WinUAE, U*AE). You can also create/modify ADF files. If you are an old Amiga user who have installed WinUAE or other Amiga emulator then this plugin is for you. Source available.
mais , bon boulot quand meme
bien que ça risque d’intéresser peut de monde non ?
Oui, je l'ai utilisé pour faire quelques essais. Le seul problème est que traiter quelques milliers de fichiers de la sorte devient un peu pénible... Pour le reste Micoute a raison ;)
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: ADFLib et PureBASIC

Message par Ar-S »

J'ai pas bien pigé, ça créé des ADF à partir de quoi, d'un lecteur physique de disquette amiga/usb ?
Il faut tout de même un emulateur genre WinUAE pour les lire ou pas, pas bien compris non plus ce amiga.exe ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: ADFLib et PureBASIC

Message par djes »

Non, sur Amiga, les démos et les jeux étaient parfois diffusés sous forme de disquettes plus ou moins cryptées, qu'on mettait dans la machine au démarrage, et parfois sous forme de fichiers. Le plus souvent c'était un seul gros fichier exécutable contenant tout, images, musiques et code.
Avec un disque dur, on peut facilement démarrer l'os, mettre tous les fichiers dans un dossier et les exécuter les uns après les autres. Sans disque dur, ou avec le lecteur Gotek, on est obligé de démarrer la machine avec une disquette d'amorçage (virtuelle dans le cas du gotek, c'est à dire un fichier adf ou dms), puis ensuite lancer le jeu ou la démo en cliquant sur son icône ou en tapant son nom dans une fenêtre de la console (genre dos ou ligne de commande).

Le programme d'exemple crée des disquettes virtuelles adf qui vont démarrer automatiquement et lancer la démo dans la foulée.
Pour l'utilisateur du lecteur gotek (ou de winuae), il suffira de sélectionner le fichier adf pour voir la démo correspondante sans avoir à rien faire.
Bon, en fait, winuae n'en a pas besoin, puisqu'il reconnaît les programmes Amiga dans avoir besoin de disquette de démarrage.
Je profite simplement de ce programme pour permettre à tous d'utiliser l'adflib, et donc de gérer les adf par code PureBASIC. Je sais que ça servira quand même à quelques utilisateurs, assez peu nombreux il est vrai.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Re: ADFLib et PureBASIC

Message par Flype »

Et bien moi je trouve ça super. En plus c'est propre.
Je préfère de loin la méthode Import que OpenLibrary.
Merci djes, je pense que ça peut me servir.
Image
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: ADFLib et PureBASIC

Message par Backup »

t'avais perdu l'adresse du forum ? :mrgreen:

nous aussi on trouve ça super ;)
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Re: ADFLib et PureBASIC

Message par Flype »

;-) Non, je la connais par coeur :)

Content de vous faire un coucou à tous. Toujours aussi actifs à ce que je vois !
Image
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: ADFLib et PureBASIC

Message par Backup »

c'est toujours sympath de revoir les Anciens :D

Image
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ADFLib et PureBASIC

Message par Ollivier »

Salut Flype, vraiment content de te voir aussi. J'espère que ça va. Moi, à part un intense mal de crâne inopiné, tout va bien, ça roule impeccable comme sur des chaussettes.

@DJ e/s

Excuse pour le hs, j'y connais rien aux Amiga. Mais là, c'était plus amigo qu'amiga.

Bon... Je vais me coucher...
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: ADFLib et PureBASIC

Message par djes »

Salut Flype :wink:

Ollivier> Pas de souci, nul n'est parfait :mrgreen:
Ps: J'ai commencé sur un PC un peu comme le tiens, maintenant il me sert d'ordinateur de bord pour ma ford "T"
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Re: ADFLib et PureBASIC

Message par Flype »

@Ollivier
Mon Amiga est largement plus puissant que ton PQ ;-)
Image
Avatar de l’utilisateur
SPH
Messages : 4945
Inscription : mer. 09/nov./2005 9:53

Re: ADFLib et PureBASIC

Message par SPH »

Flype a écrit :@Ollivier
Mon Amiga est largement plus puissant que ton PQ ;-)
Tu as quoi comme amiga ? Un peg ?

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Re: ADFLib et PureBASIC

Message par Flype »

Oh non, juste un 1200 avec une carte accélératrice 1230 à 50 MHz.
Une bécane d'origine, de 1992, ma préférée ;-) parfaite pour entretenir ma nostalgie.
Image
Répondre