Friday, June 13, 2014

Programming Tips: Comfortably Enum

After reading Casey Muratori's great articles on programming I've been inspired to post a few things on how I program.  In the last article he talked about enums, something I didn't really start using until after Gish, which can be very useful.  However, it can be unwieldy if you try to enumerate too many types, like for example a list of textures.  Say I have 4 player types, and 4 vehicle types, I could do something like this:

enum vehiclelist
  {
  VEHICLE_CAR,
  VEHICLE_TRUCK,
  VEHICLE_PLANE,
  VEHICLE_VAN,
  VEHICLE_END
  };

enum texturelist
  {
  TEXTURE_PLAYER01,
  TEXTURE_PLAYER02,
  TEXTURE_PLAYER03,
  TEXTURE_PLAYER04,
  TEXTURE_VEHICLE01,
  TEXTURE_VEHICLE02,
  TEXTURE_VEHICLE03,
  TEXTURE_VEHICLE04,
  TEXTURE_END
  };


Then to bind the texture for the plane I would use:

  vehicletype=VEHICLE_PLANE;
  glBindTexture(GL_TEXTURE_2D,texture[TEXTURE_VEHICLE01+vehicletype].glname);


The problem I ran into was if I wanted to add more vehicle types, or support more players, I would have to change the texturelist enum.  Also the enum would start to get very long, and while there's ways to shorten it I still felt that it was getting messy.

What I came up with instead is using a simple struct that's enumerated at run-time.  So the texture enum looks like this:

struct
  {
  int loc;
  int player[MAXNUMOFPLAYERS];
  int vehicle[VEHICLE_END];
  } texturelist;

void setuptexturelist(void)
  {
  int count;

  texturelist.loc=0;
  for (count=0;count<MAXNUMOFPLAYERS;count++)
    texturelist.player[count]=texturelist.loc++;
  for (count=0;count<VEHICLE_END;count++)
    texturelist.vehicle[count]=texturelist.loc++;
  }


And to bind the texture:

  vehicletype=VEHICLE_PLANE;
  glBindTexture(GL_TEXTURE_2D,texture[texturelist.vehicle[vehicletype]].glname);


The advantage here is I can add or remove vehicle types without having to change the texture enum, and I can have all types of textures without having a giant enum.  The only disadvantage is you have to call the setuptexturelist function at the beginning of the program.  This is actually the cause of the sound bug in Sub Rosa, where the car crashing into something plays the gunshot sound.  I wasn't calling the setupsoundlist function in the dedicated server, so all the of the soundlist is set to 0, which is the gunshot sound.  So you do have to remember to call the functions to enumerate even if the dedicated server isn't playing any sounds or displaying any textures.

And for making it through that here's a video of boxman falling over a wall: