3547
|
1 |
//
|
|
2 |
// gameSetup.m
|
|
3 |
// hwengine
|
|
4 |
//
|
|
5 |
// Created by Vittorio on 10/01/10.
|
|
6 |
// Copyright 2010 __MyCompanyName__. All rights reserved.
|
|
7 |
//
|
|
8 |
|
|
9 |
#include <sys/types.h>
|
|
10 |
#include <sys/sysctl.h>
|
|
11 |
|
|
12 |
#import "GameSetup.h"
|
|
13 |
#import "SDL_uikitappdelegate.h"
|
|
14 |
#import "SDL_net.h"
|
|
15 |
#import "PascalImports.h"
|
|
16 |
#import "CommodityFunctions.h"
|
|
17 |
|
|
18 |
#define BUFFER_SIZE 256
|
|
19 |
#define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
|
|
20 |
|
|
21 |
@implementation GameSetup
|
|
22 |
|
|
23 |
@synthesize systemSettings, gameConfig;
|
|
24 |
|
|
25 |
-(id) init {
|
|
26 |
if (self = [super init]) {
|
|
27 |
ipcPort = randomPort();
|
|
28 |
|
|
29 |
// should check they exist and throw and exection if not
|
|
30 |
NSDictionary *dictSett = [[NSDictionary alloc] initWithContentsOfFile:SETTINGS_FILE()];
|
|
31 |
self.systemSettings = dictSett;
|
|
32 |
[dictSett release];
|
|
33 |
|
|
34 |
NSDictionary *dictGame = [[NSDictionary alloc] initWithContentsOfFile:GAMECONFIG_FILE()];
|
|
35 |
self.gameConfig = dictGame;
|
|
36 |
[dictGame release];
|
|
37 |
}
|
|
38 |
return self;
|
|
39 |
}
|
|
40 |
|
|
41 |
-(NSString *)description {
|
|
42 |
return [NSString stringWithFormat:@"ipcport: %d\nsockets: %d,%d\n teams: %@\n systemSettings: %@",ipcPort,sd,csd,gameConfig,systemSettings];
|
|
43 |
}
|
|
44 |
|
|
45 |
-(void) dealloc {
|
|
46 |
[gameConfig release];
|
|
47 |
[systemSettings release];
|
|
48 |
[super dealloc];
|
|
49 |
}
|
|
50 |
|
|
51 |
#pragma mark -
|
|
52 |
#pragma mark Provider functions
|
|
53 |
// unpacks team data from the selected team.plist to a sequence of engine commands
|
|
54 |
-(void) provideTeamData:(NSString *)teamName forHogs:(NSInteger) numberOfPlayingHogs withHealth:(NSInteger) initialHealth ofColor:(NSNumber *)teamColor {
|
|
55 |
/*
|
|
56 |
addteam <32charsMD5hash> <color> <team name>
|
|
57 |
addhh <level> <health> <hedgehog name>
|
|
58 |
<level> is 0 for human, 1-5 for bots (5 is the most stupid)
|
|
59 |
*/
|
|
60 |
|
|
61 |
NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@", TEAMS_DIRECTORY(), teamName];
|
|
62 |
NSDictionary *teamData = [[NSDictionary alloc] initWithContentsOfFile:teamFile];
|
|
63 |
[teamFile release];
|
|
64 |
|
|
65 |
NSString *teamHashColorAndName = [[NSString alloc] initWithFormat:@"eaddteam %@ %@ %@",
|
|
66 |
[teamData objectForKey:@"hash"], [teamColor stringValue], [teamData objectForKey:@"teamname"]];
|
|
67 |
[self sendToEngine: teamHashColorAndName];
|
|
68 |
[teamHashColorAndName release];
|
|
69 |
|
|
70 |
NSString *grave = [[NSString alloc] initWithFormat:@"egrave %@", [teamData objectForKey:@"grave"]];
|
|
71 |
[self sendToEngine: grave];
|
|
72 |
[grave release];
|
|
73 |
|
|
74 |
NSString *fort = [[NSString alloc] initWithFormat:@"efort %@", [teamData objectForKey:@"fort"]];
|
|
75 |
[self sendToEngine: fort];
|
|
76 |
[fort release];
|
|
77 |
|
|
78 |
NSString *voicepack = [[NSString alloc] initWithFormat:@"evoicepack %@", [teamData objectForKey:@"voicepack"]];
|
|
79 |
[self sendToEngine: voicepack];
|
|
80 |
[voicepack release];
|
|
81 |
|
|
82 |
NSString *flag = [[NSString alloc] initWithFormat:@"eflag %@", [teamData objectForKey:@"flag"]];
|
|
83 |
[self sendToEngine: flag];
|
|
84 |
[flag release];
|
|
85 |
|
|
86 |
NSArray *hogs = [teamData objectForKey:@"hedgehogs"];
|
|
87 |
for (int i = 0; i < numberOfPlayingHogs; i++) {
|
|
88 |
NSDictionary *hog = [hogs objectAtIndex:i];
|
|
89 |
|
|
90 |
NSString *hogLevelHealthAndName = [[NSString alloc] initWithFormat:@"eaddhh %@ %d %@",
|
|
91 |
[hog objectForKey:@"level"], initialHealth, [hog objectForKey:@"hogname"]];
|
|
92 |
[self sendToEngine: hogLevelHealthAndName];
|
|
93 |
[hogLevelHealthAndName release];
|
|
94 |
|
|
95 |
NSString *hogHat = [[NSString alloc] initWithFormat:@"ehat %@", [hog objectForKey:@"hat"]];
|
|
96 |
[self sendToEngine: hogHat];
|
|
97 |
[hogHat release];
|
|
98 |
}
|
|
99 |
|
|
100 |
[teamData release];
|
|
101 |
}
|
|
102 |
|
|
103 |
// unpacks ammostore data from the selected ammo.plist to a sequence of engine commands
|
|
104 |
-(void) provideAmmoData:(NSString *)ammostoreName forPlayingTeams:(NSInteger) numberOfTeams {
|
|
105 |
NSString *weaponPath = [[NSString alloc] initWithFormat:@"%@/%@",WEAPONS_DIRECTORY(),ammostoreName];
|
|
106 |
NSDictionary *ammoData = [[NSDictionary alloc] initWithContentsOfFile:weaponPath];
|
|
107 |
[weaponPath release];
|
|
108 |
|
|
109 |
NSString *ammloadt = [[NSString alloc] initWithFormat:@"eammloadt %@", [ammoData objectForKey:@"ammostore_initialqt"]];
|
|
110 |
[self sendToEngine: ammloadt];
|
|
111 |
[ammloadt release];
|
|
112 |
|
|
113 |
NSString *ammprob = [[NSString alloc] initWithFormat:@"eammprob %@", [ammoData objectForKey:@"ammostore_probability"]];
|
|
114 |
[self sendToEngine: ammprob];
|
|
115 |
[ammprob release];
|
|
116 |
|
|
117 |
NSString *ammdelay = [[NSString alloc] initWithFormat:@"eammdelay %@", [ammoData objectForKey:@"ammostore_delay"]];
|
|
118 |
[self sendToEngine: ammdelay];
|
|
119 |
[ammdelay release];
|
|
120 |
|
|
121 |
NSString *ammreinf = [[NSString alloc] initWithFormat:@"eammreinf %@", [ammoData objectForKey:@"ammostore_crate"]];
|
|
122 |
[self sendToEngine: ammreinf];
|
|
123 |
[ammreinf release];
|
|
124 |
|
|
125 |
// sent twice so it applies to both teams
|
|
126 |
NSString *ammstore = [[NSString alloc] initWithString:@"eammstore"];
|
|
127 |
for (int i = 0; i < numberOfTeams; i++)
|
|
128 |
[self sendToEngine: ammstore];
|
|
129 |
[ammstore release];
|
|
130 |
|
|
131 |
[ammoData release];
|
|
132 |
}
|
|
133 |
|
|
134 |
// unpacks scheme data from the selected scheme.plist to a sequence of engine commands
|
|
135 |
-(NSInteger) provideScheme:(NSString *)schemeName {
|
|
136 |
NSString *schemePath = [[NSString alloc] initWithFormat:@"%@/%@",SCHEMES_DIRECTORY(),schemeName];
|
|
137 |
NSArray *scheme = [[NSArray alloc] initWithContentsOfFile:schemePath];
|
|
138 |
[schemePath release];
|
|
139 |
int result = 0;
|
|
140 |
int i = 0;
|
|
141 |
|
|
142 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
143 |
result |= 0x01;
|
|
144 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
145 |
result |= 0x10;
|
|
146 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
147 |
result |= 0x04;
|
|
148 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
149 |
result |= 0x08;
|
|
150 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
151 |
result |= 0x20;
|
|
152 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
153 |
result |= 0x40;
|
|
154 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
155 |
result |= 0x80;
|
|
156 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
157 |
result |= 0x100;
|
|
158 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
159 |
result |= 0x200;
|
|
160 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
161 |
result |= 0x400;
|
|
162 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
163 |
result |= 0x800;
|
|
164 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
165 |
result |= 0x2000;
|
|
166 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
167 |
result |= 0x4000;
|
|
168 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
169 |
result |= 0x8000;
|
|
170 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
171 |
result |= 0x10000;
|
|
172 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
173 |
result |= 0x20000;
|
|
174 |
if ([[scheme objectAtIndex:i++] boolValue])
|
|
175 |
result |= 0x80000;
|
|
176 |
|
|
177 |
NSString *flags = [[NSString alloc] initWithFormat:@"e$gmflags %d",result];
|
|
178 |
[self sendToEngine:flags];
|
|
179 |
[flags release];
|
|
180 |
|
|
181 |
NSString *dmgMod = [[NSString alloc] initWithFormat:@"e$damagepct %d",[[scheme objectAtIndex:i++] intValue]];
|
|
182 |
[self sendToEngine:dmgMod];
|
|
183 |
[dmgMod release];
|
|
184 |
|
|
185 |
NSString *turnTime = [[NSString alloc] initWithFormat:@"e$turntime %d",[[scheme objectAtIndex:i++] intValue] * 1000];
|
|
186 |
[self sendToEngine:turnTime];
|
|
187 |
[turnTime release];
|
|
188 |
|
|
189 |
result = [[scheme objectAtIndex:i++] intValue]; // initial health
|
|
190 |
|
|
191 |
NSString *sdTime = [[NSString alloc] initWithFormat:@"e$sd_turns %d",[[scheme objectAtIndex:i++] intValue]];
|
|
192 |
[self sendToEngine:sdTime];
|
|
193 |
[sdTime release];
|
|
194 |
|
|
195 |
NSString *crateDrops = [[NSString alloc] initWithFormat:@"e$casefreq %d",[[scheme objectAtIndex:i++] intValue]];
|
|
196 |
[self sendToEngine:crateDrops];
|
|
197 |
[crateDrops release];
|
|
198 |
|
|
199 |
NSString *minesTime = [[NSString alloc] initWithFormat:@"e$minestime %d",[[scheme objectAtIndex:i++] intValue] * 1000];
|
|
200 |
[self sendToEngine:minesTime];
|
|
201 |
[minesTime release];
|
|
202 |
|
|
203 |
NSString *minesNumber = [[NSString alloc] initWithFormat:@"e$landadds %d",[[scheme objectAtIndex:i++] intValue]];
|
|
204 |
[self sendToEngine:minesNumber];
|
|
205 |
[minesNumber release];
|
|
206 |
|
|
207 |
NSString *dudMines = [[NSString alloc] initWithFormat:@"e$minedudpct %d",[[scheme objectAtIndex:i++] intValue]];
|
|
208 |
[self sendToEngine:dudMines];
|
|
209 |
[dudMines release];
|
|
210 |
|
|
211 |
NSString *explosives = [[NSString alloc] initWithFormat:@"e$explosives %d",[[scheme objectAtIndex:i++] intValue]];
|
|
212 |
[self sendToEngine:explosives];
|
|
213 |
[explosives release];
|
|
214 |
|
|
215 |
[scheme release];
|
|
216 |
return result;
|
|
217 |
}
|
|
218 |
|
|
219 |
#pragma mark -
|
|
220 |
#pragma mark Thread/Network relevant code
|
|
221 |
// select one of GameSetup method and execute it in a seprate thread
|
|
222 |
-(void) startThread: (NSString *) selector {
|
|
223 |
SEL usage = NSSelectorFromString(selector);
|
|
224 |
[NSThread detachNewThreadSelector:usage toTarget:self withObject:nil];
|
|
225 |
}
|
|
226 |
|
|
227 |
// wrapper that computes the length of the message and then sends the command string
|
|
228 |
-(int) sendToEngine: (NSString *)string {
|
|
229 |
uint8_t length = [string length];
|
|
230 |
|
|
231 |
SDLNet_TCP_Send(csd, &length , 1);
|
|
232 |
return SDLNet_TCP_Send(csd, [string UTF8String], length);
|
|
233 |
}
|
|
234 |
|
|
235 |
// method that handles net setup with engine and keeps connection alive
|
|
236 |
-(void) engineProtocol {
|
|
237 |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
238 |
IPaddress ip;
|
|
239 |
int eProto;
|
|
240 |
BOOL clientQuit, serverQuit;
|
|
241 |
char buffer[BUFFER_SIZE], string[BUFFER_SIZE];
|
|
242 |
uint8_t msgSize;
|
|
243 |
uint16_t gameTicks;
|
|
244 |
|
|
245 |
serverQuit = NO;
|
|
246 |
|
|
247 |
if (SDLNet_Init() < 0) {
|
|
248 |
DLog(@"SDLNet_Init: %s", SDLNet_GetError());
|
|
249 |
serverQuit = YES;
|
|
250 |
}
|
|
251 |
|
|
252 |
// Resolving the host using NULL make network interface to listen
|
|
253 |
if (SDLNet_ResolveHost(&ip, NULL, ipcPort) < 0) {
|
|
254 |
DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
|
|
255 |
serverQuit = YES;
|
|
256 |
}
|
|
257 |
|
|
258 |
// Open a connection with the IP provided (listen on the host's port)
|
|
259 |
if (!(sd = SDLNet_TCP_Open(&ip))) {
|
|
260 |
DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), ipcPort);
|
|
261 |
serverQuit = YES;
|
|
262 |
}
|
|
263 |
|
|
264 |
DLog(@"Waiting for a client on port %d", ipcPort);
|
|
265 |
while (!serverQuit) {
|
|
266 |
// This check the sd if there is a pending connection.
|
|
267 |
// If there is one, accept that, and open a new socket for communicating
|
|
268 |
csd = SDLNet_TCP_Accept(sd);
|
|
269 |
if (NULL != csd) {
|
|
270 |
// Now we can communicate with the client using csd socket
|
|
271 |
// sd will remain opened waiting other connections
|
|
272 |
DLog(@"client found");
|
|
273 |
|
|
274 |
//first byte of the command alwayas contain the size of the command
|
|
275 |
SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t));
|
|
276 |
|
|
277 |
SDLNet_TCP_Recv(csd, buffer, msgSize);
|
|
278 |
gameTicks = SDLNet_Read16 (&buffer[msgSize - 2]);
|
|
279 |
//DLog(@"engineProtocol - %d: received [%s]", gameTicks, buffer);
|
|
280 |
|
|
281 |
if ('C' == buffer[0]) {
|
|
282 |
DLog(@"sending game config");
|
|
283 |
|
|
284 |
// local game
|
|
285 |
[self sendToEngine:@"TL"];
|
|
286 |
|
|
287 |
// seed info
|
|
288 |
[self sendToEngine:[self.gameConfig objectForKey:@"seed_command"]];
|
|
289 |
|
|
290 |
// dimension of the map
|
|
291 |
[self sendToEngine:[self.gameConfig objectForKey:@"templatefilter_command"]];
|
|
292 |
[self sendToEngine:[self.gameConfig objectForKey:@"mapgen_command"]];
|
|
293 |
[self sendToEngine:[self.gameConfig objectForKey:@"mazesize_command"]];
|
|
294 |
|
|
295 |
// theme info
|
|
296 |
[self sendToEngine:[self.gameConfig objectForKey:@"theme_command"]];
|
|
297 |
|
|
298 |
// scheme (returns initial health)
|
|
299 |
NSInteger health = [self provideScheme:[self.gameConfig objectForKey:@"scheme"]];
|
|
300 |
|
|
301 |
NSArray *teamsConfig = [self.gameConfig objectForKey:@"teams_list"];
|
|
302 |
for (NSDictionary *teamData in teamsConfig) {
|
|
303 |
[self provideTeamData:[teamData objectForKey:@"team"]
|
|
304 |
forHogs:[[teamData objectForKey:@"number"] intValue]
|
|
305 |
withHealth:health
|
|
306 |
ofColor:[teamData objectForKey:@"color"]];
|
|
307 |
}
|
|
308 |
|
|
309 |
[self provideAmmoData:@"Default.plist" forPlayingTeams:[teamsConfig count]];
|
|
310 |
|
|
311 |
clientQuit = NO;
|
|
312 |
} else {
|
|
313 |
DLog(@"wrong message or client closed connection");
|
|
314 |
clientQuit = YES;
|
|
315 |
}
|
|
316 |
|
|
317 |
while (!clientQuit){
|
|
318 |
msgSize = 0;
|
|
319 |
memset(buffer, 0, BUFFER_SIZE);
|
|
320 |
memset(string, 0, BUFFER_SIZE);
|
|
321 |
if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t)) <= 0)
|
|
322 |
clientQuit = YES;
|
|
323 |
if (SDLNet_TCP_Recv(csd, buffer, msgSize) <=0)
|
|
324 |
clientQuit = YES;
|
|
325 |
|
|
326 |
gameTicks = SDLNet_Read16(&buffer[msgSize - 2]);
|
|
327 |
//DLog(@"engineProtocolThread - %d: received [%s]", gameTicks, buffer);
|
|
328 |
|
|
329 |
switch (buffer[0]) {
|
|
330 |
case '?':
|
|
331 |
DLog(@"Ping? Pong!");
|
|
332 |
[self sendToEngine:@"!"];
|
|
333 |
break;
|
|
334 |
case 'E':
|
|
335 |
DLog(@"ERROR - last console line: [%s]", buffer);
|
|
336 |
clientQuit = YES;
|
|
337 |
break;
|
|
338 |
case 'e':
|
|
339 |
sscanf(buffer, "%*s %d", &eProto);
|
|
340 |
short int netProto = 0;
|
|
341 |
char *versionStr;
|
|
342 |
|
|
343 |
HW_versionInfo(&netProto, &versionStr);
|
|
344 |
if (netProto == eProto) {
|
|
345 |
DLog(@"Setting protocol version %d (%s)", eProto, versionStr);
|
|
346 |
} else {
|
|
347 |
DLog(@"ERROR - wrong protocol number: [%s] - expecting %d", buffer, eProto);
|
|
348 |
clientQuit = YES;
|
|
349 |
}
|
|
350 |
|
|
351 |
break;
|
|
352 |
case 'i':
|
|
353 |
switch (buffer[1]) {
|
|
354 |
case 'r':
|
|
355 |
NSLog(@"Winning team: %s", &buffer[2]);
|
|
356 |
break;
|
|
357 |
case 'k':
|
|
358 |
NSLog(@"Best Hedgehog: %s", &buffer[2]);
|
|
359 |
break;
|
|
360 |
}
|
|
361 |
break;
|
|
362 |
default:
|
|
363 |
// empty packet or just statistics
|
|
364 |
break;
|
|
365 |
// missing case for exiting right away
|
|
366 |
}
|
|
367 |
}
|
|
368 |
DLog(@"Engine exited, closing server");
|
|
369 |
// wait a little to let the client close cleanly
|
|
370 |
[NSThread sleepForTimeInterval:2];
|
|
371 |
// Close the client socket
|
|
372 |
SDLNet_TCP_Close(csd);
|
|
373 |
serverQuit = YES;
|
|
374 |
}
|
|
375 |
}
|
|
376 |
|
|
377 |
SDLNet_TCP_Close(sd);
|
|
378 |
SDLNet_Quit();
|
|
379 |
|
|
380 |
[[NSFileManager defaultManager] removeItemAtPath:GAMECONFIG_FILE() error:NULL];
|
|
381 |
|
|
382 |
[pool release];
|
|
383 |
//Invoking this method should be avoided as it does not give your thread a chance to clean up any resources it allocated during its execution.
|
|
384 |
//[NSThread exit];
|
|
385 |
}
|
|
386 |
|
|
387 |
#pragma mark -
|
|
388 |
#pragma mark Setting methods
|
|
389 |
// returns an array of c-strings that are read by engine at startup
|
|
390 |
-(const char **)getSettings {
|
|
391 |
NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", ipcPort];
|
|
392 |
NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
|
|
393 |
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
|
394 |
NSString *wSize = [[NSString alloc] initWithFormat:@"%d", (int) screenBounds.size.width];
|
|
395 |
NSString *hSize = [[NSString alloc] initWithFormat:@"%d", (int) screenBounds.size.height];
|
|
396 |
const char **gameArgs = (const char**) malloc(sizeof(char *) * 9);
|
|
397 |
|
|
398 |
/*
|
|
399 |
size_t size;
|
|
400 |
// Set 'oldp' parameter to NULL to get the size of the data returned so we can allocate appropriate amount of space
|
|
401 |
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
|
|
402 |
char *name = malloc(size);
|
|
403 |
// Get the platform name
|
|
404 |
sysctlbyname("hw.machine", name, &size, NULL, 0);
|
|
405 |
NSString *machine = [[NSString alloc] initWithUTF8String:name];
|
|
406 |
free(name);
|
|
407 |
|
|
408 |
const char **gameArgs = (const char**) malloc(sizeof(char*) * 9);
|
|
409 |
|
|
410 |
// if the machine is less than iphone 3gs or less than ipod touch 3g use reduced graphics (land array)
|
|
411 |
if ([machine hasPrefix:@"iPhone1"] || ([machine hasPrefix:@"iPod"] && ([machine hasSuffix:@"1,1"] || [machine hasSuffix:@"2,1"])))
|
|
412 |
gameArgs[8] = "1";
|
|
413 |
else
|
|
414 |
gameArgs[8] = "0";
|
|
415 |
[machine release];
|
|
416 |
*/
|
|
417 |
|
|
418 |
// prevents using an empty nickname
|
|
419 |
NSString *username;
|
|
420 |
NSString *originalUsername = [self.systemSettings objectForKey:@"username"];
|
|
421 |
if ([originalUsername length] == 0)
|
|
422 |
username = [[NSString alloc] initWithFormat:@"MobileUser-%@",ipcString];
|
|
423 |
else
|
|
424 |
username = [[NSString alloc] initWithString:originalUsername];
|
|
425 |
|
|
426 |
gameArgs[0] = [username UTF8String]; //UserNick
|
|
427 |
gameArgs[1] = [ipcString UTF8String]; //ipcPort
|
|
428 |
gameArgs[2] = [[[self.systemSettings objectForKey:@"sound"] stringValue] UTF8String]; //isSoundEnabled
|
|
429 |
gameArgs[3] = [[[self.systemSettings objectForKey:@"music"] stringValue] UTF8String]; //isMusicEnabled
|
|
430 |
gameArgs[4] = [localeString UTF8String]; //cLocaleFName
|
|
431 |
gameArgs[5] = [[[self.systemSettings objectForKey:@"alternate"] stringValue] UTF8String]; //cAltDamage
|
|
432 |
gameArgs[6] = [wSize UTF8String]; //cScreenHeight
|
|
433 |
gameArgs[7] = [hSize UTF8String]; //cScreenWidth
|
|
434 |
gameArgs[8] = NULL; //recordFileName
|
|
435 |
|
|
436 |
[wSize release];
|
|
437 |
[hSize release];
|
|
438 |
[localeString release];
|
|
439 |
[ipcString release];
|
|
440 |
[username release];
|
|
441 |
return gameArgs;
|
|
442 |
}
|
|
443 |
|
|
444 |
|
|
445 |
@end
|