PSP Hacks - Forums

Go Back   PSP Hacks - Forums > PSP Community > PSP Programming & Development

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 03-30-2009, 08:14 PM
lokiare1's Avatar
lokiare1 lokiare1 is offline
Programmer
PSP Enthusiast
 

Join Date: Jul 2005
Location: Arkansas, USA
Posts: 466
lokiare1 is on a distinguished road
Post [TUTORIAL] LTE Game Engine Splash Screen

This is a simple tutorial on how to create a splash screen using LTE Game Engine. The first thing you will want to do is check out the How to use game states tutorial I wrote earlier. If you don't you'll kick yourself about half-way into creating your game.

This tutorial assumes you know a fair amount of C++ and have at least attempted to program a simple game (and that you were partially successful).

Lets get started... We will need to create a new class to handle the events (this will come in handy later)

Code:
// GameEngine.h file

// This is included so we can manage our game states with this class
#include <stack>
#include <engine.h>
// We must include all the game states here
#include "SplashState.h"

// For stack
using namespace std;

// Main LTE namespace
using namespace engine;

// Sub namespaces for LTE
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

// The main event receiver must inherit from IEventReceiver in order to work
// with the creation of the LTE device

class GameEngine :
	public IEventReceiver
{
public:
	GameEngine(void);
	~GameEngine(void);
	// The overridden event catcher function
	bool OnEvent(SEvent e);
	// Main loop
	bool Run(void);
private:
	// Main engine device
	engineDevice * device;
	// Video driver
	IVideoDriver * driver;
	// Scene Manager
	ISceneManager * smgr;
	// Graphical user interface
	IGUIEnvironment * guienv;
	// Stack of gamestates
	stack<GameState *>stateStack;
public:
	// Sets the engine device
	void SetDevice(engineDevice * _engine);
};
Next we must fill in GameEngine.cpp:

Code:
#include "GameEngine.h"

// We can't initialize until we get a pointer to the LTE device and
// the LTE device can't be created until it gets a pointer to the
// derivative of IEventReceiver (figure that one out if you can)
GameEngine::GameEngine(void)
{
}

GameEngine::~GameEngine(void)
{
}

// This is the overridden function that actually handles the events
bool GameEngine::OnEvent(SEvent e)
{
        // Make sure both the device is created and that the game state
        // stack is not empty
	if (!device || stateStack.empty() == true)
		return false;
        // Switch through each event type and then pass it to the top state on the stack
	switch (e.EventType)
	{
        // This is used by the graphical user interface
	case EET_GUI_EVENT:
		stateStack.top()->OnEvent(e);
		return true;
		break;
        // This is for virtual mouse input (it is a fix from the original irrlicht engine)
	case EET_MOUSE_INPUT_EVENT:
		stateStack.top()->OnEvent(e);
		return true;
		break;
        // This is our input from buttons (minus the analog stick)
	case EET_KEY_INPUT_EVENT:
		stateStack.top()->OnEvent(e);
		return true;
		break;
        // This is for log events (not even sure if this works in LTE)
	case EET_LOG_TEXT_EVENT:
		return true;
		break;
        // In the release of LTE that I created this is disabled because it was done
        // extremely poorly, and barely worked (use a different one)
	case EET_AUDIO_EVENT:
		stateStack.top()->OnEvent(e);
		return true;
		break;
        // This is used if you want to pass events to it
	case EET_USER_EVENT:
		stateStack.top()->OnEvent(e);
		return true;
		break;
	default:
		break;
	};
	return false;
}

// Main loop
bool GameEngine::Run(void)
{
	// Create and add our first state
	SplashState * splash = new SplashState(device);

	// Add the state to our stack
	stateStack.push(splash);

	// Run the game loop of the top state
	if (stateStack.top())
	{
                // We loop this until LTE decides it is time to stop
                // In this loop is where you will want to conditionally change states
		while (device->run())
		{
                        // We call the run of the top state
			stateStack.top()->Run();
		}
	}
	return true;
}

// Sets the LTE engine device
void GameEngine::SetDevice(engineDevice * _engine)
{
	if (_engine)
		device = _engine;
}
To use the LTE Game Engine you must first set it up in your main file (all things added from last tutorial are preceded by /***new***/, some things have been taken out:

Code:
// where play state is an inherited class from GameState
/***new***/
#include <engine.h>
/***new***/
// This is included because it sets up the program to be run on PSP
// (this is the same common.h that is used in the examples in the LTE SDK)
#include "common.h"
#include "GameEngine.h"

/***new***/
// I prefer using namespaces you can skip this if you know what you are doing

/***new***/
// Main LTE namespace
using namespace engine;

/***new***/
// Sub namespaces
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

/***new***/
// Because we use common.h we use engineMain instead so we don't have to worry
// about setting up the PSP specific callbacks and everything like that
int engineMain(unsigned int argc, void * argv)
{
     /***new***/
     // Set up for PSP (this is in common.h it is used to set up the PSP specific stuff)
     setupPSP();

     /***new***/
     // Our device objects that are used to control LTE
     engineDevice * device = NULL;
     IVideoDriver * driver = NULL;
     ISceneManager * smgr = NULL;
     IGUIEnvironment * guienv = NULL;

     /***new***/
     // Create a new game engine
     GameEngine * ge = new GameEngine();

     /***new***/
     // Create our device, and get our handlers (the reason we set them to NULL and
     // then fill them in so we can check later to make sure they are present)
     // Here we pass our new game engine object to the createDevice function to get a
     // new device. It also sends the events to ge now.
     device = createDevice(ge, false);
     driver = device->getVideoDriver();
     smgr = device->getSceneManager();
     guienv = device->getGUIEnvironment();

     // Give ge a pointer to the device
     ge->SetDevice(device);

     // Transfer control to the game engine
     ge->Run();
}
Game state needs to change some:

Code:
// GameState.h

#include <engine.h>

// Main LTE namespace
using namespace engine;

// Sub namespaces
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class GameState
{
public:
	// Constructor (so we can get access to the LTE device
	GameState(engineDevice * _engine);
	// Destructor (virtual so that derived functions are called when calling 
        // from a GameState pointer.
	virtual ~GameState(void);
	// Main game loop (must be overriden)
	virtual void Run() = 0;
	// OnEvent (This is where we deal with our events that will be passed
        // from GameEngine
	virtual bool OnEvent(SEvent e);
protected:
	// LTE engine
	engineDevice * device;
	// Video driver
	IVideoDriver * driver;
	// Scene Manager
	ISceneManager * smgr;
	// Graphical user interface
	IGUIEnvironment * guienv;
};
Now for the implementation:

Code:
// GameState.cpp
#include "GameState.h"

GameState::GameState(engineDevice * _engine)
{
	// Point to our LTE engine
	device = _engine;
	// Grab it so it won't die. This is one way to keep track of how many
        // pointers there are to this object. When there are none it will be deleted
        // automatically
	device->grab();
	// Set the driver
	driver = device->getVideoDriver();
	// Set the scene manager
	smgr = device->getSceneManager();
	// Set the guienv
	guienv = device->getGUIEnvironment();
}

GameState::~GameState(void)
{
        // We drop the device so that it can be deleted automatically (this must be
        // called for each ->grab()
	device->drop();
	device = NULL;
}

bool GameState::OnEvent(SEvent e)
{
        // This is where we deal with any events we have
        // more on this in another tutorial
	if (!device)
		return false;
	switch (e.EventType)
	{
	case EET_GUI_EVENT:
		return true;
		break;
	case EET_MOUSE_INPUT_EVENT:
		return true;
		break;
	case EET_KEY_INPUT_EVENT:
		return true;
		break;
	case EET_LOG_TEXT_EVENT:
		return true;
		break;
	case EET_AUDIO_EVENT:
		return true;
		break;
	case EET_USER_EVENT:
		return true;
		break;
	default:
		break;
	};
	return false;
}
Inherit a new game state class called Splash.

Code:
// SplashState.h

#include "gamestate.h"
#include <engine.h>

// Main LTE namespace
using namespace engine;

// Sub namespaces
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class SplashState :
	public GameState
{
private:
	// This is our splash image that will be displayed on the screen
	ITexture * splash;
        // This is to help count how long it is displayed
	u32 oldTick;
public:
	SplashState(engineDevice * _engine);
	~SplashState(void);
	// Main loop of state
	void Run(void);
};
Implement it as follows:

Code:
// SplashState.cpp

#include "SplashState.h"

// This is our constructor we are constructing the game state from the parameters
// that are passed to SplashState
SplashState::SplashState(engineDevice * _engine)
: GameState(_engine)
{
	if (driver)
	{
		// Here we load the splash screen texture file into our Texture pointer
                // You'll need to provide a 480x272 bitmap to use as your splash screen
		splash = driver->getTexture("splash.bmp");

		// We grab the current number of ticks. Later we use this to tell how much
                // time has passed so we know when to go to the next state
		oldTick = device->getTimer()->getTime();
	}
}

SplashState::~SplashState(void)
{
        // Drop our texture
	splash->drop();
        // This is used to clear all of the textures currently in use
        // Never use this unless you are sure everything that uses a texture
        // is done using it and deleted
	driver->removeAllTextures();
}

// Main loop of state
void SplashState::Run(void)
{
        // Do any before scene stuff here

	// Call begin scene (do as little as possible between this and end scene)
        // This has to be called before rendering anything to the screen
	driver->beginScene(true, true, SColor(255, 255, 255, 255));

	// This tells the scene manager to draw everything that it has inside of it
	smgr->drawAll();

	// Here we want to draw our splash texture to the screen (this assumes it is a
        // full screen image)
	driver->draw2DImage(splash, position2d<s32>(0, 0), rect<s32>(0, 0, 480,272), 0, SColor(255, 255, 255, 255), false);

	// Draw the guienv
	guienv->drawAll();

	// Draw anything we want on top of the guienv

	// End the scene (this is called after drawing everything)
	driver->endScene();

	// Do after the scene stuff

	// Make sure the screen shows up for 2 seconds
	if (device->getTimer()->getTime() - oldTick > 2000)
	{
		// Change the splash or do whatever you want to do here because the 
                // splash screen is done showing up
	}
}
There you have it, if I didn't mess anything up and if you understand what I did you should see a splash screen show up, otherwise I probably left something out, or you made a mistake.
__________________
A wise man once said "...what was I saying..."
Reply With Quote
  #2  
Old 03-31-2009, 06:29 AM
pirata nervo pirata nervo is offline
Moderator
PSP Titan
 

Join Date: Mar 2007
Location: www.consoleworld.net
Posts: 5,556
pirata nervo is on a distinguished road
Default

Thanks for posting another tutorial. I'm adding it to the mega thread
__________________

Reply With Quote
  #3  
Old 04-01-2009, 01:33 PM
lokiare1's Avatar
lokiare1 lokiare1 is offline
Programmer
PSP Enthusiast
 

Join Date: Jul 2005
Location: Arkansas, USA
Posts: 466
lokiare1 is on a distinguished road
Default

You are welcome If this doesnt work please tell me. So I can fix it. The next tutorial will be about how to load a level and make it run at a decent frame rate. It will include how to set up the camera for an FPS style shooter.
__________________
A wise man once said "...what was I saying..."
Reply With Quote
  #4  
Old 04-30-2009, 07:42 PM
SG57's Avatar
SG57 SG57 is offline
Homebrew Idol 2 Winner
PSP Guru
 

Join Date: Apr 2007
Location: Washington
Posts: 1,568
SG57 Has a Beginner Reputation
Default

Hey - that's a nice structured flow, but I have a few concerns regarding resource management..

That deconstructor is very poor... Imagine implementing a 'paused' state or even a 'sub-menu' state, constantly unloading/reloading textures and resources - it'd be horrendous, though i think you are just using this as an example and are well aware of that lol.

But hey - you are committing a taboo by dropping the 'splash' ITexture and only are getting away with it due to the 'removeAllTextures' proceeding it. I don't know if i may be seeing things wrong but rule of thumb, unless you clearly use the word 'create' when defining that variable, don't drop it as the driver has it stored somewhere.

Better:
Code:
SplashState::~SplashState(void)
{
	driver->removeTexture(splash);
	splash = NULL;
}
__________________
...at what speed must I live.. to be able to see you again?...

Win money while playing Kitten Cannon!

Check out all my work on my new site - from Kitten Cannon to Boxhead to Light Cycle 3D
Reply With Quote
  #5  
Old 05-04-2009, 10:40 AM
MTN's Avatar
MTN MTN is offline
Programmer
PSP Hacks Member
 
Join Date: Jan 2009
Location: ...
Posts: 272
MTN Has a Beginner Reputation
Default

hi . i know your busy probably for Homebrew idol but is this (LTE) a different sdk for psp or its something like oslib ? how can it use oop with C?
Reply With Quote
  #6  
Old 05-04-2009, 06:01 PM
SG57's Avatar
SG57 SG57 is offline
Homebrew Idol 2 Winner
PSP Guru
 

Join Date: Apr 2007
Location: Washington
Posts: 1,568
SG57 Has a Beginner Reputation
Default

http://www.ltestudios.com/

Read up on it there, if you still don't understand I don't think it's worth your time figuring it out.
__________________
...at what speed must I live.. to be able to see you again?...

Win money while playing Kitten Cannon!

Check out all my work on my new site - from Kitten Cannon to Boxhead to Light Cycle 3D
Reply With Quote
  #7  
Old 05-05-2009, 07:33 AM
MTN's Avatar
MTN MTN is offline
Programmer
PSP Hacks Member
 
Join Date: Jan 2009
Location: ...
Posts: 272
MTN Has a Beginner Reputation
Default

thanks i did . i guess i have to do that in summer . is there a way to download Doxygen's doc from the site ?

Last edited by MTN; 05-05-2009 at 07:36 AM.
Reply With Quote
  #8  
Old 05-05-2009, 05:53 PM
SG57's Avatar
SG57 SG57 is offline
Homebrew Idol 2 Winner
PSP Guru
 

Join Date: Apr 2007
Location: Washington
Posts: 1,568
SG57 Has a Beginner Reputation
Default

Download the engine from the site (or anywhere really) and it will come with the documentation.
__________________
...at what speed must I live.. to be able to see you again?...

Win money while playing Kitten Cannon!

Check out all my work on my new site - from Kitten Cannon to Boxhead to Light Cycle 3D
Reply With Quote
  #9  
Old 05-07-2009, 08:41 PM
lokiare1's Avatar
lokiare1 lokiare1 is offline
Programmer
PSP Enthusiast
 

Join Date: Jul 2005
Location: Arkansas, USA
Posts: 466
lokiare1 is on a distinguished road
Default

You probably want to download the version I uploaded, or the version that Brick is working on if they ever release it. Since the version on the LTE site is messed up. It also has a steep learning curve. You should stick with OsLib until you find that it is not robust enough for what you are wanting to do, such as making a 3D game.
__________________
A wise man once said "...what was I saying..."
Reply With Quote
  #10  
Old 05-15-2009, 12:02 AM
SG57's Avatar
SG57 SG57 is offline
Homebrew Idol 2 Winner
PSP Guru
 

Join Date: Apr 2007
Location: Washington
Posts: 1,568
SG57 Has a Beginner Reputation
Default

Think you can give me a link to the post containing either ?

Would love to get the one with the PSPGL texture memory leak fix, sliding fix and falling through the floor fix heh.

Oh and hey - as an update lokaire - why not use a GUI in-out fader? It adds polish to the game as well as is your timer to tell when it's time to transition to the next state

For instance....

Add this to existing GameState.h as 'protected':
Code:
	// Used for fading in out of this gamestate
  IGUIInOutFader* fader;
Add this to existing GameState.cpp:

GameState::GameState()
Code:
  // add fader to this gamestate
  fader = guienv->addInOutFader();
  fader->setColor(SColor(0,0,0,0));
  fader->fadeIn(4000 /* 4 seconds */);
GameState::~GameState
Code:
	// Remove fader
	fader->remove();
	fader = NULL;
Add this to existing SplashState.cpp (any state):

Run() - NOTE: after the scene
Code:
  if (fader->isReady())
  {
    if (fader->getColor() == SColor(0,0,0,0))
    {
      printf("Done fading In, Fading out now\n");
      fader->setColor(SColor(255,0,0,0));
      fader->fadeOut(4000 /* 4 seconds */);
    }
    else
    {
      EndState(200); // end your state (go to next state)
    }
  }
This is jsut my setup and works great and looks fabulous
__________________
...at what speed must I live.. to be able to see you again?...

Win money while playing Kitten Cannon!

Check out all my work on my new site - from Kitten Cannon to Boxhead to Light Cycle 3D
Reply With Quote
Reply

 



Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:38 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©