source: abuse/trunk/src/clisp.cpp @ 491

Last change on this file since 491 was 491, checked in by Sam Hocevar, 12 years ago

lisp: miscellaneous work on type safety.

File size: 81.4 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
12#include <string.h>
13
14#include "sdlport/joy.h"
15
16#include "ant.h"
17#include "lisp.h"
18#include "game.h"
19#include "jrand.h"
20#include "dev.h"
21#include "pcxread.h"
22#include "menu.h"
23#include "dprint.h"
24#include "clisp.h"
25#include "chars.h"
26#include "lisp_gc.h"
27#include "cop.h"
28#include "loadgame.h"
29#include "nfserver.h"
30#include "demo.h"
31#include "chat.h"
32#include "jdir.h"
33#include "netcfg.h"
34
35#define ENGINE_MAJOR 1
36#define ENGINE_MINOR 20
37
38extern int has_joystick;
39
40// the following are references to lisp symbols
41LispSymbol *l_chat_input, *l_post_render;
42
43LispSymbol *l_difficulty, *l_easy, *l_hard, *l_medium, *l_extreme,
44    *l_max_hp, *l_max_power,
45    *l_empty_cache;
46
47// FIXME: port these to LispSymbol
48void *l_main_menu, *l_logo,*l_state_art,*l_abilities,*l_state_sfx,
49     *l_song_list,*l_filename,*l_sfx_directory,*l_default_font,
50     *l_morph,*l_default_abilities,*l_default_ai_function,
51     *l_tile_files,*l_range,*l_hurt_all,*l_death_handler,
52     *l_title_screen,*l_console_font,*l_fields,*l_dist,*l_pushx,*l_pushy,
53     *l_object,*l_tile,*l_fire_object,*l_FIRE,*l_cop_dead_parts,*l_restart_player,
54     *l_help_screens,*l_player_draw,*l_sneaky_draw,*l_health_image,*l_fly_image,
55     *l_sneaky_image,*l_draw_fast,*l_player_tints,*l_save_order,*l_next_song,
56     *l_level_load_start,
57     *l_level_load_end,        *l_cdc_logo,
58     *l_keep_backup,
59     *l_switch_to_powerful,
60     *l_mouse_can_switch,
61     *l_ask_save_slot,
62     *l_get_local_input,
63     *l_player_text_color,
64     *l_level_loaded;        // called when a new level is loaded
65
66
67char game_name[50];
68void *sensor_ai();
69
70// variables for the status bar
71void        *l_statbar_ammo_x,*l_statbar_ammo_y,
72            *l_statbar_ammo_w,*l_statbar_ammo_h,
73        *l_statbar_ammo_bg_color,
74
75            *l_statbar_health_x,*l_statbar_health_y,
76            *l_statbar_health_w,*l_statbar_health_h,
77        *l_statbar_health_bg_color,
78
79        *l_statbar_logo_x,*l_statbar_logo_y;
80uint8_t chatting_enabled=0;
81
82extern void scatter_line(int x1, int y1, int x2, int y2, int c, int s);
83extern void ascatter_line(int x1, int y1, int x2, int y2, int c1, int c2, int s);
84extern void show_end();
85
86static view *lget_view(void *arg, char const *msg)
87{
88  game_object *o=(game_object *)lpointer_value(arg);
89  view *c=o->controller();
90  if (!c)
91  {
92    dprintf("%s : object does not have a view\n",msg);
93    lbreak("");
94    exit(0);
95  }
96  return c;
97}
98
99extern int get_option(char const *name);
100extern void set_login(char const *name);
101
102void clisp_init()                            // call by lisp_init, defines symbols and functions
103                                             // to irnterface with c
104{
105  l_easy = LispSymbol::FindOrCreate("easy");
106  l_medium = LispSymbol::FindOrCreate("medium");
107  l_hard = LispSymbol::FindOrCreate("hard");
108  l_extreme = LispSymbol::FindOrCreate("extreme");
109
110  l_logo = LispSymbol::FindOrCreate("logo");
111  l_morph = LispSymbol::FindOrCreate("morph");
112
113  l_pushx = LispSymbol::FindOrCreate("pushx");
114  l_pushy = LispSymbol::FindOrCreate("pushy");
115
116  l_dist = LispSymbol::FindOrCreate("dist");
117  l_state_art = LispSymbol::FindOrCreate("state_art");
118  l_abilities = LispSymbol::FindOrCreate("abilities");
119  l_default_abilities = LispSymbol::FindOrCreate("default_abilities");
120  l_state_sfx = LispSymbol::FindOrCreate("state_sfx");
121  l_filename = LispSymbol::FindOrCreate("filename");
122  l_sfx_directory = LispSymbol::FindOrCreate("sfx_directory");
123  l_default_font = LispSymbol::FindOrCreate("default_font");
124  l_console_font = LispSymbol::FindOrCreate("console_font");
125  l_default_ai_function = LispSymbol::FindOrCreate("default_ai");
126  l_tile_files = LispSymbol::FindOrCreate("tile_files");
127  l_empty_cache = LispSymbol::FindOrCreate("empty_cache");
128  l_range = LispSymbol::FindOrCreate("range");
129  l_difficulty = LispSymbol::FindOrCreate("difficulty");
130  l_death_handler = LispSymbol::FindOrCreate("death_handler");
131  l_title_screen = LispSymbol::FindOrCreate("title_screen");
132  l_fields = LispSymbol::FindOrCreate("fields");
133  l_FIRE = LispSymbol::FindOrCreate("FIRE");
134  l_fire_object = LispSymbol::FindOrCreate("fire_object");
135  l_cop_dead_parts = LispSymbol::FindOrCreate("cop_dead_parts");
136  l_difficulty->SetValue(l_hard);
137  l_restart_player = LispSymbol::FindOrCreate("restart_player");
138  l_help_screens = LispSymbol::FindOrCreate("help_screens");
139  l_save_order = LispSymbol::FindOrCreate("save_order");
140  l_next_song = LispSymbol::FindOrCreate("next_song");
141  l_player_draw = LispSymbol::FindOrCreate("player_draw");
142  l_sneaky_draw = LispSymbol::FindOrCreate("sneaky_draw");
143  l_keep_backup = LispSymbol::FindOrCreate("keep_backup");
144  l_level_loaded = LispSymbol::FindOrCreate("level_loaded");
145
146  l_draw_fast = LispSymbol::FindOrCreate("draw_fast");
147  l_player_tints = LispSymbol::FindOrCreate("player_tints");
148
149  l_max_hp = LispSymbol::FindOrCreate("max_hp");
150  l_max_hp->SetNumber(200);
151  l_max_power = LispSymbol::FindOrCreate("max_power");
152  l_main_menu = LispSymbol::FindOrCreate("main_menu");
153  l_max_power->SetNumber(999);
154
155  LispSymbol::FindOrCreate("run_state")->SetNumber(RUN_STATE);
156  LispSymbol::FindOrCreate("pause_state")->SetNumber(PAUSE_STATE);
157  LispSymbol::FindOrCreate("menu_state")->SetNumber(MENU_STATE);
158  LispSymbol::FindOrCreate("scene_state")->SetNumber(SCENE_STATE);
159
160  l_statbar_ammo_x = LispSymbol::FindOrCreate("statbar_ammo_x");
161  l_statbar_ammo_y = LispSymbol::FindOrCreate("statbar_ammo_y");
162  l_statbar_ammo_w = LispSymbol::FindOrCreate("statbar_ammo_w");
163  l_statbar_ammo_h = LispSymbol::FindOrCreate("statbar_ammo_h");
164  l_statbar_ammo_bg_color = LispSymbol::FindOrCreate("statbar_ammo_bg_color");
165
166  l_statbar_health_x = LispSymbol::FindOrCreate("statbar_health_x");
167  l_statbar_health_y = LispSymbol::FindOrCreate("statbar_health_y");
168  l_statbar_health_w = LispSymbol::FindOrCreate("statbar_health_w");
169  l_statbar_health_h = LispSymbol::FindOrCreate("statbar_health_h");
170  l_statbar_health_bg_color = LispSymbol::FindOrCreate("statbar_health_bg_color");
171
172  l_statbar_logo_x = LispSymbol::FindOrCreate("statbar_logo_x");
173  l_statbar_logo_y = LispSymbol::FindOrCreate("statbar_logo_y");
174  l_object = LispSymbol::FindOrCreate("object");
175  l_tile = LispSymbol::FindOrCreate("tile");
176  l_cdc_logo = LispSymbol::FindOrCreate("logo");
177
178  l_switch_to_powerful = LispSymbol::FindOrCreate("switch_to_powerful");
179  l_mouse_can_switch = LispSymbol::FindOrCreate("mouse_can_switch");
180  l_ask_save_slot = LispSymbol::FindOrCreate("ask_save_slot");
181
182  l_level_load_start = LispSymbol::FindOrCreate("level_load_start");
183  l_level_load_end = LispSymbol::FindOrCreate("level_load_end");
184  l_get_local_input = LispSymbol::FindOrCreate("get_local_input");
185  l_chat_input = LispSymbol::FindOrCreate("chat_input");
186  l_player_text_color = LispSymbol::FindOrCreate("player_text_color");
187
188  int i;
189  for (i=0;i<MAX_STATE;i++)
190    LispSymbol::FindOrCreate(state_names[i])->SetNumber(i);
191  for (i=0;i<TOTAL_ABILITIES;i++)
192    LispSymbol::FindOrCreate(ability_names[i])->SetNumber(i);
193  for (i=0;i<TOTAL_CFLAGS;i++)
194    LispSymbol::FindOrCreate(cflag_names[i])->SetNumber(i);
195
196  l_song_list = LispSymbol::FindOrCreate("song_list");
197  l_post_render = LispSymbol::FindOrCreate("post_render");
198
199  add_c_function("distx",0,0,                   1);
200  add_c_function("disty",0,0,                   2);
201  add_c_bool_fun("key_pressed",1,1,             3);
202  add_c_bool_fun("local_key_pressed",1,1,       4);
203
204  add_c_function("bg_state",0,0,                5);
205  add_c_function("aitype",0,0,                  6);
206  add_c_function("aistate",0,0,                 7);
207  add_c_function("set_aistate",1,1,             8);
208  add_c_function("random",1,1,                  9);
209  add_c_function("state_time",0,0,             10);
210  add_c_function("state",0,0,                  11);
211  add_c_function("toward",0,0,                 12);
212  add_c_function("move",3,3,                   13);
213  add_c_function("facing",0,0,                 14);
214  add_c_function("otype",0,0,                  15);
215  add_c_bool_fun("next_picture",0,0,           16);
216  add_c_bool_fun("set_fade_dir",1,1,           17);
217  add_c_function("mover",3,3,                  18);
218  add_c_bool_fun("set_fade_count",1,1,         19);
219  add_c_function("fade_count",0,0,             20);
220  add_c_function("fade_dir",0,0,               21);
221  add_c_bool_fun("touching_bg",0,0,            22);
222  add_c_function("add_power",1,1,              23);
223  add_c_function("add_hp",1,1,                 24);
224
225  add_c_bool_fun("draw",0,0,                   27);
226  add_c_bool_fun("edit_mode",0,0,              28);
227  add_c_bool_fun("draw_above",0,0,             29);
228  add_c_function("x",0,0,                      30);
229  add_c_function("y",0,0,                      31);
230  add_c_bool_fun("set_x",1,1,                  32);
231  add_c_bool_fun("set_y",1,1,                  33);
232  add_c_bool_fun("push_characters",2,2,        34);
233
234
235
236  add_c_bool_fun("set_state",1,1,              37);
237  add_c_function("bg_x",0,0,                   38);
238  add_c_function("bg_y",0,0,                   39);
239  add_c_bool_fun("set_aitype",1,1,             40);
240
241  add_c_function("xvel",0,0,                   42);
242  add_c_function("yvel",0,0,                   43);
243  add_c_bool_fun("set_xvel",1,1,               44);
244  add_c_bool_fun("set_yvel",1,1,               45);
245  add_c_function("away",0,0,                   46);
246  add_c_bool_fun("blocked_left",1,1,           47);
247  add_c_bool_fun("blocked_right",1,1,          48);
248
249  add_c_function("add_palette",1,-1,           50);    // name, w,h,x,y,scale, tiles
250  add_c_bool_fun("screen_shot",1,1,            51);    // filename
251
252  add_c_bool_fun("set_zoom",1,1,               52);
253  add_c_function("show_help",1,1,              55);    // type, x,y
254  add_c_function("direction",0,0,              56);
255  add_c_function("set_direction",1,1,          57);
256
257  add_c_bool_fun("freeze_player",1,1,          58);   // freeze time
258
259  add_c_function("menu",1,-1,                  59);
260  add_c_bool_fun("do_command",1,1,             60);   // command string
261  add_c_bool_fun("set_game_state",1,1,         61);
262
263
264// scene control functions, game must first be set to scene mode.
265  add_c_bool_fun("scene:set_text_region",4,4,  62);
266  add_c_bool_fun("scene:set_frame_speed",1,1,  63);
267  add_c_bool_fun("scene:set_scroll_speed",1,1, 64);
268  add_c_bool_fun("scene:set_pan_speed",1,1,    65);
269  add_c_bool_fun("scene:scroll_text",1,1,      66);
270  add_c_bool_fun("scene:pan",3,3,              67);
271  add_c_bool_fun("scene:wait",1,1,             68);
272
273  add_c_bool_fun("level:new",3,3,              74);    // width, height, name
274
275  add_c_bool_fun("do_damage",2,4,              75);    // amount, to_object, [pushx pushy]
276  add_c_function("hp",0,0,                     76);
277  add_c_bool_fun("set_shift_down",2,2,         77);
278  add_c_bool_fun("set_shift_right",2,2,        78);
279  add_c_bool_fun("set_gravity",1,1,            79);
280  add_c_function("tick",0,0,                   80);
281
282  add_c_bool_fun("set_xacel",1,1,              81);
283  add_c_bool_fun("set_yacel",1,1,              82);
284  add_c_bool_fun("set_local_players",1,1,      84);   // set # of players on this machine, unsupported?
285  add_c_function("local_players",0,0,          85);
286
287  add_c_bool_fun("set_light_detail",1,1,       86);
288  add_c_function("light_detail",0,0,           87);
289  add_c_bool_fun("set_morph_detail",1,1,       88);
290  add_c_function("morph_detail",0,0,           89);
291  add_c_bool_fun("morph_into",3,3,             90);       // type aneal frames
292  add_c_bool_fun("link_object",1,1,            91);
293
294  add_c_bool_fun("draw_line",5,5,              92);
295  add_c_function("dark_color",0,0,             93);
296  add_c_function("medium_color",0,0,           94);
297  add_c_function("bright_color",0,0,           95);
298
299  add_c_bool_fun("remove_object",1,1,          99);
300  add_c_bool_fun("link_light",1,1,            100);
301  add_c_bool_fun("remove_light",1,1,          101);
302  add_c_function("total_objects",0,0,         102);
303  add_c_function("total_lights",0,0,          103);
304
305  add_c_bool_fun("set_light_r1",2,2,          104);
306  add_c_bool_fun("set_light_r2",2,2,          105);
307  add_c_bool_fun("set_light_x",2,2,           106);
308  add_c_bool_fun("set_light_y",2,2,           107);
309  add_c_bool_fun("set_light_xshift",2,2,      108);
310  add_c_bool_fun("set_light_yshift",2,2,      109);
311
312  add_c_function("light_r1",1,1,              110);
313  add_c_function("light_r2",1,1,              111);
314  add_c_function("light_x",1,1,               112);
315  add_c_function("light_y",1,1,               113);
316  add_c_function("light_xshift",1,1,          114);
317  add_c_function("light_yshift",1,1,          115);
318
319  add_c_function("xacel",0,0,                 116);
320  add_c_function("yacel",0,0,                 117);
321  add_c_bool_fun("delete_light",1,1,          118);
322
323  add_c_bool_fun("set_fx",1,1,                119);
324  add_c_bool_fun("set_fy",1,1,                120);
325  add_c_bool_fun("set_fxvel",1,1,             121);
326  add_c_bool_fun("set_fyvel",1,1,             122);
327  add_c_bool_fun("set_fxacel",1,1,            123);
328  add_c_bool_fun("set_fyacel",1,1,            124);
329  add_c_function("picture_width",0,0,         125);
330  add_c_function("picture_height",0,0,        126);
331  add_c_bool_fun("trap",0,0,                  127);
332  add_c_bool_fun("platform_push",2,2,         128);
333
334  add_c_function("def_sound",1,2,             133);  // symbol, filename [ or just filenmae]
335  add_c_bool_fun("play_sound",1,4,            134);
336
337  add_c_function("def_particle",2,2,          137);  // symbol, filename
338  add_c_function("add_panim",4,4,             138);  // id, x, y, dir
339
340  add_c_function("weapon_to_type",1,1,        142);  // returns total for type weapon
341  add_c_bool_fun("hurt_radius",6,6,           143);  // x y radius max_damage exclude_object max_push
342
343  add_c_bool_fun("add_ammo",2,2,              144);  // weapon_type, amount
344  add_c_function("ammo_total",1,1,            145);  // returns total for type weapon
345  add_c_function("current_weapon",0,0,        146);  // weapon_type, amount
346  add_c_function("current_weapon_type",0,0,   147);  // returns total for type weapon
347
348  add_c_bool_fun("blocked_up",1,1,            148);
349  add_c_bool_fun("blocked_down",1,1,          149);
350  add_c_bool_fun("give_weapon",1,1,           150);  // type
351  add_c_function("get_ability",1,1,           151);
352  add_c_bool_fun("reset_player",0,0,          152);
353  add_c_function("site_angle",1,1,            153);
354  add_c_bool_fun("set_course",2,2,            154);  // angle, magnitude
355  add_c_bool_fun("set_frame_angle",3,3,       155);  // ang1,ang2, ang
356  add_c_bool_fun("jump_state",1,1,            156);  // don't reset current_frame
357
358  add_c_bool_fun("morphing",0,0,              168);
359  add_c_bool_fun("damage_fun",6,6,            169);
360  add_c_bool_fun("gravity",0,0,               170);
361  add_c_bool_fun("make_view_solid",1,1,       171);
362  add_c_function("find_rgb",3,3,              172);
363
364  add_c_function("player_x_suggest",0,0,      173);  // return player "joystick" x
365  add_c_function("player_y_suggest",0,0,      174);
366  add_c_function("player_b1_suggest",0,0,     175);
367  add_c_function("player_b2_suggest",0,0,     176);
368  add_c_function("player_b3_suggest",0,0,     177);
369
370  add_c_bool_fun("set_bg_scroll",4,4,         178);  // xmul xdiv ymul ydiv
371  add_c_bool_fun("set_ambient_light",2,2,     179);  // player, 0..63 (out of bounds ignored)
372  add_c_function("ambient_light",1,1,         180);  // player
373  add_c_bool_fun("has_object",1,1,            181);  // true if linked with object x
374  add_c_bool_fun("set_otype",1,1,             182);  // otype
375
376  add_c_function("current_frame",0,0,         184);
377  add_c_function("fx",0,0,                    185);
378  add_c_function("fy",0,0,                    186);
379  add_c_function("fxvel",0,0,                 187);
380  add_c_function("fyvel",0,0,                 188);
381  add_c_function("fxacel",0,0,                189);
382  add_c_function("fyacel",0,0,                190);
383  add_c_bool_fun("set_stat_bar",2,2,          191);  // filename, object
384  add_c_bool_fun("set_fg_tile",3,3,           192);  // x,y, tile #
385  add_c_function("fg_tile",2,2,               193);  // x,y
386  add_c_bool_fun("set_bg_tile",3,3,           194);  // x,y, tile #
387  add_c_function("bg_tile",2,2,               195);  // x,y
388  add_c_bool_fun("load_tiles",1,-1,           196);  // filename1, filename2...
389  add_c_bool_fun("load_palette",1,1,          197);  // filename
390  add_c_bool_fun("load_color_filter",1,1,     198);  // filename
391  add_c_bool_fun("create_players",1,1,        199);  // player type, returns true if game is networked
392  add_c_bool_fun("try_move",2,3,              200);  // xv yv (check_top=t) -> returns T if not blocked
393  add_c_function("sequence_length",1,1,       201);  // sequence number
394  add_c_bool_fun("can_see",5,5,               202);  // x1,y1, x2,y2, chars_block
395  add_c_function("load_big_font",2,2,         203);  // filename, name
396  add_c_function("load_small_font",2,2,       204);  // filename, name
397  add_c_function("load_console_font",2,2,     205);  // filename, name
398  add_c_function("set_current_frame",1,1,     206);
399
400  add_c_bool_fun("draw_transparent",2,2,      208);  // count, max
401  add_c_bool_fun("draw_tint",1,1,             209);  // tint id number
402  add_c_bool_fun("draw_predator",0,0,         210);  // tint_number
403
404  add_c_function("shift_down",1,1,            211);  // player
405  add_c_function("shift_right",1,1,           212);  // player
406  add_c_bool_fun("set_no_scroll_range",5,5,   213);  // player, x1,y1,x2,y2
407
408  add_c_function("def_image",2,2,             215);  // filename,name
409  add_c_bool_fun("put_image",3,3,             216);  // x,y,id
410  add_c_function("view_x1",0,0,               217);
411  add_c_function("view_y1",0,0,               218);
412  add_c_function("view_x2",0,0,               219);
413  add_c_function("view_y2",0,0,               220);
414  add_c_function("view_push_down",1,1,        221);
415  add_c_bool_fun("local_player",0,0,          222);
416  add_c_bool_fun("save_game",1,1,             223);  // filename
417  add_c_bool_fun("set_hp",1,1,                224);
418  add_c_bool_fun("request_level_load",1,1,    225);  // filename
419  add_c_bool_fun("set_first_level",1,1,       226);  // filename
420  add_c_function("def_tint",1,1,              227);  // filename
421  add_c_function("tint_palette",3,3,          228);  // radd,gadd,badd
422  add_c_function("player_number",0,0,         229);
423  add_c_bool_fun("set_current_weapon",1,1,    230);  // type
424  add_c_bool_fun("has_weapon",1,1,            231);  // type
425  add_c_bool_fun("ambient_ramp",1,1,          232);
426  add_c_function("total_players",0,0,         233);
427  add_c_bool_fun("scatter_line",6,6,          234);  // x1,y1,x2,y2, color, scatter value
428  add_c_function("game_tick",0,0,             235);
429  add_c_bool_fun("isa_player",0,0,            236);
430  add_c_bool_fun("shift_rand_table",1,1,      237);  // amount
431  add_c_function("total_frames",0,0,          238);
432  add_c_function("raise",0,0,                 239);  // call only from reload constructor!
433  add_c_function("lower",0,0,                 240);  // call only from reload constructor!
434
435  add_c_function("player_pointer_x",0,0,      241);
436  add_c_function("player_pointer_y",0,0,      242);
437  add_c_bool_fun("frame_panic",0,0,           243);
438  add_c_bool_fun("ascatter_line",7,7,         244);  // x1,y1,x2,y2, color1, color2, scatter value
439  add_c_function("rand_on",0,0,               245);
440  add_c_function("set_rand_on",1,1,           246);
441  add_c_function("bar",5,5,                   247);
442  add_c_function("argc",0,0,                  248);
443  add_c_bool_fun("play_song",1,1,             249);  // filename
444  add_c_bool_fun("stop_song",0,0,             250);
445  add_c_bool_fun("targetable",0,0,            251);
446  add_c_bool_fun("set_targetable",1,1,        252);  // T or nil
447  add_c_bool_fun("show_stats",0,0,            253);
448
449  add_c_function("kills",0,0,                 254);
450  add_c_function("tkills",0,0,                255);
451  add_c_function("secrets",0,0,               256);
452  add_c_function("tsecrets",0,0,              257);
453
454  add_c_bool_fun("set_kills",1,1,             258);
455  add_c_bool_fun("set_tkills",1,1,            259);
456  add_c_bool_fun("set_secrets",1,1,           260);
457  add_c_bool_fun("set_tsecrets",1,1,          261);
458  add_c_bool_fun("request_end_game",0,0,      262);
459  add_c_function("get_save_slot",0,0,         263);
460  add_c_bool_fun("mem_report",0,0,            264);
461  add_c_function("major_version",0,0,         265);
462  add_c_function("minor_version",0,0,         266);
463  add_c_bool_fun("draw_double_tint",2,2,      267);  // tint1 id number, tint 2 id number
464  add_c_function("image_width",1,1,           268);  // image number
465  add_c_function("image_height",1,1,          269);  // image number
466  add_c_function("foreground_width",0,0,      270);
467  add_c_function("foreground_height",0,0,     271);
468  add_c_function("background_width",0,0,      272);
469  add_c_function("background_height",0,0,     273);
470  add_c_function("get_key_code",1,1,          274);  // name of key, returns code that can be used with keypressed
471  add_c_bool_fun("set_cursor_shape",3,3,      275);  // image id, x hot, y hot
472  add_c_bool_fun("start_server",0,0,          276);
473  add_c_bool_fun("put_string",4,5,            277);  // font,x,y,string, [color]
474  add_c_function("font_width",1,1,            278);  // font
475  add_c_function("font_height",1,1,           279);  // font
476  add_c_bool_fun("chat_print",1,1,            280);  // chat string
477  add_c_bool_fun("set_player_name",1,1,       281);  // name
478  add_c_bool_fun("draw_bar",5,5,              282);  // x1,y1,x2,y2,color
479  add_c_bool_fun("draw_rect",5,5,             283);  // x1,y1,x2,y2,color
480  add_c_bool_fun("get_option",1,1,            284);
481  add_c_bool_fun("set_delay_on",1,1,          288);  // T or nil
482  add_c_bool_fun("set_login",1,1,             289);  // name
483  add_c_bool_fun("enable_chatting",0,0,       290);
484  add_c_bool_fun("demo_break_enable",0,0,     291);
485  add_c_bool_fun("am_a_client",0,0,           292);
486  add_c_bool_fun("time_for_next_level",0,0,   293);
487  add_c_bool_fun("reset_kills",0,0,           294);
488  add_c_bool_fun("set_game_name",1,1,         295);  // server game name
489  add_c_bool_fun("set_net_min_players",1,1,   296);
490
491  add_c_bool_fun("set_object_tint", 1, 1,    1001);  // set_object_tint
492  add_c_function("get_object_tint", 0, 0,    1002);  // get_object_tint
493  add_c_bool_fun("set_object_team", 1, 1,    1003);  // set_object_team
494  add_c_function("get_object_team", 0, 0,    1004);  // get_object_tint
495
496
497  add_lisp_function("go_state",1,1,              0);
498  add_lisp_function("with_object",2,-1,          1);
499  add_lisp_function("bmove",0,1,                 2);   // returns true=unblocked, nil=block, or object
500  add_lisp_function("me",0,0,                    3);
501  add_lisp_function("bg",0,0,                    4);
502  add_lisp_function("find_closest",1,1,          5);
503  add_lisp_function("find_xclosest",1,1,         6);
504  add_lisp_function("find_xrange",2,2,           7);
505  add_lisp_function("add_object",3,4,            8);    // type, x,y (type)
506  add_lisp_function("first_focus",0,0,           9);
507  add_lisp_function("next_focus",1,1,           10);
508  add_lisp_function("get_object",1,1,           11);
509  add_lisp_function("get_light",1,1,            12);
510  add_lisp_function("with_objects",1,1,         13);
511  add_lisp_function("add_light",7,7,            14);   // type, x, y, r1, r2, xshift, yshift
512  add_lisp_function("find_enemy",1,1,           15);   // exclude
513  add_lisp_function("user_fun",0,-1,            16);   // calls anobject's user function
514  add_lisp_function("time",2,2,                 17);   // returns a fixed point (times and operation)
515  add_lisp_function("name",0,0,                 18);   // returns current object's name (for debugin)
516  add_lisp_function("float_tick",0,0,           19);
517  add_lisp_function("find_object_in_area",5,5,  20);  // x1, y1, x2, y2  type_list
518  add_lisp_function("find_object_in_angle",3,3, 21);  // start_angle end_angle type_list
519  add_lisp_function("add_object_after",3,4,     22);  // type, x,y (type)
520  add_lisp_function("def_char",2,-1,            23);  // needs at least 2 parms
521  add_lisp_function("see_dist",4,4,             24);  // returns longest unblocked path from x1,y1,x2,y2
522  add_lisp_function("platform",0,0,             25);
523  add_lisp_function("level_name",0,0,           26);
524  add_lisp_function("ant_ai",0,0,               27);
525  add_lisp_function("sensor_ai",0,0,            28);
526  add_lisp_function("dev_draw",0,0,             29);
527  add_lisp_function("top_ai",0,0,               30);
528  add_lisp_function("laser_ufun",2,2,           31);
529  add_lisp_function("top_ufun",2,2,             32);
530
531  add_lisp_function("player_rocket_ufun",2,2,   34);
532
533  add_lisp_function("plaser_ufun",2,2,          33);
534  add_lisp_function("lsaber_ufun",2,2,          35);
535
536  add_lisp_function("cop_mover",3,3,            36);
537  add_lisp_function("latter_ai",0,0,            37);
538  add_lisp_function("with_obj0",-1,-1,          38);
539  add_lisp_function("activated",0,0,            39);
540  add_lisp_function("top_draw",0,0,             40);
541  add_lisp_function("bottom_draw",0,0,          41);
542  add_lisp_function("mover_ai",0,0,             42);
543  add_lisp_function("sgun_ai",0,0,              43);
544  add_lisp_function("last_savegame_name",0,0,   44);
545  add_lisp_function("next_savegame_name",0,0,   45);
546  add_lisp_function("argv",1,1,                 46);
547  add_lisp_function("joy_stat",0,0,             47);  // xm ym b1 b2 b3
548  add_lisp_function("mouse_stat",0,0,           48);  // mx my b1 b2 b3
549  add_lisp_function("mouse_to_game",2,2,        49);  // pass in x,y -> x,y
550  add_lisp_function("game_to_mouse",2,2,        50);  // pass in x,y -> x,y
551  add_lisp_function("get_main_font",0,0,        51);
552  add_lisp_function("player_name",0,0,          52);
553  add_lisp_function("get_cwd",0,0,              54);
554  add_lisp_function("system",1,1,               55);
555  add_lisp_function("convert_slashes",2,2,      56);
556  add_lisp_function("get_directory",1,1,        58);  // path
557  add_lisp_function("respawn_ai",0,0,           60);
558
559  add_lisp_function("score_draw",0,0,           61);
560  add_lisp_function("show_kills",0,0,           62);
561  add_lisp_function("mkptr",1,1,                63);
562  add_lisp_function("seq",3,3,                  64);
563}
564
565
566// Note : args for l_caller have not been evaluated yet!
567void *l_caller(long number, void *args)
568{
569  PtrRef r1(args);
570  switch (number)
571  {
572    case 0 :
573    {
574      current_object->set_aistate(lnumber_value(eval(CAR(args))));
575      current_object->set_aistate_time(0);
576      void *ai=figures[current_object->otype]->get_fun(OFUN_AI);
577      if (!ai)
578      {
579    lbreak("hrump... call to go_state, and no ai function defined?\n"
580           "Are you calling from move function (not mover)?\n");
581    exit(0);
582      }
583      return eval_function((LispSymbol *)ai,NULL);
584    } break;
585    case 1 :
586    {
587      game_object *old_cur=current_object;
588      current_object=(game_object *)lpointer_value(eval(CAR(args)));
589      void *ret=eval_block(CDR(args));
590      current_object=old_cur;
591      return ret;
592    }  break;
593
594
595    case 2 :
596    {
597      int whit;
598      game_object *o;
599      if (args)
600        o=(game_object *)lpointer_value(eval(CAR(args)));
601      else o=current_object;
602      game_object *hit=current_object->bmove(whit,o);
603      if (hit)
604        return new_lisp_pointer(hit);
605      else if (whit) return NULL;
606      else return true_symbol;
607    } break;
608
609    case 3 : return new_lisp_pointer(current_object); break;
610    case 4 :
611    { if (player_list->next)
612        return new_lisp_pointer(current_level->attacker(current_object));
613      else return new_lisp_pointer(player_list->focus); } break;
614    case 5 : return new_lisp_pointer(current_level->find_closest(current_object->x,
615                                 current_object->y,
616                               lnumber_value(eval(CAR(args))),
617                                       current_object)); break;
618    case 6 : return new_lisp_pointer(current_level->find_xclosest(current_object->x,
619                                  current_object->y,
620                                  lnumber_value(eval(CAR(args))),
621                                  current_object
622                                  )); break;
623    case 7 :
624    {
625      long n1=lnumber_value(eval(CAR(args)));
626      long n2=lnumber_value(eval(CAR(CDR(args))));
627      return new_lisp_pointer(current_level->find_xrange(current_object->x,
628                             current_object->y,
629                             n1,
630                             n2
631                             ));
632    } break;
633    case 8 :
634    {
635      int type=lnumber_value(eval(CAR(args)));          args=CDR(args);
636      long x=lnumber_value(eval(CAR(args)));       args=CDR(args);
637      long y=lnumber_value(eval(CAR(args)));  args=CDR(args);
638      game_object *o;
639      if (args)
640        o=create(type,x,y,0,lnumber_value(eval(CAR(args))));
641      else
642        o=create(type,x,y);
643      if (current_level)
644        current_level->add_object(o);
645      return new_lisp_pointer(o);
646    } break;
647    case 22 :
648    {
649      int type=lnumber_value(eval(CAR(args)));          args=CDR(args);
650      long x=lnumber_value(eval(CAR(args)));       args=CDR(args);
651      long y=lnumber_value(eval(CAR(args)));  args=CDR(args);
652      game_object *o;
653      if (args)
654        o=create(type,x,y,0,lnumber_value(eval(CAR(args))));
655      else
656        o=create(type,x,y);
657      if (current_level)
658        current_level->add_object_after(o,current_object);
659      return new_lisp_pointer(o);
660    } break;
661
662    case 9 : return new_lisp_pointer(the_game->first_view->focus); break;
663    case 10 :
664    {
665      view *v=((game_object *)lpointer_value(eval(CAR(args))))->controller()->next;
666      if (v)
667        return new_lisp_pointer(v->focus);
668      else return NULL;
669    } break;
670    case 11 :
671    {
672      return new_lisp_pointer
673      ((void *)current_object->get_object(lnumber_value(eval(CAR(args)))));
674    } break;
675    case 12 :
676    {
677      return new_lisp_pointer
678      ((void *)current_object->get_light(lnumber_value(eval(CAR(args)))));
679    } break;
680    case 13 :
681    {
682      game_object *old_cur=current_object;
683      void *ret=NULL;
684      for (int i=0;i<old_cur->total_objects();i++)
685      {   
686    current_object=old_cur->get_object(i);
687    ret=eval(CAR(args));
688      }
689      current_object=old_cur;
690      return ret;
691    } break;
692    case 14 :
693    {
694      int t=lnumber_value(eval(CAR(args))); args=lcdr(args);
695      int x=lnumber_value(eval(CAR(args))); args=lcdr(args);
696      int y=lnumber_value(eval(CAR(args))); args=lcdr(args);
697      int r1=lnumber_value(eval(CAR(args))); args=lcdr(args);
698      int r2=lnumber_value(eval(CAR(args))); args=lcdr(args);
699      int xs=lnumber_value(eval(CAR(args))); args=lcdr(args);
700      int ys=lnumber_value(eval(CAR(args)));
701      return new_lisp_pointer(add_light_source(t,x,y,r1,r2,xs,ys));
702    } break;
703    case 15 :
704    {
705//      return current_lev shit
706    } break;
707    case 16 :
708    {
709      void *f=figures[current_object->otype]->get_fun(OFUN_USER_FUN);
710      if (!f) return NULL;
711      return eval_function((LispSymbol *)f,args);
712    } break;
713    case 17 :
714    {
715      long trials=lnumber_value(eval(CAR(args)));
716      args=CDR(args);
717      time_marker start;
718      for (int x=0;x<trials;x++)
719      {
720    clear_tmp();
721    eval(CAR(args));
722      }
723      time_marker end;
724      return new_lisp_fixed_point((long)(end.diff_time(&start)*(1<<16)));
725    } break;
726    case 18 :
727    { return LispString::Create(object_names[current_object->otype]); } break;
728    case 19 :
729    { return current_object->float_tick(); } break;
730    case 20 :
731    {
732      long x1=lnumber_value(eval(CAR(args))); args=CDR(args);
733      long y1=lnumber_value(eval(CAR(args))); args=CDR(args);
734      long x2=lnumber_value(eval(CAR(args))); args=CDR(args);
735      long y2=lnumber_value(eval(CAR(args))); args=CDR(args);
736
737      void *list=eval(CAR(args));
738      game_object *find=current_level->find_object_in_area(current_object->x,
739                          current_object->y,
740                          x1,y1,x2,y2,list,current_object);
741      if (find) return new_lisp_pointer(find);
742      else return NULL;
743    } break;
744
745    case 21 :
746    {
747      long a1=lnumber_value(eval(CAR(args))); args=CDR(args);
748      long a2=lnumber_value(eval(CAR(args))); args=CDR(args);
749
750      void *list=eval(CAR(args));
751      PtrRef r1(list);
752      game_object *find=current_level->find_object_in_angle(current_object->x,
753                            current_object->y,
754                            a1,a2,list,current_object);
755      if (find) return new_lisp_pointer(find);
756      else return NULL;
757    } break;
758    case 23 :         // def_character
759    {
760      LispSymbol *sym=(LispSymbol *)lcar(args);
761      if (item_type(sym)!=L_SYMBOL)
762      {
763        lbreak("expecting first arg to def-character to be a symbol!\n");
764        exit(0);
765      }
766      int sp=current_space;
767      current_space=PERM_SPACE;
768      sym->SetNumber(total_objects);   // set the symbol value to the object number
769      current_space=sp;
770      if (!total_objects)
771      {
772        object_names=(char **)malloc(sizeof(char *)*(total_objects+1));
773    figures=(character_type **)malloc(sizeof(character_type *)*(total_objects+1));
774      }
775      else
776      {
777        object_names=(char **)realloc(object_names,sizeof(char *)*(total_objects+1));
778    figures=(character_type **)realloc(figures,sizeof(character_type *)*(total_objects+1));
779      }
780
781      object_names[total_objects] = strdup(lstring_value(sym->GetName()));
782      figures[total_objects]=new character_type(CDR(args),sym);
783      total_objects++;
784      return LispNumber::Create(total_objects-1);
785    } break;
786    case 24 :
787    {
788      int32_t x1=lnumber_value(eval(CAR(args)));  args=CDR(args);
789      int32_t y1=lnumber_value(eval(CAR(args)));  args=CDR(args);
790      int32_t x2=lnumber_value(eval(CAR(args)));  args=CDR(args);
791      int32_t y2=lnumber_value(eval(CAR(args)));
792      current_level->foreground_intersect(x1,y1,x2,y2);
793      void *ret=NULL;
794      push_onto_list(LispNumber::Create(y2),ret);
795      push_onto_list(LispNumber::Create(x2),ret);
796      return ret;
797    } break;
798    case 25 :
799    {
800#ifdef __linux__
801      return LispSymbol::FindOrCreate("LINUX");
802#endif
803#ifdef __sgi
804      return LispSymbol::FindOrCreate("IRIX");
805#endif
806#ifdef __WIN32
807      return LispSymbol::FindOrCreate("WIN32");
808#endif
809    } break;
810    case 26 :
811    {
812      return LispString::Create(current_level->name());
813    } break;
814    case 27 : return ant_ai(); break;
815    case 28 : return sensor_ai(); break;
816    case 29 : if (dev&EDIT_MODE) current_object->drawer(); break;
817    case 30 : return top_ai(); break;
818    case 31 : return laser_ufun(args); break;
819    case 32 : return top_ufun(args); break;
820    case 33 : return plaser_ufun(args); break;
821    case 34 : return player_rocket_ufun(args); break;
822    case 35 : return lsaber_ufun(args); break;
823    case 36 :
824    {
825
826      int32_t xm,ym,but;
827      xm=lnumber_value(CAR(args)); args=CDR(args);
828      ym=lnumber_value(CAR(args)); args=CDR(args);
829      but=lnumber_value(CAR(args));
830      return cop_mover(xm,ym,but);
831    } break;
832    case 37 : return ladder_ai(); break;
833    case 38 :
834    {
835      game_object *old_cur=current_object;
836      current_object=current_object->get_object(0);
837      void *ret=eval_block(args);
838      current_object=old_cur;
839      return ret;
840    }  break;
841    case 39 :
842    {
843      if (current_object->total_objects()==0)
844        return true_symbol;
845      else if (current_object->get_object(0)->aistate())
846        return true_symbol;
847      else return NULL;
848    } break;
849    case 40 : top_draw(); break;
850    case 41 : bottom_draw(); break;
851    case 42 : return mover_ai(); break;
852    case 43 : return sgun_ai();
853    case 44 :
854    {
855      char nm[50];
856      last_savegame_name(nm);
857      return LispString::Create(nm);
858    } break;
859    case 45 :
860    {
861      char nm[50];
862      sprintf(nm,"save%04d.pcx", load_game(1,symbol_str("LOAD")));
863//      get_savegame_name(nm);
864      the_game->reset_keymap();
865      return LispString::Create(nm);
866    } break;
867    case 46 :
868    {
869      return LispString::Create(start_argv[lnumber_value(eval(CAR(args)))]);
870    } break;
871    case 47 :
872    {
873      int xv,yv,b1,b2,b3;
874      if (has_joystick)
875        joy_status(b1,b2,b3,xv,yv);
876      else b1=b2=b3=xv=yv=0;
877
878      void *ret=NULL;
879      PtrRef r1(ret);
880      push_onto_list(LispNumber::Create(b3),ret);
881      push_onto_list(LispNumber::Create(b2),ret);
882      push_onto_list(LispNumber::Create(b1),ret);
883      push_onto_list(LispNumber::Create(yv),ret);
884      push_onto_list(LispNumber::Create(xv),ret);
885      return ret;
886    } break;
887    case 48 :
888    {
889      void *ret=NULL;
890      {
891    PtrRef r1(ret);
892    push_onto_list(LispNumber::Create((last_demo_mbut&4)==4),ret);
893    push_onto_list(LispNumber::Create((last_demo_mbut&2)==2),ret);
894    push_onto_list(LispNumber::Create((last_demo_mbut&1)==1),ret);
895    push_onto_list(LispNumber::Create(last_demo_my),ret);
896    push_onto_list(LispNumber::Create(last_demo_mx),ret);
897      }
898      return ret;
899    } break;
900    case 49 :
901    {
902      int32_t x=lnumber_value(eval(CAR(args))); args=CDR(args);
903      int32_t y=lnumber_value(eval(CAR(args))); args=CDR(args);
904
905      int32_t rx,ry;
906      the_game->mouse_to_game(x,y,rx,ry);
907      void *ret=NULL;
908      {
909    PtrRef r1(ret);
910    push_onto_list(LispNumber::Create(ry),ret);
911    push_onto_list(LispNumber::Create(rx),ret);
912      }
913      return ret;
914    } break;
915    case 50 :
916    {
917      int32_t x=lnumber_value(eval(CAR(args))); args=CDR(args);
918      int32_t y=lnumber_value(eval(CAR(args))); args=CDR(args);
919
920      int32_t rx,ry;
921      the_game->game_to_mouse(x,y,current_view,rx,ry);
922      void *ret=NULL;
923      {
924    PtrRef r1(ret);
925    push_onto_list(LispNumber::Create(ry),ret);
926    push_onto_list(LispNumber::Create(rx),ret);
927      }
928      return ret;
929    } break;
930    case 51 :   return new_lisp_pointer(wm->font()); break;
931    case 52 :
932    {
933      view *c=current_object->controller();
934      if (!c)
935        lbreak("object is not a player, cannot return name");
936      else
937        return LispString::Create(c->name);
938    } break;
939    case 54 :
940    {
941      char cd[150];
942      getcwd(cd,100);
943      return LispString::Create(cd);
944    } break;
945    case 55 :
946    { system(lstring_value(eval(CAR(args)))); } break;
947    case 56 :
948    {
949      void *fn=eval(CAR(args)); args=CDR(args);
950      char tmp[200];
951      {
952    PtrRef r1(fn);
953    char *slash=lstring_value(eval(CAR(args)));
954    char *filename=lstring_value(fn);
955
956    char *s=filename,*tp;
957   
958    for (tp=tmp;*s;s++,tp++)
959    {
960      if (*s=='/' || *s=='\\')
961      *tp=*slash;
962      else *tp=*s;
963    }
964    *tp=0;
965      }
966      return LispString::Create(tmp);
967    } break;
968    case 58 :
969    {
970      char **files,**dirs;
971      int tfiles,tdirs,i;
972
973      get_directory(lstring_value(eval(CAR(args))),files,tfiles,dirs,tdirs);
974      void *fl=NULL,*dl=NULL,*rl=NULL;
975      {
976    PtrRef r1(fl),r2(dl);
977   
978    for (i=tfiles-1;i>=0;i--) { push_onto_list(LispString::Create(files[i]),fl); free(files[i]); }
979    free(files);
980
981    for (i=tdirs-1;i>=0;i--) { push_onto_list(LispString::Create(dirs[i]),dl); free(dirs[i]); }
982    free(dirs);
983   
984    push_onto_list(dl,rl);
985    push_onto_list(fl,rl);
986      }
987
988      return rl;
989    } break;
990    case 60 : return respawn_ai(); break;
991    case 61 : return score_draw();  break;
992    case 62 : return show_kills(); break;
993    case 63 :
994    {
995        long x;
996        sscanf(lstring_value(eval(CAR(args))),"%lx",&x);
997        return new_lisp_pointer((void *)(intptr_t)x);
998    } break;
999    case 64 :
1000    {
1001      char name[256],name2[256];
1002      strcpy(name,lstring_value(eval(CAR(args))));  args=CDR(args);
1003      long first=lnumber_value(eval(CAR(args)));  args=CDR(args);
1004      long last=lnumber_value(eval(CAR(args)));
1005      long i;
1006      void *ret=NULL;
1007      PtrRef r1(ret);
1008
1009      if (last>=first)
1010      {
1011        for (i=last;i>=first;i--)
1012        {
1013          sprintf(name2,"%s%04ld.pcx",name,i);
1014          push_onto_list(LispString::Create(name2),ret);
1015        }
1016      } else
1017      {
1018        for (i=last;i<=first;i++)
1019        {
1020          sprintf(name2,"%s%04ld.pcx",name,i);
1021          push_onto_list(LispString::Create(name2),ret);
1022        }
1023      }
1024      return ret;
1025    }
1026  }
1027  return NULL;
1028}
1029
1030//extern bFILE *rcheck,*rcheck_lp;
1031
1032// arguments have already been evaled..
1033long c_caller(long number, void *args)
1034{
1035    PtrRef r1(args);
1036    switch (number)
1037    {
1038        case 1:
1039        {
1040            return abs(current_object->x-current_level->attacker(current_object)->x);
1041        } break;
1042        case 2:
1043        {
1044            return abs(current_object->y-current_level->attacker(current_object)->y);
1045        } break;
1046        case 3:
1047        {
1048            if( !current_object->controller() )
1049            {
1050                lbreak("object is not a player, cannot determine keypresses");
1051            }
1052            else
1053            {
1054                return current_object->controller()->key_down(lnumber_value(CAR(args)));
1055            }
1056        } break;
1057        case 4:
1058        {
1059            return the_game->key_down(lnumber_value(CAR(args)));
1060        } break;
1061        case 5:
1062        {
1063            return current_level->attacker(current_object)->state;
1064        } break;
1065        case 6:
1066        {
1067            return current_object->aitype();
1068        } break;
1069        case 7:
1070        {
1071            if (!current_object->keep_ai_info())
1072                current_object->set_aistate(0);
1073            return current_object->aistate();
1074        } break;
1075        case 8:
1076        {
1077            int ns=lnumber_value(CAR(args));
1078            current_object->set_aistate_time(0);
1079            current_object->set_aistate(ns); return 1;
1080        } break;
1081        case 9:
1082        {
1083/*      if (rcheck_lp)
1084      {
1085    char str[100];
1086    sprintf(str,"\n\nTick %d, Rand_on %d\n",current_level->tick_counter(),rand_on);
1087    rcheck_lp->write(str,strlen(str)+1);
1088    current_print_file=rcheck_lp;
1089    print_trace_stack(6);
1090    current_print_file=NULL;
1091      }*/
1092
1093            return jrandom(lnumber_value(CAR(args)));
1094        } break;
1095        case 10 : return current_object->aistate_time(); break;
1096        case 11 : return current_object->state; break;
1097        case 12:
1098        {
1099            if (current_level->attacker(current_object)->x>current_object->x)
1100                return 1;
1101            else
1102                return -1;
1103        } break;
1104        case 13:
1105        {
1106            return current_object->move(lnumber_value(CAR(args)),lnumber_value(CAR(CDR(args))), lnumber_value(CAR(CDR(CDR(args)))));
1107        } break;
1108        case 14:
1109        {
1110            if (current_object->direction>0)
1111                return 1;
1112            else
1113                return -1;
1114        } break;
1115    case 15 : return current_object->otype; break;
1116    case 16 : return current_object->next_picture(); break;
1117    case 17 : current_object->set_fade_dir(lnumber_value(CAR(args))); return 1; break;
1118    case 18 :
1119    {
1120      int cx=lnumber_value(CAR(args));
1121      args=CDR(args);
1122      int cy=lnumber_value(CAR(args));
1123      args=CDR(args);
1124      int but=lnumber_value(CAR(args));
1125      return current_object->mover(cx,cy,but);
1126    } break;
1127    case 19 : current_object->set_fade_count(lnumber_value(CAR(args))); return 1; break;
1128    case 20 : return current_object->fade_count(); break;
1129    case 21 : return current_object->fade_dir(); break;
1130    case 22 :
1131    {
1132      int32_t x1,y1,x2,y2,xp1,yp1,xp2,yp2;
1133      current_level->attacker(current_object)->picture_space(x1,y1,x2,y2);
1134      current_object->picture_space(xp1,yp1,xp2,yp2);
1135      if (xp1>x2 || xp2<x1 || yp1>y2 || yp2<y1) return 0;
1136      else return 1;
1137    } break;
1138    case 23 : current_object->add_power(lnumber_value(CAR(args))); break;
1139    case 24 : current_object->add_hp(lnumber_value(CAR(args))); break;
1140
1141    case 27 :
1142    { current_object->drawer(); return 1; } break;
1143    case 28 :
1144    { return (dev & EDIT_MODE); } break;
1145    case 29 :
1146    { current_object->draw_above(current_view); return 1; } break;
1147    case 30 : return current_object->x; break;
1148    case 31 : return current_object->y; break;
1149    case 32 :
1150    { int32_t v=lnumber_value(CAR(args));
1151      current_object->x=v;
1152//      current_object->last_x=v;
1153      return 1;
1154    } break;
1155    case 33 :
1156    { int32_t v=lnumber_value(CAR(args));
1157      current_object->y=v;
1158//      current_object->last_y=v;
1159      return 1;
1160    } break;
1161
1162    case 34 : { return current_level->push_characters(current_object,lnumber_value(CAR(args)),
1163                        lnumber_value(CAR(CDR(args))));
1164          } break;
1165
1166    case 37 :
1167    {
1168      int32_t s=lnumber_value(CAR(args));
1169      current_object->set_state((character_state)s);
1170      return (s==current_object->state);
1171    } break;
1172
1173    case 38 : return current_level->attacker(current_object)->x; break;
1174    case 39 : return current_level->attacker(current_object)->y; break;
1175    case 40 : current_object->change_aitype(lnumber_value(CAR(args))); return 1; break;
1176
1177    case 42 : return current_object->xvel(); break;
1178    case 43 : return current_object->yvel(); break;
1179    case 44 : current_object->set_xvel(lnumber_value(CAR(args))); return 1; break;
1180    case 45 : current_object->set_yvel(lnumber_value(CAR(args))); return 1; break;
1181    case 46 : if (current_level->attacker(current_object)->x>current_object->x) return -1;
1182              else return 1; break;
1183    case 47 : return lnumber_value(CAR(args))&BLOCKED_LEFT; break;
1184    case 48 : return lnumber_value(CAR(args))&BLOCKED_RIGHT; break;
1185
1186    case 50 : dev_cont->add_palette(args); break;
1187    case 51 : write_PCX(screen,pal,lstring_value(CAR(args))); break;
1188
1189    case 52 : the_game->zoom=lnumber_value(CAR(args)); the_game->draw(); break;
1190    case 55 : the_game->show_help(lstring_value(CAR(args))); break;
1191
1192    case 56 : return current_object->direction; break;
1193    case 57 : current_object->direction=lnumber_value(CAR(args)); break;
1194    case 58 :
1195    {
1196      int x1=lnumber_value(CAR(args));
1197      if (!current_object->controller())
1198      { lbreak("set_freeze_time : object is not a focus\n"); }
1199      else current_object->controller()->freeze_time=x1; return 1;
1200    } break;
1201    case 59 : return menu(args,big_font); break;
1202    case 60 :
1203    { event ev; dev_cont->do_command(lstring_value(CAR(args)),ev); return 1; } break;
1204    case 61 : the_game->set_state(lnumber_value(CAR(args))); break;
1205
1206    case 62 :
1207    {
1208      int x1=lnumber_value(CAR(args)); args=CDR(args);
1209      int y1=lnumber_value(CAR(args)); args=CDR(args);
1210      int x2=lnumber_value(CAR(args)); args=CDR(args);
1211      int y2=lnumber_value(CAR(args));
1212      scene_director.set_text_region(x1,y1,x2,y2);
1213    } break;
1214    case 63 : scene_director.set_frame_speed(lnumber_value(CAR(args))); break;
1215    case 64 : scene_director.set_scroll_speed(lnumber_value(CAR(args))); break;
1216    case 65 : scene_director.set_pan_speed(lnumber_value(CAR(args))); break;
1217    case 66 : scene_director.scroll_text(lstring_value(CAR(args))); break;
1218    case 67 : scene_director.set_pan(lnumber_value(CAR(args)),
1219                 lnumber_value(CAR(CDR(args))),
1220                 lnumber_value(CAR(CDR(CDR(args))))); break;
1221    case 68 : scene_director.wait(CAR(args)); break;
1222
1223
1224    case 73 : the_game->set_level(new level(lnumber_value(CAR(args)),
1225                        lnumber_value(CAR(CDR(args))),
1226                        lstring_value(CAR(CDR(CDR(args)))))); break;
1227    case 74 :
1228    { if (current_level) delete current_level;
1229      current_level=new level(100,100,"new_level");
1230    } break;
1231    case 75 :
1232    {
1233      int amount=lnumber_value(CAR(args)); args=CDR(args);
1234      game_object *o=((game_object *)lpointer_value(CAR(args))); args=CDR(args);
1235      int xv=0,yv=0;
1236      if (args)
1237      {
1238    xv=lnumber_value(CAR(args)); args=CDR(args);
1239    yv=lnumber_value(CAR(args));
1240      }
1241      o->do_damage(amount,current_object,current_object->x,current_object->y,xv,yv);
1242    } break;
1243    case 76 : return current_object->hp(); break;
1244    case 77 :
1245    {
1246      game_object *o=(game_object *)lpointer_value(CAR(args));
1247      if (!o->controller())
1248    printf("set shift : object is not a focus\n");
1249      else o->controller()->shift_down=lnumber_value(CAR(CDR(args))); return 1;
1250    } break;
1251    case 78 :
1252    {
1253      game_object *o=(game_object *)lpointer_value(CAR(args));
1254      if (!o->controller())
1255    printf("set shift : object is not a focus\n");
1256      else o->controller()->shift_right=lnumber_value(CAR(CDR(args))); return 1;
1257    } break;
1258    case 79 : current_object->set_gravity(lnumber_value(CAR(args))); return 1; break;
1259    case 80 : return current_object->tick(); break;
1260    case 81 : current_object->set_xacel((lnumber_value(CAR(args)))); return 1; break;
1261    case 82 : current_object->set_yacel((lnumber_value(CAR(args)))); return 1; break;
1262    case 84 : set_local_players(lnumber_value(CAR(args))); return 1; break;
1263    case 85 : return total_local_players(); break;
1264    case 86 : light_detail=lnumber_value(CAR(args)); return 1; break;
1265    case 87 : return light_detail; break;
1266    case 88 : morph_detail=lnumber_value(CAR(args)); return 1; break;
1267    case 89 : return morph_detail; break;
1268    case 90 : current_object->morph_into(lnumber_value(CAR(args)),NULL,
1269                     lnumber_value(CAR(CDR(args))),
1270                     lnumber_value(CAR(CDR(CDR(args))))); return 1; break;
1271    case 91 : current_object->add_object((game_object *)lpointer_value(CAR(args))); return 1; break;
1272    case 92 :
1273    {
1274      int32_t cx1,x1=lnumber_value(CAR(args)); args=lcdr(args);
1275      int32_t cy1,y1=lnumber_value(CAR(args)); args=lcdr(args);
1276      int32_t cx2,x2=lnumber_value(CAR(args)); args=lcdr(args);
1277      int32_t cy2,y2=lnumber_value(CAR(args)); args=lcdr(args);
1278      int32_t c=lnumber_value(CAR(args));
1279      the_game->game_to_mouse(x1,y1,current_view,cx1,cy1);
1280      the_game->game_to_mouse(x2,y2,current_view,cx2,cy2);
1281      screen->line(cx1,cy1,cx2,cy2,c);
1282      return 1;
1283    } break;
1284    case 93 : return wm->dark_color(); break;
1285    case 94 : return wm->medium_color(); break;
1286    case 95 : return wm->bright_color(); break;
1287
1288    case 99 : current_object->remove_object((game_object *)lpointer_value(CAR(args))); return 1; break;
1289    case 100 : current_object->add_light((light_source *)lpointer_value(CAR(args))); return 1; break;
1290    case 101 : current_object->remove_light((light_source *)lpointer_value(CAR(args))); return 1; break;
1291    case 102 : return current_object->total_objects(); break;
1292    case 103 : return current_object->total_lights(); break;
1293
1294    case 104 :
1295    { light_source *l=(light_source *)lpointer_value(CAR(args));
1296      int32_t x=lnumber_value(CAR(CDR(args)));
1297      if (x>=1)
1298        l->inner_radius=x;
1299      l->calc_range();
1300      return 1;
1301    } break;
1302    case 105 :
1303    { light_source *l=(light_source *)lpointer_value(CAR(args));
1304      int32_t x=lnumber_value(CAR(CDR(args)));
1305      if (x>l->inner_radius)
1306        l->outer_radius=x;
1307      l->calc_range();
1308      return 1;
1309    } break;
1310    case 106 :
1311    { light_source *l=(light_source *)lpointer_value(CAR(args));
1312      l->x=lnumber_value(CAR(CDR(args)));
1313      l->calc_range();
1314      return 1;
1315    } break;
1316    case 107 :
1317    { light_source *l=(light_source *)lpointer_value(CAR(args));
1318      l->y=lnumber_value(CAR(CDR(args)));
1319      l->calc_range();
1320      return 1;
1321    } break;
1322    case 108 :
1323    { light_source *l=(light_source *)lpointer_value(CAR(args));
1324      l->xshift=lnumber_value(CAR(CDR(args)));
1325      l->calc_range();
1326      return 1;
1327    } break;
1328    case 109 :
1329    { light_source *l=(light_source *)lpointer_value(CAR(args));
1330      l->yshift=lnumber_value(CAR(CDR(args)));
1331      l->calc_range();
1332      return 1;
1333    } break;
1334    case 110 : return ((light_source *)lpointer_value(CAR(args)))->inner_radius; break;
1335    case 111 : return ((light_source *)lpointer_value(CAR(args)))->outer_radius; break;
1336    case 112 : return ((light_source *)lpointer_value(CAR(args)))->x; break;
1337    case 113 : return ((light_source *)lpointer_value(CAR(args)))->y; break;
1338    case 114 : return ((light_source *)lpointer_value(CAR(args)))->xshift; break;
1339    case 115 : return ((light_source *)lpointer_value(CAR(args)))->yshift; break;
1340    case 116 : return current_object->xacel(); break;
1341    case 117 : return current_object->yacel(); break;
1342    case 118 : current_level->remove_light((light_source *)lpointer_value(CAR(args))); break;
1343    case 119 : current_object->set_fx(lnumber_value(CAR(args))); break;
1344    case 120 : current_object->set_fy(lnumber_value(CAR(args))); break;
1345    case 121 : current_object->set_fxvel(lnumber_value(CAR(args))); break;
1346    case 122 : current_object->set_fyvel(lnumber_value(CAR(args))); break;
1347    case 123 : current_object->set_fxacel(lnumber_value(CAR(args))); break;
1348    case 124 : current_object->set_fyacel(lnumber_value(CAR(args))); break;
1349    case 125 : return current_object->picture()->width(); break;
1350    case 126 : return current_object->picture()->height(); break;
1351    case 127 : { dprintf("trap\n"); } break;   // I use this to set gdb break points
1352    case 128 : { return current_level->platform_push(current_object,lnumber_value(CAR(args)),
1353                        lnumber_value(CAR(CDR(args))));
1354                        } break;
1355    case 133 :  // def_sound
1356    {
1357      LispSymbol *sym=NULL;
1358      if (CDR(args))
1359      {
1360    sym=(LispSymbol *)lcar(args);
1361    if (item_type(sym)!=L_SYMBOL)
1362    {
1363      lbreak("expecting first arg to def-character to be a symbol!\n");
1364      exit(0);
1365    }
1366    args=CDR(args);
1367      }
1368
1369      int sp=current_space;
1370      current_space=PERM_SPACE;
1371      int id=cache.reg(lstring_value(lcar(args)),NULL,SPEC_EXTERN_SFX,1);
1372      if (sym)
1373        sym->SetNumber(id);    // set the symbol value to sfx id
1374      current_space=sp;
1375      return id;
1376    } break;
1377    case 134 :  // play_sound
1378    {
1379      void *a=args;
1380      PtrRef r1(a);
1381      int id=lnumber_value(lcar(a));
1382      if (id<0) return 0;
1383      a=CDR(a);
1384      if (!a)
1385        cache.sfx(id)->play(127);
1386      else
1387      {
1388    int vol=lnumber_value(lcar(a)); a=CDR(a);
1389    if (a)
1390    {
1391      int32_t x=lnumber_value(lcar(a)); a=CDR(a);
1392      if (!a)
1393      {
1394        lprint(args);
1395        lbreak("expecting y after x in play_sound\n");
1396        exit(1);
1397      }
1398      int32_t y=lnumber_value(lcar(a));
1399      the_game->play_sound(id,vol,x,y);
1400    } else cache.sfx(id)->play(vol);
1401      }
1402
1403    } break;
1404
1405    case 137 : return defun_pseq(args); break;
1406    case 138 :
1407    { int id=lnumber_value(CAR(args)); args=CDR(args);
1408      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1409      int32_t y=lnumber_value(CAR(args)); args=CDR(args);
1410      int32_t dir=lnumber_value(CAR(args));
1411      add_panim(id,x,y,dir);
1412    } break;
1413    case 142 :
1414    {
1415      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1416      if (x<0 || x>=total_weapons)
1417      {
1418    lbreak("weapon out of range (%d)\n",x);
1419    exit(0);
1420      }
1421      return weapon_types[x];
1422    } break;
1423    case 143 :
1424    {
1425      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1426      int32_t y=lnumber_value(CAR(args)); args=CDR(args);
1427      int32_t r=lnumber_value(CAR(args)); args=CDR(args);
1428      int32_t m=lnumber_value(CAR(args)); args=CDR(args);
1429      game_object *o=(game_object *)lpointer_value(CAR(args)); args=CDR(args);
1430      int32_t mp=lnumber_value(CAR(args));
1431      current_level->hurt_radius(x,y,r,m,current_object,o,mp);
1432    } break;
1433
1434    case 144 :
1435    {
1436      view *v=current_object->controller();
1437      if (!v) dprintf("Can't add weapons for non-players\n");
1438      else
1439      {
1440    int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1441    int32_t y=lnumber_value(CAR(args)); args=CDR(args);
1442    if (x<0 || x>=total_weapons)
1443    { lbreak("weapon out of range (%d)\n",x); exit(0); }
1444    v->add_ammo(x,y);
1445      }
1446    } break;
1447    case 145 :
1448    {
1449      view *v=current_object->controller();
1450      if (!v) return 0;
1451      else return v->weapon_total(lnumber_value(CAR(args)));
1452    } break;
1453    case 146 :
1454    {
1455      view *v=current_object->controller();
1456      if (!v) return 0; else return v->current_weapon;
1457    } break;
1458    case 147 :
1459    {
1460      view *v=current_object->controller();
1461      if (!v) { lbreak("current_weapon_type : object cannot hold weapons\n");
1462        return 0; }
1463      else return v->current_weapon;
1464    } break;
1465    case 148 : return lnumber_value(CAR(args))&BLOCKED_UP; break;
1466    case 149 : return lnumber_value(CAR(args))&BLOCKED_DOWN; break;
1467    case 150 :
1468    {
1469      view *v=current_object->controller();
1470      int x=lnumber_value(CAR(args));
1471      if (x<0 || x>=total_weapons)
1472      { lbreak("weapon out of range (%d)\n",x); exit(0); }
1473      if (v) v->give_weapon(x);
1474    } break;
1475    case 151 :
1476    {
1477      int a=lnumber_value(CAR(args));
1478      if (a<0 || a>=TOTAL_ABILITIES)
1479      {
1480    lprint(args);
1481    lbreak("bad ability number for get_ability, should be 0..%d, not %d\n",
1482        TOTAL_ABILITIES,a);
1483    exit(0);
1484      }
1485      return get_ability(current_object->otype,(ability)a);
1486    } break;
1487    case 152 :
1488    {
1489      view *v=current_object->controller();
1490      if (!v) dprintf("Can't use reset_player on non-players\n");
1491      else
1492        v->reset_player();   
1493    } break;
1494    case 153 :
1495    {
1496      game_object *o=(game_object *)lpointer_value(CAR(args));
1497      int32_t x=o->x-current_object->x,
1498        y=-(o->y-o->picture()->height()/2-(current_object->y-(current_object->picture()->height()/2)));
1499      return lisp_atan2(y,x);
1500    } break;
1501    case 154 :
1502    {
1503      int32_t ang=lnumber_value(CAR(args)); args=CDR(args);
1504      int32_t mag=lfixed_point_value(CAR(args));
1505      int32_t xvel=(lisp_cos(ang)>>8)*(mag>>8);
1506      current_object->set_xvel(xvel>>16);
1507      current_object->set_fxvel((xvel&0xffff)>>8);
1508      int32_t yvel=-(lisp_sin(ang)>>8)*(mag>>8);
1509      current_object->set_yvel(yvel>>16);
1510      current_object->set_fyvel((yvel&0xffff)>>8);
1511    } break;
1512    case 155 :
1513    {
1514      int tframes=current_object->total_frames(),f;
1515
1516      int32_t ang1=lnumber_value(CAR(args)); args=CDR(args);
1517      if (ang1<0) ang1=(ang1%360)+360;
1518      else if (ang1>=360) ang1=ang1%360;
1519      int32_t ang2=lnumber_value(CAR(args)); args=CDR(args);
1520      if (ang2<0) ang2=(ang2%360)+360;
1521      else if (ang2>=360) ang2=ang2%360;
1522
1523      int32_t ang=(lnumber_value(CAR(args))+90/tframes)%360;
1524      if (ang1>ang2)
1525      {
1526        if (ang<ang1 && ang>ang2)     
1527      return 0;
1528    else if (ang>=ang1)   
1529      f=(ang-ang1)*tframes/(359-ang1+ang2+1);
1530    else
1531      f=(359-ang1+ang)*tframes/(359-ang1+ang2+1);
1532      } else if (ang<ang1 || ang>ang2)
1533        return 0;
1534      else f=(ang-ang1)*tframes/(ang2-ang1+1);
1535      if (current_object->direction>0)
1536        current_object->current_frame=f;
1537      else
1538        current_object->current_frame=tframes-f-1;
1539      return 1;
1540    } break;
1541    case 156 :
1542    {
1543      int x=current_object->current_frame;
1544      current_object->set_state((character_state)lnumber_value(CAR(args)));
1545      current_object->current_frame=x;
1546    } break;
1547
1548    case 168 : if (current_object->morph_status()) return 1; else return 0; break;
1549    case 169 :
1550    {
1551      int32_t am=lnumber_value(CAR(args)); args=CDR(args);
1552      game_object *from=(game_object *)lpointer_value(CAR(args)); args=CDR(args);
1553      int32_t hitx=lnumber_value(CAR(args)); args=CDR(args);
1554      int32_t hity=lnumber_value(CAR(args)); args=CDR(args);
1555      int32_t px=lnumber_value(CAR(args)); args=CDR(args);
1556      int32_t py=lnumber_value(CAR(args)); args=CDR(args);
1557      current_object->damage_fun(am,from,hitx,hity,px,py);
1558    } break;
1559    case 170 : return current_object->gravity(); break;
1560    case 171 :
1561    {
1562      view *v=current_object->controller();
1563      if (!v) dprintf("make_view_solid : object has no view\n");
1564      else
1565        v->draw_solid=lnumber_value(CAR(args));
1566    } break;
1567    case 172 :
1568    {
1569      void *a=args;
1570      int r=lnumber_value(CAR(a)); a=CDR(a);
1571      int g=lnumber_value(CAR(a)); a=CDR(a);
1572      int b=lnumber_value(CAR(a));
1573      if (r<0 || b<0 || g<0 || r>255 || g>255 || b>255)
1574      {
1575    lprint(args);
1576    lbreak("color out of range (0..255) in color lookup\n");
1577    exit(0);
1578      }
1579      return color_table->lookup_color(r>>3,g>>3,b>>3);
1580    } break;
1581    case 173 :
1582    {
1583      view *v=current_object->controller();
1584      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1585      else return v->x_suggestion;
1586    } break;
1587    case 174 :
1588    {
1589      view *v=current_object->controller();
1590      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1591      else return v->y_suggestion;
1592    } break;
1593    case 175 :
1594    {
1595      view *v=current_object->controller();
1596      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1597      else return v->b1_suggestion;
1598    } break;
1599    case 176 :
1600    {
1601      view *v=current_object->controller();
1602      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1603      else return v->b2_suggestion;
1604    } break;
1605    case 177 :
1606    {
1607      view *v=current_object->controller();
1608      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1609      else return v->b3_suggestion;
1610    } break;
1611    case 178 :
1612    {
1613      bg_xmul=lnumber_value(CAR(args)); args=CDR(args);
1614      bg_xdiv=lnumber_value(CAR(args)); args=CDR(args);
1615      bg_ymul=lnumber_value(CAR(args)); args=CDR(args);
1616      bg_ydiv=lnumber_value(CAR(args));
1617      if (bg_xdiv==0) { bg_xdiv=1; lprint(args); dprintf("bg_set_scroll : cannot set xdiv to 0\n"); }
1618      if (bg_ydiv==0) { bg_ydiv=1; lprint(args); dprintf("bg_set_scroll : cannot set ydiv to 0\n"); }
1619    } break;
1620    case 179 :
1621    {
1622      view *v=lget_view(CAR(args),"set_ambient_light");       args=CDR(args);
1623      int32_t x=lnumber_value(CAR(args));
1624      if (x>=0 && x<64) v->ambient=x;
1625    } break;
1626    case 180 : return lget_view(CAR(args),"ambient_light")->ambient; break;
1627    case 181 :
1628    {
1629      int x=current_object->total_objects();
1630      game_object *who=(game_object *)lpointer_value(CAR(args));
1631      for (int i=0;i<x;i++)
1632        if (current_object->get_object(i)==who) return 1;
1633      return 0;
1634    } break;
1635    case 182 : current_object->change_type(lnumber_value(CAR(args))); break;
1636    case 184 : return current_object->current_frame; break;
1637
1638    case 185 : return current_object->fx(); break;
1639    case 186 : return current_object->fy(); break;
1640    case 187 : return current_object->fxvel(); break;
1641    case 188 : return current_object->fyvel(); break;
1642    case 189 : return current_object->fxacel(); break;
1643    case 190 : return current_object->fyacel(); break;
1644    case 191 :
1645    {
1646//      char *fn=lstring_value(CAR(args)); args=CDR(args);
1647//      stat_bar=cache.reg_object(fn,CAR(args),SPEC_IMAGE,1);
1648    } break;
1649    case 192 :
1650    {
1651      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1652      int32_t y=lnumber_value(CAR(args)); args=CDR(args);
1653      int32_t type=lnumber_value(CAR(args));
1654      if (x<0 || y<0 || x>=current_level->foreground_width() || y>=current_level->foreground_width())
1655        lbreak("%d %d is out of range of fg map",x,y);
1656      else   
1657        current_level->put_fg(x,y,type);
1658    } break;
1659    case 193 :
1660    {
1661      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1662      int32_t y=lnumber_value(CAR(args));
1663      if (x<0 || y<0 || x>=current_level->foreground_width() || y>=current_level->foreground_width())
1664        lbreak("%d %d is out of range of fg map",x,y);
1665      else return current_level->get_fg(x,y);
1666    } break;
1667    case 194 :
1668    {
1669      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1670      int32_t y=lnumber_value(CAR(args)); args=CDR(args);
1671      int32_t type=lnumber_value(CAR(args));
1672      if (x<0 || y<0 || x>=current_level->background_width() || y>=current_level->background_width())
1673        lbreak("%d %d is out of range of fg map",x,y);
1674      else   
1675        current_level->put_bg(x,y,type);
1676    } break;
1677    case 195 :
1678    {
1679      int32_t x=lnumber_value(CAR(args)); args=CDR(args);
1680      int32_t y=lnumber_value(CAR(args));
1681      if (x<0 || y<0 || x>=current_level->background_width() || y>=current_level->background_width())
1682        lbreak("%d %d is out of range of fg map",x,y);
1683      else return current_level->get_bg(x,y);
1684    } break;
1685    case 196 : load_tiles(args); break;
1686    case 197 :
1687    {
1688      bFILE *fp=open_file(lstring_value(CAR(args)),"rb");
1689      if (fp->open_failure())
1690      {
1691    delete fp;
1692        lbreak("load_palette : could not open file %s for reading",lstring_value(CAR(args)));
1693    exit(1);
1694      } else
1695      {
1696    spec_directory sd(fp);
1697    spec_entry *se=sd.find(SPEC_PALETTE);
1698    if (!se) lbreak("File %s has no palette!\n",lstring_value(CAR(args)));
1699    else
1700    {
1701      if (pal) delete pal;
1702      pal=new palette(se,fp);
1703    }
1704    delete fp;
1705      }
1706    } break;
1707    case 198 :
1708    {
1709      bFILE *fp=open_file(lstring_value(CAR(args)),"rb");
1710      if (fp->open_failure())
1711      {
1712    delete fp;
1713        lbreak("load_color_filter : could not open file %s for reading",lstring_value(CAR(args)));
1714    exit(1);
1715      } else
1716      {
1717    spec_directory sd(fp);
1718    spec_entry *se=sd.find(SPEC_COLOR_TABLE);
1719    if (!se) lbreak("File %s has no color filter!",lstring_value(CAR(args)));
1720    else
1721    {
1722      if (color_table) delete color_table;
1723      color_table=new color_filter(se,fp);
1724    }
1725    delete fp;
1726      }
1727    } break;
1728    case 199 :
1729    {
1730      current_start_type=lnumber_value(CAR(args));
1731      set_local_players(1);
1732    } break;
1733    case 200 :
1734    {
1735      int32_t xv=lnumber_value(CAR(args));  args=CDR(args);
1736      int32_t yv=lnumber_value(CAR(args));  args=CDR(args);
1737      int top=2;
1738      if (args)
1739        if (!CAR(args)) top=0;
1740
1741      int32_t oxv=xv,oyv=yv;
1742      current_object->try_move(current_object->x,current_object->y,xv,yv,1|top);
1743      current_object->x+=xv;
1744      current_object->y+=yv;
1745      return (oxv==xv && oyv==yv);
1746    } break;
1747    case 201 :
1748    {
1749      int32_t x=lnumber_value(CAR(args));
1750      return figures[current_object->otype]->get_sequence((character_state)x)->length();
1751    } break;
1752    case 202 :
1753    {
1754      int32_t x1=lnumber_value(CAR(args)); args=CDR(args);
1755      int32_t y1=lnumber_value(CAR(args)); args=CDR(args);
1756      int32_t x2=lnumber_value(CAR(args)); args=CDR(args);
1757      int32_t y2=lnumber_value(CAR(args)); args=CDR(args);
1758      void *block_all=CAR(args);
1759      int32_t nx2=x2,ny2=y2;
1760      current_level->foreground_intersect(x1,y1,x2,y2);
1761      if (x2!=nx2 || y2!=ny2) return 0;
1762
1763      if (block_all)
1764        current_level->all_boundary_setback(current_object,x1,y1,x2,y2);
1765      else
1766        current_level->boundary_setback(current_object,x1,y1,x2,y2);
1767      return (x2==nx2 && y2==ny2);
1768
1769    } break;
1770    case 203 :
1771    {
1772      char *fn=lstring_value(CAR(args)); args=CDR(args);
1773      char *name=lstring_value(CAR(args));
1774      big_font_pict=cache.reg(fn,name,SPEC_IMAGE,1);
1775    } break;
1776    case 204 :
1777    {
1778      char *fn=lstring_value(CAR(args)); args=CDR(args);
1779      char *name=lstring_value(CAR(args));
1780      small_font_pict=cache.reg(fn,name,SPEC_IMAGE,1);
1781    } break;
1782    case 205 :
1783    {
1784      char *fn=lstring_value(CAR(args)); args=CDR(args);
1785      char *name=lstring_value(CAR(args));
1786      console_font_pict=cache.reg(fn,name,SPEC_IMAGE,1);
1787    } break;
1788    case 206 :
1789    {
1790      int32_t x=lnumber_value(CAR(args));
1791      if (x<current_object->total_frames())
1792        current_object->current_frame=x;
1793      else
1794    lbreak("%d out of range for set_current_frame",x);
1795    } break;
1796
1797    case 208 :
1798    {
1799      current_object->draw_trans(lnumber_value(CAR(args)),lnumber_value(CAR(CDR(args))));
1800    } break;
1801    case 209 :
1802    {
1803      current_object->draw_tint(lnumber_value(CAR(args)));
1804    } break;
1805    case 210 :
1806    {
1807      current_object->draw_predator();
1808    } break;
1809    case 211:
1810    { return lget_view(CAR(args),"shift_down")->shift_right; } break;
1811    case 212:
1812    { return lget_view(CAR(args),"shift_right")->shift_down; } break;
1813    case 213 :
1814    { view *v=lget_view(CAR(args),"set_no_scroll_range"); args=CDR(args);
1815      v->no_xleft=lnumber_value(CAR(args)); args=CDR(args);
1816      v->no_ytop=lnumber_value(CAR(args));  args=CDR(args);
1817      v->no_xright=lnumber_value(CAR(args)); args=CDR(args);
1818      v->no_ybottom=lnumber_value(CAR(args));
1819    } break;
1820    case 215 :
1821    {
1822      char *fn=lstring_value(CAR(args)); args=CDR(args);
1823      char *name=lstring_value(CAR(args)); args=CDR(args);
1824      return cache.reg(fn,name,SPEC_IMAGE,1);
1825    } break;
1826    case 216 :
1827    {
1828      int32_t x1=lnumber_value(CAR(args)); args=lcdr(args);
1829      int32_t y1=lnumber_value(CAR(args)); args=lcdr(args);
1830      int32_t id=lnumber_value(CAR(args));
1831      cache.img(id)->put_image(screen,x1,y1,1);
1832    } break;
1833    case 217 :
1834    {
1835      view *v=current_object->controller();
1836      if (!v) lbreak("object has no view : view_x1");
1837      else return v->cx1;
1838    } break;
1839    case 218 :
1840    {
1841      view *v=current_object->controller();
1842      if (!v) lbreak("object has no view : view_x1");
1843      else return v->cy1;
1844    } break;
1845    case 219 :
1846    {
1847      view *v=current_object->controller();
1848      if (!v) lbreak("object has no view : view_x1");
1849      else return v->cx2;
1850    } break;
1851    case 220 :
1852    {
1853      view *v=current_object->controller();
1854      if (!v) lbreak("object has no view : view_x1");
1855      else return v->cy2;
1856    } break;
1857    case 221 :
1858    {
1859      view *v=current_object->controller();
1860      if (!v) lbreak("object has no view : view_push_down");
1861      else v->last_y-=lnumber_value(CAR(args));
1862    } break;
1863    case 222 :
1864    {
1865      view *v=current_object->controller();
1866      if (!v) lbreak("object has no view : local_player");
1867      else return v->local_player();
1868    } break;
1869    case 223 :
1870    {
1871      char *fn=lstring_value(CAR(args));
1872      current_level->save(fn,1);
1873    } break;
1874    case 224 :
1875    {
1876      current_object->set_hp(lnumber_value(CAR(args)));
1877    } break;
1878    case 225 :
1879    {
1880      char fn[255];
1881      // If a save filename is requested, prepend the savegame directory.
1882      if( strncmp( lstring_value( CAR(args) ), "save", 4 ) == 0 )
1883      {
1884        sprintf( fn, "%s%s", get_save_filename_prefix(), lstring_value( CAR(args) ) );
1885      }
1886      else
1887      {
1888        strcpy( fn, lstring_value(CAR(args)) );
1889      }
1890      the_game->request_level_load(fn);
1891    } break;
1892    case 226 :
1893    {
1894      strcpy(level_file,lstring_value(CAR(args)));
1895    } break;
1896    case 227 :
1897    {
1898      return cache.reg(lstring_value(CAR(args)),"palette",SPEC_PALETTE,1);
1899    } break;
1900    case 228 :
1901    {
1902      palette *p=pal->copy();
1903      uint8_t *addr=(uint8_t *)p->addr();
1904      int r,g,b;
1905      int ra=lnumber_value(CAR(args)); args=CDR(args);
1906      int ga=lnumber_value(CAR(args)); args=CDR(args);
1907      int ba=lnumber_value(CAR(args));
1908      for (int i=0;i<256;i++)
1909      {
1910    r=(int)*addr+ra; if (r>255) r=255; else if (r<0) r=0; *addr=(uint8_t)r; addr++;
1911    g=(int)*addr+ga; if (g>255) g=255; else if (g<0) g=0; *addr=(uint8_t)g; addr++;
1912    b=(int)*addr+ba; if (b>255) b=255; else if (b<0) b=0; *addr=(uint8_t)b; addr++;
1913      }
1914      p->load();
1915      delete p;
1916    } break;
1917    case 229 :
1918    {
1919      view *v=current_object->controller();
1920      if (!v) lbreak("object has no view : local_player");
1921      else return v->player_number;
1922    } break;
1923    case 230 :
1924    {
1925      view *v=current_object->controller();
1926      if (!v) lbreak("object has no view : local_player");
1927      else
1928      {
1929    int32_t x=lnumber_value(CAR(args));
1930    if (x<0 || x>=total_weapons)
1931    { lbreak("weapon out of range (%d)\n",x); exit(0); }
1932    v->current_weapon=x;   
1933      }
1934    } break;
1935    case 231 :
1936    {
1937      view *v=current_object->controller();
1938      if (!v) lbreak("object has no view : local_player");
1939      else return v->has_weapon(lnumber_value(CAR(args)));
1940    } break;
1941    case 232 :
1942    {
1943      ambient_ramp+=lnumber_value(CAR(args));
1944    } break;
1945
1946    case 233 :
1947    { int x=0; view *v=player_list; for (;v;v=v->next,x++); return x; } break;
1948
1949    case 234 :
1950    {
1951      int32_t cx1,x1=lnumber_value(CAR(args)); args=lcdr(args);
1952      int32_t cy1,y1=lnumber_value(CAR(args)); args=lcdr(args);
1953      int32_t cx2,x2=lnumber_value(CAR(args)); args=lcdr(args);
1954      int32_t cy2,y2=lnumber_value(CAR(args)); args=lcdr(args);
1955      int32_t c=lnumber_value(CAR(args)); args=lcdr(args);
1956      int32_t s=lnumber_value(CAR(args));
1957      the_game->game_to_mouse(x1,y1,current_view,cx1,cy1);
1958      the_game->game_to_mouse(x2,y2,current_view,cx2,cy2);
1959      scatter_line(cx1,cy1,cx2,cy2,c,s);
1960      return 1;
1961
1962    } break;
1963    case 235 :
1964    { if (current_level) return current_level->tick_counter();
1965      else return 0; } break;
1966    case 236 :
1967    {
1968      return current_object->controller()!=NULL;
1969    } break;
1970    case 237 :
1971    {
1972      rand_on+=lnumber_value(CAR(args)); return 1;
1973    } break;
1974    case 238 :
1975    {
1976      return current_object->total_frames();
1977    } break;
1978    case 239 :
1979    { current_level->to_front(current_object); } break;
1980    case 240 :
1981    { current_level->to_back(current_object); } break;
1982    case 241 :
1983    {
1984      view *v=current_object->controller();
1985      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1986      else return v->pointer_x;
1987    } break;
1988    case 242 :
1989    {
1990      view *v=current_object->controller();
1991      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
1992      else return v->pointer_y;
1993    } break;
1994    case 243 :
1995    {
1996      if (player_list->next || demo_man.current_state()!=demo_manager::NORMAL)
1997        return 0;
1998      else
1999        return (frame_panic>10);
2000    } break;
2001    case 244 :
2002    {
2003      int32_t cx1,x1=lnumber_value(CAR(args)); args=lcdr(args);
2004      int32_t cy1,y1=lnumber_value(CAR(args)); args=lcdr(args);
2005      int32_t cx2,x2=lnumber_value(CAR(args)); args=lcdr(args);
2006      int32_t cy2,y2=lnumber_value(CAR(args)); args=lcdr(args);
2007      int32_t c1=lnumber_value(CAR(args)); args=lcdr(args);
2008      int32_t c2=lnumber_value(CAR(args)); args=lcdr(args);
2009      int32_t s=lnumber_value(CAR(args));
2010      the_game->game_to_mouse(x1,y1,current_view,cx1,cy1);
2011      the_game->game_to_mouse(x2,y2,current_view,cx2,cy2);
2012      ascatter_line(cx1,cy1,cx2,cy2,c1,c2,s);
2013      return 1;
2014
2015    } break;
2016    case 245 :
2017    {
2018      return rand_on;
2019    } break;
2020    case 246 :
2021    {
2022      rand_on=lnumber_value(CAR(args));
2023    } break;
2024    case 247 :
2025    {
2026      int32_t cx1=lnumber_value(CAR(args)); args=lcdr(args);
2027      int32_t cy1=lnumber_value(CAR(args)); args=lcdr(args);
2028      int32_t cx2=lnumber_value(CAR(args)); args=lcdr(args);
2029      int32_t cy2=lnumber_value(CAR(args)); args=lcdr(args);
2030      int32_t c1=lnumber_value(CAR(args)); args=lcdr(args);
2031      screen->bar(cx1,cy1,cx2,cy2,c1);
2032    } break;
2033    case 248 :
2034    {
2035      return start_argc;
2036    } break;
2037    case 249 :
2038    {
2039      if ((sound_avail&MUSIC_INITIALIZED))
2040      {
2041    char *fn=lstring_value(CAR(args));
2042    if (current_song)
2043    {
2044      if (current_song->playing())
2045      current_song->stop();
2046      delete current_song;
2047    }
2048    current_song=new song(fn);
2049    current_song->play(music_volume);
2050    dprintf("Playing %s at volume %d\n",fn,music_volume);
2051      }
2052    } break;
2053    case 250 :
2054    {
2055      if (current_song && current_song->playing())
2056        current_song->stop();
2057      delete current_song;
2058      current_song=NULL;
2059    } break;
2060    case 251 : return current_object->targetable(); break;
2061    case 252 : current_object->set_targetable( CAR(args)==NULL ? 0 : 1); break;
2062    case 253 : show_stats(); break;
2063    case 254 :
2064    {
2065      view *v=current_object->controller();
2066      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2067      else return v->kills;
2068    } break;
2069    case 255 :
2070    {
2071      view *v=current_object->controller();
2072      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2073      else return v->tkills;
2074    } break;
2075    case 256 :
2076    {
2077      view *v=current_object->controller();
2078      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2079      else return v->secrets;
2080    } break;
2081    case 257 :
2082    {
2083      view *v=current_object->controller();
2084      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2085      else return v->tsecrets;
2086    } break;
2087    case 258 :
2088    {
2089      view *v=current_object->controller();
2090      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2091      else v->kills=lnumber_value(CAR(args));
2092    } break;
2093    case 259 :
2094    {
2095      view *v=current_object->controller();
2096      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2097      else v->tkills=lnumber_value(CAR(args));
2098    } break;
2099    case 260 :
2100    {
2101      view *v=current_object->controller();
2102      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2103      else v->secrets=lnumber_value(CAR(args));
2104    } break;
2105    case 261 :
2106    {
2107      view *v=current_object->controller();
2108      if (!v) { lprint(args); printf("get_player_inputs : object has no view!\n"); }
2109      else v->tsecrets=lnumber_value(CAR(args));
2110    } break;
2111    case 262 :
2112    {
2113      the_game->request_end();
2114    } break;
2115    case 263 :
2116    {
2117      the_game->reset_keymap();
2118      return load_game(1,symbol_str("SAVE")); //get_save_spot(); shit
2119    } break;
2120    case 264 :
2121    {
2122      printf("mem_report is deprecated\n");
2123    } break;
2124    case 265 :
2125    {
2126      return ENGINE_MAJOR;
2127    } break;
2128    case 266 :
2129    {
2130      return ENGINE_MINOR;
2131    } break;
2132    case 267 :
2133    {
2134      current_object->draw_double_tint(lnumber_value(CAR(args)),lnumber_value(CAR(CDR(args))));
2135    } break;
2136    case 268 :
2137    {
2138      return cache.img(lnumber_value(CAR(args)))->width();
2139    } break;
2140    case 269 :
2141    {
2142      return cache.img(lnumber_value(CAR(args)))->height();
2143    } break;
2144    case 270 :
2145    {
2146      return current_level->foreground_width();
2147    } break;
2148    case 271 :
2149    {
2150      return current_level->foreground_height();
2151    } break;
2152    case 272 :
2153    {
2154      return current_level->background_width();
2155    } break;
2156    case 273 :
2157    {
2158      return current_level->background_height();
2159    } break;
2160    case 274 :
2161    {
2162      return get_keycode(lstring_value(CAR(args)));
2163    }
2164    case 275 :
2165    {
2166      int id=lnumber_value(CAR(args));  args=CDR(args);
2167      int x=lnumber_value(CAR(args));  args=CDR(args);
2168      int y=lnumber_value(CAR(args));
2169      c_target=id;
2170      if (screen)
2171        wm->set_mouse_shape(cache.img(c_target)->copy(),x,y);
2172    } break;
2173    case 276 :
2174    {
2175      if (!main_net_cfg) return 0;
2176      return become_server(game_name);
2177    } break;
2178    case 277 :
2179    {
2180      JCFont *fnt=(JCFont *)lpointer_value(CAR(args)); args=CDR(args);
2181      int32_t x=lnumber_value(CAR(args));       args=CDR(args);
2182      int32_t y=lnumber_value(CAR(args));       args=CDR(args);
2183      char *st=lstring_value(CAR(args));     args=CDR(args);
2184      int color=-1;
2185      if (args)
2186        color=lnumber_value(CAR(args));
2187      fnt->put_string(screen,x,y,st,color);
2188    } break;
2189    case 278 : return ((JCFont *)lpointer_value(CAR(args)))->width(); break;
2190    case 279 : return ((JCFont *)lpointer_value(CAR(args)))->height(); break;
2191    case 280 : if (chat) chat->put_all(lstring_value(CAR(args))); break;
2192    case 281 :
2193    {
2194      view *v=current_object->controller();
2195      if (!v) { lbreak("get_player_name : object has no view!\n"); }
2196      else strcpy(v->name,lstring_value(CAR(args)));
2197    } break;
2198    case 282 :
2199    {
2200      int32_t x1=lnumber_value(CAR(args));   args=CDR(args);
2201      int32_t y1=lnumber_value(CAR(args));   args=CDR(args);
2202      int32_t x2=lnumber_value(CAR(args));   args=CDR(args);
2203      int32_t y2=lnumber_value(CAR(args));   args=CDR(args);
2204      int32_t c=lnumber_value(CAR(args));
2205      screen->bar(x1,y1,x2,y2,c);
2206    } break;
2207    case 283 :
2208    {
2209      int32_t x1=lnumber_value(CAR(args));   args=CDR(args);
2210      int32_t y1=lnumber_value(CAR(args));   args=CDR(args);
2211      int32_t x2=lnumber_value(CAR(args));   args=CDR(args);
2212      int32_t y2=lnumber_value(CAR(args));   args=CDR(args);
2213      int32_t c=lnumber_value(CAR(args));
2214      screen->rectangle(x1,y1,x2,y2,c);
2215    } break;
2216    case 284 :
2217    {
2218      if (get_option(lstring_value(CAR(args))))
2219        return 1;
2220      else return 0;
2221    } break;
2222    case 288 :
2223    {
2224      if (CAR(args)) the_game->set_delay(1); else the_game->set_delay(0);
2225    } break;
2226    case 289 :
2227    {
2228      set_login(lstring_value(CAR(args)));
2229    } break;
2230    case 290 :
2231    {
2232      chatting_enabled=1;
2233    } break;
2234    case 291 :
2235    {
2236      demo_start=1;
2237    } break;
2238    case 292 :
2239    {
2240      if (main_net_cfg && main_net_cfg->state==net_configuration::CLIENT)
2241        return 1;
2242    } break;
2243    case 293 :
2244    {
2245      if (main_net_cfg && (main_net_cfg->state==net_configuration::CLIENT || main_net_cfg->state==net_configuration::SERVER))
2246      {
2247    view *v=player_list;
2248    for (;v;v=v->next)
2249       if (v->kills>=main_net_cfg->kills)
2250         return 1;
2251   
2252
2253      } else return 0;
2254    } break;
2255    case 294 :
2256    {
2257      view *v=player_list;
2258      for (;v;v=v->next)
2259      {
2260    v->tkills+=v->kills;
2261
2262        v->kills=0;
2263    game_object *o=current_object;
2264    current_object=v->focus;
2265
2266    eval_function((LispSymbol *)l_restart_player,NULL);
2267    v->reset_player();
2268    v->focus->set_aistate(0);
2269    current_object=o;   
2270      }
2271
2272    } break;
2273    case 295 :
2274    {
2275      strncpy(game_name,lstring_value(CAR(args)),sizeof(game_name));
2276      game_name[sizeof(game_name)-1]=0;
2277
2278    } break;
2279    case 296 :
2280    {
2281      if (main_net_cfg)
2282        main_net_cfg->min_players=lnumber_value(CAR(args));
2283    } break;
2284    case 1001: // (set_object_tint)
2285      if(current_object->Controller)
2286        current_object->Controller->set_tint(lnumber_value(CAR(args)));
2287      else
2288        current_object->set_tint(lnumber_value(CAR(args)));
2289      break;
2290    case 1002: //(get_object_tint)
2291      if(current_object->Controller)
2292        return current_object->Controller->get_tint();
2293      else
2294        return current_object->get_tint();
2295      break;
2296    case 1003: //(set_object_team)
2297      if(current_object->Controller)
2298        current_object->Controller->set_team(lnumber_value(CAR(args)));
2299      else
2300        current_object->set_team(lnumber_value(CAR(args)));
2301      break;
2302    case 1004: //(get_object_team)
2303      if(current_object->Controller)
2304        return current_object->Controller->get_team();
2305      else
2306        return current_object->get_team();
2307      break;
2308    default :
2309      printf("Undefined c function %ld\n",number);
2310      return 0;
2311  }
2312  return 0;
2313}
2314
2315int get_lprop_number(void *symbol, int def)  // returns def if symbol undefined or not number type
2316{
2317  void *v=symbol_value(symbol);
2318  if (v)
2319  {
2320    switch (item_type(v))
2321    {
2322      case L_FIXED_POINT :
2323      case L_NUMBER :
2324      { return lnumber_value(v); } break;
2325      default : return def;       
2326    }
2327  } else return def;
2328}
2329
2330
Note: See TracBrowser for help on using the repository browser.