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

Last change on this file since 481 was 481, checked in by Sam Hocevar, 7 years ago

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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