ucinternal.h

Go to the documentation of this file.
00001 /*
00002  *  ucinternal.h - Interpreter for usecode.
00003  *
00004  *  Usecode_internal is the implementation, so this header should only
00005  *  be included within .cc's in the 'usecode' directory.
00006  *
00007  *
00008  *  Copyright (C) 2001-2002  The Exult Team
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023  */
00024 
00025 #ifndef _UCINTERNAL_H
00026 #define _UCINTERNAL_H
00027 
00028 #ifndef ALPHA_LINUX_CXX
00029 #  include <iosfwd>
00030 #endif
00031 
00032 #include "exult_types.h"
00033 
00034 class Actor;
00035 class Barge_object;
00036 class Npc_actor;
00037 class Usecode_value;
00038 class Text_gump;
00039 class Vector;
00040 class Stack_frame;
00041 class Usecode_function;
00042 
00043 #include "useval.h"
00044 #include "ucmachine.h"
00045 #include "ucdebugging.h"
00046 #include "tiles.h"
00047 #include "vec.h"  // Includes STL vector.
00048 #include <string> // STL string
00049 #include <deque>
00050 
00051 /*
00052  *  Recursively look for a barge that an object is a part of, or on.
00053  *
00054  *  Output: ->barge if found, else 0.
00055  */
00056 
00057 Barge_object *Get_barge
00058   (
00059   Game_object *obj
00060   );
00061 
00062 #define USECODE_INTRINSIC_DECL(NAME)  Usecode_value UI_## NAME (int event,int intrinsic,int num_parms,Usecode_value parms[12])
00063 
00064 /*
00065  *  Here's our virtual machine for running usecode.
00066  */
00067 class Usecode_internal : public Usecode_machine
00068   {
00069           // I'th entry contains funs for ID's
00070           //    256*i + n.
00071   Exult_vector<Usecode_function*> funs[16];
00072   Exult_vector<Usecode_value> statics;  // Global persistent vars.
00073   std::deque<Stack_frame*> call_stack; // the call stack
00074   Stack_frame *frame;   // One intrinsic uses this for now...
00075   bool modified_map;    // We add/deleted/moved an object.
00076   unsigned long timers[20]; // Each has time in hours when set.
00077   int speech_track;   // Set/read by some intrinsics.
00078   Text_gump *book;    // Book/scroll being displayed.
00079   Game_object *caller_item; // Item this is being called on.
00080   Game_object_vector last_created;// Stack of last items created with 
00081           //   intrins. x24.
00082   Actor *path_npc;    // Last NPC in path_run_usecode().
00083   const char *user_choice;  // String user clicked on.
00084   bool found_answer;    // Did we already handle the 
00085           //   conversation option?
00086   Tile_coord saved_pos;   // For a couple SI intrinsics.
00087   char *String;     // The single string register.
00088   int telekenesis_fun;    // For next Usecode call from spell.
00089   void append_string(const char *txt);  // Append to string.
00090   void show_pending_text(); // Make sure user's seen all text.
00091   void show_book();   // "Say" book/scroll text.
00092   void say_string();    // "Say" the string.
00093   Usecode_value *stack;   // Stack.
00094   Usecode_value *sp;    // Stack ptr.  Grows upwards.
00095   void stack_error(int under);
00096   void push(Usecode_value& val);  // Push/pop stack.
00097   Usecode_value pop();
00098   void pushref(Game_object* obj); // Push itemref
00099   void pushi(long val);   // Push/pop integers.
00100   int popi();
00101           // Push/pop strings.
00102   void pushs(char *s);
00103           // Get ->obj. from 'itemref'.
00104   Game_object *get_item(Usecode_value& itemref);
00105           // "Safe" cast to Actor and Npc_actor.
00106   Actor *as_actor(Game_object *obj);
00107           // Get position.
00108   Tile_coord get_position(Usecode_value& itemref);
00109   /*
00110    *  Built-in usecode functions:
00111    */
00112   typedef Usecode_value (Usecode_internal::*UsecodeIntrinsicFn)(
00113     int event,int intrinsic,int num_parms,Usecode_value parms[12]);
00114 
00115   void show_npc_face(Usecode_value& arg1, Usecode_value& arg2,
00116               int slot = -1);
00117   void remove_npc_face(Usecode_value& arg1);
00118   void set_item_shape(Usecode_value& item_arg, Usecode_value& shape_arg);
00119   void set_item_frame(Game_object *item, int frame, int check_empty = 0,
00120               int set_rotated = 0);
00121   void add_dirty(Game_object *obj);
00122   void remove_item(Game_object *obj);
00123   Usecode_value get_party();
00124   void item_say(Usecode_value& objval, Usecode_value& strval);
00125   void activate_cached(Tile_coord pos);
00126   Usecode_value find_nearby(Usecode_value& objval,
00127     Usecode_value& shapeval, Usecode_value& qval,
00128               Usecode_value& mval);
00129   Usecode_value find_nearest(Usecode_value& objval,
00130       Usecode_value& shapeval, Usecode_value& unknown);
00131   Usecode_value find_direction(Usecode_value& from, Usecode_value& to);
00132   Usecode_value count_objects(Usecode_value& objval,
00133     Usecode_value& shapeval, Usecode_value& qualval,
00134             Usecode_value& frameval);
00135   Usecode_value get_objects(Usecode_value& objval,
00136     Usecode_value& shapeval, Usecode_value& qualval,
00137             Usecode_value& frameval);
00138   Usecode_value remove_party_items(Usecode_value& quantval,
00139     Usecode_value& shapeval, Usecode_value& qualval,
00140       Usecode_value& frameval, Usecode_value& flagval);
00141   Usecode_value add_party_items(Usecode_value& quantval,
00142     Usecode_value& shapeval, Usecode_value& qualval,
00143       Usecode_value& frameval, Usecode_value& flagval);
00144   Usecode_value add_cont_items(Usecode_value& container, Usecode_value& quantval,
00145     Usecode_value& shapeval, Usecode_value& qualval,
00146       Usecode_value& frameval, Usecode_value& flagval);
00147   Usecode_value remove_cont_items(Usecode_value& container, Usecode_value& quantval,
00148     Usecode_value& shapeval, Usecode_value& qualval,
00149       Usecode_value& frameval, Usecode_value& flagval);
00150 
00151   int path_run_usecode(Usecode_value& npcval, Usecode_value& locval,
00152     Usecode_value& useval, Usecode_value& itemval,
00153     Usecode_value& eventval, int find_free = 0, int always = 0);
00154   void create_script(Usecode_value& objval, Usecode_value& codeval,
00155                 long delay);
00156 
00157   /*
00158          *  Embedded intrinsics
00159    */
00160 
00161   static struct IntrinsicTableEntry
00162     {
00163     UsecodeIntrinsicFn  func;
00164     const char *name;
00165     } intrinsic_table[], serpent_table[];
00166   Usecode_value Execute_Intrinsic(UsecodeIntrinsicFn func,const char *name,int event,int intrinsic,int num_parms,Usecode_value parms[12]);
00167   USECODE_INTRINSIC_DECL(NOP);
00168   USECODE_INTRINSIC_DECL(UNKNOWN);
00169   USECODE_INTRINSIC_DECL(get_random);
00170   USECODE_INTRINSIC_DECL(execute_usecode_array);
00171   USECODE_INTRINSIC_DECL(delayed_execute_usecode_array);
00172   USECODE_INTRINSIC_DECL(show_npc_face);
00173   USECODE_INTRINSIC_DECL(remove_npc_face);
00174   USECODE_INTRINSIC_DECL(add_answer);
00175   USECODE_INTRINSIC_DECL(remove_answer);
00176   USECODE_INTRINSIC_DECL(push_answers);
00177   USECODE_INTRINSIC_DECL(pop_answers);
00178   USECODE_INTRINSIC_DECL(clear_answers);
00179   USECODE_INTRINSIC_DECL(select_from_menu);
00180   USECODE_INTRINSIC_DECL(select_from_menu2);
00181   USECODE_INTRINSIC_DECL(input_numeric_value);
00182   USECODE_INTRINSIC_DECL(set_item_shape);
00183   USECODE_INTRINSIC_DECL(find_nearest);
00184   USECODE_INTRINSIC_DECL(die_roll);
00185   USECODE_INTRINSIC_DECL(get_item_shape);
00186   USECODE_INTRINSIC_DECL(get_item_frame);
00187   USECODE_INTRINSIC_DECL(set_item_frame);
00188   USECODE_INTRINSIC_DECL(get_item_quality);
00189   USECODE_INTRINSIC_DECL(set_item_quality);
00190         USECODE_INTRINSIC_DECL(get_item_quantity);
00191         USECODE_INTRINSIC_DECL(set_item_quantity);
00192         USECODE_INTRINSIC_DECL(get_object_position);
00193   USECODE_INTRINSIC_DECL(get_distance);
00194         USECODE_INTRINSIC_DECL(find_direction);
00195         USECODE_INTRINSIC_DECL(get_npc_object);
00196         USECODE_INTRINSIC_DECL(get_schedule_type);
00197         USECODE_INTRINSIC_DECL(set_schedule_type);
00198         USECODE_INTRINSIC_DECL(add_to_party);
00199         USECODE_INTRINSIC_DECL(remove_from_party);
00200         USECODE_INTRINSIC_DECL(get_npc_prop);
00201         USECODE_INTRINSIC_DECL(set_npc_prop);
00202         USECODE_INTRINSIC_DECL(get_avatar_ref);
00203         USECODE_INTRINSIC_DECL(get_party_list);
00204         USECODE_INTRINSIC_DECL(create_new_object);
00205         USECODE_INTRINSIC_DECL(create_new_object2);
00206         USECODE_INTRINSIC_DECL(set_last_created);
00207         USECODE_INTRINSIC_DECL(update_last_created);
00208         USECODE_INTRINSIC_DECL(get_npc_name);
00209         USECODE_INTRINSIC_DECL(count_objects);
00210   USECODE_INTRINSIC_DECL(find_object);
00211         USECODE_INTRINSIC_DECL(get_cont_items);
00212         USECODE_INTRINSIC_DECL(remove_party_items);
00213         USECODE_INTRINSIC_DECL(add_party_items);
00214         USECODE_INTRINSIC_DECL(play_music);
00215         USECODE_INTRINSIC_DECL(npc_nearby);
00216   USECODE_INTRINSIC_DECL(npc_nearby2);
00217         USECODE_INTRINSIC_DECL(find_nearby_avatar);
00218         USECODE_INTRINSIC_DECL(is_npc);
00219         USECODE_INTRINSIC_DECL(display_runes);
00220         USECODE_INTRINSIC_DECL(click_on_item);
00221   USECODE_INTRINSIC_DECL(set_intercept_item);
00222         USECODE_INTRINSIC_DECL(find_nearby);
00223         USECODE_INTRINSIC_DECL(give_last_created);
00224   USECODE_INTRINSIC_DECL(is_dead);
00225         USECODE_INTRINSIC_DECL(game_hour);
00226         USECODE_INTRINSIC_DECL(game_minute);
00227   USECODE_INTRINSIC_DECL(get_npc_number);
00228   USECODE_INTRINSIC_DECL(part_of_day);
00229   USECODE_INTRINSIC_DECL(get_alignment);
00230   USECODE_INTRINSIC_DECL(set_alignment);
00231   USECODE_INTRINSIC_DECL(move_object);
00232   USECODE_INTRINSIC_DECL(remove_npc);
00233   USECODE_INTRINSIC_DECL(item_say);
00234   USECODE_INTRINSIC_DECL(clear_item_say);
00235   USECODE_INTRINSIC_DECL(projectile_effect);
00236   USECODE_INTRINSIC_DECL(get_lift);
00237   USECODE_INTRINSIC_DECL(set_lift);
00238   USECODE_INTRINSIC_DECL(get_weather);
00239   USECODE_INTRINSIC_DECL(set_weather);
00240   USECODE_INTRINSIC_DECL(sit_down);
00241   USECODE_INTRINSIC_DECL(summon);
00242   USECODE_INTRINSIC_DECL(display_map);
00243   USECODE_INTRINSIC_DECL(si_display_map);
00244   USECODE_INTRINSIC_DECL(kill_npc);
00245   USECODE_INTRINSIC_DECL(roll_to_win);
00246   USECODE_INTRINSIC_DECL(set_attack_mode);
00247   USECODE_INTRINSIC_DECL(get_attack_mode);
00248   USECODE_INTRINSIC_DECL(set_opponent);
00249   USECODE_INTRINSIC_DECL(clone);
00250   USECODE_INTRINSIC_DECL(get_oppressor);
00251   USECODE_INTRINSIC_DECL(set_oppressor);
00252   USECODE_INTRINSIC_DECL(get_weapon);
00253   USECODE_INTRINSIC_DECL(display_area);
00254   USECODE_INTRINSIC_DECL(wizard_eye);
00255   USECODE_INTRINSIC_DECL(resurrect);
00256   USECODE_INTRINSIC_DECL(get_body_npc);
00257   USECODE_INTRINSIC_DECL(add_spell);
00258   USECODE_INTRINSIC_DECL(sprite_effect);
00259   USECODE_INTRINSIC_DECL(obj_sprite_effect);
00260   USECODE_INTRINSIC_DECL(explode);
00261   USECODE_INTRINSIC_DECL(book_mode);
00262   USECODE_INTRINSIC_DECL(stop_time);
00263   USECODE_INTRINSIC_DECL(cause_light);
00264   USECODE_INTRINSIC_DECL(get_barge);
00265   USECODE_INTRINSIC_DECL(earthquake);
00266   USECODE_INTRINSIC_DECL(is_pc_female);
00267   USECODE_INTRINSIC_DECL(armageddon);
00268   USECODE_INTRINSIC_DECL(halt_scheduled);
00269   USECODE_INTRINSIC_DECL(lightning);
00270   USECODE_INTRINSIC_DECL(get_array_size);
00271   USECODE_INTRINSIC_DECL(mark_virtue_stone);
00272   USECODE_INTRINSIC_DECL(recall_virtue_stone);
00273   USECODE_INTRINSIC_DECL(apply_damage);
00274   USECODE_INTRINSIC_DECL(is_pc_inside);
00275   USECODE_INTRINSIC_DECL(get_timer);
00276   USECODE_INTRINSIC_DECL(set_timer);
00277   USECODE_INTRINSIC_DECL(wearing_fellowship);
00278   USECODE_INTRINSIC_DECL(mouse_exists);
00279   USECODE_INTRINSIC_DECL(get_speech_track);
00280   USECODE_INTRINSIC_DECL(flash_mouse);
00281   USECODE_INTRINSIC_DECL(get_item_frame_rot);
00282   USECODE_INTRINSIC_DECL(set_item_frame_rot);
00283   USECODE_INTRINSIC_DECL(on_barge);
00284   USECODE_INTRINSIC_DECL(get_container);
00285   USECODE_INTRINSIC_DECL(remove_item);
00286   USECODE_INTRINSIC_DECL(reduce_health);
00287   USECODE_INTRINSIC_DECL(is_readied);
00288   USECODE_INTRINSIC_DECL(get_readied);
00289   USECODE_INTRINSIC_DECL(restart_game);
00290   USECODE_INTRINSIC_DECL(start_speech);
00291   USECODE_INTRINSIC_DECL(is_water);
00292   USECODE_INTRINSIC_DECL(run_endgame);
00293   USECODE_INTRINSIC_DECL(fire_cannon);
00294   USECODE_INTRINSIC_DECL(nap_time);
00295   USECODE_INTRINSIC_DECL(advance_time);
00296   USECODE_INTRINSIC_DECL(in_usecode);
00297   USECODE_INTRINSIC_DECL(call_guards);
00298   USECODE_INTRINSIC_DECL(attack_avatar);
00299   USECODE_INTRINSIC_DECL(path_run_usecode);
00300   USECODE_INTRINSIC_DECL(close_gumps);
00301   USECODE_INTRINSIC_DECL(in_gump_mode);
00302   USECODE_INTRINSIC_DECL(is_not_blocked);
00303   USECODE_INTRINSIC_DECL(direction_from);
00304   USECODE_INTRINSIC_DECL(get_item_flag);
00305   USECODE_INTRINSIC_DECL(set_item_flag);
00306   USECODE_INTRINSIC_DECL(clear_item_flag);
00307   USECODE_INTRINSIC_DECL(set_path_failure);
00308   USECODE_INTRINSIC_DECL(fade_palette);
00309   USECODE_INTRINSIC_DECL(get_party_list2);
00310   USECODE_INTRINSIC_DECL(set_camera);
00311   USECODE_INTRINSIC_DECL(in_combat);
00312   USECODE_INTRINSIC_DECL(center_view);
00313   USECODE_INTRINSIC_DECL(get_dead_party);
00314   USECODE_INTRINSIC_DECL(play_sound_effect);
00315   USECODE_INTRINSIC_DECL(play_sound_effect2);
00316   USECODE_INTRINSIC_DECL(get_npc_id);
00317   USECODE_INTRINSIC_DECL(set_npc_id);
00318   USECODE_INTRINSIC_DECL(add_cont_items);
00319   USECODE_INTRINSIC_DECL(remove_cont_items);
00320           // Serpent Isle:
00321   USECODE_INTRINSIC_DECL(si_path_run_usecode);
00322   USECODE_INTRINSIC_DECL(remove_from_area);
00323   USECODE_INTRINSIC_DECL(infravision);
00324   USECODE_INTRINSIC_DECL(error_message);
00325   USECODE_INTRINSIC_DECL(set_polymorph);
00326   USECODE_INTRINSIC_DECL(show_npc_face0);
00327   USECODE_INTRINSIC_DECL(show_npc_face1);
00328   USECODE_INTRINSIC_DECL(remove_npc_face0);
00329   USECODE_INTRINSIC_DECL(remove_npc_face1);
00330   USECODE_INTRINSIC_DECL(set_conversation_slot);
00331   USECODE_INTRINSIC_DECL(init_conversation);
00332   USECODE_INTRINSIC_DECL(end_conversation);
00333   USECODE_INTRINSIC_DECL(set_new_schedules);
00334   USECODE_INTRINSIC_DECL(revert_schedule);
00335   USECODE_INTRINSIC_DECL(run_schedule);
00336   USECODE_INTRINSIC_DECL(modify_schedule);
00337   USECODE_INTRINSIC_DECL(get_temperature);
00338   USECODE_INTRINSIC_DECL(set_temperature);
00339 //  USECODE_INTRINSIC_DECL(add_removed_npc);
00340   USECODE_INTRINSIC_DECL(approach_avatar);
00341   USECODE_INTRINSIC_DECL(set_barge_dir);
00342   USECODE_INTRINSIC_DECL(telekenesis);
00343   USECODE_INTRINSIC_DECL(a_or_an);
00344   USECODE_INTRINSIC_DECL(add_to_keyring);
00345   USECODE_INTRINSIC_DECL(is_on_keyring);
00346   USECODE_INTRINSIC_DECL(save_pos);
00347   USECODE_INTRINSIC_DECL(teleport_to_saved_pos);
00348   USECODE_INTRINSIC_DECL(get_item_usability);
00349   USECODE_INTRINSIC_DECL(get_skin_colour);
00350   USECODE_INTRINSIC_DECL(printf);
00351 
00352   /*
00353    *  Other private methods:
00354    */
00355           // Call instrinsic function.
00356   Usecode_value call_intrinsic(int event, int intrinsic, int num_parms);
00357   void click_to_continue(); // Wait for user to click.
00358   void set_book(Text_gump *b);  // Set book/scroll to display.
00359   const char *get_user_choice();  // Get user's choice.
00360   int get_user_choice_num();
00361   void read_usevars(std::istream& in);  // Read static variables.
00362 
00363   Game_object *intercept_item;
00364   Game_object *temp_to_be_deleted;
00365 
00366   // execution functions
00367   bool call_function(int funcid, int event, Game_object *caller = 0,
00368          bool entrypoint = false, bool orig = false);
00369   void previous_stack_frame();
00370   void return_from_function(Usecode_value& retval);
00371   void return_from_procedure();
00372   void abort_function();
00373   int run();
00374 
00375   // debugging functions
00376   void uc_trace_disasm(Stack_frame* frame);
00377   void uc_trace_disasm(Usecode_value* locals, int num_locals,
00378              uint8* data, uint8* externals, uint8* code,
00379              uint8* ip);
00380   static int get_opcode_length(int opcode);
00381   void stack_trace(std::ostream& out);
00382 
00383 #ifdef USECODE_DEBUGGER
00384 
00385   Breakpoints breakpoints;
00386 
00387   bool on_breakpoint; // are we on a breakpoint?
00388   int breakpoint_action; // stay on breakpoint/continue/abort?
00389 
00390 public:
00391   bool is_on_breakpoint() const { return on_breakpoint; }
00392   void set_breakpoint_action(int a) { breakpoint_action = a; }
00393 
00394   void set_breakpoint();
00395   int set_location_breakpoint(int funcid, int ip);
00396   bool clear_breakpoint(int id) { return breakpoints.remove(id); }
00397 
00398   void transmit_breakpoints(int fd) { breakpoints.transmit(fd); }
00399 
00400   void dbg_stepover();
00401   void dbg_finish();
00402 
00403   int get_callstack_size() const;
00404   Stack_frame* get_stackframe(int i);
00405 
00406   int get_stack_size() const;
00407   Usecode_value* peek_stack(int depth) const;
00408   void poke_stack(int depth, Usecode_value& val);
00409 #endif
00410 public:
00411   friend class Usecode_script;
00412   Usecode_internal();
00413   ~Usecode_internal();
00414           // Read in usecode functions.
00415   virtual void read_usecode(std::istream& file, bool patch = false);
00416           // Call desired function.
00417   virtual int call_usecode(int id, Game_object *obj, 
00418               Usecode_events event);
00419   virtual void do_speech(int num);// Start speech, or show text.
00420   virtual int in_usecode()  // Currently in a usecode function?
00421     { return !call_stack.empty(); }
00422   virtual void write();   // Write out 'gamedat/usecode.dat'.
00423   virtual void read();    // Read in 'gamedat/usecode.dat'.
00424 
00425   virtual void intercept_click_on_item(Game_object *obj) 
00426     { intercept_item = obj; }
00427 
00428 };
00429 
00430 
00431 #endif

Generated on Mon Jul 9 14:42:52 2007 for ExultEngine by  doxygen 1.5.1