6 //registercvar("menu_reloadlist","0");
9 // do one frame to make it possible to debug the parser
14 Menu_InitGarbageStats();
20 Parser_ParseMenu( MENU_MAINFILE, MENU_PLUGINDIR );
25 // the good thing is, finddef doesnt fuck up any chain lists
26 entity(entity pStart, .string pFind1, string pMatch, .float pFind2, float pMatch2) finddef =
29 pStart = findstring( pStart, pFind1, pMatch );
30 if( pStart == null_entity )
32 if( pStart.pFind2 == pMatch2 )
39 void( entity pParent ) Menu_LinkChildren =
43 local entity lPrevious;
45 // build a list of all children
46 lChild = findchainstring( parent, pParent.name );
47 if( lChild == null_entity )
51 lPrevious = null_entity;
56 lChild.chain = lPrevious;
62 lOrder = 1; // we start with orderPos 1 (0 is auto-set)
63 lPrevious = null_entity;
65 local entity lOverwrite;
66 // try to find an item that has the current orderPos set
67 lOverwrite = finddef( null_entity, parent, pParent.name, orderPos, lOrder );
68 if( lOverwrite == lChild )
69 lChild.orderPos = lOrder;
70 else if( lOverwrite ) {
71 // insert lOverwrite in front of lChild
72 local entity lOPrevious;
74 lOPrevious = findentity( null_entity, chain, lOverwrite );
75 lOPrevious.chain = lOverwrite.chain;
76 lOverwrite.chain = lChild;
79 lChild.orderPos = 0 - lOrder; //INFO: HACK: tell Spike
83 lPrevious._next = lChild;
85 pParent._child = lChild;
86 lChild._prev = lPrevious;
87 lChild._parent = pParent;
90 lChild = lChild.chain;
93 lPrevious._next = null_entity;
96 void() Menu_LinkWindows =
98 // first verify that MENU_NORMAL_NAME and MENU_INGAME_NAME exist
99 // if not add the default strings
100 local entity lEntity;
102 dprint( "Loading defaults if necessary\n" );
104 lEntity = findstring( null_entity, name, MENU_NORMAL_NAME );
105 if( lEntity == null_entity )
106 loadfromdata( MENU_NORMAL_DEFAULT );
108 // verify again if MENU_NORMAL_NAME is there now
109 lEntity = findstring( null_entity, name, MENU_NORMAL_NAME );
110 if( lEntity == null_entity )
111 error( "Bad MENU_NORMAL_DEFAULT!\n" );
113 lEntity = findstring( null_entity, name, MENU_INGAME_NAME );
114 if( lEntity == null_entity )
115 loadfromdata( MENU_INGAME_DEFAULT );
117 // verify again if MENU_INGAME_NAME is there now
118 lEntity = findstring( null_entity, name, MENU_INGAME_NAME );
119 if( lEntity == null_entity )
120 error( "Bad MENU_INGAME_DEFAULT!\n" );
122 dprint( "Verifying that every name is used only once\n" );
124 // verify that every name is only used *once*
125 lEntity = null_entity;
126 while( ( lEntity = nextent( lEntity ) ) != null_entity ) {
128 while( ( self = findstring( self, name, lEntity.name ) ) != null_entity )
129 if( self != null_entity )
130 objerror( "Name ", lEntity.name, " already used!\n" );
133 dprint( "Verification of: name, type and parent fields\n" );
136 // set the parent field with parent_name
137 // check the type field
139 while( ( self = nextent( self ) ) != null_entity ) {
140 if( self.name == "" ) {
141 objerror( "Name is missing!\n" );
145 if( self.type == "" ) {
146 objerror( "Type is missing!\n" );
150 if( !isfunction( strcat( self.type, "_Spawn" ) ) ) {
151 objerror( "Control ", self.type, " not found!\n" );
156 // if parent_name is "" do nothing else check whether the parent exists
157 if( self.parent != "" ) {
158 lEntity = findstring( null_entity, name, self.parent );
160 if( lEntity == null_entity ) {
161 objerror( "Item ", self.parent, " not found!\n" );
166 self._parent = null_entity;
169 dprint( "Building the child lists\n" );
170 // call LinkChildren for all entities
171 lEntity = null_entity;
172 while( ( lEntity = nextent( lEntity ) ) != null_entity )
173 Menu_LinkChildren( lEntity );
175 dprint( "Calling the type functions\n" );
177 // call the type functions (former classname functions)
178 lEntity = null_entity;
179 while( ( lEntity = nextent( lEntity ) ) != null_entity ) {
181 //dprint("Calling ",self.type," (", etos(self),")\n");
182 if( !Menu_HasFlag( self, FLAG_TEMPLATE ) && !Menu_HasRunFlag( self, RUNFLAG_SPAWNED ) ) {
183 //print( lEntity.name, "\n" );
184 callfunction( strcat( self.type, "_Spawn" ) );
185 self._runFlag = self._runFlag | RUNFLAG_SPAWNED;
187 //print( "X ", lEntity.name, "\n" );
190 dprint( "Linking windows finished.\n" );
193 void( entity pItem ) Menu_LinkItem =
195 local entity lEntity;
196 local entity lOldSelf;
198 if( Menu_HasRunFlag( pItem, RUNFLAG_SPAWNED ) )
202 if( pItem.type == "" )
203 error( "LinkItem: Type is missing (", etos( pItem ), ")!\n" );
205 if( !isfunction( strcat( pItem.type, "_Spawn" ) ) )
206 error( "LinkItem: Control ", pItem.type, " not found (", etos( pItem ), ")!\n" );
208 // verify name and parent
209 lEntity = null_entity;
210 while( (lEntity = findstring( lEntity, name, pItem.name )) != null_entity )
211 if( lEntity != pItem )
212 error( "LinkItem: Name '", pItem.name, "' already in use (", etos( pItem ), ", ", etos( lEntity ), ")!" );
214 if( pItem.parent != "" ) {
215 pItem._parent = findstring( null_entity, name, pItem.parent );
218 error( "LinkItem: Couldnt find parent '", pItem.parent, "' (", etos( pItem ), ")!" );
220 pItem._parent = null_entity;
223 Menu_LinkChildren( pItem );
226 for( lEntity = pItem._child ; lEntity ; lEntity = lEntity._next )
227 Menu_LinkItem( lEntity );
229 // call the spawn function
232 if( !Menu_HasFlag( self, FLAG_TEMPLATE ) ) {
233 callfunction( strcat( self.type, "_Spawn" ) );
234 self._runFlag = self._runFlag | RUNFLAG_SPAWNED;
241 Raise_Select( Menu_ActiveItem, false, false );
242 Menu_CollectGarbage( true );
243 Menu_ResetGarbageStats();
246 void() Menu_PerformReinit =
249 Menu_History_Clear();
251 // reset the key hook (if necessary at all)
252 Menu_KeyHook = Util_NullFunction;
254 // choose which menu to display
255 // AK 05: added support for scmenu_directmenu
256 if( cvar_string( "scmenu_directmenu" ) != "" ) {
257 Menu_ActiveWindow = findstring( null_entity, name, cvar_string( "scmenu_directmenu" ) );
258 cvar_set( "scmenu_directmenu", "" );
259 } else if( MENU_ALLOWINGAME && ( gamestatus & GAME_CONNECTED ) )
260 Menu_ActiveWindow = findstring( null_entity, name, MENU_INGAME_NAME );
262 Menu_ActiveWindow = findstring( null_entity, name, MENU_NORMAL_NAME );
264 // and reinit all menu items
266 while( (self = nextent( self ) ) != null_entity ) {
267 if( self.parent == "" )
268 self._parent = null_entity;
269 //else actually this shouldnt happen
270 else if( self._parent.name != self.parent )
271 objerror( "Parent (should be ", self.parent, ") of menu item ", self.name, " changed to ", self._parent.name, " !\n" );
273 Raise_Reinit( self ); // always call reinit
276 // run one runflag frame to (re)init the runflags
277 Menu_UpdateRunFlags();
279 Menu_Reselect( false );
282 void() Menu_Shutdown =
284 // call the terminate event for each object
286 while( ( self = nextent( self ) ) != null_entity )
287 Raise_Destroy( self );
291 entity( string pType, string pName, string pParent ) Menu_CreateItem =
296 error( "Bad pType '", pType, "'!" );
298 error( "Bad pName '", pName, "'!" );
301 parseentitydata( lItem, strcat( "{ type \"", pType, "\" name \"", strcat( pParent, "::", pName ), "\" parent \"", pParent, "\" }" ) );
305 entity( entity pTemplate, string pName, string pParent, bool pTree ) Menu_DeriveItem =
311 error( "Null pTemplate!" );
313 error( "Bad pName '", pName, "'!" );
316 copyentity( pTemplate, lItem );
317 if( lItem.flag & FLAG_TEMPLATE )
318 lItem.flag = lItem.flag - FLAG_TEMPLATE;
319 if( lItem._runFlag & RUNFLAG_SPAWNED )
320 lItem._runFlag = lItem._runFlag - RUNFLAG_SPAWNED;
321 parseentitydata( lItem, strcat( "{ name \"", strcat( pParent, "::", pName ), "\" parent \"", pParent, "\" }" ) );
324 for( lChild = pTemplate._child ; lChild ; lChild = lChild._next ) {
326 lName = String_Zone( substring( lChild.name, strlen( lChild.parent ) + 2, 100000 ) );
327 Menu_DeriveItem( lChild, lName, lItem.name, true );
328 String_Free( lName );
334 void( entity pItem, string pData ) Menu_AddEntityData =
336 parseentitydata( pItem, pData );
339 void( entity pWindow ) Menu_LinkWindow =
341 Menu_LinkItem( pWindow );