Changeset 958

Show
Ignore:
Timestamp:
06/09/08 21:56:12 (5 months ago)
Author:
takkaria
Message:

A bunch of fixes by Rowan Beentje:

  • Remove the now useless arg_fiddle, as discussed in #angband-dev
  • Remove arg_sound (no longer used)

OS X only:

  • Removes the Fiddle and (non-functional) Wizard mode and non-[V] 54x54 graphics tile menu entries.
  • Removal of more unused/disabled menu items: Page Setup and Print, and the Edit menu.
  • Corrects the Sound menu entry to update use_sound instead of the old arg_sound.
  • Final mac cleanup as part of r538, replacing game_in_progress with cmd.command checks.
  • Reshuffle of Open Recent menu redraw into a function with far fewer calls, add comment to validate_menus() to indicate it is called on every use of the menubar.
  • Complete rewrite of the sound code. Add support for the sound.cfg file, and at the same time replace the Carbon SoundManager? code with Cocoa NSSound-based code.
  • Cleanup of event handler definitions in osx-tables.h (just to make my life easier tying to track down: )
  • Fix to unhiding application being broken on some Intel machines. I believe the functions intended to flush input events were flushing setup/update events.
  • (#511) Fix to unhiding application not refreshing all windows
  • Improvement to release build rules to build a 20% smaller compressed file.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/Makefile.osx

    r910 r958  
    3232        -DPRIVATE_USER_PATH=\"~/Library/Preferences\" -DUSE_PRIVATE_PATHS \ 
    3333        -arch ppc -arch i386 -mmacosx-version-min=10.0 
    34 LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon 
     34LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon \ 
     35        -framework Cocoa 
    3536 
    3637# 
     
    100101# 
    101102 
     103main-crb.o : main-crb.c 
     104        CC $(CFLAGS) -x objective-c -c -o $@ $< 
    102105%.o : %.c 
    103106        CC $(CFLAGS) -c -o $@ $< 
     
    170173        -cp $(TILES) $(APPRES)/lib/xtra/graf 
    171174        -cp ../lib/xtra/sound/*.wav $(APPRES)/lib/xtra/sound 
     175        -cp ../lib/xtra/sound/sound.cfg $(APPRES)/lib/xtra/sound 
    172176 
    173177        install -m 755 $(EXE) $(APPBIN) 
     
    193197 
    194198dist: install 
    195         @rm -rf disttemp 
     199        @rm -rf disttemp* 
    196200        mkdir -p disttemp/Docs 
    197201        cp ../readme.txt ../changes.txt disttemp/Docs 
     
    201205        @-rm ../"$(PACKAGE_NAME)-osx.dmg" 
    202206 
    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  
    7979Start a new character 
    8080.TP 
    81 .BR \-f 
    82 Request fiddle mode (no high score entry) 
    83 .TP 
    8481.BR \-w 
    8582Request wizard mode (no high score entry) 
    86 .TP 
    87 .BR \-v 
    88 Request sound mode 
    8983.TP 
    9084.BR \-g 
  • trunk/src/externs.h

    r938 r958  
    9292extern u16b sf_lives; 
    9393extern u16b sf_saves; 
    94 extern bool arg_fiddle; 
    9594extern bool arg_wizard; 
    96 extern bool arg_sound; 
    9795extern int arg_graphics; 
    9896extern bool character_generated; 
  • trunk/src/load.c

    r949 r958  
    16721672        /* Read RNG state */ 
    16731673        rd_randomizer(); 
    1674         if (arg_fiddle) note("Loaded Randomizer Info"); 
    1675  
    16761674 
    16771675        /* Then the options */ 
    16781676        rd_options(); 
    1679         if (arg_fiddle) note("Loaded Option Flags"); 
    1680  
    16811677 
    16821678        /* Then the "messages" */ 
    16831679        rd_messages(); 
    1684         if (arg_fiddle) note("Loaded Messages"); 
    1685  
    16861680 
    16871681        /* Monster Memory */ 
     
    17011695                rd_lore(i); 
    17021696        } 
    1703         if (arg_fiddle) note("Loaded Monster Memory"); 
    1704  
    17051697 
    17061698        /* Object Memory */ 
     
    17271719                k_ptr->everseen = (tmp8u & 0x08) ? TRUE : FALSE; 
    17281720        } 
    1729  
    1730         if (arg_fiddle) note("Loaded Object Memory"); 
    17311721 
    17321722 
     
    17501740                rd_byte(&tmp8u); 
    17511741        } 
    1752         if (arg_fiddle) note("Loaded Quests"); 
    1753  
    17541742 
    17551743        /* Load the Artifacts */ 
     
    17721760                rd_byte(&tmp8u); 
    17731761        } 
    1774         if (arg_fiddle) note("Loaded Artifacts"); 
    1775  
    17761762 
    17771763        /* Read the extra stuff */ 
    17781764        if (rd_extra()) return (-1); 
    1779         if (arg_fiddle) note("Loaded extra information"); 
    1780  
    17811765 
    17821766        /* Read random artifacts */ 
     
    17841768        { 
    17851769                if (rd_randarts()) return (-1); 
    1786                 if (arg_fiddle) note("Loaded Random Artifacts"); 
    17871770        } 
    17881771 
  • trunk/src/main-crb.c

    r918 r958  
    163163#include "angband.h" 
    164164 
     165#include <Cocoa/Cocoa.h> 
    165166#include <Carbon/Carbon.h> 
    166167#include <QuickTime/QuickTime.h> 
     
    298299static void graphics_tiles_nuke(void); 
    299300static void play_sound(int num); 
    300  
     301static void redrawRecentItemsMenu(); 
    301302/* 
    302303 * Available values for 'wait' 
     
    319320 
    320321static long mac_os_version; 
    321  
    322  
    323 /* 
    324  * Hack -- game in progress 
    325  */ 
    326 static bool game_in_progress = FALSE; 
    327  
    328322 
    329323 
     
    12591253 
    12601254        /* Flush events */ 
    1261         FlushEventQueue(GetMainEventQueue()); 
     1255        if (initialized) FlushEventQueue(GetMainEventQueue()); 
    12621256 
    12631257        /* Success */ 
     
    12661260 
    12671261 
    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 */ 
     1266typedef 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 */ 
     1273static 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. 
    13211282 */ 
    13221283static void load_sounds(void) 
    13231284{ 
    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]; 
    13291308 
    13301309        /* 
    13311310         * This loop may take a while depending on the count and size of samples 
    13321311         * to load. 
    1333          * 
    1334          * We should use a progress dialog for this. 
    13351312         */ 
    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--) 
    13891340                { 
    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                } 
    13951358                else 
    13961359                { 
    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); 
    14131413 
    14141414        /* Register the sound hook */ 
     
    14161416} 
    14171417 
    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 
     1425static 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); 
    15321439         
    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]; 
    16021449} 
    16031450 
     
    17401587                } 
    17411588 
    1742                 /* Flush all pending events (if any) */ 
     1589                /* Flush all pending input events (if any) */ 
    17431590                case TERM_XTRA_FLUSH: 
    17441591                { 
    1745                         FlushEventQueue(GetMainEventQueue()); 
     1592                        FlushEventsMatchingListFromQueue(GetMainEventQueue(), 
     1593                                N_ELEMENTS(input_event_types), input_event_types); 
    17461594 
    17471595                        /* Success */ 
     
    21842032 
    21852033        /* Gfx settings */ 
    2186         /* sound */ 
    2187         save_pref_short("arg.arg_sound", arg_sound); 
    2188  
    21892034        /* double-width tiles */ 
    21902035        save_pref_short("arg.use_bigtile", use_bigtile); 
     
    23132158        short pref_tmp; 
    23142159 
    2315         /* sound */ 
    2316         if (load_pref_short("arg.arg_sound", &pref_tmp)) 
    2317                 arg_sound = pref_tmp; 
    2318  
    23192160        /* double-width tiles */ 
    23202161        if (load_pref_short("arg.use_bigtile", &pref_tmp)) 
     
    23672208                kCFPreferencesCurrentApplication); 
    23682209        if (recentItemsLoaded != NULL) 
     2210        { 
    23692211                recentItemsArrayRef = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, recentItemsLoaded); 
     2212                redrawRecentItemsMenu(); 
     2213        } 
    23702214} 
    23712215 
     
    27222566static int funcConst(int a, int c) {return c; } 
    27232567 
    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 */ 
    27262572static void validate_menus(void) 
    27272573{ 
     
    27612607                                EnableMenuItem(m, j); 
    27622608                        } 
    2763                         else { 
     2609                        else 
     2610                        { 
    27642611                                DisableMenuItem(m, j); 
    27652612                        } 
     
    27672614        } 
    27682615 
    2769         m = MyGetMenuHandle(kFileMenu); 
    2770         if(inkey_flag && character_generated) 
     2616        if(cmd.command != CMD_NULL && character_generated) 
    27712617        { 
    27722618                EnableMenuItem(MyGetMenuHandle(kFileMenu), kSave); 
     2619                EnableMenuItem(MyGetMenuHandle(kSpecialMenu), kSound); 
    27732620        } 
    27742621        else 
    27752622        { 
    27762623                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); 
    27782629 
    27792630        for(int i = 0; i < N_ELEMENTS(toggle_defs); i++) { 
     
    27812632                CheckMenuItem(m, toggle_defs[i].menuItem, *(toggle_defs[i].var)); 
    27822633        } 
    2783          
    2784         /* Populate the recent items menu */ 
     2634
     2635 
     2636static OSStatus ValidateMenuCommand(EventHandlerCallRef inCallRef, 
     2637                                                                        EventRef inEvent, void *inUserData ) 
     2638
     2639        validate_menus(); 
     2640        return noErr; 
     2641
     2642 
     2643/* Populate the recent items menu */ 
     2644static void redrawRecentItemsMenu() 
     2645
    27852646        DeleteMenuItems(MyGetMenuHandle(kOpenRecentMenu), 1, CountMenuItems(MyGetMenuHandle(kOpenRecentMenu))); 
    27862647        if (!recentItemsArrayRef || CFArrayGetCount(recentItemsArrayRef) == 0) 
     
    28172678} 
    28182679 
    2819 static OSStatus ValidateMenuCommand(EventHandlerCallRef inCallRef, 
    2820                                                                         EventRef inEvent, void *inUserData ) 
    2821 { 
    2822         validate_menus(); 
    2823         return noErr; 
    2824 } 
    2825  
    28262680/* Add a savefile to the recent items list, or update its existing status */ 
    28272681static void updateRecentItems(char *savefile) 
     
    28802734        if (CFArrayGetCount(recentItemsArrayRef) > 10) 
    28812735                CFArrayRemoveValueAtIndex(recentItemsArrayRef, 10); 
     2736 
     2737        /* Redraw the menu */ 
     2738        redrawRecentItemsMenu(); 
    28822739} 
    28832740 
     
    29172774                cmd.command = CMD_LOADFILE; 
    29182775        } 
     2776 
     2777        /* Redraw the menu */ 
     2778        redrawRecentItemsMenu(); 
    29192779 
    29202780        return noErr; 
     
    30022862                 
    30032863        /* A game is starting - update status and tracking as appropriate. */  
    3004         game_in_progress = TRUE;  
    30052864        term_data *td0 = &data[0]; 
    30062865        ChangeWindowAttributes(td0->w, kWindowNoAttributes, kWindowCloseBoxAttribute); 
     
    30152874        /* If supplied with a savefile, update the Recent Items list */ 
    30162875        if (savefile[0]) 
     2876        { 
    30172877                updateRecentItems(savefile); 
    3018  
     2878                redrawRecentItemsMenu(); 
     2879        } 
     2880         
    30192881        return cmd;  
    30202882}  
     
    30242886                                                        EventRef inEvent, void *inUserData ) 
    30252887{ 
    3026         if (!game_in_progress && !character_generated) 
     2888        if (cmd.command == CMD_NULL && !character_generated) 
    30272889                quit(0);         
    30282890        else Term_key_push(KTRL('x')); 
     
    30442906                return eventNotHandledErr; 
    30452907        case 'save': 
    3046                 if(game_in_progress && character_generated) 
     2908                if(cmd.command != CMD_NULL && character_generated) 
    30472909                        Term_key_push(KTRL('S')); 
    30482910                break; 
     
    30822944        td = (term_data*) GetWRefCon(w); 
    30832945 
    3084         if(!game_in_progress && !character_generated && td == &data[0]) 
     2946        if(cmd.command == CMD_NULL && !character_generated && td == &data[0]) 
    30852947                quit(0); 
    30862948 
     
    32253087        } 
    32263088        /* Reset visuals, without updating the screen */ 
    3227         if (initialized && game_in_progress
     3089        if (initialized && cmd.command != CMD_NULL
    32283090        { 
    32293091                reset_visuals(TRUE); 
     
    33883250        return noErr; 
    33893251} 
     3252 
     3253/* Handle toggling sound via the menu option */ 
     3254/* Handle a selection in the recent items menu */ 
     3255static 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 
    33903268 
    33913269static OSStatus ToggleCommand(EventHandlerCallRef inCallRef, 
     
    36293507} 
    36303508 
    3631 static OSStatus PrintCommand(EventHandlerCallRef inCallRef, EventRef inEvent, 
    3632         void *inUserData ) 
    3633 { 
    3634         mac_warning((const char*) inUserData); 
    3635         return noErr; 
    3636 } 
    3637  
    36383509/* About angband... */ 
    36393510static OSStatus AboutCommand(EventHandlerCallRef inCallRef, EventRef inEvent, 
     
    36843555                                                                EventRef inEvent, void *inUserData ) 
    36853556{ 
    3686         WindowRef w = FrontWindow(); 
    3687         term_data *td = (term_data *)GetWRefCon(w); 
    3688         if(!td) return noErr; 
     3557        term_data *td; 
    36893558 
    36903559        hibernate(); 
    36913560        Cursor tempCursor; 
    3692         SetPort(GetWindowPort(w)); 
    36933561        SetCursor(GetQDGlobalsArrow(&tempCursor)); 
    36943562 
    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 
    36973574        return noErr; 
    36983575} 
     
    37533630{ 
    37543631        /* 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); 
    37563633 
    37573634        /* Save the game and Quit (if it's safe) */ 
     
    39133790        if (str) mac_warning(str); 
    39143791 
    3915         /* Clean up sound support */ 
    3916         cleanup_sound(); 
    3917  
    39183792        /* Update the Recent Items list - inserts newly created characters */ 
    39193793        if (savefile[0]) 
     
    39813855        (void)Gestalt(gestaltSystemVersion, &mac_os_version); 
    39823856 
     3857        /* Initiliases Cocoa */ 
     3858        NSApplicationLoad(); 
     3859         
    39833860        /* Hooks in some "z-util.c" hooks */ 
    39843861        plog_aux = hook_plog; 
     
    39913868        SetCursor(*(GetCursor(watchCursor))); 
    39923869 
    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 */ 
    39943871        recentItemsArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 
    3995          
     3872        redrawRecentItemsMenu(); 
     3873 
    39963874        /* Prepare the menubar */ 
    39973875        init_menubar(); 
     
    40143892        install_handlers(0); 
    40153893 
    4016         /* Hack -- process all events */ 
    4017         FlushEventQueue(GetMainEventQueue()); 
    4018  
    4019  
    40203894        /* Reset the cursor */ 
    40213895        Cursor tempCursor; 
     
    40303904        ANGBAND_SYS = "mac"; 
    40313905 
    4032  
    40333906        /* Validate the contents of the main window */ 
    40343907        validate_main_window(); 
    40353908 
    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); 
    40383912 
    40393913        /* Set command hook */  
     
    40433917        init_display(); 
    40443918 
     3919        if(graf_mode) graphics_aux(graf_mode); 
     3920 
    40453921        /* We are now initialized */ 
    40463922        initialized = TRUE; 
    40473923 
    40483924        validate_menus(); 
    4049  
    4050         if(graf_mode) graphics_aux(graf_mode); 
    40513925 
    40523926        /* Start playing! */ 
  • trunk/src/main-win.c

    r918 r958  
    999999        use_bigtile = GetPrivateProfileInt("Angband", "Bigtile", FALSE, ini_file); 
    10001000 
    1001         /* Extract the "arg_fiddle" flag */ 
    1002         arg_fiddle = (GetPrivateProfileInt("Angband", "Fiddle", 0, ini_file) != 0); 
    1003