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

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