i needed a PBI include for the new FMOD version. After searching the forum & the Web, it seems that no satisfying tool is available.
I know the not anymore maintened SDK Header Converter but it dont' process enough for the PB V5.x.
Anyway, i have try my luck coding and i end up with something enough advanced for FMOD include & my immediate needs.
Note that some additional work is necessary after the conversion.
The code is rather straightforward but if asked, i could rework the comments part.
Hopes it help someone.
Code: Select all
;======================================================================
; Programm: C Include to PB Converter
;
; Author: Starwolf20
; Date: 2015-10-09
; Version: 0.1
; Target Compiler: PureBasic 5.31
; Target OS: Not tested
; License: Free, unrestricted, no warranty whatsoever.
; Use at your own risk.
; Feel free to modify for your needs.
;======================================================================
; This script is intended to facilitate the conversion from C Include Header to PureBasic Pbi.
; Note that the result still need some work, hopefully 1 ot 2 minutes will do.
;
; The script process Comments, Define, Structure, Enumeration and Prototype declarations.
; Each type of declarations is processed by one pass and stored in array for later use.
; The last step produce a procedure who explain the value of enums.
;======================================================================
EnableExplicit
;==================================================================================================== Parametrage du Traitement.
Global Header_Fnamed$
Global DLL_ShortName$
Global DLL_x32Path$
Global DLL_x64Path$
Global GTabSet
;==================================================================================================== Enregistrement des resultats.
;--- Tableau des Prototypes.
Global Dim PB_DLL_Init$(1000)
Global PB_DLL_Init_Cpt.l = 0
;--- Tableau des Structures.
Structure Struct_PB_Structure
Structure_Name$
Structure_RubriqueName$
Structure_InitialRubriqueName$
Structure_RubriqueType$
Structure_RubriqueComment$
EndStructure
Global Dim PB_Structure.Struct_PB_Structure(1000)
Global PB_Structure_Cpt.l = 0
;--- Tableau des Defines.
Structure Struct_PB_Define
Define_Name$
Define_Value$
Define_InitialValue$
Define_Comment$
EndStructure
Global Dim PB_Define.Struct_PB_Define(1000)
Global PB_Define_Cpt.l = 0
;--- Tableau des Enum.
Structure Struct_PB_Enum
Enum_Name$
Enum_ItemName$
;Enum_InitialValue$
Enum_ItemComment$
EndStructure
Global Dim PB_Enum.Struct_PB_Enum(1000)
Global PB_Enum_Cpt.l = 0
;==================================================================================================== Declarations et Macros.
Declare IsStructure(StructureNameToTest$)
Macro M_Open_INOUTFile(LastCall = #False)
Protected IxFileResult, IxFileSource
If LastCall = #False : IxFileResult = CreateFile(#PB_Any, Right("00" + Str(NEtape), 2) + Header_Fnamed$)
Else : IxFileResult = CreateFile(#PB_Any, Header_Fnamed$ + "_Final.pbi")
EndIf
If IxFileResult = 0
Debug #PB_Compiler_Procedure + ": PB ouverture du fichier Source - " + Header_Fnamed$
End
EndIf
If NEtape <= 1 : IxFileSource = ReadFile(#PB_Any, Header_Fnamed$)
Else : IxFileSource = ReadFile(#PB_Any, Right("00" + Str(NEtape - 1), 2) + Header_Fnamed$)
EndIf
If IxFileSource = 0
Debug #PB_Compiler_Procedure + ": PB ouverture du fichier Source - " + Header_Fnamed$
End
EndIf
EndMacro
Macro M_Close_INOUTFile()
CloseFile(IxFileSource) ; Ferme le fichier précédemment ouvert
CloseFile(IxFileResult)
EndMacro
;==================================================================================================== Fonctions diverses.
Procedure.s Suppr_Comments(HLine$)
; Suppression des commentaires entre "/*" et "*/"
Protected DPos, FPos
Repeat
Dpos = FindString(Hline$, "/*")
FPos = FindString(Hline$, "*/")
If DPos = 0 Or FPos = 0
Break
Else
HLine$ = Left(Hline$, DPos - 1) + Right(Hline$, Len(Hline$) - FPos - 1)
EndIf
ForEver
ProcedureReturn Hline$
EndProcedure
Procedure FindString_Comment(HLine$, FString$, PositionDepart = 1, Mode = #PB_String_CaseSensitive)
; Recherche dans la chaine de caracteres en excluant les commentaires entre "/*" et "*/"
Protected DPos, FPos
Repeat
Dpos = FindString(Hline$, "/*")
FPos = FindString(Hline$, "*/")
If DPos = 0 Or FPos = 0
Break
Else
;Debug "$$" + Left(Hline$, 300)
HLine$ = Left(Hline$, DPos - 1) + Space(FPos - DPos + 2) + Right(Hline$, Len(Hline$) - FPos - 1)
;Debug "$$" + Left(Hline$, 300)
;Debug "tttttttttttttttttttttttttttttttttttttttttttttttttttttttt"
EndIf
ForEver
ProcedureReturn FindString(HLine$, FString$, PositionDepart, Mode)
EndProcedure
;==================================================================================================== Initialisation.
Procedure ConvertPass_Initialisation(NEtape, Header_Fnamed$)
;--- Preparation du fichier initial par l'ajout d'un Tag (3 caracteres) de ligne.
Protected HLine$
M_Open_INOUTFile()
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Lit le fichier Source ligne par ligne
If Trim(Hline$) = ""
WriteStringN(IxFileResult, "COM;") ; on garde la ligne blanche comme commentaire
Else
HLine$ = ReplaceString(HLine$, Chr(9), " ") ; Elimination des Tabulations eventuelles
WriteStringN(IxFileResult, "???" + Hline$) ; Affiche ligne par ligne le contenu du fichier
EndIf
Wend
M_Close_INOUTFile()
EndProcedure
;==================================================================================================== Commentaires.
Procedure ConvertPass_Comment(NEtape, Header_Fnamed$)
;--------------- Etape - Traitement des blocs de commentaires.
Protected Flag_CommentBloc
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$
M_Open_INOUTFile()
Flag_CommentBloc = #False
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Affiche ligne par ligne le contenu du fichier
Hline_Tag$ = Left(Hline$, 3)
Hline_Text$ = Right(Hline$, Len(Hline$)-3)
Hline_Trim$ = Trim(HLine_Text$)
If Hline_Tag$ <> "???"
WriteStringN(IxFileResult, Hline$)
Else
If Left(Hline_Trim$, 2) = "/*" And Right(Hline_Trim$, 2) = "*/"
; detection d'une ligne de commentaires complete.
WriteStringN(IxFileResult, "COM;" + Hline_Text$)
Else
If Left(Hline_Trim$, 2) = "/*"
WriteStringN(IxFileResult, "COM;" + Hline_Text$)
Flag_CommentBloc = #True
Else
If Right(Hline_Trim$, 2) = "*/" And Flag_CommentBloc = #True
WriteStringN(IxFileResult, "COM;" + Hline_Text$)
Flag_CommentBloc = #False
Else
; pas trouve de /* ou de */ dans la ligne !
If Flag_CommentBloc = #True
WriteStringN(IxFileResult, "COM;" + Hline_Text$)
Else
WriteStringN(IxFileResult, Hline$ )
EndIf
EndIf
EndIf
EndIf
EndIf
Wend
M_Close_INOUTFile()
EndProcedure
;==================================================================================================== Define.
Procedure.s Translate_LitteralValue(Item$)
Protected PB_Value$
Item$ = Trim(Item$)
If LCase(Right(Item$, 3)) = "ull"
Item$ = Left(Item$, Len(Item$) - 3 )
EndIf
PB_Value$ = Item$
If Left(Item$,2) = "0x"
PB_Value$ = "$" + Right(Item$, Len(Item$) - 2 )
EndIf
ProcedureReturn(PB_Value$)
EndProcedure
Procedure ConvertPass_Define(NEtape, Header_Fnamed$)
;--------------- Etape - Traitement des Define.
;--- ex
;#define FMOD_VERSION 0x00010608
;--> #FMOD_VERSION = $00010608
;--- ex
;#define FMOD_PRESET_OFF { 1000, 7, 11, 5000, 100, 100, 100, 250, 0, 20, 96, -80.0f }
;--- ex
;#define FMOD_CHANNELMASK_FRONT_LEFT 0x00000001
;#define FMOD_CHANNELMASK_FRONT_RIGHT 0x00000002
;#define FMOD_CHANNELMASK_MONO (FMOD_CHANNELMASK_FRONT_LEFT)
;#define FMOD_CHANNELMASK_STEREO (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT)
;--- ex
;#define Abs(X) ( ((X) < 0) ? -(X) : (X) )
Protected Flag_CommentBloc
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Text2$, Hline_Trim$, HLine_Uncom$
Protected DPos
Protected PB_DeclareName$, PB_Declare_InitialValue$, PB_Declare_Comment$, PB_Declare_Value$
M_Open_INOUTFile()
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Affiche ligne par ligne le contenu du fichier
HLine_Tag$ = Left(HLine$,3)
HLine_Text$ = Right(HLine$,Len(HLine$)-3)
HLine_Trim$ = Trim(HLine_Text$)
HLine_UnCom$ = Suppr_Comments(HLine_Text$)
If Hline_Tag$ <> "???"
WriteStringN(IxFileResult,Hline$ )
Else
If LCase(Left(Hline_Trim$,8)) <> "#define "
WriteStringN(IxFileResult,Hline$ )
Else
If FindString(Hline_uncom$,"{") <> 0
; non traitée
WriteStringN(IxFileResult, "IGN" + Hline_Text$)
Else
If FindString(Hline_uncom$,"(") <> 0
; non traitée
WriteStringN(IxFileResult, "IGN" + Hline_Text$)
Else
;#define FMOD_VERSION 0x00010608
;--> #FMOD_VERSION = $00010608
Hline_Text2$ = Trim(ReplaceString(HLine_Text$, "#define ", "", #PB_String_NoCase))
Dpos = FindString(Hline_Text2$, " ")
PB_DeclareName$ = Left(Hline_Text2$, DPos - 1 )
Hline_Text2$ = Trim(Right(Hline_Text2$, Len(Hline_Text2$) - Dpos ))
DPos = FindString(Hline_Text2$, "/*")
If Dpos = 0
PB_Declare_InitialValue$ = Hline_Text2$
PB_Declare_Comment$ = ""
Else
PB_Declare_InitialValue$ = Trim(Left(Hline_Text2$, DPos - 1 ))
PB_Declare_Comment$ = Right(Hline_Text2$, Len(Hline_Text2$) - Dpos + 1 )
PB_Declare_Comment$ = ReplaceString(PB_Declare_Comment$, "/*", ";")
PB_Declare_Comment$ = ReplaceString(PB_Declare_Comment$, "*/", "")
EndIf
If PB_DeclareName$ = "" ;Quick hack for "#define _FMOD_COMMON_H" style
PB_DeclareName$ = PB_Declare_InitialValue$
PB_Declare_InitialValue$ = Chr(34) + Chr(34)
EndIf
PB_Declare_Value$ = Translate_LitteralValue(PB_Declare_InitialValue$)
WriteStringN(IxFileResult, "DF1 #" + PB_DeclareName$ + " = " + PB_Declare_Value$ + " " + PB_Declare_Comment$ )
;Debug "#" + PB_DeclareName$ + " = " + PB_Declare_Value$ + " " + PB_Declare_Comment$
;--- Memorisation des Defines pour reutilisation ulterieure.
PB_Define_Cpt +1
PB_Define(PB_Define_Cpt)\Define_Name$ = PB_DeclareName$
PB_Define(PB_Define_Cpt)\Define_InitialValue$ = PB_Declare_InitialValue$
PB_Define(PB_Define_Cpt)\Define_Value$ = PB_Declare_Value$
PB_Define(PB_Define_Cpt)\Define_Comment$ = PB_Declare_Comment$
EndIf
EndIf
EndIf
EndIf
Wend
M_Close_INOUTFile()
EndProcedure
;==================================================================================================== Prototypes.
Procedure.s Translate_TypeDeclaration(Item$, Alter$ = "")
; Renvoie une declaration de type au format PB.
; ex : int value --> value.l
; ex : void value --> value
; ex : float *value --> *value
; ex : unsigned char* value --> *value
; ex : FMOD_DSP **dsp --> *dsp
; ex : unsigned char Data4[8] --> Data4.a[8]
; si Alter$ = "Prototype", on renvoie une declaration de prototype.
; ex : FMOD_RESULT FMOD_System_SetOutput -> Prototype.l __proto_FMOD_System_SetOutput(
;---------------------- PB
; Nom Extension Encombrement en mémoire Plage
; Byte .b 1 octet -128 à +127
; Ascii .a 1 octet 0 à +255
; Caractère .c 1 octet (en mode ascii) 0 à +255
; Caractère .c 2 octets (en mode unicode) 0 à +65535
; Word .w 2 octets -32768 à +32767
; Unicode .u 2 octets 0 à +65535
; Long .l 4 octets -2147483648 à +2147483647
; Integer .i 4 octets (avec compilateur 32-bit) -2147483648 à +2147483647
; Integer .i 8 octets (avec compilateur 64-bit) -9223372036854775808 à +9223372036854775807
; Float .f 4 octets illimité (voir informations plus bas)
; Quad .q 8 octets -9223372036854775808 à +9223372036854775807
; Double .d 8 octets illimité (voir informations plus bas)
; String .s longueur de la chaine + 1 illimité
; String Fixe .s{Longueur} longueur de la chaine illimité
;---------------------- C
; Type de donnée Signification Taille (en octets) Plage de valeurs acceptée
; char Caractère 1 -128 à 127
; unsigned char Caractère non signé 1 0 à 255
; short int Entier court 2 -32 768 à 32 767
; unsigned short int Entier court non signé 2 0 à 65 535
; int Entier 2 (sur processeur 16 bits) -32 768 à 32 767
; 4 (sur processeur 32 bits) -2 147 483 648 à 2 147 483 647
; unsigned int Entier non signé 2 (sur processeur 16 bits) 0 à 65 535
; 4 (sur processeur 32 bits) 0 à 4 294 967 295
; long int Entier long 4 -2 147 483 648 à 2 147 483 647
; unsigned long int Entier long non signé 4 0 à 4 294 967 295
; float Flottant (réel) 4 3.4*10-38 à 3.4*1038
; double Flottant double 8 1.7*10-308 à 1.7*10308
; long double Flottant double long 10 3.4*10-4932 à 3.4*104932
Protected LastSpacePos, Item_Type$, Item_Name$, Item_Array$
Protected Result$, DPosArray
; Decoupage de la variable Item (a gauche le type et a droite le nom) en fonction du dernier espace
; et extraction de l'envetuelle declaration de tableaux.
LastSpacePos = Len(Item$) - FindString(ReverseString(Item$), " ")
Item_Type$ = Trim(Left(Item$, LastSpacePos))
Item_Name$ = Trim(Right(Item$, Len(Item$) - LastSpacePos - 1))
DPosArray = FindString(Item_Name$, "[")
If DPosArray > 0
Item_Array$ = Trim(Right(Item_Name$, Len(Item_Name$) - DPosArray + 1))
Item_Name$ = Trim(Left(Item_Name$, DPosArray - 1))
Else
Item_Array$ = ""
EndIf
; Detection d'un pointeur par la presence d'une "*".
If FindString(Item$, "*") <> 0
If Alter$ = ""
ProcedureReturn "*" + ReplaceString(Item_Name$, "*", "")
Else
ProcedureReturn "TODO : cas non prevu = prototype pointeur"
EndIf
EndIf
; Conversion du type.
Select LCase(Item_Type$)
Case "char"
Result$ = ".b"
;Case "char", "const char"
; Result$ = ".p-ascii"
Case "unsigned char"
Result$ = ".a"
Case "short int"
Result$ = ".w"
Case "unsigned short int"
Result$ = ".u"
Case "float"
Result$ = ".f"
Case "int", "unsigned int"
Result$ = ".i"
Case "long int", "unsigned long int"
Result$ = ".l"
Case "double"
Result$ = ".d"
Default
If IsStructure(Item_Type$)
Result$ = "." + Item_Type$ ;".l" ou Item_Type$ ????
Else
Result$ = ".l" ;".l" ou Item_Type$ ????
EndIf
EndSelect
If Alter$ = ""
ProcedureReturn Item_Name$ + Result$ + Item_Array$
Else
ProcedureReturn "Prototype" + Result$ + " __proto_" + Item_Name$
EndIf
EndProcedure
Procedure.s Translate_Prototype(Item$, IxFileResult)
; Si detection d'une declaration de prototype,
; traitement et ecriture vers le fichier output de la syntaxe adaquate et renvoi de "OK"
; de plus, un tableau memorise la liste de prototype pour generer une fonction Initialize()
; lors de la derniere etape de la conversion.
; sinon renvoi de "KO".
;
; La declaration doit correspondre au modele suivant :
; type nom_Fonction ( type_parm1 nom_parm1, type_parm1 nom_parm1, type_parm1 nom_parm1 );
;
;ex :
;FMOD_RESULT F_API FMOD_System_SetPluginPath (FMOD_SYSTEM *system, const char *path);
;FMOD_RESULT F_API FMOD_System_LoadPlugin (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority);
;
; donne pour resultat :
; ;FMOD_RESULT F_API FMOD_System_SetPluginPath (FMOD_SYSTEM *system, const char *path);
; Prototype.l __proto_FMOD_System_SetPluginPath (*system, path.p-ascii)
; Global FMOD_System_SetPluginPath.__proto_FMOD_System_SetPluginPath
;
; ;FMOD_RESULT F_API FMOD_System_LoadPlugin (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority);
; Prototype.l __proto_FMOD_System_LoadPlugin (*system, filename.p-ascii, *handle, priority.l)
; Global FMOD_System_LoadPlugin.__proto_FMOD_System_LoadPlugin
Protected DParanthesePos, FParanthesePos
Protected LastSpacePos, Proto_Type$, Proto_Name$
Protected PB_Prototyp$, PB_GlobalDef$
Protected LArg$, Arg$, VirgPos, Part1$, Part2$
DParanthesePos = FindString( Item$, "(")
FParanthesePos = FindString( Item$, ");")
; doit etre du type "text1 ( text2 );"
If (DParanthesePos =0) Or (FParanthesePos=0) Or (DParanthesePos > FParanthesePos)
ProcedureReturn "KO"
EndIf
If Left(Item$,1) = "#" ; ne doit pas etre un mot cle commencant par #
ProcedureReturn "KO"
EndIf
Part1$ = Trim(Left(Item$, DParanthesePos - 1))
Part2$ = Trim(Mid(Item$, DParanthesePos + 1 , FParanthesePos - DParanthesePos -1))
;Debug Item$
;Debug Part1$
;Debug part2$
LastSpacePos = Len(Part1$) - FindString(ReverseString(Part1$), " ")
Proto_Type$ = Left(Part1$, LastSpacePos - 1)
Proto_Name$ = Right(Part1$, Len(Part1$) - LastSpacePos - 1)
PB_Prototyp$ = Translate_TypeDeclaration(Part1$, "Prototype") + "("
LArg$ = Part2$
While LArg$ <> ""
VirgPos = FindString(LArg$, ",")
If VirgPos = 0
Arg$ = LArg$
LArg$ = ""
Else
Arg$ = Left(LArg$, VirgPos - 1)
LArg$ = Right(LArg$, Len(LArg$) - VirgPos - 1)
EndIf
PB_Prototyp$ = PB_Prototyp$ + Translate_TypeDeclaration(Arg$) + ", "
Wend
PB_Prototyp$ = Left(PB_Prototyp$, Len(PB_Prototyp$) - 2) + ")"
PB_GlobalDef$ = "Global " + Proto_Name$ + ".__proto_" + Proto_Name$
;--- Memorisation des Prototypes pour reutilisation ulterieure.
PB_DLL_Init_Cpt = PB_DLL_Init_Cpt + 1
PB_DLL_Init$(PB_DLL_Init_Cpt) = Proto_Name$ + " = GetFunction(DLL_" + DLL_ShortName$ + "," + Chr(34) + Proto_Name$ + Chr(34) + ")"
;Debug "---"
;Debug PB_Prototyp$
;Debug PB_DLL_Init$(PB_DLL_Init_Cpt)
;Debug "--------------------------------"
WriteStringN(IxFileResult,"PRT;" + Item$ )
WriteStringN(IxFileResult,"PRT" + PB_Prototyp$ )
WriteStringN(IxFileResult,"PRT" + PB_GlobalDef$ )
ProcedureReturn "OK"
EndProcedure
Procedure ConvertPass_Prototype(NEtape, Header_Fnamed$)
;--------------- Etape - Traitement des definitions de prototypes.
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
Protected Result$
M_Open_INOUTFile()
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Affiche ligne par ligne le contenu du fichier
HLine_Tag$ = Left(HLine$, 3)
If Hline_Tag$ <> "???"
WriteStringN(IxFileResult, Hline$)
Else
HLine_Text$ = Right(HLine$,Len(HLine$) - 3)
HLine_Trim$ = Trim(HLine_Text$)
HLine_UnCom$ = Suppr_Comments(HLine_Text$)
Result$ = Translate_Prototype(HLine_UnCom$, IxFileResult)
If Result$ = "KO"
WriteStringN(IxFileResult, Hline$)
EndIf
EndIf
Wend
M_Close_INOUTFile()
EndProcedure
;==================================================================================================== Structures.
Procedure IsStructure(StructureNameToTest$)
; renvoie True / False suivant que le nom est present dans le tableau des structures connues
; cad si le nom correspond a une structure connue.
Protected i
i = 1
While i < PB_Structure_Cpt
If PB_Structure(i)\Structure_Name$ = StructureNameToTest$
ProcedureReturn #True
EndIf
i +1
Wend
ProcedureReturn #False
EndProcedure
Procedure.s Translate_Structure(Item$, IxFileSource, IxFileResult)
; Ex :
; typedef int km_per_hour ;
; Ex :
; typedef struct MyStruct newtype;
; Ex :
; typedef struct MyStruct {
; int data1;
; char data2;
; } newtype;
; Ex :
; struct s
; {
; int x;
; float y;
; char *z;
; } tee;
; ex :
; struct FMOD_ASYNCREADINFO
; {
; void *handle; /* [r] The file handle that was filled out in the open callback. */
; unsigned int offset; /* [r] Seek position, make sure you read from this file offset. */
; unsigned int sizebytes; /* [r] how many bytes requested for read. */
; int priority; /* [r] 0 = low importance. 100 = extremely important (ie 'must read now or stuttering may occur') */
;
; void *userdata; /* [r/w] User data pointer specific to this request. Initially 0, can be ignored or set by the user. Not related to the file's main userdata member. */
;
; void *buffer; /* [w] Buffer to read file data into. */
; unsigned int bytesread; /* [w] Fill this in before setting result code to tell FMOD how many bytes were read. */
;
; FMOD_FILE_ASYNCDONE done; /* [r] FMOD file system wake up function. Call this when user file read is finished. Pass result of file read as a parameter. */
; };
; ---> Syntaxe PB
; Structure FMOD_ASYNCREADINFO
; *handle ; [r] The file handle that was filled out in the open callback.
; offset.l ; [r] Seek position, make sure you read from this file offset.
; sizebytes.l ; [r] how many bytes requested for read.
; priority.l ; [r] 0 = low importance. 100 = extremely important (ie 'must read now or stuttering may occur').
; *userdata ; [r/w] User data pointer specific to this request. Initially 0, can be ignored or set by the user. Not related to the file's main userdata member.
; *buffer ; [w] Buffer to read file data into.
; bytesread.l ; [w] Fill this in before setting result code to tell FMOD how many bytes were read.
; *done.__proto_FMOD_ASYNCREADINFO_DONE ; [r] FMOD file system wake up function. Call this when user file read is finished. Pass result of file read as a parameter.
; EndStructure
;
; ex :
; typedef struct
; {
; unsigned int Data1; /* Specifies the first 8 hexadecimal digits of the GUID */
; unsigned short Data2; /* Specifies the first group of 4 hexadecimal digits. */
; unsigned short Data3; /* Specifies the second group of 4 hexadecimal digits. */
; unsigned char Data4[8]; /* Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. The remaining 6 bytes contain the final 12 hexadecimal digits. */
; } FMOD_GUID;
; ---> Syntaxe PB
; Structure FMOD_GUID
; Data1.l ; Specifies the first 8 hexadecimal digits of the GUID.
; Data2.u ; Specifies the first group of 4 hexadecimal digits.
; Data3.u ; Specifies the second group of 4 hexadecimal digits.
; Data4.a[8] ; Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. The remaining 6 bytes contain the final 12 hexadecimal digits.
; EndStructure
Protected DPos, FPos, Part1$, Part2$, Part3$
Protected LastSpacePos, Proto_Type$, Proto_Name$
Protected PB_Prototyp$, PB_GlobalDef$
Protected LArg$, Arg$, VirgPos, T$
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
Protected Structure_Name$, Structure_InitialRubriqueName$, Structure_RubriqueName$, Structure_RubriqueComment$
Protected PB_Structure$
Protected FPcomment, TabSet
; doit commencer par "typedef struct " ou par "struct "
If LCase(Left(Trim(Item$), 7)) <> "typedef" And LCase(Left(Trim(Item$), 6)) <> "struct"
ProcedureReturn "KO"
EndIf
;If Left(Item$, 1) = "#" ; ne doit pas etre un mot cle commencant par #
; ProcedureReturn "KO"
;EndIf
If LCase(Left(Trim(Item$), 12)) = "typedef enum"
ProcedureReturn "KO"
EndIf
If LCase(Left(Trim(Item$), 14)) <> "typedef struct" And LCase(Left(Trim(Item$), 6)) <> "struct"
WriteStringN(IxFileResult, "STR;" + Item$)
ProcedureReturn "OK"
EndIf
; Traitement ( on n'en tient pas compte : pas d'equivalent en PB ??? ) des structures du genre :
; typedef struct FMOD_SYSTEM FMOD_SYSTEM;
If Right(Suppr_Comments(Item$), 1) = ";"
WriteStringN(IxFileResult,"STR;" + Item$)
ProcedureReturn "OK"
EndIf
;--- Lecture du fichier Source jusqu'a la lecture du "}" final pour avoir la structure entiere dans Item$.
;Item_UnCommented$ = Suppr_Comments(Item$)
While FindString(Item$, "{") = 0 Or FindString(Item$, "}") = 0
HLine$ = ReadString(IxFileSource)
HLine_Tag$ = Left(HLine$, 3)
HLine_Text$ = Right(HLine$, Len(HLine$) - 3)
Item$ = Item$ + HLine_Text$
;Item_UnCommented$ = Item_UnCommented$ + Uncomment(HLine_Text$)
;Debug FindString(Item_UnCommented$, "{")
;Debug FindString(Item_UnCommented$, "}")
Wend
;Debug Item$
;Debug Item_UnCommented$
;Debug "-----------------------------------"
;--- Decoupage en 3 parties suivant la position de "{" et de "}"
DPos = FindString(Item$, "{")
FPos = FindString(Item$, "}")
Part1$ = Trim(Left(Item$, DPos - 1))
Part2$ = Trim(Mid(Item$, DPos + 1 , FPos - DPos -1))
Part3$ = Trim(Right(Item$, Len(Item$) - FPos - 1))
;Debug Part1$
;Debug Part2$
;Debug Part3$
;--- Traitement de l'entete de declaration Structure PB.
; on prend le nom de la structure en fin de declaration (Apres le "}")
; ou alors en debut de declaration (avant le "{")
If Part3$ <> ""
Structure_Name$ = Left(Part3$, Len(Part3$) - 1) ;On enleve le ";" final.
WriteStringN(IxFileResult,"STR Structure " + Structure_Name$)
Else
Structure_Name$ = ReplaceString(Part1$, "typedef" , "", #PB_String_NoCase )
Structure_Name$ = ReplaceString(Structure_Name$, "struct" , "", #PB_String_NoCase )
Structure_Name$= Trim(Structure_Name$)
WriteStringN(IxFileResult,"STR Structure " + Structure_Name$)
EndIf
;--- Boucle de traitement des arguments separés par des ","
LArg$ = Part2$
While LArg$ <> ""
VirgPos = FindString(LArg$, ";")
If VirgPos = 0
Arg$ = LArg$
LArg$ = ""
Else
Arg$ = Trim(Left(LArg$, VirgPos - 1))
LArg$ = Trim(Right(LArg$, Len(LArg$) - VirgPos - 1))
EndIf
;Debug Arg$
;Debug LArg$
;Debug "--"
Structure_InitialRubriqueName$ = Arg$
Structure_RubriqueName$ = Translate_TypeDeclaration(Structure_InitialRubriqueName$)
;Debug ">>>>>" + Arg$ + ">>>>>" + PB_Structure$
If Left(LArg$,2) = "/*"
FPcomment = FindString(LArg$, "*/")
TabSet = GTabSet - Len(Structure_RubriqueName$)
If TabSet < 1 : TabSet = 1 : EndIf
Structure_RubriqueComment$ = Left(Larg$, FPcomment + 1)
PB_Structure$ = Structure_RubriqueName$ + Space(TabSet) + ";" + Structure_RubriqueComment$
LArg$ = Right(LArg$, Len(LArg$) - FPcomment - 2)
Else
PB_Structure$ = Structure_RubriqueName$
Structure_RubriqueComment$ = ""
EndIf
;Debug "Final ---->" + PB_Structure$
WriteStringN(IxFileResult,"STR " + PB_Structure$)
;--- Memorisation de la structure pour reutilisation ulterieure.
PB_Structure_Cpt +1
PB_Structure(PB_Structure_Cpt)\Structure_Name$ = Structure_Name$
PB_Structure(PB_Structure_Cpt)\Structure_InitialRubriqueName$ = Structure_InitialRubriqueName$
PB_Structure(PB_Structure_Cpt)\Structure_RubriqueName$ = Structure_RubriqueName$
PB_Structure(PB_Structure_Cpt)\Structure_RubriqueComment$ = Structure_RubriqueComment$
;Debug "Structure " + Structure_Name$ + " : " + Structure_RubriqueName$ + " / " + Structure_InitialRubriqueName$
Wend
WriteStringN(IxFileResult,"STR EndStructure")
ProcedureReturn "OK"
EndProcedure
Procedure ConvertPass_Structure(NEtape, Header_Fnamed$)
;--------------- Etape - Traitement des definitions de structures.
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
Protected Result$
M_Open_INOUTFile()
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Affiche ligne par ligne le contenu du fichier
HLine_Tag$ = Left(HLine$, 3)
If Hline_Tag$ <> "???"
WriteStringN(IxFileResult, Hline$)
Else
HLine_Text$ = Right(HLine$,Len(HLine$) - 3)
HLine_Trim$ = Trim(HLine_Text$)
HLine_UnCom$ = Suppr_Comments(HLine_Text$)
Result$ = Translate_Structure(HLine_UnCom$, IxFileSource, IxFileResult)
If Result$ = "KO"
WriteStringN(IxFileResult, Hline$)
EndIf
EndIf
Wend
M_Close_INOUTFile()
EndProcedure
;=================================================================================================== Enumerations.
Procedure.s Translate_Enumeration(Item$, IxFileSource, IxFileResult)
; // Changing the Default value of enum elements
; enum suit{
; club=0;
; diamonds=10;
; hearts=20;
; spades=3;
; };
;
;
; typedef enum
; {
; FMOD_OK, /* No errors. */
; FMOD_ERR_BADCOMMAND, /* Tried To call a function on a Data type that does Not allow this type of functionality (ie calling Sound::lock on a streaming sound). */
; FMOD_ERR_CHANNEL_ALLOC /* Error trying To allocate a channel. */
; } FMOD_RESULT;
Protected DPos, FPos, Part1$, Part2$, Part3$
Protected LastSpacePos, Proto_Type$, Proto_Name$
Protected PB_Prototyp$, PB_GlobalDef$
Protected LArg$, Arg$, VirgPos, T$
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
Protected PB_Enumeration$
Protected FPcomment, TabSet
Protected Enum_Name$, Enum_ItemName$, Enum_ItemComment$
; doit commencer par "typedef enum " ou par "enum "
If LCase(Left(Trim(Item$), 7)) <> "typedef" And LCase(Left(Trim(Item$), 4)) <> "enum"
ProcedureReturn "KO"
EndIf
;If Left(Item$, 1) = "#" ; ne doit pas etre un mot cle commencant par #
; ProcedureReturn "KO"
;EndIf
If LCase(Left(Trim(Item$), 12)) <> "typedef enum" And LCase(Left(Trim(Item$), 4)) <> "enum"
WriteStringN(IxFileResult, "STR;" + Item$)
ProcedureReturn "OK"
EndIf
;; Traitement ( on n'en tient pas compte : pas d'equivalent en PB ??? ) des structures du genre :
;; typedef struct FMOD_SYSTEM FMOD_SYSTEM;
;If Right(Suppr_Comments(Item$), 1) = ";"
; WriteStringN(IxFileResult,"STR;" + Item$)
; ProcedureReturn "OK"
;EndIf
;--- Lecture du fichier Source jusqu'a la lecture du "}" final pour avoir l'enum entiere dans Item$.
;Item_UnCommented$ = Suppr_Comments(Item$)
While FindString_Comment(Item$, "{") = 0 Or FindString_Comment(Item$, "}") = 0
HLine$ = ReadString(IxFileSource)
HLine_Tag$ = Left(HLine$, 3)
HLine_Text$ = Right(HLine$, Len(HLine$) - 3)
If Trim(HLine_Text$) <> ";"
Item$ = Item$ + HLine_Text$
EndIf
;Item_UnCommented$ = Item_UnCommented$ + Uncomment(HLine_Text$)
;Debug FindString(Item_UnCommented$, "{")
;Debug FindString(Item_UnCommented$, "}")
Wend
;Debug Item$
;Debug Item_UnCommented$
;Debug "-----------------------------------"
;--- Decoupage en 3 parties suivant la position de "{" et de "}"
DPos = FindString_Comment(Item$, "{")
FPos = FindString_Comment(Item$, "}")
Part1$ = Trim(Left(Item$, DPos - 1))
Part2$ = Trim(Mid(Item$, DPos + 1 , FPos - DPos -1))
Part3$ = Trim(Right(Item$, Len(Item$) - FPos - 1))
;Debug Part1$
;Debug Part2$
;Debug Part3$
;--- Traitement de l'entete de declaration Structure PB.
; on prend le nom de la structure en fin de declaration (Apres le "}")
; ou alors en debut de declaration (avant le "{")
If Part3$ <> ""
Enum_Name$ = Part3$
WriteStringN(IxFileResult,"STR Enumeration " + Enum_Name$)
Else
T$ = ReplaceString(Part1$, "typedef" , "", #PB_String_NoCase )
T$ = ReplaceString(T$, "struct" , "", #PB_String_NoCase )
T$= Trim(T$)
Enum_Name$ = T$
WriteStringN(IxFileResult,"STR Enumeration " + Enum_Name$)
EndIf
;--- Boucle de traitement des arguments separés par des ","
LArg$ = Part2$
While LArg$ <> ""
VirgPos = FindString_Comment(LArg$, ",")
;CommentPos = FindString(LArg$, "/*")
;If VirgPos > CommentPos ; essai d'intercepter une virgule dans le commentaire du dernier item de l'enumeration.
; VirgPos = 0
;EndIf
If VirgPos = 0
Arg$ = LArg$
LArg$ = ""
;--- Cas particulier : le dernier item n'a pas de virgule et est peut être suivi d'un commentaire.
VirgPos = FindString(Arg$, "/*")
If VirgPos <> 0
LArg$ = Arg$
Arg$ = Trim(Left(LArg$, VirgPos - 1))
LArg$ = Trim(Right(LArg$, Len(LArg$) - VirgPos + 1))
EndIf
Else
Arg$ = Trim(Left(LArg$, VirgPos - 1))
LArg$ = Trim(Right(LArg$, Len(LArg$) - VirgPos +1 - 1))
EndIf
;Debug Arg$
;Debug LArg$
;Debug "--"
Enum_ItemName$ = Trim(Arg$)
PB_Enumeration$ = " #" + Enum_ItemName$
;Debug ">>>>>" + Arg$ + ">>>>>" + PB_Structure$
Enum_ItemComment$ = ""
If Left(LArg$,2) = "/*"
FPcomment = FindString(LArg$, "*/")
TabSet = GTabSet - Len(PB_Enumeration$)
If TabSet < 1 : TabSet = 1 : EndIf
Enum_ItemComment$ = Left(Larg$, FPcomment + 1)
PB_Enumeration$ = PB_Enumeration$ + Space(TabSet) + ";" + Enum_ItemComment$
LArg$ = Right(LArg$, Len(LArg$) - FPcomment - 2)
EndIf
;Debug "Final ---->" + PB_Structure$
WriteStringN(IxFileResult,"STR " + PB_Enumeration$)
;--- Memorisation de la structure pour reutilisation ulterieure.
PB_Enum_Cpt +1
DPos = FindString_Comment(Enum_Name$, ";") ; pour garder le nom uniquement.
If DPos > 0
Enum_Name$ = Left(Enum_Name$, Dpos - 1)
EndIf
PB_Enum(PB_Enum_Cpt)\Enum_Name$ = Enum_Name$
DPos = FindString_Comment(Enum_ItemName$, "=") ; pour garder le nom uniquement.
If DPos > 0
Enum_ItemName$ = Trim(Left(Enum_ItemName$, Dpos - 1))
EndIf
PB_Enum(PB_Enum_Cpt)\Enum_ItemName$ = Enum_ItemName$
PB_Enum(PB_Enum_Cpt)\Enum_ItemComment$ = Enum_ItemComment$
;Debug "Enum " + Enum_Name$ + " : " + Enum_ItemName$ + " / " + Enum_ItemComment$
Wend
WriteStringN(IxFileResult,"STR EndEnumeration")
ProcedureReturn "OK"
EndProcedure
Procedure ConvertPass_Enumeration(NEtape, Header_Fnamed$)
;--------------- Etape - Traitement des definitions de structures.
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$, HLine_UnCom$
Protected Result$
M_Open_INOUTFile()
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Affiche ligne par ligne le contenu du fichier
HLine_Tag$ = Left(HLine$, 3)
If Hline_Tag$ <> "???"
WriteStringN(IxFileResult, Hline$)
Else
HLine_Text$ = Right(HLine$,Len(HLine$) - 3)
HLine_Trim$ = Trim(HLine_Text$)
HLine_UnCom$ = Suppr_Comments(HLine_Text$)
Result$ = Translate_Enumeration(HLine_UnCom$, IxFileSource, IxFileResult)
If Result$ = "KO"
WriteStringN(IxFileResult, Hline$)
EndIf
EndIf
Wend
M_Close_INOUTFile()
EndProcedure
;=================================================================================================== Trt Final.
Procedure ConvertPass_Final(NEtape,Header_Fnamed$)
;--------------- Etape - Traitement des blocs de commentaires.
Protected Flag_CommentBloc, i
Protected HLine$, Hline_Tag$, Hline_Text$, Hline_Trim$
M_Open_INOUTFile(#True)
Flag_CommentBloc = #False
While Eof(IxFileSource) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
HLine$ = ReadString(IxFileSource) ; Affiche ligne par ligne le contenu du fichier
Hline_Tag$ = Left(Hline$,3)
Hline_Text$ = Right(Hline$,Len(Hline$)-3)
Hline_Trim$ = Trim(HLine_Text$)
If Hline_Tag$ = "???" Or Hline_Tag$ = "IGN"
WriteStringN(IxFileResult, ";IGNORED : " + Hline_Text$ )
Else
WriteStringN(IxFileResult, Hline_Text$ )
EndIf
Wend
; si detection de prototype, on ajoute une fonction init() a la fin.
If PB_DLL_Init_Cpt > 0
WriteStringN(IxFileResult, ";" )
WriteStringN(IxFileResult, "Procedure " + DLL_ShortName$ + "_Initialize()")
WriteStringN(IxFileResult, " Protected DLL_" + DLL_ShortName$)
WriteStringN(IxFileResult, " Debug " + Chr(34) + DLL_ShortName$ + " Initializing." + Chr(34))
WriteStringN(IxFileResult, " ")
WriteStringN(IxFileResult, " CompilerIf #PB_Compiler_Processor = #PB_Processor_x64")
WriteStringN(IxFileResult, " DLL_" + DLL_ShortName$ + " = OpenLibrary(#PB_Any, " + Chr(34) + DLL_x64Path$ + Chr(34) + ")")
WriteStringN(IxFileResult, " CompilerElse")
WriteStringN(IxFileResult, " DLL_" + DLL_ShortName$ + " = OpenLibrary(#PB_Any, " + Chr(34) + DLL_x32Path$ + Chr(34) + ")")
WriteStringN(IxFileResult, " CompilerEndIf")
WriteStringN(IxFileResult, " ")
WriteStringN(IxFileResult, " If DLL_" + DLL_ShortName$)
For i = 1 To PB_DLL_Init_Cpt
WriteStringN(IxFileResult, " " + PB_DLL_Init$(i))
Next i
WriteStringN(IxFileResult, " Endif")
WriteStringN(IxFileResult, "")
WriteStringN(IxFileResult, " ProcedureReturn DLL_" + DLL_ShortName$)
WriteStringN(IxFileResult, "EndProcedure")
WriteStringN(IxFileResult, "")
EndIf
M_Close_INOUTFile()
EndProcedure
Procedure Explain_Enum(EnumName$ = "*")
; Procedure.s FMOD_ErrorString(errcode.l)
; Protected FMOD_ErrorString.s
;
; Select errcode
; Case #FMOD_OK: FMOD_ErrorString = "No errors."
; Case #FMOD_ERR_ALREADYLOCKED: FMOD_ErrorString = "Tried to call lock a second time before unlock was called."
; Case #FMOD_ERR_BADCOMMAND: FMOD_ErrorString = "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound)."
; Case #FMOD_ERR_CDDA_DRIVERS: FMOD_ErrorString = "Neither NTSCSI nor ASPI could be initialised."
; Default: FMOD_ErrorString = "Unknown error."
; EndSelect
;
; ProcedureReturn FMOD_ErrorString
; EndProcedure
Protected Entete = #False
Protected CurrentEnum$ = ""
Protected IxFileResult, ICpt, Comment$
IxFileResult = OpenFile(#PB_Any, Header_Fnamed$ + "_Final.pbi", #PB_File_Append)
If IxFileResult = 0
Debug #PB_Compiler_Procedure + ": PB ouverture du fichier Source - " + Header_Fnamed$
End
EndIf
ICpt = 1
While ICpt <= PB_Enum_Cpt ; boucle de parcours du tableau d'Enum.
If CurrentEnum$ <> PB_Enum(ICpt)\Enum_Name$
If Entete = #True
WriteStringN(IxFileResult, " Default: Lib$ = " + Chr(34) + "Unknown code." + Chr(34))
WriteStringN(IxFileResult, " EndSelect")
WriteStringN(IxFileResult, "")
WriteStringN(IxFileResult, " ProcedureReturn Lib$")
WriteStringN(IxFileResult, " EndProcedure")
WriteStringN(IxFileResult, "")
EndIf
Entete = #False
If EnumName$ = "*" Or EnumName$ = PB_Enum(ICpt)\Enum_Name$
CurrentEnum$ = PB_Enum(ICpt)\Enum_Name$
WriteStringN(IxFileResult, " Procedure.s Explain_" + CurrentEnum$ + "(Value.l)")
WriteStringN(IxFileResult, " Protected Lib$")
WriteStringN(IxFileResult, "")
WriteStringN(IxFileResult, " Select Value")
Entete = #True
EndIf
Else
If EnumName$ = "*" Or EnumName$ = PB_Enum(ICpt)\Enum_Name$
Comment$ = PB_Enum(ICpt)\Enum_ItemComment$
Comment$ = ReplaceString(Comment$, "/*", "")
Comment$ = ReplaceString(Comment$, "*/", "")
Comment$ = ReplaceString(Comment$, Chr(34), "'")
Comment$ = Trim(Comment$)
WriteStringN(IxFileResult, " Case #" + PB_Enum(ICpt)\Enum_ItemName$ + ": Lib$ = " + Chr(34) + Comment$ + Chr(34))
EndIf
EndIf
ICpt +1
Wend
If Entete = #True
WriteStringN(IxFileResult, " Default: Lib$ = " + Chr(34) + "Unknown code." + Chr(34))
WriteStringN(IxFileResult, " EndSelect")
WriteStringN(IxFileResult, "")
WriteStringN(IxFileResult, " ProcedureReturn Lib$")
WriteStringN(IxFileResult, " EndProcedure")
WriteStringN(IxFileResult, "")
EndIf
CloseFile(IxFileResult) ; Ferme le fichier précédemment ouvert
EndProcedure
;==================================================================================================== Parametrage du Traitement.
Global Header_Fnamed$ = "Fmod_Complet.h"
Global DLL_ShortName$ = "FMOD"
Global DLL_x32Path$ = "FmodL.dll"
Global DLL_x64Path$ = "Fmod64.dll"
Global GTabSet = 35
;==================================================================================================== Traitement.
ConvertPass_Initialisation( 1, Header_Fnamed$)
ConvertPass_Comment( 2, Header_Fnamed$)
ConvertPass_Define( 3, Header_Fnamed$)
ConvertPass_Structure( 4, Header_Fnamed$)
ConvertPass_Prototype( 5, Header_Fnamed$)
ConvertPass_Enumeration( 6, Header_Fnamed$)
ConvertPass_Final( 7, Header_Fnamed$)
Explain_Enum("FMOD_RESULT")