Previous 15994 Revisions Next

r14082 Wednesday 18th January, 2012 at 07:34:24 UTC by Miodrag Milanović
Sync with MAME r15074 (no whatsnew)
[src/build]makedep.c
[src/emu]emualloc.h
[src/emu/sound]discrete.c discrete.h
[src/lib]lib.mak
[src/lib/util]tagmap.c tagmap.h
[src/mame/drivers]aleck64.c suprnova.c timelimt.c zn.c
[src/mame/video]snk6502.c

src/build/makedep.c
r14081r14082
9595   dependency *   deplist;
9696};
9797
98typedef tagmap_t<UINT8> dependency_map;
9899
99100
101
100102/***************************************************************************
101103    GLOBAL VARIABLES
102104***************************************************************************/
r14081r14082
210212    unless we already exist in the map
211213-------------------------------------------------*/
212214
213static void recurse_dependencies(file_entry &file, tagmap_t<astring *> &map)
215static void recurse_dependencies(file_entry &file, dependency_map &map)
214216{
215217   // skip if we're in an exclude path
216218   int filelen = file.name.len();
r14081r14082
220222            return;
221223
222224   // attempt to add; if we get an error, we're already present
223   if (map.add(file.name, &file.name) != TMERR_NONE)
225   if (map.add(file.name, 0) != TMERR_NONE)
224226      return;
225227
226228   // recurse the list from there
r14081r14082
304306            // make sure we care, first
305307            if (core_filename_ends_with(curlist->name, ".c"))
306308            {
307               tagmap_t<astring *> depend_map;
309               dependency_map depend_map;
308310
309311               // find dependencies
310312               file_entry &file = compute_dependencies(srcrootlen, srcfile);
r14081r14082
317319               printf("\n%s : \\\n", target.cstr());
318320
319321               // iterate over the hashed dependencies and output them as well
320               for (int taghash = 0; taghash < TAGMAP_HASH_SIZE; taghash++)
321                  for (tagmap_entry *map_entry = depend_map.table[taghash]; map_entry != NULL; map_entry = map_entry->next)
322                     printf("\t%s \\\n", ((astring *)map_entry->object)->cstr());
322               for (dependency_map::entry_t *entry = depend_map.first(); entry != NULL; entry = depend_map.next(entry))
323                  printf("\t%s \\\n", entry->tag().cstr());
323324            }
324325         }
325326
src/mame/video/snk6502.c
r14081r14082
198198
199199   VIDEO_START_CALL( snk6502 );
200200
201   state->m_bg_tilemap->set_scrolldy(-24, 0);
202   state->m_fg_tilemap->set_scrolldy(-24, 0);
201   state->m_bg_tilemap->set_scrolldy(-16, 0);
202   state->m_fg_tilemap->set_scrolldy(-16, 0);
203203}
204204
205205
src/mame/drivers/zn.c
r14081r14082
28152815   ROM_LOAD( "ts2-10m.4k", 0x0c00000, 0x200000, CRC(ad90679a) SHA1(19dd30764f892ee7f89c78ccbccdaf4d6b0e6e09) )
28162816
28172817   ROM_REGION( 0x50000, "audiocpu", 0 ) /* 64k for the audio CPU (+banks) */
2818   ROM_LOAD( "ts2-02.2e",  0x00000, 0x08000, CRC(2f45c461) SHA1(513b6b9b5a2f7c567c30c958e0e13834cd9bd266) )
2819   ROM_CONTINUE(        0x10000, 0x18000 )
2818   ROM_LOAD( "ts2_02.2e",  0x00000, 0x08000, CRC(2f45c461) SHA1(513b6b9b5a2f7c567c30c958e0e13834cd9bd266) )
2819   ROM_CONTINUE(           0x10000, 0x18000 )
28202820
28212821   ROM_REGION( 0x400000, "qsound", 0 ) /* Q Sound Samples */
2822   ROM_LOAD16_WORD_SWAP( "ts2-01m.3b", 0x0000000, 0x400000, CRC(d7a505e0) SHA1(f1b0cdea712101f695bd326eccd753eb79a07490) )
2822   ROM_LOAD16_WORD_SWAP( "ts2-01m.3b", 0x0000000, 0x400000, CRC(d7a505e0) SHA1(f1b0cdea712101f695bd326eccd753eb79a07490) )
28232823ROM_END
28242824
28252825/* 95681-2 */
r14081r14082
28382838   ROM_LOAD( "ts2-10m.4k", 0x0c00000, 0x200000, CRC(ad90679a) SHA1(19dd30764f892ee7f89c78ccbccdaf4d6b0e6e09) )
28392839
28402840   ROM_REGION( 0x50000, "audiocpu", 0 ) /* 64k for the audio CPU (+banks) */
2841   ROM_LOAD( "ts2-02.2e",  0x00000, 0x08000, CRC(2f45c461) SHA1(513b6b9b5a2f7c567c30c958e0e13834cd9bd266) )
2841   ROM_LOAD( "ts2_02.2e",  0x00000, 0x08000, CRC(2f45c461) SHA1(513b6b9b5a2f7c567c30c958e0e13834cd9bd266) )
28422842   ROM_CONTINUE(           0x10000, 0x18000 )
28432843
28442844   ROM_REGION( 0x400000, "qsound", 0 ) /* Q Sound Samples */
r14081r14082
28592859   ROM_LOAD( "ts2-10m.4k", 0x0c00000, 0x200000, CRC(ad90679a) SHA1(19dd30764f892ee7f89c78ccbccdaf4d6b0e6e09) )
28602860
28612861   ROM_REGION( 0x50000, "audiocpu", 0 ) /* 64k for the audio CPU (+banks) */
2862   ROM_LOAD( "ts2-02.2e",  0x00000, 0x08000, CRC(2f45c461) SHA1(513b6b9b5a2f7c567c30c958e0e13834cd9bd266) )
2862   ROM_LOAD( "ts2_02.2e",  0x00000, 0x08000, CRC(2f45c461) SHA1(513b6b9b5a2f7c567c30c958e0e13834cd9bd266) )
28632863   ROM_CONTINUE(           0x10000, 0x18000 )
28642864
28652865   ROM_REGION( 0x400000, "qsound", 0 ) /* Q Sound Samples */
src/mame/drivers/timelimt.c
r14081r14082
202202static GFXDECODE_START( timelimt )
203203   GFXDECODE_ENTRY( "tiles_1", 0, charlayout,   32, 1 )   /* seems correct */
204204   GFXDECODE_ENTRY( "tiles_2", 0, charlayout,    0, 1 )   /* seems correct */
205   GFXDECODE_ENTRY( "sprites", 0, spritelayout,  0, 8 )   /* ?? */
206GFXDECODE_END
207
208static GFXDECODE_START( progress )
209   GFXDECODE_ENTRY( "tiles_1", 0, charlayout,   32, 1 )   /* seems correct */
210   GFXDECODE_ENTRY( "tiles_2", 0, charlayout,    0, 1 )   /* seems correct */
211205   GFXDECODE_ENTRY( "sprites", 0, spritelayout, 64, 4 )   /* seems correct */
212206GFXDECODE_END
213207
r14081r14082
259253   MCFG_SCREEN_UPDATE_STATIC(timelimt)
260254
261255   MCFG_GFXDECODE(timelimt)
262   MCFG_PALETTE_LENGTH(64)
256   MCFG_PALETTE_LENGTH(64+32)
263257
264258   MCFG_PALETTE_INIT(timelimt)
265259   MCFG_VIDEO_START(timelimt)
r14081r14082
275269   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
276270MACHINE_CONFIG_END
277271
278static MACHINE_CONFIG_DERIVED( progress, timelimt )
279
280   /* basic machine hardware */
281
282   MCFG_GFXDECODE(progress)
283   MCFG_PALETTE_LENGTH(96)
284
285MACHINE_CONFIG_END
286
287272/***************************************************************************
288273
289274  Game ROM(s)
r14081r14082
314299   ROM_LOAD( "tl2",    0x2000, 0x2000, CRC(4693b849) SHA1(fbebedde53599fb1eaedc648bd704b321ab096b5) )
315300   ROM_LOAD( "tl1",    0x4000, 0x2000, CRC(c4007caf) SHA1(ae05af3319545d5ca98a046bfc100138a5a3ed96) )
316301
317   ROM_REGION( 0x0040, "proms", 0 )
302   ROM_REGION( 0x0060, "proms", 0 )
318303   ROM_LOAD( "clr.35", 0x0000, 0x0020, CRC(9c9e6073) SHA1(98496175bf19a8cdb0018705bc1a2193b8a782e1) )
319   ROM_LOAD( "clr.48", 0x0020, 0x0020, BAD_DUMP CRC(a0bcac59) SHA1(e5832831b21981363509b79d89766757bd9273b0)  )   /* FIXED BITS (xxxxxx1x) */
320   /* missing a prom? */
304   ROM_LOAD( "clr.48", 0x0020, 0x0020, BAD_DUMP CRC(a0bcac59) SHA1(e5832831b21981363509b79d89766757bd9273b0) )   /* FIXED BITS (xxxxxx1x) */
305   ROM_LOAD( "clr.57", 0x0040, 0x0020, NO_DUMP )   /* missing sprite color prom? */
321306ROM_END
322307
323308ROM_START( progress )
r14081r14082
350335ROM_END
351336
352337GAME( 1983, timelimt, 0, timelimt, timelimt, 0, ROT90, "Chuo Co. Ltd", "Time Limit", GAME_IMPERFECT_COLORS )
353GAME( 1984, progress, 0, progress, progress, 0, ROT90, "Chuo Co. Ltd", "Progress", 0 )
338GAME( 1984, progress, 0, timelimt, progress, 0, ROT90, "Chuo Co. Ltd", "Progress", 0 )
src/mame/drivers/suprnova.c
r14081r14082
17501750GAME( 1996, galpani4,  skns,     sknsj, cyvern,   galpani4,  ROT0,  "Kaneko", "Gals Panic 4 (Japan)", GAME_IMPERFECT_GRAPHICS )
17511751GAME( 1996, galpani4k, galpani4, sknsk, cyvern,   galpani4,  ROT0,  "Kaneko", "Gals Panic 4 (Korea)", GAME_IMPERFECT_GRAPHICS )
17521752GAME( 1996, jjparads,  skns,     sknsj, skns_1p,  jjparads,  ROT0,  "Electro Design", "Jan Jan Paradise", GAME_IMPERFECT_GRAPHICS )
1753GAME( 1997, galpanis,  skns,     sknsj, galpanis, galpanis,  ROT0,  "Kaneko", "Gals Panic S - Extra Edition (Europe)", GAME_IMPERFECT_GRAPHICS )
1754GAME( 1997, galpanisj, galpanis, sknsk, galpanis, galpanis,  ROT0,  "Kaneko", "Gals Panic S - Extra Edition (Japan)", GAME_IMPERFECT_GRAPHICS )
1753GAME( 1997, galpanis,  skns,     sknse, galpanis, galpanis,  ROT0,  "Kaneko", "Gals Panic S - Extra Edition (Europe)", GAME_IMPERFECT_GRAPHICS )
1754GAME( 1997, galpanisj, galpanis, sknsj, galpanis, galpanis,  ROT0,  "Kaneko", "Gals Panic S - Extra Edition (Japan)", GAME_IMPERFECT_GRAPHICS )
17551755GAME( 1997, galpanisk, galpanis, sknsk, galpanis, galpanis,  ROT0,  "Kaneko", "Gals Panic S - Extra Edition (Korea)", GAME_IMPERFECT_GRAPHICS )
17561756GAME( 1997, jjparad2,  skns,     sknsj, skns_1p,  jjparad2,  ROT0,  "Electro Design", "Jan Jan Paradise 2", GAME_IMPERFECT_GRAPHICS )
17571757GAME( 1997, sengekis,  skns,     sknsa, skns,     sengekis,  ROT90, "Kaneko / Warashi", "Sengeki Striker (Asia)", GAME_IMPERFECT_GRAPHICS )
src/mame/drivers/aleck64.c
r14081r14082
837837   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
838838   MCFG_SOUND_ADD("dac2", DMADAC, 0)
839839   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
840
841   MCFG_N64_PERIPHS_ADD("rcp");
840842MACHINE_CONFIG_END
841843
842844static DRIVER_INIT( aleck64 )
src/emu/emualloc.h
r14081r14082
331331#define calloc(x,y)      __error_use_auto_alloc_clear_or_global_alloc_clear_instead__
332332#define realloc(x,y)   __error_realloc_is_dangerous__
333333#define free(x)         free_file_line(x, __FILE__, __LINE__)
334
335// disable direct deletion
336#define delete         __error_use_pool_free_mechanisms__
337334#endif
338335
339336#endif   /* __EMUALLOC_H__ */
src/emu/sound/discrete.c
r14081r14082
541541            }
542542         }
543543         for_each (int *, i, &deletethem)
544            block_list.delete(*i);
544            block_list.remove(*i);
545545      }
546546      else
547547      {
src/emu/sound/discrete.h
r14081r14082
38103810      m_count++;
38113811      return &m_arr[m_count-1];
38123812   }
3813   inline void delete(int index)
3813   inline void remove(int index)
38143814   {
38153815      for (int i=index+1; i < m_count; i++)
38163816         m_arr[i-1] = m_arr[i];
src/lib/lib.mak
r14081r14082
4848   $(LIBOBJ)/util/png.o \
4949   $(LIBOBJ)/util/pool.o \
5050   $(LIBOBJ)/util/sha1.o \
51   $(LIBOBJ)/util/tagmap.o \
5251   $(LIBOBJ)/util/unicode.o \
5352   $(LIBOBJ)/util/unzip.o \
5453   $(LIBOBJ)/util/vbiparse.o \
src/lib/util/tagmap.c
r14081r14082
1/***************************************************************************
2
3    tagmap.c
4
5    Simple tag->object mapping functions.
6
7****************************************************************************
8
9    Copyright Aaron Giles
10    All rights reserved.
11
12    Redistribution and use in source and binary forms, with or without
13    modification, are permitted provided that the following conditions are
14    met:
15
16        * Redistributions of source code must retain the above copyright
17          notice, this list of conditions and the following disclaimer.
18        * Redistributions in binary form must reproduce the above copyright
19          notice, this list of conditions and the following disclaimer in
20          the documentation and/or other materials provided with the
21          distribution.
22        * Neither the name 'MAME' nor the names of its contributors may be
23          used to endorse or promote products derived from this software
24          without specific prior written permission.
25
26    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
27    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
30    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36    POSSIBILITY OF SUCH DAMAGE.
37
38****************************************************************************/
39
40#include "tagmap.h"
41
42#include <stdlib.h>
43
44
45/***************************************************************************
46    FUNCTION PROTOTYPES
47***************************************************************************/
48
49static tagmap_error tagmap_add_common(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate, UINT8 unique_hash);
50
51
52
53/***************************************************************************
54    MAP ALLOCATION AND MANAGEMENT
55***************************************************************************/
56
57/*-------------------------------------------------
58    tagmap_alloc - allocate a new tagmap
59-------------------------------------------------*/
60
61tagmap *tagmap_alloc(void)
62{
63   tagmap *map = (tagmap *)malloc(sizeof(*map));
64   if (map != NULL)
65      memset(map, 0, sizeof(*map));
66   return map;
67}
68
69
70/*-------------------------------------------------
71    tagmap_free - free a tagmap, and all
72    entries within it
73-------------------------------------------------*/
74
75void tagmap_free(tagmap *map)
76{
77   tagmap_reset(map);
78   free(map);
79}
80
81
82/*-------------------------------------------------
83    tagmap_reset - reset a tagmap by freeing
84    all entries
85-------------------------------------------------*/
86
87void tagmap_reset(tagmap *map)
88{
89   UINT32 hashindex;
90
91   for (hashindex = 0; hashindex < ARRAY_LENGTH(map->table); hashindex++)
92   {
93      tagmap_entry *entry, *next;
94
95      for (entry = map->table[hashindex]; entry != NULL; entry = next)
96      {
97         next = entry->next;
98         free(entry);
99      }
100      map->table[hashindex] = NULL;
101   }
102}
103
104
105
106/***************************************************************************
107    MAP ALLOCATION AND MANAGEMENT
108***************************************************************************/
109
110/*-------------------------------------------------
111    tagmap_add - add a new object to the
112    tagmap
113-------------------------------------------------*/
114
115tagmap_error tagmap_add(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate)
116{
117   return tagmap_add_common(map, tag, object, replace_if_duplicate, FALSE);
118}
119
120
121/*-------------------------------------------------
122    tagmap_add_unique_hash - add a new entry to a
123    tagmap, ensuring it has a unique hash value
124-------------------------------------------------*/
125
126tagmap_error tagmap_add_unique_hash(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate)
127{
128   return tagmap_add_common(map, tag, object, replace_if_duplicate, TRUE);
129}
130
131
132/*-------------------------------------------------
133    tagmap_remove - remove an entr from a
134    tagmap
135-------------------------------------------------*/
136
137void tagmap_remove(tagmap *map, const char *tag)
138{
139   UINT32 fullhash = tagmap_hash(tag);
140   tagmap_entry **entryptr;
141
142   for (entryptr = &map->table[fullhash % ARRAY_LENGTH(map->table)]; *entryptr != NULL; entryptr = &(*entryptr)->next)
143      if ((*entryptr)->fullhash == fullhash && strcmp((*entryptr)->tag, tag) == 0)
144      {
145         tagmap_entry *entry = *entryptr;
146         *entryptr = entry->next;
147         free(entry);
148         break;
149      }
150}
151
152
153/*-------------------------------------------------
154    tagmap_remove_object - remove an entry from a
155    tagmap by object pointer
156-------------------------------------------------*/
157
158void tagmap_remove_object(tagmap *map, void *object)
159{
160   UINT32 hashindex;
161
162   for (hashindex = 0; hashindex < ARRAY_LENGTH(map->table); hashindex++)
163   {
164      tagmap_entry **entryptr;
165
166      for (entryptr = &map->table[hashindex]; *entryptr != NULL; entryptr = &(*entryptr)->next)
167         if ((*entryptr)->object == object)
168         {
169            tagmap_entry *entry = *entryptr;
170            *entryptr = entry->next;
171            free(entry);
172            return;
173         }
174   }
175}
176
177
178
179/***************************************************************************
180    LOCAL FUNCTIONS
181***************************************************************************/
182
183/*-------------------------------------------------
184    tagmap_add_common - core implementation of
185    a tagmap addition
186-------------------------------------------------*/
187
188static tagmap_error tagmap_add_common(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate, UINT8 unique_hash)
189{
190   UINT32 fullhash = tagmap_hash(tag);
191   UINT32 hashindex = fullhash % ARRAY_LENGTH(map->table);
192   tagmap_entry *entry;
193
194   /* first make sure we don't have a duplicate */
195   for (entry = map->table[hashindex]; entry != NULL; entry = entry->next)
196      if (entry->fullhash == fullhash)
197         if (unique_hash || strcmp(tag, entry->tag) == 0)
198         {
199            if (replace_if_duplicate)
200               entry->object = object;
201            return TMERR_DUPLICATE;
202         }
203
204   /* now allocate a new entry */
205   entry = (tagmap_entry *)malloc(sizeof(*entry) + strlen(tag));
206   if (entry == NULL)
207      return TMERR_OUT_OF_MEMORY;
208
209   /* fill in the entry */
210   entry->object = object;
211   entry->fullhash = fullhash;
212   strcpy(entry->tag, tag);
213
214   /* add it to the head of the list */
215   entry->next = map->table[hashindex];
216   map->table[hashindex] = entry;
217   return TMERR_NONE;
218}
src/lib/util/tagmap.h
r14081r14082
4343#define __TAGMAP_H__
4444
4545#include "osdcore.h"
46#include "astring.h"
4647
4748
4849
49/***************************************************************************
50    CONSTANTS
51***************************************************************************/
50//**************************************************************************
51//  CONSTANTS
52//**************************************************************************
5253
53#define TAGMAP_HASH_SIZE   97
54
55
56enum _tagmap_error
54enum tagmap_error
5755{
5856   TMERR_NONE,
59   TMERR_OUT_OF_MEMORY,
6057   TMERR_DUPLICATE
6158};
62typedef enum _tagmap_error tagmap_error;
6359
6460
6561
66/***************************************************************************
67    TYPE DEFINITIONS
68***************************************************************************/
62//**************************************************************************
63//  TYPE DEFINITIONS
64//**************************************************************************
6965
70/* an entry in a tagmap */
71typedef struct _tagmap_entry tagmap_entry;
72struct _tagmap_entry
66// generally used for small tables, though the hash size can be increased
67// as necessary; good primes are: 53, 97, 193, 389, 769, 1543, 3079, 6151, etc
68template<class _ElementType, int _HashSize = 53>
69class tagmap_t
7370{
74   tagmap_entry *      next;
75   void *            object;
76   UINT32            fullhash;
77   char            tag[1];
78};
71private:
72   // disable copying/assignment
73   tagmap_t(const tagmap_t &);
74   tagmap_t &operator=(const tagmap_t &);
7975
76public:
77   // an entry in the table
78   class entry_t
79   {
80      friend class tagmap_t<_ElementType, _HashSize>;
81     
82   public:
83      // construction/destruction
84      entry_t(const char *tag, UINT32 fullhash, _ElementType object)
85         : m_next(NULL),
86           m_fullhash(fullhash),
87           m_tag(tag),
88           m_object(object) { }
89   
90      // accessors
91      const astring &tag() const { return m_tag; }
92      _ElementType object() const { return m_object; }
93     
94      // setters
95      void set_object(_ElementType object) { m_object = object; }
8096
81/* base tagmap structure */
82typedef struct _tagmap tagmap;
83struct _tagmap
84{
85   tagmap_entry *      table[TAGMAP_HASH_SIZE];
86};
97   private:
98      // internal helpers
99      entry_t *next() const { return m_next; }
100      UINT32 fullhash() const { return m_fullhash; }
87101
102      // internal state
103      entry_t *      m_next;
104      UINT32         m_fullhash;
105      astring         m_tag;
106      _ElementType   m_object;
107   };
88108
109   // construction/destruction
110   tagmap_t() { memset(m_table, 0, sizeof(m_table)); }
111   ~tagmap_t() { reset(); }
89112
90/***************************************************************************
91    FUNCTION PROTOTYPES
92***************************************************************************/
113   // core hashing function
114   UINT32 hash(const char *string) const
115   {
116      UINT32 result = *string++;
117      for (char c = *string++; c != 0; c = *string++)
118         result = ((result << 5) | (result >> 27)) + c;
119      return result;
120   }
93121
122   // empty the list
123   void reset()
124   {
125      for (UINT32 hashindex = 0; hashindex < ARRAY_LENGTH(m_table); hashindex++)
126         while (m_table[hashindex] != NULL)
127            remove_common(&m_table[hashindex]);
128   }
94129
95/* ----- map allocation and management ----- */
130   // add/remove
131   tagmap_error add(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return add_common(tag, object, replace_if_duplicate, false); }
132   tagmap_error add_unique_hash(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return add_common(tag, object, replace_if_duplicate, true); }
96133
97/* allocate a new tagmap */
98tagmap *tagmap_alloc(void);
134   // remove by tag
135   void remove(const char *tag)
136   {
137      UINT32 fullhash = hash(tag);
138      for (entry_t **entryptr = &m_table[fullhash % ARRAY_LENGTH(m_table)]; *entryptr != NULL; entryptr = &(*entryptr)->m_next)
139         if ((*entryptr)->fullhash() == fullhash && (*entryptr)->tag() == tag)
140            return remove_common(entryptr);
141   }
99142
100/* free a tagmap, and all entries within it */
101void tagmap_free(tagmap *map);
143   // remove by object
144   void remove(_ElementType object)
145   {
146      for (UINT32 hashindex = 0; hashindex < ARRAY_LENGTH(m_table); hashindex++)
147         for (entry_t **entryptr = &m_table[hashindex]; *entryptr != NULL; entryptr = &(*entryptr)->m_next)
148            if ((*entryptr)->object() == object)
149               return remove_common(entryptr);
150   }
102151
103/* reset a tagmap by freeing all entries */
104void tagmap_reset(tagmap *map);
152   // find by tag
153   _ElementType find(const char *tag) const { return find(tag, hash(tag)); }
154   
155   // find by tag with precomputed hash
156   _ElementType find(const char *tag, UINT32 fullhash) const
157   {
158      for (entry_t *entry = m_table[fullhash % ARRAY_LENGTH(m_table)]; entry != NULL; entry = entry->next())
159         if (entry->fullhash() == fullhash && entry->tag() == tag)
160            return entry->object();
161      return (_ElementType)NULL;
162   }
105163
164   // find by tag without checking anything but the hash
165   _ElementType find_hash_only(const char *tag) const
166   {
167      UINT32 fullhash = hash(tag);
168      for (entry_t *entry = m_table[fullhash % ARRAY_LENGTH(m_table)]; entry != NULL; entry = entry->next())
169         if (entry->fullhash() == fullhash)
170            return entry->object();
171      return NULL;
172   }
173   
174   // return first object in the table
175   entry_t *first() const { return next(NULL); }
176   
177   // return next object in the table
178   entry_t *next(entry_t *after) const
179   {
180      // if there's another item in this hash bucket, just return it
181      if (after != NULL && after->next() != NULL)
182         return after->next();
106183
184      // otherwise scan forward for the next bucket with an entry
185      UINT32 firstindex = (after != NULL) ? (after->fullhash() % ARRAY_LENGTH(m_table) + 1) : 0;
186      for (UINT32 hashindex = firstindex; hashindex < ARRAY_LENGTH(m_table); hashindex++)
187         if (m_table[hashindex] != NULL)
188            return m_table[hashindex];
189     
190      // all out
191      return NULL;
192   }
107193
108/* ----- object management ----- */
109
110/* add a new entry to a tagmap */
111tagmap_error tagmap_add(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate);
112
113/* add a new entry to a tagmap, ensuring it has a unique hash value */
114tagmap_error tagmap_add_unique_hash(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate);
115
116/* remove an entry from a tagmap */
117void tagmap_remove(tagmap *map, const char *tag);
118
119/* remove an entry from a tagmap by object pointer */
120void tagmap_remove_object(tagmap *map, void *object);
121
122
123
124/***************************************************************************
125    C++ WRAPPERS
126***************************************************************************/
127
128#ifdef __cplusplus
129
130/* derived class for C++ */
131template<class _ElementType> class tagmap_t : public tagmap
132{
133194private:
134   tagmap_t(const tagmap &);
135   tagmap_t &operator=(const tagmap &);
195   // internal helpers
196   tagmap_error add_common(const char *tag, _ElementType object, bool replace_if_duplicate, bool unique_hash);
197   
198   // remove an entry given a pointer to its pointer
199   void remove_common(entry_t **entryptr)
200   {
201      entry_t *entry = *entryptr;
202      *entryptr = entry->next();
203      delete entry;
204   }
136205
137public:
138   tagmap_t() { memset(table, 0, sizeof(table)); }
139   ~tagmap_t() { reset(); }
140
141   void reset() { tagmap_reset(this); }
142
143   tagmap_error add(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return tagmap_add(this, tag, (void *)object, replace_if_duplicate); }
144   tagmap_error add_unique_hash(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return tagmap_add_unique_hash(this, tag, (void *)object, replace_if_duplicate); }
145   void remove(const char *tag) { tagmap_remove(this, tag); }
146   void remove(_ElementType object) { tagmap_remove_object(this, object); }
147
148   _ElementType find(const char *tag) const { return reinterpret_cast<_ElementType>(tagmap_find(this, tag)); }
149   _ElementType find(const char *tag, UINT32 hash) const { return reinterpret_cast<_ElementType>(tagmap_find_prehashed(this, tag, hash)); }
150   _ElementType find_hash_only(const char *tag) const { return reinterpret_cast<_ElementType>(tagmap_find_hash_only(this, tag)); }
206   // internal state
207   entry_t *      m_table[_HashSize];
151208};
152209
153#endif
154210
155211
212//**************************************************************************
213//  IMPLEMENTATION
214//**************************************************************************
156215
157/***************************************************************************
158    INLINE FUNCTIONS
159***************************************************************************/
216//-------------------------------------------------
217//  add_common - core implementation of a tagmap
218//  addition
219//-------------------------------------------------
160220
161/*-------------------------------------------------
162    tagmap_hash - compute the hash of a tag
163-------------------------------------------------*/
164
165INLINE UINT32 tagmap_hash(const char *string)
221template<class _ElementType, int _HashSize>
222tagmap_error tagmap_t<_ElementType, _HashSize>::add_common(const char *tag, _ElementType object, bool replace_if_duplicate, bool unique_hash)
166223{
167   UINT32 hash = *string++;
168   char c;
224   UINT32 fullhash = hash(tag);
225   UINT32 hashindex = fullhash % ARRAY_LENGTH(m_table);
169226
170   while ((c = *string++) != 0)
171      hash = ((hash << 5) | (hash >> 27)) + c;
227   // first make sure we don't have a duplicate
228   for (entry_t *entry = m_table[hashindex]; entry != NULL; entry = entry->next())
229      if (entry->fullhash() == fullhash)
230         if (unique_hash || entry->tag() == tag)
231         {
232            if (replace_if_duplicate)
233               entry->set_object(object);
234            return TMERR_DUPLICATE;
235         }
172236
173   return hash;
237   // now allocate a new entry and add to the head of the list
238   entry_t *entry = new entry_t(tag, fullhash, object);
239   entry->m_next = m_table[hashindex];
240   m_table[hashindex] = entry;
241   return TMERR_NONE;
174242}
175243
176244
177/*-------------------------------------------------
178    tagmap_find_prehashed - find an object
179    associated with a tag, given the tag's
180    hash
181-------------------------------------------------*/
182
183INLINE void *tagmap_find_prehashed(const tagmap *map, const char *tag, UINT32 fullhash)
184{
185   tagmap_entry *entry;
186
187   for (entry = map->table[fullhash % ARRAY_LENGTH(map->table)]; entry != NULL; entry = entry->next)
188      if (entry->fullhash == fullhash && strcmp(entry->tag, tag) == 0)
189         return entry->object;
190   return NULL;
191}
192
193
194/*-------------------------------------------------
195    tagmap_find - find an object associated
196    with a tag
197-------------------------------------------------*/
198
199INLINE void *tagmap_find(const tagmap *map, const char *tag)
200{
201   return tagmap_find_prehashed(map, tag, tagmap_hash(tag));
202}
203
204
205/*-------------------------------------------------
206    tagmap_find_hash_only - find an object
207    associated with a tag using only the hash;
208    this generally works well but may occasionally
209    return a false positive
210-------------------------------------------------*/
211
212INLINE void *tagmap_find_hash_only(const tagmap *map, const char *tag)
213{
214   UINT32 fullhash = tagmap_hash(tag);
215   tagmap_entry *entry;
216
217   for (entry = map->table[fullhash % ARRAY_LENGTH(map->table)]; entry != NULL; entry = entry->next)
218      if (entry->fullhash == fullhash)
219         return entry->object;
220   return NULL;
221}
222
223
224245#endif /* __TAGMAP_H__ */

Previous 15994 Revisions Next


© 1998-2018 The MESS Team