6 //registercvar("menu_reloadlist","0");
9 // do one frame to make it possible to debug the parser
12 Menu_InitGarbageStats();
18 Parser_ParseMenu( MENU_MAINFILE );
23 // the good thing is, finddef doesnt fuck up any chain lists
24 entity(entity pStart, .string pFind1, string pMatch, .float pFind2, float pMatch2) finddef =
27 pStart = findstring( pStart, pFind1, pMatch );
28 if( pStart == null_entity )
30 if( pStart.pFind2 == pMatch2 )
37 void( entity pParent ) Menu_LinkChildren =
41 local entity lPrevious;
43 // build a list of all children
44 lChild = findchainstring( parent, pParent.name );
45 if( lChild == null_entity )
49 lPrevious = null_entity;
54 lChild.chain = lPrevious;
60 lOrder = 1; // we start with orderPos 1 (0 is auto-set)
61 lPrevious = null_entity;
63 local entity lOverwrite;
64 // try to find an item that has the current orderPos set
65 lOverwrite = finddef( null_entity, parent, pParent.name, orderPos, lOrder );
66 if( lOverwrite == lChild )
67 lChild.orderPos = lOrder;
68 else if( lOverwrite ) { // insert lOverwrite in front of lChild
69 local entity lOPrevious;
71 lOPrevious = findentity( null_entity, chain, lOverwrite );
72 lOPrevious.chain = lOverwrite.chain;
73 lOverwrite.chain = lChild;
76 lChild.orderPos = 0 - lOrder; //INFO: HACK: tell Spike
80 lPrevious._next = lChild;
82 pParent._child = lChild;
83 lChild._prev = lPrevious;
84 lChild._parent = pParent;
87 lChild = lChild.chain;
90 lPrevious._next = null_entity;
93 void() Menu_LinkWindows =
95 // first verify that MENU_NORMAL_NAME and MENU_INGAME_NAME exist
96 // if not add the default strings
99 dprint( "Loading defaults if necessary\n" );
101 lEntity = findstring( null_entity, name, MENU_NORMAL_NAME );
102 if( lEntity == null_entity )
103 loadfromdata( MENU_NORMAL_DEFAULT );
105 // verify again if MENU_NORMAL_NAME is there now
106 lEntity = findstring( null_entity, name, MENU_NORMAL_NAME );
107 if( lEntity == null_entity )
108 error( "Bad MENU_NORMAL_DEFAULT!\n" );
110 lEntity = findstring( null_entity, name, MENU_INGAME_NAME );
111 if( lEntity == null_entity )
112 loadfromdata( MENU_INGAME_DEFAULT );
114 // verify again if MENU_INGAME_NAME is there now
115 lEntity = findstring( null_entity, name, MENU_INGAME_NAME );
116 if( lEntity == null_entity )
117 error( "Bad MENU_INGAME_DEFAULT!\n" );
119 dprint( "Verifying that every name is used only once\n" );
121 // verify that every name is only used *once*
122 lEntity = null_entity;
123 while( ( lEntity = nextent( lEntity ) ) != null_entity ) {
125 while( ( self = findstring( self, name, lEntity.name ) ) != null_entity )
126 if( self != null_entity )
127 objerror( "Name ", lEntity.name, " already used!\n" );
130 dprint( "Verification of: name, type and parent fields\n" );
133 // set the parent field with parent_name
134 // check the type field
136 while( ( self = nextent( self ) ) != null_entity ) {
137 if( self.name == "" ) {
138 objerror( "Name is missing!\n" );
142 if( self.type == "" ) {
143 objerror( "Type is missing!\n" );
147 if( !isfunction( strcat( self.type, "_Spawn" ) ) ) {
148 objerror( "Control ", self.type, " not found!\n" );
153 // if parent_name is "" do nothing else check whether the parent exists
154 if( self.parent != "" ) {
155 lEntity = findstring( null_entity, name, self.parent );
157 if( lEntity == null_entity ) {
158 objerror( "Item ", self.parent, " not found!\n" );
163 self._parent = null_entity;
166 dprint( "Building the child lists\n" );
167 // call LinkChildren for all entities
168 lEntity = null_entity;
169 while( ( lEntity = nextent( lEntity ) ) != null_entity )
170 Menu_LinkChildren( lEntity );
172 dprint( "Calling the type functions\n" );
174 // call the type functions (former classname functions)
175 lEntity = null_entity;
176 while( ( lEntity = nextent( lEntity ) ) != null_entity ) {
178 //dprint("Calling ",self.type," (", etos(self),")\n");
179 if( !Menu_HasFlag( self, FLAG_TEMPLATE ) && !Menu_HasRunFlag( self, RUNFLAG_SPAWNED ) ) {
180 //print( lEntity.name, "\n" );
181 callfunction( strcat( self.type, "_Spawn" ) );
182 self._runFlag = self._runFlag | RUNFLAG_SPAWNED;
184 //print( "X ", lEntity.name, "\n" );
187 dprint( "Linking windows finished.\n" );
190 void( entity pItem ) Menu_LinkItem =
192 local entity lEntity;
193 local entity lOldSelf;
195 if( Menu_HasRunFlag( pItem, RUNFLAG_SPAWNED ) )
199 if( pItem.type == "" )
200 error( "LinkItem: Type is missing (", etos( pItem ), ")!\n" );
202 if( !isfunction( strcat( pItem.type, "_Spawn" ) ) )
203 error( "LinkItem: Control ", pItem.type, " not found (", etos( pItem ), ")!\n" );
205 // verify name and parent
206 lEntity = null_entity;
207 while( (lEntity = findstring( lEntity, name, pItem.name )) != null_entity )
208 if( lEntity != pItem )
209 error( "LinkItem: Name '", pItem.name, "' already in use (", etos( pItem ), ", ", etos( lEntity ), ")!" );
211 if( pItem.parent != "" ) {
212 pItem._parent = findstring( null_entity, name, pItem.parent );
215 error( "LinkItem: Couldnt find parent '", pItem.parent, "' (", etos( pItem ), ")!" );
217 pItem._parent = null_entity;
220 Menu_LinkChildren( pItem );
223 for( lEntity = pItem._child ; lEntity ; lEntity = lEntity._next )
224 Menu_LinkItem( lEntity );
226 // call the spawn function
229 if( !Menu_HasFlag( self, FLAG_TEMPLATE ) ) {
230 callfunction( strcat( self.type, "_Spawn" ) );
231 self._runFlag = self._runFlag | RUNFLAG_SPAWNED;
238 Raise_Select( Menu_ActiveItem, false, false );
239 Menu_CollectGarbage( true );
240 Menu_ResetGarbageStats();
243 void() Menu_PerformReinit =
246 Menu_History_Clear();
248 // reset the key hook (if necessary at all)
249 Menu_KeyHook = Util_NullFunction;
251 // and reinit all menu items
253 while( (self = nextent( self ) ) != null_entity ) {
254 if( self.parent == "" )
255 self._parent = null_entity;
256 //else actually this shouldnt happen
257 else if( self._parent.name != self.parent )
258 objerror( "Parent (should be ", self.parent, ") of menu item ", self.name, " changed to ", self._parent.name, " !\n" );
260 Raise_Reinit( self ); // always call reinit
263 // choose which menu to display
264 if( MENU_ALLOWINGAME && ( gamestatus & GAME_CONNECTED ) )
265 Menu_ActiveWindow = findstring( null_entity, name, MENU_INGAME_NAME );
267 Menu_ActiveWindow = findstring( null_entity, name, MENU_NORMAL_NAME );
269 // run one runflag frame to (re)init the runflags
270 Menu_UpdateRunFlags();
272 Menu_Reselect( false );
275 void() Menu_Shutdown =
277 // call the terminate event for each object
279 while( ( self = nextent( self ) ) != null_entity )
280 Raise_Destroy( self );
283 entity( string pType, string pName, string pParent ) Menu_CreateItem =
288 error( "Bad pType '", pType, "'!" );
290 error( "Bad pName '", pName, "'!" );
293 parseentitydata( lItem, strcat( "{ type \"", pType, "\" name \"", strcat( pParent, "::", pName ), "\" parent \"", pParent, "\" }" ) );
297 entity( entity pTemplate, string pName, string pParent, bool pTree ) Menu_DeriveItem =
303 error( "Null pTemplate!" );
305 error( "Bad pName '", pName, "'!" );
308 copyentity( pTemplate, lItem );
309 if( lItem.flag & FLAG_TEMPLATE )
310 lItem.flag = lItem.flag - FLAG_TEMPLATE;
311 if( lItem._runFlag & RUNFLAG_SPAWNED )
312 lItem._runFlag = lItem._runFlag - RUNFLAG_SPAWNED;
313 parseentitydata( lItem, strcat( "{ name \"", strcat( pParent, "::", pName ), "\" parent \"", pParent, "\" }" ) );
316 for( lChild = pTemplate._child ; lChild ; lChild = lChild._next ) {
318 lName = String_Zone( substring( lChild.name, strlen( lChild.parent ) + 2, 100000 ) );
319 Menu_DeriveItem( lChild, lName, lItem.name, true );
320 String_Free( lName );
326 void( entity pItem, string pData ) Menu_AddEntityData =
328 parseentitydata( pItem, pData );
331 void( entity pWindow ) Menu_LinkWindow =
333 Menu_LinkItem( pWindow );