mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-14 08:50:58 +00:00
cfe7c44df0
And other related fields so integer is now int (and uinteger is uint). I really don't know why I went with integer in the first place, but this will make using macros easier for dealing with types.
190 lines
4.5 KiB
R
190 lines
4.5 KiB
R
/*
|
|
plistmenu.r
|
|
|
|
PropertyList menu parser.
|
|
|
|
Copyright (C) 2010 Bill Currie <bill@taniwha.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public
|
|
License along with this program; if not, write to:
|
|
|
|
Free Software Foundation, Inc.
|
|
59 Temple Place - Suite 330
|
|
Boston, MA 02111-1307, USA
|
|
*/
|
|
|
|
#include "debug.h"
|
|
#include "legacy_string.h"
|
|
#include "string.h"
|
|
#include "qfs.h"
|
|
|
|
#include "Array.h"
|
|
#include "gui/Rect.h"
|
|
#include "plistmenu.h"
|
|
|
|
@reference Pic;
|
|
@reference CenterPic;
|
|
|
|
@static @param
|
|
class_from_plist (PLDictionary *pldict)
|
|
{
|
|
local @param params[8];
|
|
local @param ret;
|
|
local @va_list va_list = { 0, params };
|
|
local string classname, selname, paramstr;
|
|
local id class;
|
|
local id obj;
|
|
local PLArray *messages, *msg;
|
|
local int message_count, i, j;
|
|
local SEL sel;
|
|
local PLItem *item;
|
|
|
|
ret = nil;
|
|
classname = [(PLString*) [pldict getObjectForKey:"Class"] string];
|
|
class = obj_lookup_class (classname);
|
|
if (!class) {
|
|
dprint ("could not find " + classname + "\n");
|
|
ret.pointer_val = nil;
|
|
return ret;
|
|
}
|
|
obj = [class alloc];
|
|
params[0].pointer_val = obj;
|
|
|
|
messages = (PLArray*) [pldict getObjectForKey:"Messages"];
|
|
message_count = [messages count];
|
|
for (i = 0; i < message_count; i++) {
|
|
msg = (PLArray*) [messages getObjectAtIndex:i];
|
|
selname = [(PLString*) [msg getObjectAtIndex:0] string];
|
|
sel = sel_get_uid (selname);
|
|
params[1].pointer_val = sel;
|
|
va_list.count = [msg count] + 1;
|
|
for (j = 2; j < va_list.count; j++) {
|
|
paramstr = [(PLString*) [msg getObjectAtIndex:j - 1] string];
|
|
switch (str_mid (paramstr, 0, 1)) {
|
|
case "\"":
|
|
va_list.list[j].string_val = str_mid (paramstr, 1, -1);
|
|
break;
|
|
case "$":
|
|
item = [pldict getObjectForKey:str_mid (paramstr, 1)];
|
|
va_list.list[j] = object_from_plist (item);
|
|
break;
|
|
case "0": case "1": case "2": case "3": case "4":
|
|
case "5": case "6": case "7": case "8": case "9":
|
|
if (str_str (paramstr, ".") >= 0)
|
|
va_list.list[j].float_val = stof (paramstr);
|
|
else
|
|
va_list.list[j].int_val = stoi (paramstr);
|
|
break;
|
|
}
|
|
}
|
|
obj_msg_sendv (obj, sel, va_list);
|
|
}
|
|
ret.pointer_val = obj;
|
|
return ret;
|
|
}
|
|
|
|
@static @param
|
|
array_from_plist (PLArray *plarray)
|
|
{
|
|
local Array *array;
|
|
local int i, count;
|
|
local @param ret;
|
|
|
|
ret = nil;
|
|
array = [[Array alloc] init];
|
|
count = [plarray count];
|
|
for (i = 0; i < count; i++) {
|
|
ret = object_from_plist ([plarray getObjectAtIndex:i]);
|
|
[array addObject: (id) ret.pointer_val];
|
|
}
|
|
ret.pointer_val = array;
|
|
return ret;
|
|
}
|
|
|
|
union ParamRect {
|
|
@param p;
|
|
Rect r;
|
|
};
|
|
|
|
@static @param
|
|
rect_from_plist (PLString *plstring)
|
|
{
|
|
local string str = [plstring string];
|
|
local string tmp;
|
|
local int xp, yp, xl, yl;
|
|
local PLItem *item;
|
|
local union ParamRect pr;
|
|
|
|
pr.r = makeRect (0, 0, 0, 0);
|
|
if (str_mid (str, 0, 1) == "[") {
|
|
tmp = "(" + str_mid (str, 1, -1) + ")";
|
|
item = [PLItem fromString:tmp];
|
|
xp = stoi ([(PLString*) [(PLArray*) item getObjectAtIndex:0] string]);
|
|
yp = stoi ([(PLString*) [(PLArray*) item getObjectAtIndex:1] string]);
|
|
xl = stoi ([(PLString*) [(PLArray*) item getObjectAtIndex:2] string]);
|
|
yl = stoi ([(PLString*) [(PLArray*) item getObjectAtIndex:3] string]);
|
|
pr.r = makeRect (xp, yp, xl, yl);
|
|
}
|
|
return pr.p;
|
|
}
|
|
|
|
@static @param
|
|
string_from_plist (PLString *plstring)
|
|
{
|
|
local @param ret;
|
|
local string str = [plstring string];
|
|
|
|
ret = nil;
|
|
if (str_mid (str, 0, 1) == "[")
|
|
return rect_from_plist (plstring);
|
|
|
|
ret.string_val = nil;
|
|
return ret;
|
|
}
|
|
|
|
@param
|
|
object_from_plist (PLItem *plist)
|
|
{
|
|
local @param ret;
|
|
|
|
ret = nil;
|
|
switch ([plist type]) {
|
|
case QFDictionary:
|
|
return class_from_plist ((PLDictionary *) plist);
|
|
case QFArray:
|
|
return array_from_plist ((PLArray *) plist);
|
|
case QFBinary:
|
|
ret.pointer_val = nil;
|
|
return ret;
|
|
case QFString:
|
|
return string_from_plist ((PLString *) plist);
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
PLItem *
|
|
read_plist (string fname)
|
|
{
|
|
local QFile file;
|
|
local PLItem *plist;
|
|
|
|
file = QFS_OpenFile (fname);
|
|
if (!file) {
|
|
dprint ("could not load menu.plist\n");
|
|
return nil;
|
|
}
|
|
plist = [PLItem fromFile:file];
|
|
Qclose (file);
|
|
return plist;
|
|
}
|