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