|
| 1 | +# MAMEDBHandler |
| 2 | + |
| 3 | +A Swift package for managing MAME arcade game emulator databases that provides functionality to query and retrieve information about arcade games, their ROM sets, and perform compliance checking. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- Create SQLite databases from MAME XML files |
| 8 | +- Query for game and ROM information |
| 9 | +- Support for multiple ROM set formats (split, merged, non-merged, etc.) |
| 10 | +- Efficient memory usage with actor-based concurrency |
| 11 | +- Game categorization and metadata support |
| 12 | + |
| 13 | +Please note this library expects to read information from the SQLite databases it creates itself and not from other conversions from MAME's XML into SQLite. This library's SQLite Mame Databases are optimized only towards size by focusing only on machine details and ROM/bios/devices details. |
| 14 | + |
| 15 | +## Requirements |
| 16 | + |
| 17 | +- macOS 12.0+ |
| 18 | +- Swift 5.5+ |
| 19 | + |
| 20 | +## Installation |
| 21 | + |
| 22 | +### Swift Package Manager |
| 23 | + |
| 24 | +Add MAMEDBHandler to your Package.swift: |
| 25 | + |
| 26 | +```swift |
| 27 | +dependencies: [ |
| 28 | + .package(url: "https://github.com/yourusername/MAMEDBHandler.git", from: "1.0.0") |
| 29 | +] |
| 30 | +``` |
| 31 | + |
| 32 | +## Quick Start |
| 33 | + |
| 34 | +```swift |
| 35 | +import MAMEDBHandler |
| 36 | + |
| 37 | +// Initialize with an existing database |
| 38 | +let dbPath = "/path/to/mame.sqlite" |
| 39 | +if let manager = await MameDBManager.forDatabase(at: dbPath) { |
| 40 | + // Get information about a game |
| 41 | + let gameData = try await manager.loadGameDetails(for: "pacman") |
| 42 | + |
| 43 | + // Get merged ROM set |
| 44 | + let mergedRoms = MameDBManager.getMergedSetRoms(from: gameData) |
| 45 | + |
| 46 | + // Print ROM information |
| 47 | + for rom in mergedRoms { |
| 48 | + print("\(rom.name): \(rom.size) bytes, CRC: \(rom.crc)") |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +// Create a database from XML |
| 53 | +let xmlPath = "/path/to/mame.xml" |
| 54 | +let outputPath = "/path/to/output.sqlite" |
| 55 | +let manager = try await MameDBManager.createDatabase( |
| 56 | + from: URL(fileURLWithPath: xmlPath), |
| 57 | + savingTo: URL(fileURLWithPath: outputPath), |
| 58 | + overwrite: true |
| 59 | +) |
| 60 | +``` |
| 61 | + |
| 62 | +## ROM Set Types |
| 63 | + |
| 64 | +The package supports several ROM set formats: |
| 65 | + |
| 66 | +- **Split**: Only ROMs specific to a game |
| 67 | +- **Merged**: ROMs from a game and its parent/clones |
| 68 | +- **Non-merged**: Game ROMs plus parent ROMs |
| 69 | +- **MergedPlus**: Merged set plus device ROMs |
| 70 | +- **MergedFull**: Merged set plus device and BIOS ROMs |
| 71 | +- **NonMergedPlus**: Non-merged set plus device ROMs |
| 72 | +- **NonMergedFull**: Non-merged set plus device and BIOS ROMs |
| 73 | + |
| 74 | +# MAMEDBHandler API Documentation |
| 75 | + |
| 76 | +## Core Components |
| 77 | + |
| 78 | +### MameDBManager |
| 79 | + |
| 80 | +The primary interface for interacting with MAME databases. |
| 81 | + |
| 82 | +#### Initialization |
| 83 | + |
| 84 | +```swift |
| 85 | +// Initialize with an existing database |
| 86 | +public static func forDatabase(at path: String) async -> MameDBManager? |
| 87 | + |
| 88 | +// Create a new database from MAME XML |
| 89 | +public static func createDatabase( |
| 90 | + from xmlURL: URL, |
| 91 | + savingTo outputURL: URL, |
| 92 | + overwrite: Bool = false |
| 93 | +) async throws -> MameDBManager |
| 94 | +``` |
| 95 | + |
| 96 | +#### Game Information |
| 97 | + |
| 98 | +```swift |
| 99 | +// Get MAME version from database |
| 100 | +public func getMameVersion() async throws -> String |
| 101 | + |
| 102 | +// Load detailed information about a specific game |
| 103 | +public func loadGameDetails(for gameId: String) async throws -> MachineData |
| 104 | + |
| 105 | +// Get list of all machines/games |
| 106 | +public func loadAllMachines() async throws -> [MachineInfo] |
| 107 | + |
| 108 | +// Find a machine by ROM CRCs |
| 109 | +public func findMachineWithCRCs(_ crcs: [String]) async throws -> Int? |
| 110 | + |
| 111 | +// Get game name for a machine ID |
| 112 | +public func getGameNameForMachine(_ machineId: Int) async throws -> String? |
| 113 | +``` |
| 114 | + |
| 115 | +#### ROM Set Processing |
| 116 | + |
| 117 | +```swift |
| 118 | +// Get split set (game-specific ROMs only) |
| 119 | +public static func getSplitSetRoms(from data: MachineData) -> [RomInfo] |
| 120 | + |
| 121 | +// Get merged set (game + parent/clone ROMs) |
| 122 | +public static func getMergedSetRoms(from data: MachineData) -> [RomInfo] |
| 123 | + |
| 124 | +// Get non-merged set (game ROMs + required parent ROMs) |
| 125 | +public static func getNonMergedSetRoms(from data: MachineData) -> [RomInfo] |
| 126 | + |
| 127 | +// Variants with device and BIOS ROMs |
| 128 | +public static func getMergedPlusSetRoms(from data: MachineData) -> [RomInfo] |
| 129 | +public static func getMergedFullSetRoms(from data: MachineData) -> [RomInfo] |
| 130 | +public static func getNonMergedPlusSetRoms(from data: MachineData) -> [RomInfo] |
| 131 | +public static func getNonMergedFullSetRoms(from data: MachineData) -> [RomInfo] |
| 132 | + |
| 133 | +// Generic function accepting SetType enum |
| 134 | +public static func getRomSet(type: SetType, from data: MachineData) -> [RomInfo] |
| 135 | +``` |
| 136 | + |
| 137 | +### MasterListManager |
| 138 | + |
| 139 | +Manages cached lists of games to improve performance. |
| 140 | + |
| 141 | +```swift |
| 142 | +// Get the shared instance |
| 143 | +public static let shared: MasterListManager |
| 144 | + |
| 145 | +// Get or load the master list for a specific database version |
| 146 | +public func getMasterList( |
| 147 | + for version: String, |
| 148 | + databasePath: String? = nil |
| 149 | +) async throws -> [MameGame] |
| 150 | +``` |
| 151 | + |
| 152 | +## Data Models |
| 153 | + |
| 154 | +### MachineInfo |
| 155 | + |
| 156 | +Contains metadata about MAME machines (games). |
| 157 | + |
| 158 | +```swift |
| 159 | +public struct MachineInfo { |
| 160 | + public let description: String |
| 161 | + public let name: String |
| 162 | + public let year: String |
| 163 | + public let manufacturer: String |
| 164 | + public let cloneof: String? |
| 165 | + public let parent_name: String? |
| 166 | + public let parent_year: String? |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +### RomInfo |
| 171 | + |
| 172 | +Represents information about ROM files. |
| 173 | + |
| 174 | +```swift |
| 175 | +public struct RomInfo { |
| 176 | + public enum RomType: String { |
| 177 | + case gameRom = "game" |
| 178 | + case cloneRom = "clone" |
| 179 | + case biosRom = "bios" |
| 180 | + case deviceRom = "device" |
| 181 | + } |
| 182 | + |
| 183 | + public let name: String |
| 184 | + public let size: Int64 |
| 185 | + public let crc: String |
| 186 | + public let status: String? |
| 187 | + public let merge: String? |
| 188 | + public let type: RomType |
| 189 | +} |
| 190 | +``` |
| 191 | + |
| 192 | +### MameGame |
| 193 | + |
| 194 | +Comprehensive representation of a MAME game with metadata. |
| 195 | + |
| 196 | +```swift |
| 197 | +public struct MameGame: Identifiable { |
| 198 | + public var id: String { name } |
| 199 | + |
| 200 | + public let name: String |
| 201 | + public let description: String |
| 202 | + public let year: String |
| 203 | + public let manufacturer: String |
| 204 | + public var roms: [RomInfo] |
| 205 | + public let gameRating: GameRating? |
| 206 | + public let languages: [String] |
| 207 | + public let machineType: String? |
| 208 | + public let category: String? |
| 209 | + public let subcategory: String? |
| 210 | + public let isMature: Bool |
| 211 | + public let shortTitle: String? |
| 212 | + public var source: GameSource |
| 213 | + public var parent: String? |
| 214 | + // Additional properties... |
| 215 | +} |
| 216 | +``` |
| 217 | + |
| 218 | +### MachineData |
| 219 | + |
| 220 | +Comprehensive data structure for a machine and its ROMs. |
| 221 | + |
| 222 | +```swift |
| 223 | +public struct MachineData { |
| 224 | + public let machine: MachineInfo |
| 225 | + public let parent: MachineInfo? |
| 226 | + public let allRoms: [RomWithMetadata] |
| 227 | + |
| 228 | + // Derived properties |
| 229 | + public var directRoms: [RomWithMetadata] |
| 230 | + public var parentRoms: [RomWithMetadata] |
| 231 | + public var deviceRoms: [RomWithMetadata] |
| 232 | + public var biosRoms: [RomWithMetadata] |
| 233 | +} |
| 234 | +``` |
| 235 | + |
| 236 | +## Error Handling |
| 237 | + |
| 238 | +```swift |
| 239 | +public enum DBError: LocalizedError { |
| 240 | + case queryPreparationFailed |
| 241 | + case recordNotFound |
| 242 | + case deviceRecursionLimit |
| 243 | + case databaseNotInitialized |
| 244 | + case operationFailed(String) |
| 245 | +} |
| 246 | +``` |
| 247 | + |
| 248 | +## Constants and Enums |
| 249 | + |
| 250 | +```swift |
| 251 | +public enum SetType: String { |
| 252 | + case split |
| 253 | + case merged |
| 254 | + case nonmerged |
| 255 | + case mergedplus |
| 256 | + case mergedfull |
| 257 | + case nonmergedplus |
| 258 | + case nonmergedfull |
| 259 | +} |
| 260 | +``` |
| 261 | + |
| 262 | +## License |
| 263 | + |
| 264 | +MIT License |
0 commit comments