Changeset 958
- Timestamp:
- 06/09/08 21:56:12 (3 months ago)
- Files:
-
- trunk/src/Makefile.osx (modified) (5 diffs)
- trunk/src/angband.man (modified) (1 diff)
- trunk/src/externs.h (modified) (1 diff)
- trunk/src/load.c (modified) (6 diffs)
- trunk/src/main-crb.c (modified) (33 diffs)
- trunk/src/main-win.c (modified) (2 diffs)
- trunk/src/main.c (modified) (2 diffs)
- trunk/src/osx/English.lproj/main.nib/objects.xib (modified) (12 diffs)
- trunk/src/osx/osx_tables.h (modified) (8 diffs)
- trunk/src/variable.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/Makefile.osx
r910 r958 32 32 -DPRIVATE_USER_PATH=\"~/Library/Preferences\" -DUSE_PRIVATE_PATHS \ 33 33 -arch ppc -arch i386 -mmacosx-version-min=10.0 34 LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon 34 LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon \ 35 -framework Cocoa 35 36 36 37 # … … 100 101 # 101 102 103 main-crb.o : main-crb.c 104 CC $(CFLAGS) -x objective-c -c -o $@ $< 102 105 %.o : %.c 103 106 CC $(CFLAGS) -c -o $@ $< … … 170 173 -cp $(TILES) $(APPRES)/lib/xtra/graf 171 174 -cp ../lib/xtra/sound/*.wav $(APPRES)/lib/xtra/sound 175 -cp ../lib/xtra/sound/sound.cfg $(APPRES)/lib/xtra/sound 172 176 173 177 install -m 755 $(EXE) $(APPBIN) … … 193 197 194 198 dist: install 195 @rm -rf disttemp 199 @rm -rf disttemp* 196 200 mkdir -p disttemp/Docs 197 201 cp ../readme.txt ../changes.txt disttemp/Docs … … 201 205 @-rm ../"$(PACKAGE_NAME)-osx.dmg" 202 206 203 hdiutil create -fs HFS+ -volname $(PACKAGE_NAME) -srcfolder disttemp ../"$(PACKAGE_NAME)-osx.dmg" 204 205 rm -rf disttemp 207 hdiutil create -quiet -fs HFS+ -volname $(PACKAGE_NAME) -srcfolder disttemp disttemp.dmg 208 hdiutil convert disttemp.dmg -quiet -format UDZO -imagekey zlib-level=6 -o ../"$(PACKAGE_NAME)-osx.dmg" 209 210 rm -rf disttemp* trunk/src/angband.man
r918 r958 79 79 Start a new character 80 80 .TP 81 .BR \-f82 Request fiddle mode (no high score entry)83 .TP84 81 .BR \-w 85 82 Request wizard mode (no high score entry) 86 .TP87 .BR \-v88 Request sound mode89 83 .TP 90 84 .BR \-g trunk/src/externs.h
r938 r958 92 92 extern u16b sf_lives; 93 93 extern u16b sf_saves; 94 extern bool arg_fiddle;95 94 extern bool arg_wizard; 96 extern bool arg_sound;97 95 extern int arg_graphics; 98 96 extern bool character_generated; trunk/src/load.c
r949 r958 1672 1672 /* Read RNG state */ 1673 1673 rd_randomizer(); 1674 if (arg_fiddle) note("Loaded Randomizer Info");1675 1676 1674 1677 1675 /* Then the options */ 1678 1676 rd_options(); 1679 if (arg_fiddle) note("Loaded Option Flags");1680 1681 1677 1682 1678 /* Then the "messages" */ 1683 1679 rd_messages(); 1684 if (arg_fiddle) note("Loaded Messages");1685 1686 1680 1687 1681 /* Monster Memory */ … … 1701 1695 rd_lore(i); 1702 1696 } 1703 if (arg_fiddle) note("Loaded Monster Memory");1704 1705 1697 1706 1698 /* Object Memory */ … … 1727 1719 k_ptr->everseen = (tmp8u & 0x08) ? TRUE : FALSE; 1728 1720 } 1729 1730 if (arg_fiddle) note("Loaded Object Memory");1731 1721 1732 1722 … … 1750 1740 rd_byte(&tmp8u); 1751 1741 } 1752 if (arg_fiddle) note("Loaded Quests");1753 1754 1742 1755 1743 /* Load the Artifacts */ … … 1772 1760 rd_byte(&tmp8u); 1773 1761 } 1774 if (arg_fiddle) note("Loaded Artifacts");1775 1776 1762 1777 1763 /* Read the extra stuff */ 1778 1764 if (rd_extra()) return (-1); 1779 if (arg_fiddle) note("Loaded extra information");1780 1781 1765 1782 1766 /* Read random artifacts */ … … 1784 1768 { 1785 1769 if (rd_randarts()) return (-1); 1786 if (arg_fiddle) note("Loaded Random Artifacts");1787 1770 } 1788 1771 trunk/src/main-crb.c
r918 r958 163 163 #include "angband.h" 164 164 165 #include <Cocoa/Cocoa.h> 165 166 #include <Carbon/Carbon.h> 166 167 #include <QuickTime/QuickTime.h> … … 298 299 static void graphics_tiles_nuke(void); 299 300 static void play_sound(int num); 300 301 static void redrawRecentItemsMenu(); 301 302 /* 302 303 * Available values for 'wait' … … 319 320 320 321 static long mac_os_version; 321 322 323 /*324 * Hack -- game in progress325 */326 static bool game_in_progress = FALSE;327 328 322 329 323 … … 1259 1253 1260 1254 /* Flush events */ 1261 FlushEventQueue(GetMainEventQueue());1255 if (initialized) FlushEventQueue(GetMainEventQueue()); 1262 1256 1263 1257 /* Success */ … … 1266 1260 1267 1261 1268 /* 1269 * How many sound channels will be pooled 1270 */ 1271 #define MAX_CHANNELS 8 1272 1273 /* 1274 * A pool of sound channels 1275 */ 1276 static SndChannelPtr channels[MAX_CHANNELS]; 1277 1278 /* 1279 * Status of the channel pool 1280 */ 1281 static bool channel_initialised = FALSE; 1282 1283 /* 1284 * Data handles containing sound samples 1285 */ 1286 static SndListHandle samples[MSG_MAX]; 1287 1288 /* 1289 * Reference counts of sound samples 1290 */ 1291 static SInt16 sample_refs[MSG_MAX]; 1292 1293 #define SOUND_VOLUME_MIN 0 /* Default minimum sound volume */ 1294 #define SOUND_VOLUME_MAX 255 /* Default maximum sound volume */ 1295 #define VOLUME_MIN 0 /* Minimum sound volume in % */ 1296 #define VOLUME_MAX 100 /* Maximum sound volume in % */ 1297 #define VOLUME_INC 5 /* Increment sound volume in % */ 1298 1299 /* 1300 * I'm just too lazy to write a panel for this XXX XXX 1301 */ 1302 static SInt16 sound_volume = SOUND_VOLUME_MAX; 1303 1304 1305 1306 /* 1307 * QuickTime sound, by Ron Anderson 1308 * 1309 * I didn't choose to use Windows-style .ini files (Ron wrote a parser 1310 * for it, but...), nor did I use lib/xtra directory, hoping someone 1311 * would code plist-based configuration code in the future -- pelpel 1312 */ 1313 1314 /* 1315 * (QuickTime) 1316 * Load sound effects from data-fork resources. They are wav files 1317 * with the same names as angband_sound_name[] (variable.c) 1318 * 1319 * Globals referenced: angband_sound_name[] 1320 * Globals updated: samples[] (they can be *huge*) 1262 /* Arbitary limit on number of possible samples per event */ 1263 #define MAX_SAMPLES 8 1264 1265 /* Struct representing all data for a set of event samples */ 1266 typedef struct 1267 { 1268 int num; /* Number of available samples for this event */ 1269 NSSound *sound[MAX_SAMPLES]; 1270 } sound_sample_list; 1271 1272 /* Array of event sound structs */ 1273 static sound_sample_list samples[MSG_MAX]; 1274 1275 /* 1276 * Load sound effects based on sound.cfg within the xtra/sound directory; 1277 * bridge to Cocoa to use NSSound for simple loading and playback, avoiding 1278 * I/O latency by cacheing all sounds at the start. Inherits full sound 1279 * format support from Quicktime base/plugins. 1280 * pelpel favoured a plist-based parser for the future but .cfg support 1281 * improves cross-platform compatibility. 1321 1282 */ 1322 1283 static void load_sounds(void) 1323 1284 { 1324 /* Start QuickTime */ 1325 OSErr err = EnterMovies(); 1326 1327 /* Error */ 1328 if (err != noErr) return; 1285 char path[2048]; 1286 char buffer[2048]; 1287 char *ANGBAND_DIR_XTRA_SOUND; 1288 ang_file *fff; 1289 1290 /* Build the "sound" path */ 1291 path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "sound"); 1292 ANGBAND_DIR_XTRA_SOUND = string_make(path); 1293 1294 /* Find and open the config file */ 1295 path_build(path, sizeof(path), ANGBAND_DIR_XTRA_SOUND, "sound.cfg"); 1296 fff = file_open(path, MODE_READ, -1); 1297 1298 /* Handle errors */ 1299 if (!fff) 1300 { 1301 mac_warning("The sound configuration file could not be opened."); 1302 return; 1303 } 1304 1305 /* Instantiate an autorelease pool for use by NSSound */ 1306 NSAutoreleasePool *autorelease_pool; 1307 autorelease_pool = [[NSAutoreleasePool alloc] init]; 1329 1308 1330 1309 /* 1331 1310 * This loop may take a while depending on the count and size of samples 1332 1311 * to load. 1333 *1334 * We should use a progress dialog for this.1335 1312 */ 1336 char path[1024]; 1337 locate_lib(path, sizeof(path)); 1338 char *tail = path+strlen(path); 1339 strncpy(tail, "/xtra/sound/", path+1024-tail); 1340 tail = tail+strlen(tail); 1341 for (int i = 1; i < MSG_MAX; i++) 1342 { 1343 /* Apple APIs always give me headache :( */ 1344 /* Me too :( */ 1345 FSSpec spec; 1346 SInt16 file_id; 1347 SInt16 res_id; 1348 Str255 movie_name; 1349 Movie movie; 1350 Track track; 1351 Handle h; 1352 1353 sprintf(tail, "%s.wav", angband_sound_name[i]); 1354 err = path_to_spec(path, &spec); 1355 if(err != noErr) continue; 1356 1357 /* Open the sound file */ 1358 err = OpenMovieFile(&spec, &file_id, fsRdPerm); 1359 1360 /* Error */ 1361 if (err != noErr) continue; 1362 1363 /* Create Movie from the file */ 1364 err = NewMovieFromFile(&movie, file_id, &res_id, movie_name, 1365 newMovieActive, NULL); 1366 1367 /* Error */ 1368 if (err != noErr) goto close_file; 1369 1370 /* Get the first track of the movie */ 1371 track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic, 1372 movieTrackCharacteristic | movieTrackEnabledOnly ); 1373 1374 /* Error */ 1375 if (track == NULL) goto close_movie; 1376 1377 /* Allocate a handle to store sample */ 1378 h = NewHandle(0); 1379 1380 /* Error */ 1381 if (h == NULL) goto close_track; 1382 1383 /* Dump the sample into the handle */ 1384 err = PutMovieIntoTypedHandle(movie, track, soundListRsrc, h, 0, 1385 GetTrackDuration(track), 0L, NULL); 1386 1387 /* Success */ 1388 if (err == noErr) 1313 1314 /* Parse the file */ 1315 /* Lines are always of the form "name = sample [sample ...]" */ 1316 while (file_getl(fff, buffer, sizeof(buffer))) 1317 { 1318 char *msg_name; 1319 char *cfg_sample_list; 1320 char *search; 1321 char *cur_token; 1322 char *next_token; 1323 int event; 1324 1325 /* Skip anything not beginning with an alphabetic character */ 1326 if (!buffer[0] || !isalpha((unsigned char)buffer[0])) continue; 1327 1328 /* Split the line into two: message name, and the rest */ 1329 search = strchr(buffer, ' '); 1330 cfg_sample_list = strchr(search + 1, ' '); 1331 if (!search) continue; 1332 if (!cfg_sample_list) continue; 1333 1334 /* Set the message name, and terminate at first space */ 1335 msg_name = buffer; 1336 search[0] = '\0'; 1337 1338 /* Make sure this is a valid event name */ 1339 for (event = MSG_MAX - 1; event >= 0; event--) 1389 1340 { 1390 /* Store the handle in the sample list */ 1391 samples[i] = (SndListHandle)h; 1392 } 1393 1394 /* Failure */ 1341 if (strcmp(msg_name, angband_sound_name[event]) == 0) 1342 break; 1343 } 1344 if (event < 0) continue; 1345 1346 /* Advance the sample list pointer so it's at the beginning of text */ 1347 cfg_sample_list++; 1348 if (!cfg_sample_list[0]) continue; 1349 1350 /* Terminate the current token */ 1351 cur_token = cfg_sample_list; 1352 search = strchr(cur_token, ' '); 1353 if (search) 1354 { 1355 search[0] = '\0'; 1356 next_token = search + 1; 1357 } 1395 1358 else 1396 1359 { 1397 /* Free unused handle */ 1398 DisposeHandle(h); 1399 } 1400 1401 /* Free the track */ 1402 close_track: DisposeMovieTrack(track); 1403 1404 /* Free the movie */ 1405 close_movie: DisposeMovie(movie); 1406 1407 /* Close the movie file */ 1408 close_file: CloseMovieFile(file_id); 1409 } 1410 1411 /* Stop QuickTime */ 1412 ExitMovies(); 1360 next_token = NULL; 1361 } 1362 1363 /* 1364 * Now we find all the sample names and add them one by one 1365 */ 1366 while (cur_token) 1367 { 1368 int num = samples[event].num; 1369 1370 /* Don't allow too many samples */ 1371 if (num >= MAX_SAMPLES) break; 1372 1373 /* Build the path to the sample */ 1374 path_build(path, sizeof(path), ANGBAND_DIR_XTRA_SOUND, cur_token); 1375 if (file_exists(path)) { 1376 1377 /* Load the sound into memory */ 1378 samples[event].sound[num] = [[NSSound alloc] initWithContentsOfFile:[NSString stringWithUTF8String:path] byReference:NO]; 1379 if (samples[event].sound[num] != nil) { 1380 1381 /* Imcrement the sample count */ 1382 samples[event].num++; 1383 } 1384 } 1385 1386 /* Figure out next token */ 1387 cur_token = next_token; 1388 if (next_token) 1389 { 1390 /* Try to find a space */ 1391 search = strchr(cur_token, ' '); 1392 1393 /* If we can find one, terminate, and set new "next" */ 1394 if (search) 1395 { 1396 search[0] = '\0'; 1397 next_token = search + 1; 1398 } 1399 else 1400 { 1401 /* Otherwise prevent infinite looping */ 1402 next_token = NULL; 1403 } 1404 } 1405 } 1406 } 1407 1408 /* Release the autorelease pool */ 1409 [autorelease_pool release]; 1410 1411 /* Close the file */ 1412 file_close(fff); 1413 1413 1414 1414 /* Register the sound hook */ … … 1416 1416 } 1417 1417 1418 /* 1419 * Return a handle of 'snd ' resource given Angband sound event number, 1420 * or NULL if it isn't found. 1421 * 1422 * Globals referenced: angband_sound_name[] (variable.c) 1423 */ 1424 static SndListHandle get_sound_resource(int num) 1425 { 1426 SndListHandle h = samples[num]; 1427 1428 if(++sample_refs[num] > 1) { 1429 return h; 1430 } 1431 if(!h) { 1432 sample_refs[num]--; 1433 return 0; 1434 } 1435 HLockHi((Handle)h); 1436 return h; 1437 } 1438 1439 void release_sound_resource(int num) 1440 { 1441 if(sample_refs[num] == 0) 1442 return; 1443 1444 /* Decrease refcount */ 1445 if(--sample_refs[num] > 0) 1446 return; 1447 1448 /* We can free it now */ 1449 /* Unlock */ 1450 HUnlock((Handle)samples[num]); 1451 1452 } 1453 1454 /* 1455 * Clean up sound support - to be called when the game exits. 1456 * 1457 * Globals referenced: channels[], samples[], sample_refs[]. 1458 */ 1459 static void cleanup_sound(void) 1460 { 1461 /* No need to clean it up */ 1462 if (!channel_initialised) return; 1463 1464 /* Dispose channels */ 1465 for (int i = 0; i < MAX_CHANNELS; i++) 1466 { 1467 /* Drain sound commands and free the channel */ 1468 SndDisposeChannel(channels[i], TRUE); 1469 } 1470 1471 /* Free sound data */ 1472 for (int i = 1; i < MSG_MAX; i++) 1473 { 1474 while(sample_refs[i] > 0) 1475 { 1476 release_sound_resource(i); 1477 } 1478 } 1479 } 1480 1481 1482 /* 1483 * Play sound effects asynchronously -- pelpel 1484 * 1485 * I don't believe those who first started using the previous implementations 1486 * imagined this is *much* more complicated as it may seem. Anyway, 1487 * introduced round-robin scheduling of channels and made it much more 1488 * paranoid about HLock/HUnlock. 1489 * 1490 * XXX XXX de-refcounting, HUnlock and ReleaseResource should be done 1491 * using channel's callback procedures, which set global flags, and 1492 * a procedure hooked into CheckEvents does housekeeping. On the other 1493 * hand, this lazy reclaiming strategy keeps things simple (no interrupt 1494 * time code) and provides a sort of cache for sound data. 1495 * 1496 * Globals referenced: channel_initialised, channels[], samples[], 1497 * sample_refs[], sound_volume. 1498 * Globals updated: channel_initialised, channels[], sample_refs[]. 1499 */ 1500 1501 static void play_sound(int num) 1502 { 1503 OSErr err; 1504 int prev_num; 1505 SndListHandle h; 1506 SndChannelPtr chan; 1507 SCStatus status; 1508 1509 static int next_chan; 1510 static SInt16 channel_occupants[MAX_CHANNELS]; 1511 static SndCommand volume_cmd, quiet_cmd; 1512 1513 SInt16 vol = sound_volume; 1514 1515 /* Initialise sound channels */ 1516 if (!channel_initialised) 1517 { 1518 for (int i = 0; i < MAX_CHANNELS; i++) 1519 { 1520 /* Paranoia - Clear occupant table */ 1521 /* channel_occupants[i] = 0; */ 1522 1523 /* Create sound channel for all sounds to play from */ 1524 err = SndNewChannel(&channels[i], sampledSynth, initMono, NULL); 1525 1526 /* Free channels */ 1527 if(err != noErr) { 1528 while (--i >= 0) 1529 { 1530 SndDisposeChannel(channels[i], TRUE); 1531 } 1418 1419 1420 /* 1421 * Play sound effects asynchronously. Select a sound from any available 1422 * for the required event, and bridge to Cocoa to play it. 1423 */ 1424 1425 static void play_sound(int event) 1426 { 1427 /* Paranoia */ 1428 if (event < 0 || event >= MSG_MAX) return; 1429 1430 /* Check there are samples for this event */ 1431 if (!samples[event].num) return; 1432 1433 /* Instantiate an autorelease pool for use by NSSound */ 1434 NSAutoreleasePool *autorelease_pool; 1435 autorelease_pool = [[NSAutoreleasePool alloc] init]; 1436 1437 /* Choose a random event */ 1438 int s = randint0(samples[event].num); 1532 1439 1533 /* Notify error */ 1534 plog("Cannot initialise sound channels!"); 1535 1536 /* Cancel request */ 1537 use_sound = arg_sound = FALSE; 1538 1539 /* Failure */ 1540 return; 1541 } 1542 } 1543 1544 /* First channel to use */ 1545 next_chan = 0; 1546 1547 /* Prepare volume command */ 1548 volume_cmd.cmd = volumeCmd; 1549 volume_cmd.param1 = 0; 1550 volume_cmd.param2 = 0; 1551 1552 /* Prepare quiet command */ 1553 quiet_cmd.cmd = quietCmd; 1554 quiet_cmd.param1 = 0; 1555 quiet_cmd.param2 = 0; 1556 1557 /* Initialisation complete */ 1558 channel_initialised = TRUE; 1559 } 1560 1561 /* Paranoia */ 1562 if ((num <= 0) || (num >= MSG_MAX)) return; 1563 1564 /* Prepare volume command */ 1565 volume_cmd.param2 = ((SInt32)vol << 16) | vol; 1566 1567 /* Channel to use (round robin) */ 1568 chan = channels[next_chan]; 1569 1570 /* Attempt to get a new sound "resource" */ 1571 h = get_sound_resource(num); 1572 if (h == NULL) return; 1573 1574 /* Poll the channel */ 1575 err = SndChannelStatus(chan, sizeof(SCStatus), &status); 1576 1577 /* It isn't available */ 1578 if ((err != noErr) || status.scChannelBusy) 1579 { 1580 /* Shut it down */ 1581 SndDoImmediate(chan, &quiet_cmd); 1582 } 1583 1584 /* Process previously played sound */ 1585 if ((prev_num = channel_occupants[next_chan]) != 0) 1586 { 1587 release_sound_resource(prev_num); 1588 } 1589 1590 /* Remember this sound as the current occupant of the channel */ 1591 channel_occupants[next_chan] = num; 1592 1593 /* Set up volume for channel */ 1594 SndDoImmediate(chan, &volume_cmd); 1595 1596 /* Play new sound asynchronously */ 1597 SndPlay(chan, h, TRUE); 1598 1599 /* Schedule next channel (round robin) */ 1600 next_chan++; 1601 if (next_chan >= MAX_CHANNELS) next_chan = 0; 1440 /* Stop the sound if it's currently playing */ 1441 if ([samples[event].sound[s] isPlaying]) 1442 [samples[event].sound[s] stop]; 1443 1444 /* Play the sound */ 1445 [samples[event].sound[s] play]; 1446 1447 /* Release the autorelease pool */ 1448 [autorelease_pool release]; 1602 1449 } 1603 1450 … … 1740 1587 } 1741 1588 1742 /* Flush all pending events (if any) */1589 /* Flush all pending input events (if any) */ 1743 1590 case TERM_XTRA_FLUSH: 1744 1591 { 1745 FlushEventQueue(GetMainEventQueue()); 1592 FlushEventsMatchingListFromQueue(GetMainEventQueue(), 1593 N_ELEMENTS(input_event_types), input_event_types); 1746 1594 1747 1595 /* Success */ … … 2184 2032 2185 2033 /* Gfx settings */ 2186 /* sound */2187 save_pref_short("arg.arg_sound", arg_sound);2188 2189 2034 /* double-width tiles */ 2190 2035 save_pref_short("arg.use_bigtile", use_bigtile); … … 2313 2158 short pref_tmp; 2314 2159 2315 /* sound */2316 if (load_pref_short("arg.arg_sound", &pref_tmp))2317 arg_sound = pref_tmp;2318 2319 2160 /* double-width tiles */ 2320 2161 if (load_pref_short("arg.use_bigtile", &pref_tmp)) … … 2367 2208 kCFPreferencesCurrentApplication); 2368 2209 if (recentItemsLoaded != NULL) 2210 { 2369 2211 recentItemsArrayRef = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, recentItemsLoaded); 2212 redrawRecentItemsMenu(); 2213 } 2370 2214 } 2371 2215 … … 2722 2566 static int funcConst(int a, int c) {return c; } 2723 2567 2724 /* This initializes all the menus with values that change unpredictably. */ 2725 /* Menus that change rarely are done at the time of change */ 2568 /* This initializes all the menus with values that change unpredictably. 2569 * This function is called on every menu draw and therefore should be kept 2570 * light and fast; menus that change rarely are done at the time of change 2571 */ 2726 2572 static void validate_menus(void) 2727 2573 { … … 2761 2607 EnableMenuItem(m, j); 2762 2608 } 2763 else { 2609 else 2610 { 2764 2611 DisableMenuItem(m, j); 2765 2612 } … … 2767 2614 } 2768 2615 2769 m = MyGetMenuHandle(kFileMenu); 2770 if(inkey_flag && character_generated) 2616 if(cmd.command != CMD_NULL && character_generated) 2771 2617 { 2772 2618 EnableMenuItem(MyGetMenuHandle(kFileMenu), kSave); 2619 EnableMenuItem(MyGetMenuHandle(kSpecialMenu), kSound); 2773 2620 } 2774 2621 else 2775 2622 { 2776 2623 DisableMenuItem(MyGetMenuHandle(kFileMenu), kSave); 2777 } 2624 DisableMenuItem(MyGetMenuHandle(kSpecialMenu), kSound); 2625 } 2626 2627 /* Keep the sound menu up-to-date */ 2628 CheckMenuItem(MyGetMenuHandle(kSpecialMenu), kSound, use_sound); 2778 2629 2779 2630 for(int i = 0; i < N_ELEMENTS(toggle_defs); i++) { … … 2781 2632 CheckMenuItem(m, toggle_defs[i].menuItem, *(toggle_defs[i].var)); 2782 2633 } 2783 2784 /* Populate the recent items menu */ 2634 } 2635 2636 static OSStatus ValidateMenuCommand(EventHandlerCallRef inCallRef, 2637 EventRef inEvent, void *inUserData ) 2638 { 2639 validate_menus(); 2640 return noErr; 2641 } 2642 2643 /* Populate the recent items menu */ 2644 static void redrawRecentItemsMenu() 2645 { 2785 2646 DeleteMenuItems(MyGetMenuHandle(kOpenRecentMenu), 1, CountMenuItems(MyGetMenuHandle(kOpenRecentMenu))); 2786 2647 if (!recentItemsArrayRef || CFArrayGetCount(recentItemsArrayRef) == 0) … … 2817 2678 } 2818 2679 2819 static OSStatus ValidateMenuCommand(EventHandlerCallRef inCallRef,2820 EventRef inEvent, void *inUserData )2821 {2822 validate_menus();2823 return noErr;2824 }2825 2826 2680 /* Add a savefile to the recent items list, or update its existing status */ 2827 2681 static void updateRecentItems(char *savefile) … … 2880 2734 if (CFArrayGetCount(recentItemsArrayRef) > 10) 2881 2735 CFArrayRemoveValueAtIndex(recentItemsArrayRef, 10); 2736 2737 /* Redraw the menu */ 2738 redrawRecentItemsMenu(); 2882 2739 } 2883 2740 … … 2917 2774 cmd.command = CMD_LOADFILE; 2918 2775 } 2776 2777 /* Redraw the menu */ 2778 redrawRecentItemsMenu(); 2919 2779 2920 2780 return noErr; … … 3002 2862 3003 2863 /* A game is starting - update status and tracking as appropriate. */ 3004 game_in_progress = TRUE;3005 2864 term_data *td0 = &data[0]; 3006 2865 ChangeWindowAttributes(td0->w, kWindowNoAttributes, kWindowCloseBoxAttribute); … … 3015 2874 /* If supplied with a savefile, update the Recent Items list */ 3016 2875 if (savefile[0]) 2876 { 3017 2877 updateRecentItems(savefile); 3018 2878 redrawRecentItemsMenu(); 2879 } 2880 3019 2881 return cmd; 3020 2882 } … … 3024 2886 EventRef inEvent, void *inUserData ) 3025 2887 { 3026 if ( !game_in_progress&& !character_generated)2888 if (cmd.command == CMD_NULL && !character_generated) 3027 2889 quit(0); 3028 2890 else Term_key_push(KTRL('x')); … … 3044 2906 return eventNotHandledErr; 3045 2907 case 'save': 3046 if( game_in_progress&& character_generated)2908 if(cmd.command != CMD_NULL && character_generated) 3047 2909 Term_key_push(KTRL('S')); 3048 2910 break; … … 3082 2944 td = (term_data*) GetWRefCon(w); 3083 2945 3084 if( !game_in_progress&& !character_generated && td == &data[0])2946 if(cmd.command == CMD_NULL && !character_generated && td == &data[0]) 3085 2947 quit(0); 3086 2948 … … 3225 3087 } 3226 3088 /* Reset visuals, without updating the screen */ 3227 if (initialized && game_in_progress)3089 if (initialized && cmd.command != CMD_NULL) 3228 3090 { 3229 3091 reset_visuals(TRUE); … … 3388 3250 return noErr; 3389 3251 } 3252 3253 /* Handle toggling sound via the menu option */ 3254 /* Handle a selection in the recent items menu */ 3255 static OSStatus SoundCommand(EventHandlerCallRef inCallRef, 3256 EventRef inEvent, void *inUserData ) 3257 { 3258 HICommand command; 3259 GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, 3260 NULL, sizeof(command), NULL, &command); 3261 if (command.menu.menuItemIndex == kSound) 3262 { 3263 use_sound = !use_sound; 3264 } 3265 return noErr; 3266 } 3267 3390 3268 3391 3269 static OSStatus ToggleCommand(EventHandlerCallRef inCallRef, … … 3629 3507 } 3630 3508 3631 static OSStatus PrintCommand(EventHandlerCallRef inCallRef, EventRef inEvent,3632 void *inUserData )3633 {3634 mac_warning((const char*) inUserData);3635 return noErr;3636 }3637 3638 3509 /* About angband... */ 3639 3510 static OSStatus AboutCommand(EventHandlerCallRef inCallRef, EventRef inEvent, … … 3684 3555 EventRef inEvent, void *inUserData ) 3685 3556 { 3686 WindowRef w = FrontWindow(); 3687 term_data *td = (term_data *)GetWRefCon(w); 3688 if(!td) return noErr; 3557 term_data *td; 3689 3558 3690 3559 hibernate(); 3691 3560 Cursor tempCursor; 3692 SetPort(GetWindowPort(w));3693 3561 SetCursor(GetQDGlobalsArrow(&tempCursor)); 3694 3562 3695 /* Synchronise term */ 3696 term_data_redraw(td); 3563 /* Redraw all visible terms */ 3564 for (int i = 0; i < MAX_TERM_DATA; i++ ) 3565 { 3566 /* Obtain */ 3567 td = &data[i]; 3568 3569 /* Redraw if mapped */ 3570 if (td->mapped) 3571 term_data_redraw(td); 3572 } 3573 3697 3574 return noErr; 3698 3575 } … … 3753 3630 { 3754 3631 /* Quit immediately if game's not started */ 3755 if ( !game_in_progress|| !character_generated) quit(NULL);3632 if (cmd.command == CMD_NULL || !character_generated) quit(NULL); 3756 3633 3757 3634 /* Save the game and Quit (if it's safe) */ … … 3913 3790 if (str) mac_warning(str); 3914 3791 3915 /* Clean up sound support */3916 cleanup_sound();3917 3918 3792 /* Update the Recent Items list - inserts newly created characters */ 3919 3793 if (savefile[0]) … … 3981 3855 (void)Gestalt(gestaltSystemVersion, &mac_os_version); 3982 3856 3857 /* Initiliases Cocoa */ 3858 NSApplicationLoad(); 3859 3983 3860 /* Hooks in some "z-util.c" hooks */ 3984 3861 plog_aux = hook_plog; … … 3991 3868 SetCursor(*(GetCursor(watchCursor))); 3992 3869 3993 /* Ensure that the recent items array is always an array */3870 /* Ensure that the recent items array is always an array and start with an empty menu */ 3994 3871 recentItemsArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 3995 3872 redrawRecentItemsMenu(); 3873 3996 3874 /* Prepare the menubar */ 3997 3875 init_menubar(); … … 4014 3892 install_handlers(0); 4015 3893 4016 /* Hack -- process all events */4017 FlushEventQueue(GetMainEventQueue());4018 4019 4020 3894 /* Reset the cursor */ 4021 3895 Cursor tempCursor; … … 4030 3904 ANGBAND_SYS = "mac"; 4031 3905 4032 4033 3906 /* Validate the contents of the main window */ 4034 3907 validate_main_window(); 4035 3908 4036 /* Reset event queue */ 4037 FlushEventQueue(GetMainEventQueue()); 3909 /* Flush input commands from the event queue */ 3910 FlushEventsMatchingListFromQueue(GetMainEventQueue(), 3911 N_ELEMENTS(input_event_types), input_event_types); 4038 3912 4039 3913 /* Set command hook */ … … 4043 3917 init_display(); 4044 3918 3919 if(graf_mode) graphics_aux(graf_mode); 3920 4045 3921 /* We are now initialized */ 4046 3922 initialized = TRUE; 4047 3923 4048 3924 validate_menus(); 4049 4050 if(graf_mode) graphics_aux(graf_mode);4051 3925 4052 3926 /* Start playing! */ trunk/src/main-win.c
r918 r958 999 999 use_bigtile = GetPrivateProfileInt("Angband", "Bigtile", FALSE, ini_file); 1000 1000 1001 /* Extract the "arg_fiddle" flag */1002 arg_fiddle = (GetPrivateProfileInt("Angband", "Fiddle", 0, ini_file) != 0);1003 <
