Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Ron AF Greve

Member Since 02 Sep 2008
Offline Last Active Yesterday, 01:20 PM

#4889403 how do i know which librarys are for commercial project?

Posted by Ron AF Greve on 01 December 2011 - 07:56 AM

I think you have to read them yourself and read them well (that's what I did). However I use:

vorbis
png
jpeg (not the intel jpeg)
zlib
freetype

So I considered (but I might be wrong) those safe to use. I also use OpenAL, but reading this thread I think I have to reread it's license. I thought it was ok as long as you used the DLL.

Additonal libraries (which I thought were also safe to include):
expat
speex

Yet, I am no lawyer and this is not legal advice.


#4865461 Looking for a good, quick spatial hash...

Posted by Ron AF Greve on 24 September 2011 - 06:52 AM

I use something like this, simple and fast but of course you have to test if it is good enough for your situation (I think I got the algo from wikipedia, lookup PRNG)

For the first time set XORValue to your seed value.

XORValue = ( XORValue * 1664525 + 1013904223 ) & 0xFFFF;
Or in x86 assembly:
    mov eax,1664525
    mov edx,XORValue
    mul edx ; result in edx:eax (
    add eax,1013904223
    mov XORValue,eax



#4814000 GUI/Window message system problem

Posted by Ron AF Greve on 21 May 2011 - 04:38 PM

Well that is actually rather simple for instance a button just creates an event object and passes that to its parent which could handle it or send it to its parent until it hits the root of the hierarchy. Currently it is stored there. So it can be either read by a containing class wich then adds it to the scheduler or I created one big hierarchy (they all derive from a scripting class) and let the non-gui object that created the gui handle them directly.

Although I tested both my scripting and gui I haven't hooked them up yet. But this is how it currently looks when a component sends an event:


class MGUIEventId
{
  private:
    size_t        Hash;
    std::string   Eventname;
    SVRefPtr<VVar> Parameters; // SVRefPtr is my smartptr ( intrusive refcnt ) type

  public:
    MGUIEventId():
      Hash     (       ),
      Eventname(       )
    {
    }

    // Probably should be constant, however it can't really be that way, since it reference counts also inside the variant (mutable would probably do)
    SVRefPtr<VVar> GetParameters() { return Parameters; }

    MGUIEventId( const std::string& Eventname ):
      Eventname( Eventname )
    {
  std::hash<const char*> HashFunction;
  Hash = HashFunction( Eventname.c_str() );
    }

    bool operator< ( const MGUIEventId& GUIEventId ) const
    {
      if( Hash < GUIEventId.Hash ) return true;
      else if( Hash == GUIEventId.Hash )
      {
        return Eventname < GUIEventId.Eventname;
      }
      return false;
    }

    bool operator==( const MGUIEventId& GUIEventId ) const
    {
      return GUIEventId.Hash      == this->Hash      &&
             GUIEventId.Eventname == this->Eventname
             ;
    }

    // ----Inspectors
    const size_t&       GetHash     () const { return Hash     ;}
    const std::string&  GetEventname() const { return Eventname;}

    // ----Mutators
    void SetHash     ( const size_t&        Hash      ) { this->Hash      = Hash     ;}
    void SetEventname( const std::string&   Eventname ) { this->Eventname = Eventname;}

    friend MChannel& operator<<( MChannel& Channel, const MGUIEventId& GUIEventId );
};

class MGUIEvent : public ISerializeScript
{
  private:
    MGUIEventId   GUIEventId;
    CLocation     Location;

  public:
    MGUIEvent():
      GUIEventId(       ),
      Location  (       )
    {
    }

    MGUIEvent( const std::string& Eventname, const CLocation& Location ):
      GUIEventId( Eventname ),
      Location  ( Location   )
    {
    }

    bool operator< ( const MGUIEvent& GUIEvent ) const
    {
      if( GUIEventId < GUIEvent.GUIEventId ) return true;
      else if( GUIEventId == GUIEvent.GUIEventId )
      {
        return Location < GUIEvent.Location;
      }
      return false;
    }

    bool operator==( const MGUIEvent& GUIEvent ) const
    {
      return GUIEvent.GUIEventId == this->GUIEventId &&
             GUIEvent.Location   == this->Location  
             ;
    }

    // ----Inspectors
    const MGUIEventId&  GetGUIEventId() const { return GUIEventId;}
    const CLocation&    GetLocation  () const { return Location  ;}

    // ----Mutators
    void SetGUIEventId( const MGUIEventId&&  GUIEventId ) { this->GUIEventId = GUIEventId;}
    void SetLocation  ( const CLocation&     Location   ) { this->Location   = Location  ;}

    friend MChannel& operator<<( MChannel& Channel, const MGUIEvent& GUIEvent );
};


// ----------------------in MComponent
void  MUIBase::Emit( const MGUIEvent& GUIEvent )

{

 if( Parent )

 {

  Parent->Emit( GUIEvent );

 }





}



void MComponent::Emit( const std::string Eventname, const CLocation& Location )

{

 MUIBase::Emit( MGUIEvent( Name + "::" + Eventname, Location ) );

}

In the root of the hierarchy  I overwirte various methods

void  MWindowGroup::Emit( const MGUIEvent& GUIEvent )
{
        Queue.push_back( GUIEvent );
}

 






edit: Ouch, forgot the most important thing, it needs a array of variants to pass on name-value pairs (the vvar contains a vvar map).


#4813982 GUI/Window message system problem

Posted by Ron AF Greve on 21 May 2011 - 04:05 PM

You're right you can't store more than one type in a map. But there is no need to since you store a pair of variants. One variant is the name, the key or the 'identifier' however you want to view it. The oter is the value so
map<*Variant, *Variant, comparator> Name2Value;




(Copy and paste of my code ) this is main part of my vairant class
class VVar : public ISerialize
{
public: 
  typedef enum { eNull = 0, eLong = 1, eDouble = 2, eString = 3, eMap = 4, eSRefPtr = 5, eWRefPtr = 6, eKey = 7, eAddress = 8, eInvalid = 254, eLastType } eType_t;



 //__declspec(align(64))
 union 
 {
  Int64         Null;   // Needed to keep scripting stuff logical (every type has a field so give one to eNull too)
  Int64         Long;
  double        Double;
  VVarString   *VarString;
  VVarMap      *VarMap;
  char SRefPtr  [ sizeof( SVRefPtr<ISerialize>            ) ];
  char WRefPtr  [ sizeof( WVRefPtr<ISerialize>            ) ];
  char KeyStroke[ sizeof( MKey                            ) ];
  VVar *Var;
 };
 UInt16 Type;


So it just remembers the type in the int Type and all possiblle types are in a union.I created a special Varmap but it is just that I tried to opitimize things a bit a regual map would do too.
In the end it will always use the size of the largest type. The RefPtrs are smart pointers to an object. So it can store int's, double, longs, and maps of variants (i.e. recursively)

Note that if you store stl strings, maps or actually any object (like the MKey object in my example) you have to understand that the array of chars only reserve bytes. The object itself still has to be creaed in that space.

So you need to create it in that location, you also need to make sure the alignment is right. Best is to make sure it is aligned on a 64 boundary.


Example creating the MKey object in the union:
For instance from my VVar deserialization code


 if( Archive.IsReading() )
 {
  CleanUp();
 }

 Archive.Serialize( Type );
 switch( Type )
 {
  case eKey:
   if( Archive.IsReading() )
   {
     new( this->KeyStroke ) MKey;  // <----- In place new
   }
   reinterpret_cast<MKey *>( KeyStroke )->Serialize( Archive );
   break;



So you could keep it simple (from the top of my head, this might contain errors and typos):


// check your compiler to make sure the union is on 64 bbyte boundary (so put char type behind it for one thing)
class CVariant

{
public:

  typedef enum { eInt, eDouble, eObject, eString, eLastType } eType_t;
private:
  union

  {

  int Int;
  double Double;
    void *Object;

    char String[ sizeof( std::string) ]

};
  char Type;

}


// Creaet variant with string inside
CVariant::CVariant( const std::string& String )

{
  new ( this->String ) std::string( String );

  Type = eString;
}

CVariant::~CVaraint()

{
  switch( Type )

  {

    case eNull:

 break;

case eString:
  delete String;
 break;
}

CVariant operator+( const CVariant& Variant )

{
  switch ( Type )

{
  case eString:
    switch( Variant.Type )

{
 case eInt:
  stringstream Stream;

  Stream << reinterpret_cast<std::string>( *String ) << Variant.Int;

return Variant( Stream.Str() );
break;
}
break;
}
}

Just begin simple with a int and double and one operator. Once you can add different types together like VarResult = Var1 + Var2 it will be fun to extent.


BTW: In my own code I use jump tables not switches in the operators. Saves expensive conditional jumps but makes it more complex. I created another program to create all combinations between types for all operators.


#4813809 GUI/Window message system problem

Posted by Ron AF Greve on 21 May 2011 - 04:56 AM

(I am also working on my gui system and haven't got everything working yet)

I think there are two ways you can do things.

1. Have a nice clean design. Every control that contains other controls knows their exact type. That means every control, that can contain other controls, needs a container for that control. For instance if I have a panel that can contain anything I need a container for buttons, one for input boxes another one for sliders etc. Every time you invent another control go over all your code to add it everywhere. Clean, correct but it will be lots of work.

2. Just call everything a component. (or window or whatever). Actually this is what you do (and what I do in my gui-system). My gui system however uses messages with an map of my own variant type (map<string, VVar>). So for instance my button would set the following values

<"name", "component name">

<"event", "component name_LButtonDown">

<"X", mouseXPos>

etc.

And then would send it to its parent which send it to its parent and so forth until it reaches the top of the chain. There it would lookup the event name in the current object to see if there is a handler with that name and call that and passing the parameters to the function. When no function is found nothing happens when it does find a function it will compile it (I wrote my compiler using a hand written front end and LLVM as backend). Variables in the function first resolves to locally declared variables (the fastest) then it will look in the map of passed in variables and lastly it will go back to the object it is running on (this is the slowest since it has to look up every time it accesses the variable since it might have been created during execution).



I haven't yet thought how to get the text from my text control. But I think I could just send the control a message that would ask it to either send the text in response. The map-variant type makes it generic very flexible but also a bit slower (but this is GUI stuff so I don't think that would be a problem).

As a side note, the way you have various methods to convert a string to float, int etc. is exactly how I implemented my XML file reader. Since the nodes themselves are always strings. this was the easiest way to keep a generic XML reader that I can use for any file by only changing the tags.


edit: Fixed some typos


#4692349 OpenAL Streaming (Queue Buffers)

Posted by Ron AF Greve on 16 August 2010 - 04:01 AM

I had the same problem. When the buffers are depleted it stopped. I solved it by remembering what state it should be in then querying OpenAL for the state it is in. When it should be playing but isn't I just call alSourcePlay again:


if( Stop && BufferQueue.empty() )

{

InfoLog << "Stopping sound because we reached end of file" << endl;

alSourceStop( Sources[ 0 ] );

State = eStopped;

Reset();

}

else

{

ALenum ALState = 0;

alGetSourcei( Sources[ 0 ], AL_SOURCE_STATE, &ALState);

if( ALState != AL_PLAYING)

{

InfoLog << "Starting sound (or resuming sound because we ran out of buffers)" << endl;

alSourcePlay( Sources[ 0 ] );

}

}





PARTNERS