// // G A M E.O.N.E - LOW LEVEL LIB V1.0 // Copyright (C) 2001 LEVEL ONE ENTERTAINMENT, // Licensed under the terms of LGPL. //:--------------------------------------------------------------------------- //:Description // // BASE CLASS ACTOR, CROOT, CSTABACTION // // CActor : CStabAction, CRoot // // CActor // +--CRoot // // // CStabAction // +--CStabAction_SetPosition // +--CStabAction_SetViewAngle // +--CStabAction_SetGravity // +--CStabAction_SetGravityPtr // +--CStabAction_Wait // +--CStabAction_MSG // +--CStabAction_RotateTo // | +--CStabAction_RotateDir // | // +--CStabAction_ScaleTimed // +--CStabAction_FadeTimed // | // +--CStabAction_MoveTimed // | +--CStabAction_MoveTarget // | +--CStabAction_MoveDirection // | +--CStabAction_OffsetTimed // | +--CStabAction_OffsetTarget // | // +--CStabAction_MoveTimedEase // | // +--CStabAction_Label // +--CStabAction_JMP // +--CStabAction_KILL // #ifndef ACTOR_H #define ACTOR_H #include "../lib_base.h" #include "../llgfx.h" #include "../llqueue.h" #include "../llqueue_squeue.h" #include "../llqueue_dequeue.h" #include "../llqueue_str_array.h" #include "../ll3d_vec2.h" #include "../llgfx_blit.h" #include "../llfile.h" #include "../llmem.h" #include using namespace ll3d; // probs mit arm gcc? #define ITERATE_QUEUE(a,q) q.Reset();while(a=q.Next())// #define ITERATE_LIST(node,li) for(node=li.GetFirst();node;node=node->GetNext())// class CStabAction; class CRoot; class CActor { public: CActor(); CActor(int type); virtual ~CActor(); virtual void Action(float delta); virtual void Draw(llgfx_id id); virtual void SetPos(float x, float y); virtual void SetPos(int x, int y); int GetXPos() { return (int)m_position.m_u; }; int GetYPos() { return (int)m_position.m_v; }; virtual bool TestCollisionRect(CActor *actor_with); virtual bool TestCollisionCircle(CActor *actor_with); virtual void AddScore(int score); virtual bool Message(const char *Type); virtual void SendMsg(const char *msg); virtual CActor * IsActor( const char *name); // returned sich selbst wenn name entspricht virtual void SetDirectionD( float deg ); virtual void SetDirectionR( float rad ); virtual void InitTarget(float time, float target_x, float target_y ); virtual void InitTarget(float time, CVec2f &targetpos ); virtual void InitMove(float x_velocity, float y_velocity ); virtual void InitMove(CVec2f &targetpos, float velocity ); virtual bool MoveToTarget(float delta); // returned true wenn target erreicht virtual bool MoveToTarget(float delta, CVec2f ¤t_pos, CVec2f &target_pos, CVec2f &direction); virtual void Move(float delta); virtual void GetBoundingRect(llgfx_sRECT *rect); virtual void RotateModel(float angle); // winkel in radians virtual void RotateLocal(float angle); // winkel in radians float GetAngleToPoint(float x, float y); void InitTargetAngleD(float time, float new_angle); // newAngle in degree void InitTargetAngleR(float time, float new_angle); // newAngle in radians float GetViewAngleD(); float GetViewAngleR(); virtual bool RotateToTargetAngle(float delta); // return true wenn target angle erreicht void SetViewAngleD( float degree ); void PlusViewAngleD( float degree ); void MinusViewAngleD( float degree ); void PlusViewAngleR( float radians ); void MinusViewAngleR( float radians ); void SetViewAngleR( float radians ); void AddChild(CActor * actor ); void SetParent(CActor * actor ); void RemoveParent(); void RemoveChild(CActor * actor); squeue m_script; CStabAction * m_cur_script; squeue m_actions; queue m_childs; CActor *m_parent; // Wenn ungleich 0 dann muss drawchild() aufgerufen werden static CRoot *gl_root; // Root Actor CVec2f m_position; // Playfield Position CVec2f m_screen_pos; // Ziel Position (Bildschirm) CVec2f m_xyoffset; // Drawing Offset CVec2f m_target_position; // Ziel Playfield Position für move_target CVec2f m_direction; // Richtungsvektor CVec2f m_old_position; // Alte Playfield Position CVec2f m_scale; // x,y scale faktor float m_velocity; // Geschwindigkeit float m_acceleration; // Beschleunigung pro Sekunde float m_view_angle; // 0 = Zeigt nach oben float m_cos_radians; float m_sin_radians; float m_target_angle; // für RotateTo float m_rdir; // rotation float m_rtleft; // zeit übrig für zielrotation float m_health; // Anzahl Health float m_power; // Power bei Kollision int m_score; // Jeder Actor hat einen Score float m_lifetime; // Actor wird entfernt wenn lifetime unter 0 geht float m_radius; // Für Kollisionsabfrage llgfx_sRECT m_bounding_rect; // Für Kollisionsabfrage llgfx_sRECT m_position_rect; // posrect = m_boudingrect + m_position // Muss durch Action() gesetzt werden int m_blitflag; // blitflag llgfx_sBLITFX m_blitfx; // blitfx int m_type; // type für z.b. CreateUpdatePacket int m_id; // Für Kollision etc. // Object Typ Informationen // Jede Klasse die die Funktion Message ableitet muss // objtype und namen im Konstruktor setzen // Messagesyntax ist = "objname::*", * steht für die Message char m_obj_name[64]; // Objekt name oder Objekt nummer int m_obj_namelen; // länge des Obektnames virtual void ParseSkriptFile(const char *filename ); virtual void ParseLine( const char * line ); void ClearScript(); static float GetAngle(CActor *A, CActor *B); private: void Draw(); void ParseCCmds(const char * line ); void ParseFCmds(const char * line ); void ParseMCmds(const char * line ); void ParseJCmds(const char * line ); void ParseKCmds(const char * line ); void ParseOCmds(const char * line ); void ParseRCmds(const char * line ); void ParseSCmds(const char * line ); void ParseWCmds(const char * line ); void ParseLabel(const char * line ); }; #include "llfrm_varmgr.h" class CRoot : public CActor { public: CRoot(); virtual ~CRoot(); virtual int InitPlayfield(); virtual void SetNewState( const char * name ); virtual CRoot * CreateStateByName(const char * name) { return 0; } virtual CActor * FindActor( const char * name); virtual void InitState(const char *name); virtual void Action(float delta); virtual void Draw(llgfx_id id); virtual bool Message(const char * Type); virtual bool TranslateMsg(char * Msg, char type); virtual bool TranslateVar(char * Msg); const char * GetAlias(char * string); int Execute( const char * filename, const char *section ); int ExecuteMemory( char * memptr, char * endptr, const char *section ); CRoot * GetStateObject(); static void PostMsg(const char * Msg); static void HighPriMsg(const char * Msg); protected: /* ** Global objects */ static queue m_global_object_queue; static CRoot *m_current_state; static queue m_state_next; static llqueue_strarray m_aliaslist; static dequeue m_msg_queue; private: void SendMsg(const char * string); }; /* ** Script controlled Actor logic ** script commands can be one of these types: */ typedef enum { stab_MOVE_TIMED, // stab_MOVE_VELOCITY, stab_MOVE_DIRECTION, stab_OFFSET_TIMED, stab_OFFSET_VELOCITY, stab_LABEL, stab_WAIT, stab_MSG, stab_ROTATE_TIMED, stab_ROTATE_DIR, stab_SET_POSITION, stab_SET_GRAVITY, stab_SET_GRAVITY_PTR, stab_SET_VIEWANGLE, stab_SCALE_TIMED, stab_FADE_TIMED, stab_CLEAR, stab_JMP, stab_KILL, } actionType; class CStabAction { public: CStabAction(CActor * actor); virtual ~CStabAction(){} virtual void Init() = 0; virtual CStabAction* Action(float delta) = 0; virtual actionType GetType() = 0; bool IsBkgAction() { return m_bkgMove; } void SetBkgAction(bool val) { m_bkgMove = val; }; protected: CActor * m_actor; bool m_bkgMove; }; /* ** Standard Actor logic ** */ class CStabAction_SetPosition : public CStabAction { public: CVec2f m_position; void Init() { m_actor->m_position = m_position; } actionType GetType() { return stab_SET_POSITION; } CStabAction *Action(float delta){ return 0;} CStabAction_SetPosition( CActor * actor, CVec2f &position ) : CStabAction(actor) { m_position = position; } }; class CStabAction_SetViewAngle : public CStabAction { public: float m_viewangle; void Init() { m_actor->SetViewAngleD(m_viewangle); } actionType GetType() { return stab_SET_VIEWANGLE; } CStabAction *Action(float delta){ return 0;} CStabAction_SetViewAngle( CActor * actor, float viewangle ) : CStabAction(actor) { m_viewangle = viewangle; } }; class CStabAction_Wait : public CStabAction { public: float m_wait; float m_timer; void Init() { m_timer = m_wait; } actionType GetType() { return stab_WAIT; }; CStabAction *Action(float delta){ m_timer -= delta; if( m_timer < 0 ) return 0; else return this;} CStabAction_Wait( CActor *actor, float wait) : CStabAction(actor) { m_wait = wait; } }; class CStabAction_MoveTimed : public CStabAction { public: float m_votime; CVec2f m_target; void Init() { m_actor->InitTarget( m_votime, m_target ); m_actor->m_velocity = 1; } actionType GetType() { return stab_MOVE_TIMED; }; CStabAction* Action(float delta){ if(m_actor->MoveToTarget(delta)) return 0; else return this;} CStabAction_MoveTimed( CActor *actor, float time, CVec2f &target ) : CStabAction(actor) { m_votime = time; m_target = target; } }; class CStabAction_MoveTimedEase : public CStabAction { public: float m_t; // time counter float m_votime; // total time CVec2f m_target; // Target float m_damp; // damping faktor float m_etime; // Ease time CVec2f m_direction_sav; // direction vector copy void Init() { m_actor->InitTarget( m_votime, m_target ); m_direction_sav = m_actor->m_direction; } actionType GetType() { return stab_MOVE_TIMED; }; CStabAction* Action(float delta){ m_t += delta; if( m_t >= m_etime ){ m_actor->m_direction -= (m_direction_sav * m_damp) * delta; } if(m_actor->MoveToTarget(delta)) return 0; else return this; } CStabAction_MoveTimedEase( CActor *actor, float time, CVec2f &target, float etime, float damp ) : CStabAction(actor) { m_votime = time; m_target = target; m_etime = etime; m_damp = damp; m_t = 0; } }; class CStabAction_MoveTarget : public CStabAction_MoveTimed { public: void Init() { m_actor->InitMove( m_target, m_votime );} actionType GetType() { return stab_MOVE_VELOCITY; }; CStabAction_MoveTarget(CActor * actor, float velocity, CVec2f &target ) : CStabAction_MoveTimed( actor, velocity, target) { } }; class CStabAction_MoveDirection : public CStabAction_MoveTimed { public: void Init() { CVec2f target = m_actor->m_position + m_target; m_actor->InitMove( target, m_votime ); }; actionType GetType() { return stab_MOVE_DIRECTION; }; CStabAction* Action(float delta){ m_actor->Move(delta); return this; }; CStabAction_MoveDirection(CActor * actor, float velocity, CVec2f &target ) : CStabAction_MoveTimed( actor, velocity, target) { } }; class CStabAction_OffsetTimed : public CStabAction_MoveTimed { public: void Init() { CVec2f ipos = m_actor->m_position + m_target; m_actor->InitTarget( m_votime, ipos ); m_actor->m_velocity = 1; } actionType GetType() { return stab_OFFSET_TIMED; }; CStabAction_OffsetTimed( CActor *actor, float time, CVec2f &target ) : CStabAction_MoveTimed(actor,time,target) { } }; class CStabAction_OffsetTarget : public CStabAction_MoveTimed { public: void Init() { CVec2f ipos = m_actor->m_position + m_target; m_actor->InitMove( ipos, m_votime ); } actionType GetType() { return stab_OFFSET_VELOCITY; }; CStabAction_OffsetTarget(CActor * actor, float velocity, CVec2f &target ) : CStabAction_MoveTimed( actor, velocity, target) { } }; class CStabAction_Label : public CStabAction { public: char * m_label; void Init() {}; actionType GetType() { return stab_LABEL; } CStabAction* Action(float delta) { return 0; } CStabAction_Label( CActor * actor, const char * labelname ) : CStabAction(actor) { m_label = strdup(labelname); } ~CStabAction_Label() { if( m_label ) free(m_label); } }; class CStabAction_Kill : public CStabAction { public: void Init() {}; actionType GetType() { return stab_KILL; } CStabAction* Action(float delta) { m_actor->m_lifetime = 0.0f; return 0; } CStabAction_Kill( CActor * actor) : CStabAction(actor) { } }; //class CStabAction_Clear : public CStabAction //{ //public: // void Init() {}; // actionType GetType() { return stab_CLEAR; } // CStabAction* Action(float delta){ CActor *dsave = m_actor; dsave->ClearScript(); dsave->ClearActions(); return 0; } // // CStabAction_Clear( CActor * actor) // : CStabAction(actor){} //}; class CStabAction_JMP : public CStabAction_Label { public: actionType GetType() { return stab_JMP; }; CStabAction* Action(float delta) { m_actor->m_script.Reset(); while( CStabAction * E = m_actor->m_script.Next() ) { if( E->GetType() == stab_LABEL ) { if( 0 == strcmp( m_label, ((CStabAction_Label*)E)->m_label ) ) { return 0; } } } return 0; }; CStabAction_JMP( CActor *actor, char * label ) : CStabAction_Label(actor, label) { } }; class CStabAction_MSG : public CStabAction { public: char * m_msg; void Init() { } actionType GetType() { return stab_MSG; }; CStabAction *Action(float delta){ m_actor->SendMsg(m_msg); return 0; } CStabAction_MSG( CActor *actor, char *msg) : CStabAction(actor) { m_msg = strdup(msg); } ~CStabAction_MSG() { if( m_msg ) free(m_msg); } }; class CStabAction_RotateTo : public CStabAction { public: float m_time; float m_target_angle; void Init() { m_actor->InitTargetAngleD(m_time,m_target_angle); } actionType GetType() { return stab_ROTATE_TIMED; }; CStabAction *Action(float delta){ if( m_actor->RotateToTargetAngle(delta)) return 0; else return this; } CStabAction_RotateTo( CActor *actor, float angle, float time) : CStabAction(actor) { m_target_angle = angle; m_time = time; } }; class CStabAction_RotateDir : public CStabAction_RotateTo { public: float m_time_left; void Init() { m_time_left = m_time; } actionType GetType() { return stab_ROTATE_DIR; } CStabAction *Action(float delta) { m_time_left -= delta; if( m_time_left >= 0 ) { m_actor->PlusViewAngleD( m_target_angle * delta); return this; } else return 0; } CStabAction_RotateDir( CActor *actor, float angle, float time) : CStabAction_RotateTo(actor, angle, time) { m_target_angle /= m_time; } }; class CStabAction_SetGravity : public CStabAction { public: CVec2f m_GravitationOrg; //gravity origin float m_time; float m_mass; //masse der gravitation void Init() { } actionType GetType() { return stab_SET_GRAVITY; } CStabAction *Action(float delta) { m_time += delta; float x = (0.5f * GRAVITY)* (m_time*m_time) * m_mass; m_actor->m_direction += m_GravitationOrg * x; return this; } CStabAction_SetGravity( CActor * actor, CVec2f &gravpos, float mass ) : CStabAction(actor) { m_GravitationOrg = gravpos; m_mass = mass; m_time = 0; } }; class CStabAction_SetGravityPtr : public CStabAction { public: CVec2f *m_GravitationOrg; //gravity origin float m_mass; //masse der gravitation void Init() { } actionType GetType() { return stab_SET_GRAVITY_PTR; } CStabAction *Action(float delta) { CVec2f vector_to_gravity_origin = *m_GravitationOrg - m_actor->m_position; float d = vector_to_gravity_origin.GetLen(); if( d > 0 ){ float x = (1.0f / d) * m_mass; m_actor->m_direction += vector_to_gravity_origin * x; } return this; } CStabAction_SetGravityPtr( CActor * actor, CVec2f *gravpos, float mass ) : CStabAction(actor) { m_GravitationOrg = gravpos; m_mass = mass*0.5f; } }; /* * Vector Scale CActor::m_scale */ class CStabAction_ScaleTimed : public CStabAction { public: float m_votime; CVec2f m_target_scale; CVec2f m_direction; void Init() { if( m_votime <= 0.0f ) { m_votime = 1.0f; } m_direction = m_target_scale - m_actor->m_scale; m_direction /= m_votime; } actionType GetType() { return stab_SCALE_TIMED; }; CStabAction* Action(float delta){ if(m_actor->MoveToTarget(delta,m_actor->m_scale,m_target_scale,m_direction)) return 0; else return this; } CStabAction_ScaleTimed( CActor *actor, float time, CVec2f &target ) : CStabAction(actor) { m_votime = time; m_target_scale = target; } }; /* * Float fade (float*) &Actor + offset */ class CStabAction_FadeTimed : public CStabAction { public: float m_votime; // zeit für eine fade spanne CVec2f m_i_fade; // initial wert. m_u = von wert, m_v = zu wert float m_fade; // aktueller fade, laufvariable float m_fadeadd; // zeitfaktor int m_offset; // offset zum float, actor+offset -> zielfloat bool m_toggle; // wenn true, wird bei endlos loop m_u, m_v umgedreht bool m_loop; // wenn true, wird endlog geloopoed int m_repeat; // wenn loop gesetzt ist hier die anzahl, 0=endlosloop int m_i_repeat; // initialwert void Init() { if( m_votime <= 0.0f ) { m_votime = 1.0f; } m_fade = m_i_fade.m_u; // aktueller fade, laufvariable m_fadeadd = (m_i_fade.m_v-m_i_fade.m_u)/m_votime; m_repeat = m_i_repeat; // wenn loop gesetzt ist hier die anzahl, 0=endlosloop } actionType GetType() { return stab_FADE_TIMED; }; CStabAction* Action(float delta){ m_fade += m_fadeadd * delta; if( m_fade > m_i_fade.m_v && m_fadeadd > 0 ){ m_fade = m_i_fade.m_v; // Rücksetzen falls über grenze } if( m_fade < m_i_fade.m_v && m_fadeadd < 0){ m_fade = m_i_fade.m_v; // Rücksetzen falls über grenze } TxU8 * P = (TxU8*) m_actor + m_offset; /*WERT SETZEN*/// *(float*) P = m_fade; /* WERT Gesetzt */ //m_actor->m_blitfx.fixalpha = m_fade; // if( m_fade != m_i_fade.m_v ){ return this; } if( m_loop == false ) return 0; // Repeat initialisieren if( m_toggle ){ m_fadeadd *= -1; m_fade = m_i_fade.m_v; // Startwert ist Endewert m_i_fade.m_v = m_i_fade.m_u; // m_i_fade.m_u = m_fade; } m_fade = m_i_fade.m_u; // Startwert, faden geht erst ab repeat loops // wenn repeatcount gesetzt, diesen prüfen sonst endlosloop if( m_repeat > 0 ){ m_repeat -- ; if( m_repeat == 0 ){ //das war der letzte return 0; } } return this; } CStabAction_FadeTimed( CActor *actor, float time, CVec2f &target, int offset, bool toggle, bool loop, int repeat) : CStabAction(actor) { m_i_repeat = repeat+1; m_offset = offset; m_votime = time; m_i_fade = target; m_toggle = toggle; // wenn true, wird bei endlos loop m_u, m_v umgedreht m_loop = loop; // wenn true, wird endlog geloopoed //init } }; #endif