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

Last change on this file since 524 was 524, checked in by Sam Hocevar, 11 years ago

core: Get rid of mostly useless headers, move endianness handling to
common.h (and rewrite functions so that they do not need the SDL headers)
and move a few functions out of sdlport's video.cpp. These functions
were in the original video.cpp (which reappears) and shouldn't be part
of the SDL port.

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