quakeforge/ruamoko/cl_menu/plistmenu.r
Bill Currie 75ec6bf244 Clean out some unnecessary types from the progs engine and clean up the mess.
This is a nasty commit, sorry, but 99% of the commit is interdependent.
2011-01-10 12:25:31 +09:00

179 lines
4.4 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 "string.h"
#include "qfs.h"
#include "Array.h"
#include "gui/Rect.h"
#include "plistmenu.h"
@static @param
class_from_plist (PLDictionary []pldict)
{
local @param [8]params;
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 integer message_count, i, j;
local SEL sel;
local PLItem []item;
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];
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);
va_list.count = [msg count] - 1;
for (j = 0; 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, "."))
va_list.list[j].float_val = stof (paramstr);
else
va_list.list[j].integer_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 integer i, count;
local @param ret;
array = [[Array alloc] init];
count = [plarray count];
for (i = 0; i < count; i++) {
ret = object_from_plist ([plarray getObjectAtIndex:i]);
[array addObject: 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 integer 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];
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;
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);
}
}
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;
}