Project REDIDIT.......

a "Flower Power" community that may be interested in ANY part of aircraft sim creation ..... from creating models all the way to creating code
sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Project REDIDIT.......

Post by sydbod » Thu May 21, 2009 3:01 pm

This is the start of the new project.

It is again a multiplayer flight sim that will be created using TV3D game library.

For once we will try and structure the game a little better than previous attempts.

A "Game State Arbitrator" will be used to provide a bit of structure within the game code.
It also has the advantage that one can easily and clearly add sections to the structure of the game to expand it.
It allows for a clean way to jump in multiple directions depending upon what is selected from a menu.

The general idea is something like:

Code: Select all

// Game State Arbitrator 
// the return values from each of the functions will redirect the program flow through the arbitrator
#define SETUPWINDOW      0
#define SETUPLIBRARY   1
#define ENTRYMENU      2
#define SETUPMENU      3
#define HOSTMENU      4
#define CLIENTMENU      5
#define GAMELOOP      6

int iGameState = 0;

do
{
   switch(iGameState){
      case SETUPWINDOW:
         iGameState = SetupWindow();
         break;
      case SETUPLIBRARY:
         iGameState = SetupLibrary();
         break;
      case ENTRYMENU:
         iGameState = EntryMenu();
         break;
      case SETUPMENU:
         iGameState = SetupMenu();
         break;
      case HOSTMENU:
         iGameState = HostMenu();
         break;
      case CLIENTMENU:
         iGameState = ClientMenu();
         break;
      case GAMELOOP:
         iGameState = GameLoop();
         break;
      default:
         iGameState = 99;
         CleanUp();
         break;
   }
}while(iGameState != 99);


This will allow different members to work on their own particular area of code, and the only thing that has to be checked is that a person returns a correct return value to the Game State Arbitration code.

The first step will be to create a working version of the Arbitrator so that multiple people can start working on the code.

The goal will be to get the Arbitrator up and running by the end of the coming weekend with dummy content active within the functions, so that we have a WORKING skeleton of the program to work with.

Any questions or suggestions .... please post them. :)
Syddy........Just another breed of COOL CAT

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Fri May 22, 2009 7:56 am

Calling Mav,

Here is something you can do towards the project for the moment, untill I get the first part sorted out.

We require an "Entry Menu" for the game.

Basically what is required are the functions as follows.

1) void EntryMenuPreload(void)
2) int EntryMenu(void)
3) void EntryMenuUnload(void)

The first function to preload all the parts of the entry menu ( screen images and sprites, as well as any other assets required).
The second function actually puts the screen on the display, it handles the code so when a particular entry is pressed, it returns a different integer value from the function (depending upon what entry is pressed). It then clears itself off the screen.
The third function unloads all the preloaded resources( we don't want any memory leaks) for the entry screen, and get used when the game terminates.

You decide upon how you want to structure it ( hot zones, or buttons, etc).
Very rough media is all that is required for a start.
A layout something like the attached picture.
It will require the following menu items.
"Setup", "Host", "Client", "Exit"

Image

The tutorial "#14 Simple_Text" could be a good starting point for modifying to insert your code and try it out.

Once you have that sorted out, I should also be ready with my work, and we then can see about how we tie the menu code into the project.

Any questions, please ask.
Syddy........Just another breed of COOL CAT

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Sat May 23, 2009 3:40 pm

Calling Mav,

I am right on schedule with the skeleton of the program.
Only have to integrate some code for storing setup information in an external file (*.ini, or similar), and add a little code in the Program State Arbitrator code for the loading of the gameloop assets.

When it is finished I shall forward the project folder to you to examine.

Are you making any progress with the menu code?

Regards Syd :)
Syddy........Just another breed of COOL CAT

Maverick
Aircrafthand
Aircrafthand
Posts: 12
Joined: Wed Nov 19, 2008 7:24 pm

Post by Maverick » Sun May 24, 2009 6:26 pm

I just glanced at this post. I'm working on it. I can make rough graphics. :wink:

I do have a suggestion for the game states. Why not use an abstract class for the current game state and have inherited classes be the actual game state. That's how I do it:

The abstract class that works it all:

Code: Select all


class CAbstractObject
{
public:
   //The update method which can be overwritten.
   virtual void Update ( void ) = 0;

        //The draw method which can be overwritten.
       virtual void Draw ( void ) = 0;

   //The initialize method which can be overwritten but also returns if successful or not.
   virtual int Initialize ( void ) = 0;

   //The end method which can be overwritten but also returns if successful or not.
   virtual int End ( void ) = 0;

   virtual ~CAbstractObject ( void ){}
};


Code: Select all

//Basic Room...
class CLevelOne : public CAbstractObject
{
public:
   //Update this object.
   void Update ( void )
   {

      //Add any object updates or room updates below----------
   }

        void Draw ( void ) {}

   //Initialize this object.
   int Initialize ( void )
   {
      R = CRoomHandler::Instance ( );

      //Add any object initializations below----------

      return 1;
   }

   //End this object.
   int End ( void )
   {
      //Add any other objects to delete below----------
      return 1;
   }

   //ctors and dtors... not really needed so much, but whatever
   CLevelOne( void ){}
   ~CLevelOne( void ){}

private:
        //Singleton to swap needed room data between rooms
   CRoomHandler *R;

   //Add objects in this room below----------
};


The CRoomHandler

Code: Select all

class CRoomHandler : public CAbstractObject
{
public:

        //This doesn't even have to be am enumerator. Add more rooms here.
   enum ROOM_ID
   {
      NONE = 0,
      TITLE_SCREEN = 1,
      EXIT = 2,//Not really a room but useful to globally exit the game
      FIRST_LEVEL = 3
   };

   static CRoomHandler *Instance ( void )
   {
      if ( thisInstance == 0 )
      { 
         thisInstance = new CRoomHandler;
      }

      return thisInstance;
   }

   int Initialize ( void )
   {
      nextRoom = 0;
      thisRoom = 0;
      return 1;
   }

   int End ( void )
   {
      thisRoom = nextRoom = 0;

      return 1;
   }

   const ROOM_ID GetRoom ( void )
   {
      return ( ROOM_ID )thisRoom;
   }

   const ROOM_ID GetNextRoom ( void )
   {
      return ( ROOM_ID )nextRoom;
   }

   void SetNextRoom ( ROOM_ID pRoom )
   {
      nextRoom = pRoom;
   }

   void MakeThisRoomNextRoom ( void ) //Rooms have changed fine
   {
      thisRoom = nextRoom;
   }

   CAbstractObject *ActualRoom; //Make life easier. Make it public.

   CRoomHandler ( ){}
   CRoomHandler ( const CRoomHandler& );
   CRoomHandler& operator = ( const CRoomHandler& );
   ~CRoomHandler ( ){}

private:
   static CRoomHandler *thisInstance;
   int nextRoom, thisRoom;
};


Usage in the game main loop:

Code: Select all

int CGameModule::CheckLevels ( void )
{
   //Check to see if the message what sent out to change rooms.
   //If the current status of the room do not match
   //then that means we are changing rooms. This function
   //handles that task.

   int OK = 1;

   if( R->GetRoom ( ) != R->GetNextRoom ( ) )
   {
      R->ActualRoom->End ( );
      delete R->ActualRoom;
      R->ActualRoom = 0; //#define NULL 0... whatever

      /*
         The room handling and transitions go here. Make any modifications
         you want for your game!
      */

      switch ( R->GetNextRoom ( ) )
      {
         case CRoomHandler::NONE:
            R->ActualRoom = new CNone ( );
            break;
         case CRoomHandler::TITLE_SCREEN:
            R->ActualRoom = new CTitleScreen ( );
            break;
         case CRoomHandler::FIRST_LEVEL:
            R->ActualRoom = new CLevelOne( );
            break;
         case CRoomHandler::EXIT:
            R->ActualRoom = new CExit ( );
            isQuit = 1;
            break;
         default: //None of these rooms for some reason?! Error screen.
            R->ActualRoom = new CTransitionError ( );
            break;
      }
         
      R->MakeThisRoomNextRoom ( ); // thisRoom = nextRoom;
      OK = ( R->ActualRoom->Initialize ( ) && isQuit == 0 ); //Make sure exit wasn't called either
   }

   return OK;
}


And in the drawing or updating phases:

Code: Select all

//It would look like this
CRoomHandler *R;
R->ActualRoom->Update ( );
R->ActualRoom->Draw ( );


This code was ripped and edited from one of my game engine frameworks. But hopefully you can see the usage and easier potential with this.
Last edited by Maverick on Sun May 24, 2009 6:29 pm, edited 2 times in total.

Maverick
Aircrafthand
Aircrafthand
Posts: 12
Joined: Wed Nov 19, 2008 7:24 pm

Post by Maverick » Sun May 24, 2009 6:27 pm

-Double posted-

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Mon May 25, 2009 4:02 am

Most impressive :) .

For such a small project, is not working with classes a bit too complex.
I know that in a huge project, it is the only way to go. I was just hoping to keep things simple so that other "noobs" (hell, I am still a noob) may find it easier to follow the code and see how it is structured. The overview is the important thing at the moment.

By simple, this is what I mean:

externals.h:

Code: Select all

/************************************************************
*All global structures and their "extern" prototypes go here*
************************************************************/
struct ProgramSettings
{
   int   iDesktopWidth;
   int   iDesktopHeight;
   int iGameWidth;
   int   iGameHeight;
   int   iGameColor;
   int   iGameZBuffer;
};
extern  struct ProgramSettings Program;

/*************************
*All global types go here*
*************************/
extern MSG msg;

/*******************************************
*All global class instance pointers go here*
*******************************************/
extern CTVEngine      *pEngine;//This is the main engine class.
extern CTVInputEngine   *pInput; //Allow for keyboard/mouse input.

/**********************
*All functions go here*
**********************/
extern void SetupLibrary(HWND Handle);
extern HWND SetupWindow(HINSTANCE hInstance, int nCmdShow);
extern void CleanUp(HINSTANCE hInstance);
extern LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
extern int GameLoop(void);

/**********************************
*All external enumerations go here*
**********************************/
enum { iENTRYMENU, iSETUPMENU, iHOSTMENU, iCLIENTMENU, iGAMEPLAY, iFINISHED, iENDVALUE};//Used in program state arbitration.


globals.h:

Code: Select all

#include "externals.h"

/******************************
*All global structures go here*
******************************/
struct ProgramSettings Program;

/*************************
*All global types go here*
*************************/
MSG msg;

/*******************************************
*All global class instance pointers go here*
*******************************************/
CTVEngine      *pEngine;
CTVInputEngine   *pInput;


main.cpp

Code: Select all

#include "TV3D.h"
#include "globals.h"

//Entry point.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   //Get current desktop size.
   Program.iDesktopWidth = GetSystemMetrics(SM_CXSCREEN);
    Program.iDesktopHeight = GetSystemMetrics(SM_CYSCREEN);

   //Check for saved screen settings.
   char szTempBuffer [10];
   Program.iGameWidth   = GetPrivateProfileInt("ProgramSetup","GameWidth",800,".\\Redidit.set");
   Program.iGameHeight   = GetPrivateProfileInt("ProgramSetup","GameHeight",600,".\\Redidit.set");
   WritePrivateProfileString("ProgramSetup","GameWidth", _itoa(Program.iGameWidth, szTempBuffer, 10),".\\Redidit.set");//update info in case file does not exist
   WritePrivateProfileString("ProgramSetup","GameHeight", _itoa(Program.iGameHeight, szTempBuffer,10),".\\Redidit.set");

   //Create a window.
   HWND hWnd;
   hWnd = SetupWindow(hInstance, nCmdShow);

   //Setup game library.
   SetupLibrary(hWnd);

   /***********************************AT THIS POINT WE STILL HAVE TO PRELOAD EVERYTHING*****************************
      WE WILL MOVE THIS STEP INTO THE PROGRAM STATE ARBITRATION AND USE A FLAG IN "struct ProgramSettings Program" TO
      FLAG THAT IT IS LOADED SO IT DOES NOT GET LOADED TWICE.*/

   //Program state arbitration.
   int iProgramState = iGAMEPLAY;//Will start with game play entry, until menu code is integrated.

   do
   {
      switch(iProgramState)
      {
         case iENTRYMENU:
            //iProgramState = EntryMenu();
            break;
         case iSETUPMENU:
            //iProgramState = SetupMenu();
            break;
         case iHOSTMENU:
            //iProgramState = HostMenu();
            break;
         case iCLIENTMENU:
            //iProgramState = ClientMenu();
            break;
         case iGAMEPLAY:
            iProgramState = GameLoop();
            break;
         case iFINISHED:
            CleanUp(hInstance);//Unload everything.
            iProgramState = iENDVALUE;
            break;
         default://Something wrong if we get here.
            CleanUp(hInstance);//Unload everything.
            iProgramState = iENDVALUE;
      }
   }while(iProgramState < iENDVALUE);


   //Now for a clean exit.
   return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }
    return DefWindowProc (hWnd, message, wParam, lParam);
}



etc.....

Yes I know all the arguments about NOT using globals, but if used properly it allows people to develop and expand a game in a very unstructured way when they are first fleshing out the operations.

It should be easy for us to knock a basic project out in a few months at the most, and then we should go to something more complex.

If you want, then why don't you also rebuild the project using classes. It would be great to see how the 2 different formats look next to each other.

After lunch I will pack the current work into a Zip and email it to you. You can have a little play and see what you think.

It looks like I have a few libraries crossed in my VC++ 2008 express compiler environment. Some old SDK libraries are having parts pulled into my compilations, and I can not get pointer to structures to work. Things compile compile fine but the code throws an exception message when run. I will probably have to do a clean install on another machine and sort the code out properly and use pointers to structures.
Syddy........Just another breed of COOL CAT

Maverick
Aircrafthand
Aircrafthand
Posts: 12
Joined: Wed Nov 19, 2008 7:24 pm

Post by Maverick » Mon May 25, 2009 6:09 am

It looks like I have a few libraries crossed in my VC++ 2008 express compiler environment. Some old SDK libraries are having parts pulled into my compilations, and I can not get pointer to structures to work. Things compile compile fine but the code throws an exception message when run. I will probably have to do a clean install on another machine and sort the code out properly and use pointers to structures.


I had the same issue happen earlier too. I had to clean up the IDE and the other SDKs. Ugh.

Simplicity s the goal for now then. Alright. Makes sense. And yeah, I'll try and format the project with classes just for kicks when we get there. Can't wait to see what you have so far! Expect a menu soon from me. 8)

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Mon May 25, 2009 8:22 am

Project sent to your GMAIL account. :)
Syddy........Just another breed of COOL CAT

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Wed Jun 03, 2009 12:16 pm

YES, work is still being done. Just a quick progress report.

An attempt has been made to try to split the work into functional areas.
Mav is currently working on a wrapper for 2 different sound libraries to be evaluated within the game. He will probably provide some updates when he has something of interest to report.

I have been playing with the frontend menu area at the moment.
The most frustrating part of any frontend is to get it working at all the possible screen settings that users may set their machines to. It should be noted that one can not just assume a menu setting of 800x600 and set the users machine to that setting for menu use. What happens if a user happens to have his/her machine connected to a HD (1920x1080) TV set and playes on it.

It became important to create a menu system that adapts to any possible screen resolution settings. This has been the area of work for me at the moment.
It has been a case of creating a menu system that measures control objects (buttons, check boxes,etc) as a proportion of the screen width, and making sure these objects get rendered at that correct proportion.
It also became necessary to allow the various controls and background images to be able to be constructed by any size image or picture without it affecting the display of the object. IE: it should not matter if the background image is 800x600 pixels in size of 2048x800 in size, the picture should render in its correct place without being warped width to height .

So far we seem to have achieved this goal with the background images, as well as the buttons.(they were the proof of concept of what we were trying to achieve. Now comes the creation of the "Slider controls", the "Check Boxes" and the "Text Boxes".
At that point we should be ready with the creation of the game frontend. Hopefully by then the sound library tests will be concluded also, and the main part of the game code can be re-created upon the old Rodnock skeleton code.

Here are 3 pictures of the frontend code in action in 3 different sized windows (should people be interested).

Image

Image

Image

As you can see, no warping of any kind, everything is scaling properly. :)
Syddy........Just another breed of COOL CAT

Maverick
Aircrafthand
Aircrafthand
Posts: 12
Joined: Wed Nov 19, 2008 7:24 pm

Post by Maverick » Wed Jun 03, 2009 5:33 pm

I'm glad you got the dreaded resolution problem down. Yeah, we had problems with the engine in different resolutions. The screen was drawn rather correctly, but the "supposed" mouse position was way off. For instance, the resolution could have been 1200x800 but the engine's mouse coordinates would still be at the defaulted 800x600. This is what Sibby found out. ( Correct me if I'm wrong Sibby :) )

I am working on the sound libraries. Since our indecisiveness too control, we cannot determine whether or not to use irrKlang for playing sounds or FMOD. They are both sound libraries, which in programming language means they make sure we can type in the right functions and they'll play sound in the game, and they are very popular. Thus, I am in charge of making a program to use either one depending on which one we choose and allow us to code without having to change any code we have already written.

So all we have to type is something like Sound.Play ( ) and not worry if FMOD or irrKlang or being used; that it will work.

By the way, Sibby, I used the wrong term. A "wrapper" allows someone to code something in C++ but other languages can use it. For instance, you should know about the OpenGL API originally for C++ and C. Well, there is a "wrapper" that allows OpenGL to be used in other languages such as Ruby or PyGame. The correct term for what I'm doing is unknown to me at the moment, but it is like a framework. Like an API over APIs. I'll get back to you on the terminology when I find the correct one. :P

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Thu Jun 04, 2009 1:09 am

Lets be bold and just make up a term.
Lets call it "Unified Interface Functions" ????? :)
Syddy........Just another breed of COOL CAT

Maverick
Aircrafthand
Aircrafthand
Posts: 12
Joined: Wed Nov 19, 2008 7:24 pm

Post by Maverick » Thu Jun 04, 2009 1:41 am

That sounds more like an acronym to some form of military to me. How about "Incasement".

Not "encasement" but incasement. Just in case. :P

Corny humor.

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Fri Jun 12, 2009 2:49 pm

Just a little update,

I had been chasing a problem within the game library that was corrupting Text Fonts when they are being rescaled.

Here is a picture of a corrupted font compared to what the font should be like.
Image

I blew more time than what I am prepared to admit to..... and it ended up being caused be a corrupted windows installation on my development machine, rather than a fault in the library.
One day I will get around to reloading windows on this machine.

Anyway, a little more progress was made with the menu code by creating "Text Class" code and "Input Class" code.

We now have the capability of producing text on the menu screens, as well as having individually focusing entry areas on the menu screens.
Both these are also auto resizing so that the menus will function on ALL current possible screen resolutions.

Image

This is just a proof of concept of these 2 new features.
I will next create proper "Host" and "Client" screens that will use these new menu features, rather than just dump it onto the main screen as was done at the moment (for the picture).

Hopefully in around one week time the menu code will be ready and we can start on re-porting the old game code to the new engine.

For those that are interested, this is what the current Menu Classes look like.

Code: Select all

#include "TV3D.h"
#define NoKeyPressed 0

extern CTVScreen2DImmediate *p2D;
extern CTVTextureFactory    *pTextureFactory;
extern CTVScreen2DText      *pText;
extern CTVInputEngine      *pInput;
extern ProgramSettings      Program;


//#################### Background Class ###########################
class Background
{
   protected:
      int TextureId;
      cTV_TEXTURE Texture;
      float RealX1, RealY1, RealX2, RealY2;//Real screen values
   public:
      void BackgroundTexture(int);
      void BackgroundSizeUp(int, int);
      void BackgroundRender();
};

void Background::BackgroundTexture(int background_texture_id)
{
   TextureId = background_texture_id;
}

void Background::BackgroundSizeUp(int GameWidth, int GameHeight)
{
   //ScreenNormalisedHeight = GameHeight*(Texture.RealWidth / GameWidth);
   Texture   = pTextureFactory->GetTextureInfo( TextureId);
   RealY1   = ((GameHeight*(Texture.RealWidth / GameWidth)) - Texture.RealHeight) / 2;
   RealY2   = GameHeight - RealY1;
   RealX1   = 0;
   RealX2   = GameWidth;
}

void Background::BackgroundRender()
{
   p2D->Draw_Texture(TextureId, RealX1, RealY1, RealX2, RealY2, -1, -2, -2, -2, 0.0, 0.0, 1.0, 1.0);; 

}



//###################### Button Class #############################
class Button
{
   protected:
      float X1, Y1, X2, Y2;//Normalised values
      float RealX1, RealY1, RealX2, RealY2;//Real screen values
      int UpTextureId, DownTextureId;
      int TextureToRender;
   public:
      Button(float,float,float,float);//X1, Y1, X2, Y2
      void Texture(int,int);//Texture Up ID, Texture Down ID.
      void SizeUp(int, int);//Screen width, Screen height
      int MouseToButton();//Returns a clicked validation
      void ButtonRender();
      //void ~Button();
};

Button::Button(float x1, float y1, float x2, float y2)
{
   X1 = x1;
   Y1 = y1;
   X2 = x2;
   Y2 = y2;
}

void Button::Texture(int up_texture_id, int down_texture_id)
{
   UpTextureId = up_texture_id;
   DownTextureId = down_texture_id;
   TextureToRender = UpTextureId;// initialise with the UpTextureId
}


void Button::SizeUp(int GameWidth, int GameHeight)
{
   RealX1 = (X1*GameWidth);
   RealY1 = (Y1*GameWidth*0.56f + (GameHeight - GameWidth*0.56f)/2.0f);
   RealX2 = (X2*GameWidth);
   RealY2 = (Y2*GameWidth*0.56f + (GameHeight - GameWidth*0.56f)/2.0f);
}


int Button::MouseToButton()
{
   int X,Y,MouseLPressed;
   POINT MousePoint;

   if (!Program.iWindowedMode)//External flag
   {
      GetCursorPos(&MousePoint);
      X = (int)MousePoint.x;
      Y = (int)MousePoint.y;
   }
   else
      pInput->GetMousePosition ( &X, &Y);

   MouseLPressed = pInput->IsMouseButtonPressed(0);

   if ((X>(int)RealX1) && (X<(int)RealX2) && (Y>(int)RealY1) && (Y<(int)RealY2))
   {
      TextureToRender = DownTextureId;
      if(MouseLPressed)
         return(true);//Button is pressed
      else
         return(false);//Button is not pressed
   }
   else
   {
      TextureToRender = UpTextureId;
      return(false);//Cursor is not on the button
   }
}

void Button::ButtonRender()
{
   p2D->Draw_Texture(TextureToRender, RealX1, RealY1, RealX2, RealY2, -1, -2, -2, -2, 0.0, 0.0, 1.0, 1.0);
}



//###################### Input Class #############################
class Input
{
   protected:
      float X1, Y1, X2, Y2;//Normalised values
      float RealX1, RealY1, RealX2, RealY2;//Real screen values
      bool InputBoxActive;
      unsigned char KeyArray[255];
      int Color,ActiveColor, InactiveColor;
      int OldActiveKey, ActiveKey;
      int IDFont;
      int EntrySize;

   public:
      Input(float,float,float,float,int);//X1, Y1, X2, Y2.
      char CurrentText[255];
      void InputSizeUp(int, int);//Screen width, Screen height.
      void InputToInput();//Handles input to text window.
      void InputRender();//Renders the completed text box.
};



Input::Input(float x1, float y1, float x2, float y2, int entrysize)
{
   X1 = x1;
   Y1 = y1;
   X2 = x2;
   Y2 = y2;
   EntrySize = entrysize;
}

void Input::InputSizeUp(int GameWidth, int GameHeight)
{
   RealX1 = (X1*GameWidth);
   RealY1 = (Y1*GameWidth*0.56f + (GameHeight - GameWidth*0.56f)/2.0f);
   RealX2 = (X2*GameWidth);
   RealY2 = (Y2*GameWidth*0.56f + (GameHeight - GameWidth*0.56f)/2.0f);

   //Lets create our texture font, clear type AA.
   IDFont   = pText->TextureFont_Create("our_font_name_string", "Comic Sans MS", (RealY2 - RealY1)/2, false, false, true, false, true);
   InactiveColor = RGBA(0.5, 0.5, 0.5, 1);
   ActiveColor = RGBA(1, 0, 0, 1);
}

void Input::InputToInput()
{
   char ASCIIFromKey[2];
   int X,Y,MouseLPressed;
   POINT MousePoint;


   if (!Program.iWindowedMode)//External flag
   {
      GetCursorPos(&MousePoint);
      X = (int)MousePoint.x;
      Y = (int)MousePoint.y;
   }
   else
      pInput->GetMousePosition ( &X, &Y);

   MouseLPressed = pInput->IsMouseButtonPressed(0);

   if(MouseLPressed)
   {
      if ((X>(int)RealX1) && (X<(int)RealX2) && (Y>(int)RealY1) && (Y<(int)RealY2))
         InputBoxActive = true;
      else
         InputBoxActive = false;
   }

   OldActiveKey = ActiveKey;

   pInput->GetKeyPressedArray(KeyArray);

   if (InputBoxActive)
   {
      Color = ActiveColor;
      for(int loop=1; loop<255; loop++)
      {
         if (KeyArray[loop])
         {
            ActiveKey = loop;
            break;
         }
         else
         {
            ActiveKey = NoKeyPressed;
         }
      }

      if((ActiveKey != OldActiveKey) && (ActiveKey != NoKeyPressed))
      {
         ASCIIFromKey[0] = (char) pInput->GetASCIIFromKey((cCONST_TV_KEY) ActiveKey);
         ASCIIFromKey[1] = NULL;
         if (strlen(CurrentText) < EntrySize)//Maximum sized nt reached yet
         {
            if(((ASCIIFromKey[0]> 47) && (ASCIIFromKey[0] < 58)) || ((ASCIIFromKey[0]> 64) && (ASCIIFromKey[0] < 91)) || (ASCIIFromKey[0] == 46))
               strcat (CurrentText, ASCIIFromKey );
         }

         if ((ASCIIFromKey[0] == 8) && (strlen(CurrentText) > 0))//Backspace 8
            CurrentText[strlen(CurrentText) - 1] = NULL;

      }
   }
   else
      Color = InactiveColor;
}


void Input::InputRender()
{
      pText->Action_BeginText(true);
      p2D->Draw_Box(RealX1, RealY1, RealX2, RealY2, Color);//Draw a 2D box for the HOT zone.
      pText->TextureFont_DrawText(CurrentText , RealX1, RealY1, RGBA(1, 1, 1, 1), IDFont);//Draw the font in our viewport.
      pText->Action_EndText();
}




//###################### Text Class #############################

class Text
{
   protected:
      float X1, Y1, X2, Y2;//Normalised values
      float RealX1, RealY1, RealX2, RealY2;//Real screen values
      char * Content;
      int Color;
      int IDFont;

   public:
      Text(float,float,float,float,char*);//X1, Y1, X2, Y2.
      void TextSizeUp(int, int);//Screen width, Screen height.
      void TextRender();//Renders the text.
};

Text::Text(float x1, float y1, float x2, float y2, char * content)
{
   X1 = x1;
   Y1 = y1;
   X2 = x2;
   Y2 = y2;
   Content = content;
}

void Text::TextSizeUp(int GameWidth, int GameHeight)
{
   RealX1 = (X1*GameWidth);
   RealY1 = (Y1*GameWidth*0.56f + (GameHeight - GameWidth*0.56f)/2.0f);
   RealX2 = (X2*GameWidth);
   RealY2 = (Y2*GameWidth*0.56f + (GameHeight - GameWidth*0.56f)/2.0f);

   //Lets create our texture font, clear type AA.
   IDFont   = pText->TextureFont_Create("our_font_name_string", "Comic Sans MS", (RealY2 - RealY1)/2, true, false, true, false, true);
   Color = RGBA(1.0, 1.0, 1.0, 1);
}

void Text::TextRender()
{
      pText->Action_BeginText(true);
      pText->TextureFont_DrawText(Content , RealX1, RealY1, Color, IDFont);//Draw the font in our viewport.
      pText->Action_EndText();
}
Syddy........Just another breed of COOL CAT

Maverick
Aircrafthand
Aircrafthand
Posts: 12
Joined: Wed Nov 19, 2008 7:24 pm

Post by Maverick » Sat Jun 13, 2009 1:39 am

... So .... Many ... Globals ... :crying:

I've been on and off trying to get the sound libraries to work. It's not the libraries, but I'm trying to program it so that which ever library we use will work 100% without rewriting anything. I'm not used to the way the project is laid out so I've bee having some global management issues. For instance I have a macro:

USING_FMOD

When FMOD is plugged in, it is set to "1". If not, it is "0". I can't seem to get the other files knowing that USING_FMOD even exists. So that leads to my question:

Should I create the sound class so all the rooms and objects can use it like I originally set up the buttons, or should I create the sound class only for the intro menu like you are currently doing with the backgrounds and buttons?

sydbod
Flight Sergeant
Flight Sergeant
Posts: 1679
Joined: Sat Aug 13, 2005 12:39 pm
Location: Sydney,NSW,Australia

Post by sydbod » Sat Jun 13, 2009 2:04 am

Hi Mav,

All the programs Globals are managed in the structure:

Code: Select all

struct ProgramSettings
{
   int         iWindowedMode;
   int         iDesktopWidth;
   int         iDesktopHeight;
   int         iGameWidth;
   int         iGameHeight;
   int         iGameColor;
   int         iGameZBuffer;
   int         iUseMusic;//If true then music will be used
   int         iMusicPlaying;//If true then music is looping and producing sound
   char      szMusicFile [128];//The file name stored in this variable will be used for the music
};

That resides in the "datatype.h" file.
Decide what globals you will require and just ADD them and let me know.
IE: "iUse_Fmod" , "iUse_irrKlang", etc.

This way we will have all the globals managed in a common area and eventually I will create the code to preload these values from the games setup file so that one can just edit this setup file to vary the games operating configuration.

By the way, all my classes can be used anywhere in the code in any menu rooms or even the game proper. It is only a matter of when the render part of the class gets called, that determines if the object will be displayed.

I still have to clean up the new code and make it layout compliant with how we started the code, and then I will post it to you to look over. Should be finished some time over the weekend.

EDIT: By the way, I have moved all the Menu Object classes into "menu.h", so to be consistent, it would be great if you could confine all your sound classes into something like "sound_irrKlang.h", "sound_Fmod.h", or just "sound.h" if it will fit cleanly into a single "h" file. :)
Syddy........Just another breed of COOL CAT

Post Reply