Skip to content

Commit 5fb3a46

Browse files
committed
Fixes map & bot image previews in iOS menu.
1 parent c36e341 commit 5fb3a46

File tree

4 files changed

+175
-16
lines changed

4 files changed

+175
-16
lines changed

Quake3-iOS/BotMatchBotViewController.swift

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,16 @@ extension BotMatchBotViewController : UICollectionViewDelegate {
209209

210210
let fileManager = FileManager()
211211
if fileManager.fileExists(atPath: destinationURL.path) {
212-
213212
let img: UIImage = UIImage.image(fromTGAFile: destinationURL.path) as! UIImage
214213
cell.botAvatar.contentMode = .scaleAspectFit
215214
cell.botAvatar.image = img
215+
} else {
216+
// Create a fallback image with bot name initials
217+
let botName = bots[indexPath.row].name
218+
let initials = String(botName.prefix(2)).uppercased()
219+
let fallbackImage = createFallbackImage(with: initials)
220+
cell.botAvatar.contentMode = .scaleAspectFit
221+
cell.botAvatar.image = fallbackImage
216222
}
217223

218224
cell.botName.text = bots[indexPath.row].name
@@ -225,10 +231,40 @@ extension BotMatchBotViewController : UICollectionViewDelegate {
225231
cell.botAvatar.layer.borderWidth = 0
226232
}
227233

228-
229234
return cell
230235
}
231236

237+
private func createFallbackImage(with text: String) -> UIImage {
238+
let size = CGSize(width: 64, height: 64)
239+
UIGraphicsBeginImageContextWithOptions(size, false, 0)
240+
241+
// Draw background
242+
UIColor.darkGray.setFill()
243+
UIRectFill(CGRect(origin: .zero, size: size))
244+
245+
// Draw text
246+
let font = UIFont.boldSystemFont(ofSize: 20)
247+
let attributes: [NSAttributedString.Key: Any] = [
248+
.font: font,
249+
.foregroundColor: UIColor.orange
250+
]
251+
252+
let textSize = text.size(withAttributes: attributes)
253+
let textRect = CGRect(
254+
x: (size.width - textSize.width) / 2,
255+
y: (size.height - textSize.height) / 2,
256+
width: textSize.width,
257+
height: textSize.height
258+
)
259+
260+
text.draw(in: textRect, withAttributes: attributes)
261+
262+
let image = UIGraphicsGetImageFromCurrentImageContext()
263+
UIGraphicsEndImageContext()
264+
265+
return image ?? UIImage()
266+
}
267+
232268
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
233269
let cell = collectionView.cellForItem(at: indexPath) as! BotCollectionViewCell
234270
self.selectedBot = bots[indexPath.row].name

Quake3-iOS/BotMatchMapViewController.swift

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ class BotMatchMapViewController: UIViewController {
5555
mapList.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
5656

5757
#if os(tvOS)
58-
let documentsDir = try! FileManager().url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
58+
currentWorkingPath = try! FileManager().url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
5959
#else
60-
let documentsDir = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
60+
currentWorkingPath = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
6161
#endif
6262
}
6363

@@ -85,7 +85,52 @@ extension BotMatchMapViewController : UITableViewDelegate {
8585
self.delegate?.setMap(map: maps[indexPath.row].map, name: maps[indexPath.row].name)
8686
var destinationURL = URL(fileURLWithPath: currentWorkingPath)
8787
destinationURL.appendPathComponent("graphics/\(maps[indexPath.row].map).jpg")
88-
mapShot.image = UIImage(contentsOfFile: destinationURL.path)
88+
89+
if let image = UIImage(contentsOfFile: destinationURL.path) {
90+
mapShot.image = image
91+
} else {
92+
// Create fallback image with map name
93+
let fallbackImage = createFallbackMapImage(with: maps[indexPath.row].map)
94+
mapShot.image = fallbackImage
95+
}
96+
}
97+
98+
private func createFallbackMapImage(with mapName: String) -> UIImage {
99+
let size = CGSize(width: 200, height: 150)
100+
UIGraphicsBeginImageContextWithOptions(size, false, 0)
101+
102+
// Draw background
103+
UIColor.darkGray.setFill()
104+
UIRectFill(CGRect(origin: .zero, size: size))
105+
106+
// Draw border
107+
UIColor.orange.setStroke()
108+
let borderRect = CGRect(origin: .zero, size: size).insetBy(dx: 2, dy: 2)
109+
let borderPath = UIBezierPath(rect: borderRect)
110+
borderPath.lineWidth = 2
111+
borderPath.stroke()
112+
113+
// Draw text
114+
let font = UIFont.boldSystemFont(ofSize: 16)
115+
let attributes: [NSAttributedString.Key: Any] = [
116+
.font: font,
117+
.foregroundColor: UIColor.orange
118+
]
119+
120+
let textSize = mapName.size(withAttributes: attributes)
121+
let textRect = CGRect(
122+
x: (size.width - textSize.width) / 2,
123+
y: (size.height - textSize.height) / 2,
124+
width: textSize.width,
125+
height: textSize.height
126+
)
127+
128+
mapName.draw(in: textRect, withAttributes: attributes)
129+
130+
let image = UIGraphicsGetImageFromCurrentImageContext()
131+
UIGraphicsEndImageContext()
132+
133+
return image ?? UIImage()
89134
}
90135

91136
}
@@ -103,7 +148,14 @@ extension BotMatchMapViewController : UITableViewDataSource {
103148
cell.setSelected(true, animated: false)
104149
var destinationURL = URL(fileURLWithPath: currentWorkingPath)
105150
destinationURL.appendPathComponent("graphics/\(maps[indexPath.row].map).jpg")
106-
mapShot.image = UIImage(contentsOfFile: destinationURL.path)
151+
152+
if let image = UIImage(contentsOfFile: destinationURL.path) {
153+
mapShot.image = image
154+
} else {
155+
// Create fallback image with map name
156+
let fallbackImage = createFallbackMapImage(with: maps[indexPath.row].map)
157+
mapShot.image = fallbackImage
158+
}
107159
}
108160

109161
return cell

Quake3-iOS/BotMatchViewController.swift

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,12 @@ class BotMatchViewController: UIViewController {
5454
botList.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
5555

5656
#if os(tvOS)
57-
let documentsDir = try! FileManager().url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
57+
documentsDir = try! FileManager().url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
5858
#else
59-
let documentsDir = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
59+
documentsDir = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
6060
#endif
6161

62-
var destinationURL = URL(fileURLWithPath: documentsDir)
63-
destinationURL.appendPathComponent("graphics/\(selectedMap).jpg")
64-
mapShot.image = UIImage(contentsOfFile: destinationURL.path)
62+
updateMapPreview()
6563

6664
var skill1URL = URL(fileURLWithPath: documentsDir)
6765
skill1URL.appendPathComponent("graphics/menu/art/skill1.tga")
@@ -89,6 +87,57 @@ class BotMatchViewController: UIViewController {
8987
skill5Button.setImage(UIImage.image(fromTGAFile: skill5URL.path) as? UIImage, for: .normal)
9088
skill5Button.layer.borderColor = UIColor.red.cgColor
9189
}
90+
91+
private func updateMapPreview() {
92+
var destinationURL = URL(fileURLWithPath: documentsDir)
93+
destinationURL.appendPathComponent("graphics/\(selectedMap).jpg")
94+
95+
if let image = UIImage(contentsOfFile: destinationURL.path) {
96+
mapShot.image = image
97+
} else {
98+
// Create fallback image with map name
99+
let fallbackImage = createFallbackMapImage(with: selectedMap)
100+
mapShot.image = fallbackImage
101+
}
102+
}
103+
104+
private func createFallbackMapImage(with mapName: String) -> UIImage {
105+
let size = CGSize(width: 200, height: 150)
106+
UIGraphicsBeginImageContextWithOptions(size, false, 0)
107+
108+
// Draw background
109+
UIColor.darkGray.setFill()
110+
UIRectFill(CGRect(origin: .zero, size: size))
111+
112+
// Draw border
113+
UIColor.orange.setStroke()
114+
let borderRect = CGRect(origin: .zero, size: size).insetBy(dx: 2, dy: 2)
115+
let borderPath = UIBezierPath(rect: borderRect)
116+
borderPath.lineWidth = 2
117+
borderPath.stroke()
118+
119+
// Draw text
120+
let font = UIFont.boldSystemFont(ofSize: 16)
121+
let attributes: [NSAttributedString.Key: Any] = [
122+
.font: font,
123+
.foregroundColor: UIColor.orange
124+
]
125+
126+
let textSize = mapName.size(withAttributes: attributes)
127+
let textRect = CGRect(
128+
x: (size.width - textSize.width) / 2,
129+
y: (size.height - textSize.height) / 2,
130+
width: textSize.width,
131+
height: textSize.height
132+
)
133+
134+
mapName.draw(in: textRect, withAttributes: attributes)
135+
136+
let image = UIGraphicsGetImageFromCurrentImageContext()
137+
UIGraphicsEndImageContext()
138+
139+
return image ?? UIImage()
140+
}
92141

93142
// MARK: - Navigation
94143

@@ -171,9 +220,7 @@ extension BotMatchViewController: BotMatchProtocol {
171220
func setMap(map: String, name: String) {
172221
mapButton.setTitle(map, for: .normal)
173222
selectedMap = map
174-
var destinationURL = URL(fileURLWithPath: documentsDir)
175-
destinationURL.appendPathComponent("graphics/\(selectedMap).jpg")
176-
mapShot.image = UIImage(contentsOfFile: destinationURL.path)
223+
updateMapPreview()
177224
}
178225

179226
func addBot(bot: String, difficulty: Float, icon:String) {

Quake3-iOS/MainMenuViewController.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ class MainMenuViewController: UIViewController {
161161

162162
func extractFile(pk3: String, source: String, destination: String) {
163163
let fileManager = FileManager()
164-
let currentWorkingPath = fileManager.currentDirectoryPath
165164
#if os(tvOS)
166165
let documentsDir = try! FileManager().url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true).path
167166
#else
@@ -172,19 +171,44 @@ class MainMenuViewController: UIViewController {
172171
destinationURL.appendPathComponent(destination)
173172

174173
if fileManager.fileExists(atPath: destinationURL.path) {
174+
print("File already exists at \(destinationURL.path)")
175175
return
176176
}
177177

178-
var archiveURL = URL(fileURLWithPath: currentWorkingPath)
178+
// Look for PK3 files in Documents/baseq3 directory
179+
var archiveURL = URL(fileURLWithPath: documentsDir)
179180
archiveURL.appendPathComponent(pk3)
181+
182+
// If PK3 doesn't exist in Documents, try app bundle as fallback
183+
if !fileManager.fileExists(atPath: archiveURL.path) {
184+
print("PK3 not found at \(archiveURL.path), trying app bundle...")
185+
if let bundlePath = Bundle.main.resourcePath {
186+
archiveURL = URL(fileURLWithPath: bundlePath)
187+
archiveURL.appendPathComponent(pk3)
188+
}
189+
}
190+
191+
print("Attempting to open archive at: \(archiveURL.path)")
180192
guard let archive = Archive(url: archiveURL, accessMode: .read) else {
193+
print("Could not open archive at path: \(archiveURL.path)")
181194
return
182195
}
183196
guard let entry = archive[source] else {
197+
print("Could not find entry '\(source)' in archive \(archiveURL.path)")
184198
return
185199
}
200+
201+
// Create directory structure if needed
202+
let destinationDir = destinationURL.deletingLastPathComponent()
203+
do {
204+
try fileManager.createDirectory(at: destinationDir, withIntermediateDirectories: true, attributes: nil)
205+
} catch {
206+
print("Failed to create directory \(destinationDir.path): \(error)")
207+
}
208+
186209
do {
187210
let _ = try archive.extract(entry, to: destinationURL)
211+
print("Successfully extracted \(source) to \(destinationURL.path)")
188212
} catch {
189213
print("Extracting entry from archive failed with error:\(error)")
190214
}

0 commit comments

Comments
 (0)