Changeset 479

Show
Ignore:
Timestamp:
08/09/07 13:42:54 (1 year ago)
Author:
takkaria
Message:

Use a clean rewrite of the message memorisation code by Elly, placed in a new z-msg.c. Documentation and tests to follow. (another part of #65)

Files:

Legend:

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

    r466 r479  
    1414HEADERS = $(HDRS) $(INCS) 
    1515 
    16 ZFILES = z-file.o z-form.o z-quark.o z-rand.o z-term.o z-type.o z-util.o z-virt.o 
     16ZFILES = z-file.o z-form.o z-msg.o z-quark.o z-rand.o z-term.o z-type.o \ 
     17         z-util.o z-virt.o 
    1718MAINFILES = main.o maid-x11.o main-crb.o main-gcu.o main-gtk.o \ 
    18        main-ros.o main-sdl.o main-win.o main-x11.o main-xaw.o snd-sdl.o 
     19            main-ros.o main-sdl.o main-win.o main-x11.o main-xaw.o snd-sdl.o 
    1920 
    2021ANGFILES = \ 
  • trunk/src/angband.h

    r463 r479  
    2727#include "z-term.h" 
    2828#include "z-quark.h" 
     29#include "z-msg.h" 
    2930 
    3031/* 
  • trunk/src/cmd4.c

    r469 r479  
    20542054 
    20552055        /* Total messages */ 
    2056         n = message_num(); 
     2056        n = messages_num(); 
    20572057 
    20582058        /* Start on first message */ 
     
    20772077                for (j = 0; (j < hgt - 4) && (i + j < n); j++) 
    20782078                { 
    2079                         cptr msg = message_str((s16b)(i+j)); 
    2080                         byte attr = message_color((s16b)(i+j)); 
     2079                        const char *msg; 
     2080                        const char *str = message_str(i + j); 
     2081                        byte attr = message_color(i + j); 
     2082                        u16b count = message_count(i + j); 
     2083 
     2084                        if (count == 1) 
     2085                                msg = str; 
     2086                        else 
     2087                                msg = format("%s <%dx>", str, count); 
    20812088 
    20822089                        /* Apply horizontal scroll */ 
  • trunk/src/defines.h

    r478 r479  
    212212 */ 
    213213#define AUTOINSCRIPTIONS_MAX 216 
    214  
    215 /* 
    216  * OPTION: Maximum number of messages to remember (see "util.c") 
    217  * Default: assume maximal memorization of 2048 total messages 
    218  */ 
    219 #define MESSAGE_MAX     2048 
    220  
    221 /* 
    222  * OPTION: Maximum space for the message text buffer (see "util.c") 
    223  * Default: assume that each of the 2048 messages is repeated an 
    224  * average of three times, and has an average length of 48 
    225  */ 
    226 #define MESSAGE_BUF     32768 
    227214 
    228215 
     
    26422629 
    26432630 
    2644 /*** Message constants ***/ 
    2645  
    2646 #define MSG_GENERIC          0 
    2647 #define MSG_HIT              1 
    2648 #define MSG_MISS             2 
    2649 #define MSG_FLEE             3 
    2650 #define MSG_DROP             4 
    2651 #define MSG_KILL             5 
    2652 #define MSG_LEVEL            6 
    2653 #define MSG_DEATH            7 
    2654 #define MSG_STUDY            8 
    2655 #define MSG_TELEPORT         9 
    2656 #define MSG_SHOOT           10 
    2657 #define MSG_QUAFF           11 
    2658 #define MSG_ZAP_ROD         12 
    2659 #define MSG_WALK            13 
    2660 #define MSG_TPOTHER         14 
    2661 #define MSG_HITWALL         15 
    2662 #define MSG_EAT             16 
    2663 #define MSG_STORE1          17 
    2664 #define MSG_STORE2          18 
    2665 #define MSG_STORE3          19 
    2666 #define MSG_STORE4          20 
    2667 #define MSG_DIG             21 
    2668 #define MSG_OPENDOOR        22 
    2669 #define MSG_SHUTDOOR        23 
    2670 #define MSG_TPLEVEL         24 
    2671 #define MSG_BELL            25 
    2672 #define MSG_NOTHING_TO_OPEN 26 
    2673 #define MSG_LOCKPICK_FAIL   27 
    2674 #define MSG_STAIRS_DOWN     28  
    2675 #define MSG_HITPOINT_WARN   29 
    2676 #define MSG_ACT_ARTIFACT    30  
    2677 #define MSG_USE_STAFF       31  
    2678 #define MSG_DESTROY         32  
    2679 #define MSG_MON_HIT         33  
    2680 #define MSG_MON_TOUCH       34  
    2681 #define MSG_MON_PUNCH       35  
    2682 #define MSG_MON_KICK        36  
    2683 #define MSG_MON_CLAW        37  
    2684 #define MSG_MON_BITE        38  
    2685 #define MSG_MON_STING       39  
    2686 #define MSG_MON_BUTT        40  
    2687 #define MSG_MON_CRUSH       41  
    2688 #define MSG_MON_ENGULF      42  
    2689 #define MSG_MON_CRAWL       43  
    2690 #define MSG_MON_DROOL       44  
    2691 #define MSG_MON_SPIT        45  
    2692 #define MSG_MON_GAZE        46  
    2693 #define MSG_MON_WAIL        47  
    2694 #define MSG_MON_SPORE       48  
    2695 #define MSG_MON_BEG         49  
    2696 #define MSG_MON_INSULT      50  
    2697 #define MSG_MON_MOAN        51  
    2698 #define MSG_RECOVER         52  
    2699 #define MSG_BLIND           53  
    2700 #define MSG_CONFUSED        54  
    2701 #define MSG_POISONED        55  
    2702 #define MSG_AFRAID          56  
    2703 #define MSG_PARALYZED       57  
    2704 #define MSG_DRUGGED         58  
    2705 #define MSG_SPEED           59  
    2706 #define MSG_SLOW            60  
    2707 #define MSG_SHIELD          61  
    2708 #define MSG_BLESSED         62  
    2709 #define MSG_HERO            63  
    2710 #define MSG_BERSERK         64  
    2711 #define MSG_PROT_EVIL       65  
    2712 #define MSG_INVULN          66  
    2713 #define MSG_SEE_INVIS       67  
    2714 #define MSG_INFRARED        68  
    2715 #define MSG_RES_ACID        69  
    2716 #define MSG_RES_ELEC        70  
    2717 #define MSG_RES_FIRE        71  
    2718 #define MSG_RES_COLD        72  
    2719 #define MSG_RES_POIS        73  
    2720 #define MSG_STUN            74  
    2721 #define MSG_CUT             75  
    2722 #define MSG_STAIRS_UP       76  
    2723 #define MSG_STORE_ENTER     77  
    2724 #define MSG_STORE_LEAVE     78  
    2725 #define MSG_STORE_HOME      79  
    2726 #define MSG_MONEY1          80  
    2727 #define MSG_MONEY2          81  
    2728 #define MSG_MONEY3          82  
    2729 #define MSG_SHOOT_HIT       83  
    2730 #define MSG_STORE5          84  
    2731 #define MSG_LOCKPICK        85  
    2732 #define MSG_DISARM          86  
    2733 #define MSG_IDENT_BAD       87  
    2734 #define MSG_IDENT_EGO       88  
    2735 #define MSG_IDENT_ART       89  
    2736 #define MSG_BR_ELEMENTS     90 
    2737 #define MSG_BR_FROST        91 
    2738 #define MSG_BR_ELEC         92 
    2739 #define MSG_BR_ACID         93 
    2740 #define MSG_BR_GAS          94 
    2741 #define MSG_BR_FIRE         95 
    2742 #define MSG_BR_CONF         96 
    2743 #define MSG_BR_DISENCHANT   97 
    2744 #define MSG_BR_CHAOS        98 
    2745 #define MSG_BR_SHARDS       99 
    2746 #define MSG_BR_SOUND        100 
    2747 #define MSG_BR_LIGHT        101 
    2748 #define MSG_BR_DARK         102 
    2749 #define MSG_BR_NETHER       103 
    2750 #define MSG_BR_NEXUS        104 
    2751 #define MSG_BR_TIME         105 
    2752 #define MSG_BR_INERTIA      106 
    2753 #define MSG_BR_GRAVITY      107 
    2754 #define MSG_BR_PLASMA       108 
    2755 #define MSG_BR_FORCE        109 
    2756 #define MSG_SUM_MONSTER     110 
    2757 #define MSG_SUM_ANGEL       111 
    2758 #define MSG_SUM_UNDEAD      112 
    2759 #define MSG_SUM_ANIMAL      113 
    2760 #define MSG_SUM_SPIDER      114 
    2761 #define MSG_SUM_HOUND       115 
    2762 #define MSG_SUM_HYDRA       116 
    2763 #define MSG_SUM_DEMON       117 
    2764 #define MSG_SUM_DRAGON      118 
    2765 #define MSG_SUM_HI_UNDEAD   119 
    2766 #define MSG_SUM_HI_DRAGON   120 
    2767 #define MSG_SUM_HI_DEMON    121 
    2768 #define MSG_SUM_WRAITH      122 
    2769 #define MSG_SUM_UNIQUE      123 
    2770 #define MSG_WIELD           124 
    2771 #define MSG_CURSED          125 
    2772 #define MSG_PSEUDOID        126 
    2773 #define MSG_HUNGRY          127 
    2774 #define MSG_NOTICE          128 
    2775 #define MSG_AMBIENT_DAY     129 
    2776 #define MSG_AMBIENT_NITE    130 
    2777 #define MSG_AMBIENT_DNG1    131 
    2778 #define MSG_AMBIENT_DNG2    132 
    2779 #define MSG_AMBIENT_DNG3    133 
    2780 #define MSG_AMBIENT_DNG4    134 
    2781 #define MSG_AMBIENT_DNG5    135 
    2782 #define MSG_CREATE_TRAP     136 
    2783 #define MSG_SHRIEK          137 
    2784 #define MSG_CAST_FEAR       138 
    2785 #define MSG_HIT_GOOD        139 
    2786 #define MSG_HIT_GREAT       140 
    2787 #define MSG_HIT_SUPERB      141 
    2788 #define MSG_HIT_HI_GREAT    142 
    2789 #define MSG_HIT_HI_SUPERB   143 
    2790 #define MSG_SPELL           144 
    2791 #define MSG_PRAYER          145 
    2792 #define MSG_KILL_UNIQUE     146 
    2793 #define MSG_KILL_KING       147 
    2794 #define MSG_DRAIN_STAT      148 
    2795 #define MSG_MULTIPLY        149 
    2796  
    2797 #define MSG_MAX             150 
    2798  
    2799 /* 
    2800  * Hack -- maximum known sounds 
    2801  * 
    2802  * Should be the same as MSG_MAX for compatibility reasons. 
    2803  */ 
    2804 #define SOUND_MAX MSG_MAX 
    2805  
    28062631 
    28072632/* 
     
    28212646# undef MACRO_MAX 
    28222647# define MACRO_MAX      128 
    2823 # undef MESSAGE_MAX 
    2824 # define MESSAGE_MAX    128 
    2825 # undef MESSAGE_BUF 
    2826 # define MESSAGE_BUF    4096 
    28272648#endif 
    28282649 
  • trunk/src/externs.h

    r472 r479  
    632632extern void sound(int val); 
    633633extern bool check_for_inscrip(const object_type *o_ptr, const char *inscrip); 
    634 extern s16b message_num(void); 
    635 extern cptr message_str(s16b age); 
    636 extern u16b message_type(s16b age); 
    637 extern byte message_color(s16b age); 
    638 extern errr message_color_define(u16b type, byte color); 
    639 extern void message_add(cptr str, u16b type); 
    640 extern errr messages_init(void); 
    641 extern void messages_free(void); 
    642634extern void msg_print(cptr msg); 
    643635extern void msg_format(cptr fmt, ...); 
  • trunk/src/files.c

    r473 r479  
    18701870        if (p_ptr->is_dead) 
    18711871        { 
    1872                 i = message_num(); 
     1872                i = messages_num(); 
    18731873                if (i > 15) i = 15; 
    18741874                file_putf(fp, "  [Last Messages]\n\n"); 
  • trunk/src/save.c

    r469 r479  
    877877 
    878878        /* Dump the number of "messages" */ 
    879         tmp16u = message_num(); 
     879        tmp16u = messages_num(); 
    880880        if (tmp16u > 80) tmp16u = 80; 
    881881        wr_u16b(tmp16u); 
  • trunk/src/util.c

    r469 r479  
    13441344} 
    13451345 
    1346  
    1347 /* 
    1348  * The "message memorization" package. 
    1349  * 
    1350  * Each call to "message_add(s)" will add a new "most recent" message 
    1351  * to the "message recall list", using the contents of the string "s". 
    1352  * 
    1353  * The number of memorized messages is available as "message_num()". 
    1354  * 
    1355  * Old messages can be retrieved by "message_str(age)", where the "age" 
    1356  * of the most recently memorized message is zero, and the oldest "age" 
    1357  * which is available is "message_num() - 1".  Messages outside this 
    1358  * range are returned as the empty string. 
    1359  * 
    1360  * The messages are stored in a special manner that maximizes "efficiency", 
    1361  * that is, we attempt to maximize the number of semi-sequential messages 
    1362  * that can be retrieved, given a limited amount of storage space, without 
    1363  * causing the memorization of new messages or the recall of old messages 
    1364  * to be too expensive. 
    1365  * 
    1366  * We keep a buffer of chars to hold the "text" of the messages, more or 
    1367  * less in the order they were memorized, and an array of offsets into that 
    1368  * buffer, representing the actual messages, but we allow the "text" to be 
    1369  * "shared" by two messages with "similar" ages, as long as we never cause 
    1370  * sharing to reach too far back in the the buffer. 
    1371  * 
    1372  * The implementation is complicated by the fact that both the array of 
    1373  * offsets, and the buffer itself, are both treated as "circular arrays" 
    1374  * for efficiency purposes, but the strings may not be "broken" across 
    1375  * the ends of the array. 
    1376  * 
    1377  * When we want to memorize a new message, we attempt to "reuse" the buffer 
    1378  * space by checking for message duplication within the recent messages. 
    1379  * 
    1380  * Otherwise, if we need more buffer space, we grab a full quarter of the 
    1381  * total buffer space at a time, to keep the reclamation code efficient. 
    1382  * 
    1383  * The "message_add()" function is rather "complex", because it must be 
    1384  * extremely efficient, both in space and time, for use with the Borg. 
    1385  */ 
    1386  
    1387  
    1388 /* 
    1389  * The next "free" index to use 
    1390  */ 
    1391 static u16b message__next; 
    1392  
    1393 /* 
    1394  * The index of the oldest message (none yet) 
    1395  */ 
    1396 static u16b message__last; 
    1397  
    1398 /* 
    1399  * The next "free" offset 
    1400  */ 
    1401 static u16b message__head; 
    1402  
    1403 /* 
    1404  * The offset to the oldest used char (none yet) 
    1405  */ 
    1406 static u16b message__tail; 
    1407  
    1408 /* 
    1409  * The array[MESSAGE_MAX] of offsets, by index 
    1410  */ 
    1411 static u16b *message__ptr; 
    1412  
    1413 /* 
    1414  * The array[MESSAGE_BUF] of chars, by offset 
    1415  */ 
    1416 static char *message__buf; 
    1417  
    1418 /* 
    1419  * The array[MESSAGE_MAX] of u16b for the types of messages 
    1420  */ 
    1421 static u16b *message__type; 
    1422  
    1423 /* 
    1424  * The array[MESSAGE_MAX] of u16b for the count of messages 
    1425  */ 
    1426 static u16b *message__count; 
    1427  
    1428  
    1429 /* 
    1430  * Table of colors associated to message-types 
    1431  */ 
    1432 static byte message__color[MSG_MAX]; 
    1433  
    1434  
    1435 /* 
    1436  * Calculate the index of a message 
    1437  */ 
    1438 static s16b message_age2idx(int age) 
    1439 { 
    1440         return ((message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX); 
    1441 } 
    1442  
    1443  
    1444 /* 
    1445  * How many messages are "available"? 
    1446  */ 
    1447 s16b message_num(void) 
    1448 { 
    1449         /* Determine how many messages are "available" */ 
    1450         return (message_age2idx(message__last - 1)); 
    1451 } 
    1452  
    1453  
    1454  
    1455 /* 
    1456  * Recall the "text" of a saved message 
    1457  */ 
    1458 cptr message_str(s16b age) 
    1459 { 
    1460         static char buf[1024]; 
    1461         s16b x; 
    1462         u16b o; 
    1463         cptr s; 
    1464  
    1465         /* Forgotten messages have no text */ 
    1466         if ((age < 0) || (age >= message_num())) return (""); 
    1467  
    1468         /* Get the "logical" index */ 
    1469         x = message_age2idx(age); 
    1470  
    1471         /* Get the "offset" for the message */ 
    1472         o = message__ptr[x]; 
    1473  
    1474         /* Get the message text */ 
    1475         s = &message__buf[o]; 
    1476  
    1477         /* HACK - Handle repeated messages */ 
    1478         if (message__count[x] > 1) 
    1479         { 
    1480                 strnfmt(buf, sizeof(buf), "%s <%dx>", s, message__count[x]); 
    1481                 s = buf; 
    1482         } 
    1483  
    1484         /* Return the message text */ 
    1485         return (s); 
    1486 } 
    1487  
    1488  
    1489 /* 
    1490  * Recall the "type" of a saved message 
    1491  */ 
    1492 u16b message_type(s16b age) 
    1493 { 
    1494         /* Paranoia */ 
    1495         if (!message__type) 
    1496                 return MSG_GENERIC; 
    1497  
    1498         /* Forgotten messages are generic */ 
    1499         if ((age < 0) || (age >= message_num())) 
    1500                 return MSG_GENERIC; 
    1501  
    1502         /* Return the message type */ 
    1503         return (message__type[message_age2idx(age)]); 
    1504 } 
    1505  
    1506  
    1507 /* 
    1508  * Recall the "color" of a message type 
    1509  */ 
    1510 static byte message_type_color(u16b type) 
    1511 { 
    1512         byte color = message__color[type]; 
    1513  
    1514         if (color == TERM_DARK) color = TERM_WHITE; 
    1515  
    1516         return color; 
    1517 } 
    1518  
    1519  
    1520 /* 
    1521  * Recall the "color" of a saved message 
    1522  */ 
    1523 byte message_color(s16b age) 
    1524 { 
    1525         return message_type_color(message_type(age)); 
    1526 } 
    1527  
    1528  
    1529 errr message_color_define(u16b type, byte color) 
    1530 { 
    1531         if (type >= MSG_MAX) return 1; 
    1532  
    1533         /* Store the color */ 
    1534         message__color[type] = color; 
    1535         return 0; 
    1536 } 
    1537  
    1538  
    1539 /* 
    1540  * Add a new message, with great efficiency 
    1541  * 
    1542  * We must ignore long messages to prevent internal overflow, since we 
    1543  * assume that we can always get enough space by advancing "message__tail" 
    1544  * by one quarter the total buffer space. 
    1545  * 
    1546  * We must not attempt to optimize using a message index or buffer space 
    1547  * which is "far away" from the most recent entries, or we will lose a lot 
    1548  * of messages when we "expire" the old message index and/or buffer space. 
    1549  */ 
    1550 void message_add(cptr str, u16b type) 
    1551 { 
    1552         int k, i, x, o; 
    1553         size_t n; 
    1554  
    1555         cptr s; 
    1556  
    1557         cptr u; 
    1558         char *v; 
    1559  
    1560  
    1561         /*** Step 1 -- Analyze the message ***/ 
    1562  
    1563         /* Hack -- Ignore "non-messages" */ 
    1564         if (!str) return; 
    1565  
    1566         /* Message length */ 
    1567         n = strlen(str); 
    1568  
    1569         /* Hack -- Ignore "long" messages */ 
    1570         if (n >= MESSAGE_BUF / 4) return; 
    1571  
    1572  
    1573         /*** Step 2 -- Attempt to optimize ***/ 
    1574  
    1575         /* Get the "logical" last index */ 
    1576         x = message_age2idx(0); 
    1577  
    1578         /* Get the "offset" for the last message */ 
    1579         o = message__ptr[x]; 
    1580  
    1581         /* Get the message text */ 
    1582         s = &message__buf[o]; 
    1583  
    1584         /* Last message repeated? */ 
    1585         if (streq(str, s)) 
    1586         { 
    1587                 /* Increase the message count */ 
    1588                 message__count[x]++; 
    1589                 return; 
    1590         } 
    1591  
    1592         /*** Step 3 -- Attempt to optimize ***/ 
    1593  
    1594         /* Limit number of messages to check */ 
    1595         k = message_num() / 4; 
    1596  
    1597         /* Limit number of messages to check */ 
    1598         if (k > 32) k = 32; 
    1599  
    1600         /* Start just after the most recent message */ 
    1601         i = message__next; 
    1602  
    1603         /* Check the last few messages for duplication */ 
    1604         for ( ; k; k--) 
    1605         { 
    1606                 u16b q; 
    1607  
    1608                 cptr old; 
    1609  
    1610                 /* Back up, wrap if needed */ 
    1611                 if (i-- == 0) i = MESSAGE_MAX - 1; 
    1612  
    1613                 /* Stop before oldest message */ 
    1614                 if (i == message__last) break; 
    1615  
    1616                 /* Index */ 
    1617                 o = message__ptr[i]; 
    1618  
    1619                 /* Extract "distance" from "head" */ 
    1620                 q = (message__head + MESSAGE_BUF - o) % MESSAGE_BUF; 
    1621  
    1622                 /* Do not optimize over large distances */ 
    1623                 if (q >= MESSAGE_BUF / 4) continue; 
    1624  
    1625                 /* Get the old string */ 
    1626                 old = &message__buf[o]; 
    1627  
    1628                 /* Continue if not equal */ 
    1629                 if (!streq(str, old)) continue; 
    1630  
    1631                 /* Get the next available message index */ 
    1632                 x = message__next; 
    1633  
    1634                 /* Advance 'message__next', wrap if needed */ 
    1635                 if (++message__next == MESSAGE_MAX) message__next = 0; 
    1636  
    1637                 /* Kill last message if needed */ 
    1638                 if (message__next == message__last) 
    1639                 { 
    1640                         /* Advance 'message__last', wrap if needed */ 
    1641                         if (++message__last == MESSAGE_MAX) message__last = 0; 
    1642                 } 
    1643  
    1644                 /* Assign the starting address */ 
    1645                 message__ptr[x] = message__ptr[i]; 
    1646  
    1647                 /* Store the message type */ 
    1648                 message__type[x] = type; 
    1649  
    1650                 /* Store the message count */ 
    1651                 message__count[x] = 1; 
    1652  
    1653                 /* Success */ 
    1654                 return; 
    1655         } 
    1656  
    1657         /*** Step 4 -- Ensure space before end of buffer ***/ 
    1658  
    1659         /* Kill messages, and wrap, if needed */ 
    1660         if (message__head + (n + 1) >= MESSAGE_BUF) 
    1661         { 
    1662                 /* Kill all "dead" messages */ 
    1663                 for (i = message__last; TRUE; i++) 
    1664                 { 
    1665                         /* Wrap if needed */ 
    1666                         if (i == MESSAGE_MAX) i = 0; 
    1667  
    1668                         /* Stop before the new message */ 
    1669                         if (i == message__next) break; 
    1670  
    1671                         /* Get offset */ 
    1672                         o = message__ptr[i]; 
    1673  
    1674                         /* Kill "dead" messages */ 
    1675                         if (o >= message__head) 
    1676                         { 
    1677                                 /* Track oldest message */ 
    1678                                 message__last = i + 1; 
    1679                         } 
    1680                 } 
    1681  
    1682                 /* Wrap "tail" if needed */ 
    1683                 if (message__tail >= message__head) message__tail = 0; 
    1684  
    1685                 /* Start over */ 
    1686                 message__head = 0; 
    1687         } 
    1688  
    1689  
    1690         /*** Step 5 -- Ensure space for actual characters ***/ 
    1691  
    1692         /* Kill messages, if needed */ 
    1693         if (message__head + (n + 1) > message__tail) 
    1694         { 
    1695                 /* Advance to new "tail" location */ 
    1696                 message__tail += (MESSAGE_BUF / 4); 
    1697  
    1698                 /* Kill all "dead" messages */ 
    1699                 for (i = message__last; TRUE; i++) 
    1700                 { 
    1701                         /* Wrap if needed */ 
    1702                         if (i == MESSAGE_MAX) i = 0; 
    1703  
    1704                         /* Stop before the new message */ 
    1705                         if (i == message__next) break; 
    1706  
    1707                         /* Get offset */ 
    1708                         o = message__ptr[i]; 
    1709  
    1710                         /* Kill "dead" messages */ 
    1711                         if ((o >= message__head) && (o < message__tail)) 
    1712                         { 
    1713                                 /* Track oldest message */ 
    1714                                 message__last = i + 1; 
    1715                         } 
    1716                 } 
    1717         } 
    1718  
    1719  
    1720         /*** Step 6 -- Grab a new message index ***/ 
    1721  
    1722         /* Get the next available message index */ 
    1723         x = message__next; 
    1724  
    1725         /* Advance 'message__next', wrap if needed */ 
    1726         if (++message__next == MESSAGE_MAX) message__next = 0; 
    1727  
    1728         /* Kill last message if needed */ 
    1729         if (message__next == message__last) 
    1730         { 
    1731                 /* Advance 'message__last', wrap if needed */ 
    1732                 if (++message__last == MESSAGE_MAX) message__last = 0; 
    1733         } 
    1734  
    1735  
    1736         /*** Step 7 -- Insert the message text ***/ 
    1737  
    1738         /* Assign the starting address */ 
    1739         message__ptr[x] = message__head; 
    1740  
    1741         /* Inline 'strcpy(message__buf + message__head, str)' */ 
    1742         v = message__buf + message__head; 
    1743         for (u = str; *u; ) *v++ = *u++; 
    1744         *v = '\0'; 
    1745  
    1746         /* Advance the "head" pointer */ 
    1747         message__head += (n + 1); 
    1748  
    1749         /* Store the message type */ 
    1750         message__type[x] = type; 
    1751  
    1752         /* Store the message count */ 
    1753         message__count[x] = 1; 
    1754 } 
    1755  
    1756  
    1757 /* 
    1758  * Initialize the "message" package 
    1759  */ 
    1760 errr messages_init(void) 
    1761 { 
    1762         /* Message variables */ 
    1763         message__ptr = C_ZNEW(MESSAGE_MAX, u16b); 
    1764         message__buf = C_ZNEW(MESSAGE_BUF, char); 
    1765         message__type = C_ZNEW(MESSAGE_MAX, u16b); 
    1766         message__count = C_ZNEW(MESSAGE_MAX, u16b); 
    1767  
    1768         /* Init the message colors to white */ 
    1769         memset(message__color, TERM_WHITE, MSG_MAX); 
    1770  
    1771         /* Hack -- No messages yet */ 
    1772         message__tail = MESSAGE_BUF; 
    1773  
    1774         /* Success */ 
    1775         return 0; 
    1776 } 
    1777  
    1778  
    1779 /* 
    1780  * Free the "message" package 
    1781  */ 
    1782 void messages_free(void) 
    1783 { 
    1784         /* Free the messages */ 
    1785         FREE(message__ptr); 
    1786         FREE(message__buf); 
    1787         FREE(message__type); 
    1788         FREE(message__count); 
    1789 } 
    1790  
    1791  
    1792  
    1793  
    1794  
    1795  
    1796  
    17971346/* 
    17981347 * Hack -- flush 
  • trunk/src/xtra1.c

    r456 r479  
    985985        int x, y; 
    986986 
     987        const char *msg; 
     988 
    987989        /* Get size */ 
    988990        Term_get_size(&w, &h); 
     
    991993        for (i = 0; i < h; i++) 
    992994        { 
    993                 byte color = message_color((s16b)i); 
    994  
    995                 /* Dump the message on the appropriate line */ 
    996                 Term_putstr(0, (h - 1) - i, -1, color, message_str((s16b)i)); 
     995                byte color = message_color(i); 
     996                u16b count = message_count(i); 
     997                const char *str = message_str(i); 
     998 
     999                if (count == 1) 
     1000                        msg = str; 
     1001                else 
     1002                        msg = format("%s <%dx>", str, count); 
     1003 
     1004                Term_putstr(0, (h - 1) - i, -1, color, msg); 
     1005 
    9971006 
    9981007                /* Cursor */