intro.bbdoc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. ## Introduction
  2. MaxIO is a powerful feature of BlitzMax that enables developers to work with archives
  3. (such as ZIP files) as if they were regular file systems. This is achieved through an
  4. underlying mechanism provided by PhysFS. The integration of PhysFS with BlitzMax allows
  5. the standard FileSystem functions to seamlessly work with mounted archives.
  6. ## Writing Directory and Search Path
  7. MaxIO uses a single writing directory and multiple reading directories called the "search path".
  8. The writing directory is the root of the writable filesystem, and the search path is a list
  9. of directories and archives that MaxIO can read from.
  10. ### Writing Directory
  11. The writing directory is a secure location where your application can store files. By
  12. setting the writing directory, you prevent the application from accessing any directories
  13. above it, enhancing security. For example, if you were to set the writing directory to
  14. "C:\MyGame\MyWritingDirectory" (on Windows), then no MaxIO calls could touch anything
  15. above this directory, including the "C:\MyGame" and "C:" directories.
  16. To give MaxIO full access to the system's real file system, you can set the writing
  17. directory to the root directory, but this is generally not recommended as it may expose
  18. your application to potential security risks.
  19. ### Search Path
  20. The search path is a list of directories and archives that MaxIO can read from. When
  21. opening a file for reading, MaxIO goes through the search path, checking each location
  22. for the requested file. The search path creates a single, hierarchical directory structure
  23. that lends itself well to general abstraction with archives and provides better support
  24. for various operating systems.
  25. Drive letters are hidden in MaxIO once you set up your initial paths. This means that you
  26. should not hardcode a drive letter when specifying file paths. Instead, use
  27. platform-independent notation, which ensures compatibility across different operating
  28. systems.
  29. For example, if you want to write to "C:\MyGame\MyConfigFiles\game.cfg" (on Windows), you
  30. might set the writing directory to "C:\MyGame" and then open the file with the
  31. platform-independent notation "MyConfigFiles/game.cfg". This abstraction allows your
  32. application to work seamlessly across multiple platforms.
  33. ## Platform-Independent Notation
  34. Platform-independent notation is a standardized way of specifying file paths that works
  35. across different operating systems. When using MaxIO, you should always specify file paths
  36. using platform-independent notation. This notation uses forward slashes ("/") as directory
  37. separators and omits drive letters.
  38. ## Supported Archive Types
  39. MaxIO supports the following archive types:
  40. - .ZIP (pkZip/WinZip/Info-ZIP compatible)
  41. - .7Z (7zip archives)
  42. - .ISO (ISO9660 files, CD-ROM images)
  43. - .GRP (Build Engine groupfile archives)
  44. - .PAK (Quake I/II archive format)
  45. - .HOG (Descent I/II HOG file archives)
  46. - .MVL (Descent II movielib archives)
  47. - .WAD (DOOM engine archives)
  48. - .VDF (Gothic I/II engine archives)
  49. - .SLB (Independence War archives)
  50. ## Initializing MaxIO
  51. Before you can use any MaxIO features, you need to initialise it.
  52. Initialization sets up the necessary internal structures and prepares MaxIO for use.
  53. To initialise MaxIO, call the `MaxIO.Init()` function. This function returns an
  54. Int value indicating the success or failure of the initialization process.
  55. Here's an example of how to initialise MaxIO:
  56. ```blitzmax
  57. If MaxIO.Init() Then
  58. ' MaxIO is initialised and ready to use
  59. Else
  60. Print "Failed to initialise MaxIO"
  61. End
  62. End If
  63. ```
  64. It's important to check the return value of `MaxIO.Init()` to ensure that MaxIO has been
  65. properly initialised. If the initialization fails, you should not attempt to use MaxIO
  66. functions, as they will not behave correctly and may cause unexpected issues.
  67. Once you've finished using the MaxIO module, you should deinitialise it to release any
  68. resources it has acquired. To deinitialise MaxIO, call the `MaxIO.DeInit()` function:
  69. ```blitzmax
  70. MaxIO.DeInit()
  71. ```
  72. Keep in mind that deinitializing MaxIO while it's still in use can lead to unexpected
  73. behaviour. Always make sure that you have finished working with the module before
  74. deinitializing it.
  75. ## Mounting Archives and Directories
  76. Mounting archives and directories in MaxIO refers to the process of attaching an archive
  77. (such as a ZIP file) or a directory to the search path. This allows you to access the
  78. files and directories within the mounted archive or directory as if they were part of the
  79. native file system.
  80. ### Mounting Archives
  81. To mount an archive, use the `MaxIO.Mount()` function. This function takes two parameters:
  82. the path to the archive file and the mount point within the search path. The mount point
  83. is a virtual directory where the archive will be attached in the search path.
  84. Here's an example of how to mount a ZIP archive:
  85. ```blitzmax
  86. Local archivePath:String = "path/to/your/archive.zip"
  87. Local mountPoint:String = "myArchive"
  88. If MaxIO.Mount(archivePath, mountPoint) Then
  89. ' Archive is mounted and ready for use
  90. Else
  91. Print "Failed to mount the archive"
  92. End If
  93. ```
  94. Once the archive is mounted, you can access its contents using platform-independent
  95. notation and the standard BlitzMax file functions. For example, if the archive contains
  96. a file named `data.txt`, you can access it using the file path `myArchive/data.txt`.
  97. ### Mounting Directories
  98. Mounting directories is similar to mounting archives. You can use the `MaxIO.Mount()`
  99. function to attach a directory to the search path, just like you would with an archive.
  100. Here's an example of how to mount a directory:
  101. ```blitzmax
  102. Local dirPath:String = "path/to/your/directory"
  103. Local mountPoint:String = "myDir"
  104. If MaxIO.Mount(dirPath, mountPoint) Then
  105. ' Directory is mounted and ready for use
  106. Else
  107. Print "Failed to mount the directory"
  108. End If
  109. ```
  110. Once the directory is mounted, you can access its contents using platform-independent
  111. notation and the standard BlitzMax file functions.
  112. There are several optional parameters you can pass to the `MaxIO.Mount()`` function to
  113. control the behaviour of the mounted archive or directory:
  114. - `append:Bool = True` : By default, the mounted archive or directory is appended to the
  115. end of the search path. If you set append to False, the archive or directory will be
  116. inserted at the beginning of the search path instead.
  117. - `createVirtualDir:Bool = False`: If set to True, MaxIO will create a virtual directory
  118. for the mount point if it doesn't already exist.
  119. ## Accessing Files Within Archives
  120. After an archive is mounted, you can use the standard BlitzMax file functions to access
  121. files within the archive. MaxIO treats the mounted archive as if it were a regular file
  122. system, allowing you to read and write files with ease.
  123. Here are some examples of how you can read and write files within a mounted archive using
  124. BlitzMax file functions:
  125. ### Reading a File from an Archive
  126. To read a file from a mounted archive, you can use the #ReadFile function, just as you
  127. would when working with regular files:
  128. ```blitzmax
  129. Local file:TStream = ReadFile("path/to/file/in/archive.txt")
  130. If file
  131. Local content:String = ReadString(file)
  132. file.Close()
  133. Print "Content of the file: " + content
  134. Else
  135. Print "Failed to open the file in the archive"
  136. End If
  137. ```
  138. ### Writing a File to an Archive
  139. Writing to files within an archive is generally not supported. Instead, you should extract
  140. the file, modify it, and then add it back to the archive if necessary. However, if the
  141. archive is mounted to a writable directory, you can write a new file to the directory that
  142. will be accessible alongside the archive's contents:
  143. ```blitzmax
  144. Local file:TStream = WriteFile("path/to/writable/directory/newfile.txt")
  145. If file
  146. WriteString(file, "This is a new file.")
  147. CloseStream(file)
  148. Print "New file created successfully"
  149. Else
  150. Print "Failed to create a new file"
  151. End If
  152. ```
  153. Remember that the writing directory should be set up to allow writing to the desired
  154. location in the virtual file system created by MaxIO.
  155. ## Listing Files and Directories
  156. You can use the standard BlitzMax directory listing functions to obtain a list of files
  157. and directories within the mounted archive. This allows you to navigate and explore
  158. the contents of an archive as if it were a regular directory on your file system.
  159. Here's an example of how to list files and directories within a mounted archive:
  160. ``` blitzmax
  161. Function ListDirContents(dirPath:String)
  162. Local dir:Byte Ptr = ReadDir(dirPath)
  163. If Not dir
  164. Print "Failed to open directory: " + dirPath
  165. Return
  166. End If
  167. Local entry:String = NextFile(dir)
  168. While entry
  169. Print "Entry: " + entry
  170. ' Check if the entry is a directory
  171. If FileType(dirPath + "/" + entry) = FILETYPE_DIR Then
  172. Print "This is a directory"
  173. ' Recursively list the contents of the subdirectory
  174. ListDirContents(dirPath + "/" + entry)
  175. End If
  176. entry = NextFile(dir)
  177. Wend
  178. CloseDir(dir)
  179. End Function
  180. ' Call the function with the path to the mounted archive or a directory within the archive
  181. ListDirContents("path/to/mounted/archive")
  182. ```
  183. In this example, the `ListDirContents` function takes a directory path as a parameter and
  184. lists all files and directories within the specified directory. If it encounters a
  185. subdirectory, it calls itself recursively to list the contents of the subdirectory as well.
  186. ## Combining Multiple Archives
  187. By mounting multiple archives to the same search path, you can treat them as a single,
  188. unified file system. This means that when you access files using MaxIO, the system will
  189. automatically search through all mounted archives in the search path to find the
  190. requested file. This can be particularly useful for managing game assets, mods, or updates,
  191. where you might want to overlay newer files on top of older ones without altering the
  192. original archive.
  193. Here's an example of how to mount multiple archives to the same search path:
  194. ```blitzmax
  195. ' Mount the base archive
  196. If Not MaxIO.Mount("base_archive.zip", "/") Then
  197. Print "Failed to mount base_archive.zip"
  198. End
  199. End If
  200. ' Mount the mod archive
  201. If Not MaxIO.Mount("mod_archive.zip", "/") Then
  202. Print "Failed to mount mod_archive.zip"
  203. End
  204. End If
  205. ' Mount the update archive
  206. If Not MaxIO.Mount("update_archive.zip", "/") Then
  207. Print "Failed to mount update_archive.zip"
  208. End
  209. End If
  210. ```
  211. In this example, three archives (`base_archive.zip`, `mod_archive.zip`, and `update_archive.zip`)
  212. are mounted to the root of the search path. When accessing files, MaxIO will search through
  213. these archives, effectively combining their contents into a single file system.
  214. If a file exists in more than one archive, the file from the most recently mounted archive
  215. will take precedence. This allows you to easily overlay new files on top of older ones, making
  216. it easy to manage updates or modifications to your application's assets.
  217. ## Thread Safety
  218. MaxIO is mostly thread-safe, with errors returned by `MaxIO.GetLastErrorCode()` being
  219. unique to each thread. However, individual file accesses are not locked, so you cannot
  220. safely read, write, seek, or close the same file from two threads simultaneously.