zengine/src/ZE_ZEngine.cpp

605 lines
13 KiB
C++
Raw Normal View History

2002-11-21 05:40:49 +00:00
/*******************************************************************************
This file is Part of the ZEngine Library for SDL Game Development.
Copyright (C) 2002 ConceptOfZero.net
Licensed under the BSD License, see licensing.txt.
The maintainer of this library is James Turk (james@conceptofzero.net)
and the home of this Library is http://www.conceptofzero.net/
*******************************************************************************/
/*!
\par File Header:
File: ZE_ZEngine.cpp <br>
Description: Implementation source file for ZEngine library main singleton class. <br>
Author(s): James Turk <br>
2002-11-28 23:15:52 +00:00
$Id: ZE_ZEngine.cpp,v 1.2 2002/11/28 23:19:55 cozman Exp $<br>
2002-11-21 05:40:49 +00:00
\file ZE_ZEngine.cpp
\brief Central source file for ZEngine.
Actual implementation of ZEngine singleton class at heart of ZEngine.
**/
#include "ZE_ZEngine.h"
namespace ZE
{
ZEngine *ZEngine::sInstance=NULL;
ZEngine::ZEngine()
{
mWidth = 640;
mHeight = 480;
mBPP = 16;
mFullscreen = true;
#ifdef USE_SDL_MIXER
mRate = 22050;
mStereo = false;
#endif
mScreen = NULL;
mActive = mQuit = false;
mKeyPressed = NULL;
mMouseX = mMouseY = 0;
mMouseB = 0;
mUnpauseOnActive = mPaused = false;
mLastPause = mPausedTime = mLastTime = 0;
mSecPerFrame = 0.0;
}
ZEngine* ZEngine::GetInstance()
{
if(!sInstance)
sInstance = new ZEngine;
return sInstance;
}
void ZEngine::ReleaseInstance()
{
if(sInstance)
{
2002-11-28 23:15:52 +00:00
sInstance->CloseDisplay();
2002-11-21 05:40:49 +00:00
delete sInstance;
}
sInstance = NULL;
}
string ZEngine::GetVersion()
{
return VERSION;
}
void ZEngine::SetupDisplay(int width, int height, int bpp, bool fullscreen)
{
mWidth = width;
mHeight = height;
mBPP = bpp;
mFullscreen = fullscreen;
}
#ifdef USE_SDL_MIXER
void ZEngine::SetupSound(int rate, bool stereo)
{
mRate = rate;
mStereo = stereo;
}
#endif
2002-11-28 23:15:52 +00:00
void ZEngine::CreateDisplay(string title, string icon)
2002-11-21 05:40:49 +00:00
{
2002-11-28 23:15:52 +00:00
Uint32 flags;
2002-11-21 05:40:49 +00:00
ImageData iconImg;
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0)
{
LogError(FormatStr("SDL could not be Initialized: %s", SDL_GetError()));
//CloseWindow();
}
#ifdef USE_SDL_MIXER
Mix_OpenAudio(mRate, AUDIO_S16SYS, mStereo?2:1, 4096); //Open Audio Stream (Stereo?2:1 is conditional for number of channels)
#endif
2002-11-28 23:15:52 +00:00
#ifdef USE_OPENGL_2D
int rgb_size[3];
2002-11-21 05:40:49 +00:00
2002-11-28 23:15:52 +00:00
switch (mBPP)
{
case 8:
rgb_size[0] = 3;
rgb_size[1] = 3;
rgb_size[2] = 2;
break;
case 15:
case 16:
rgb_size[0] = 5;
rgb_size[1] = 5;
rgb_size[2] = 5;
break;
default:
rgb_size[0] = 8;
rgb_size[1] = 8;
rgb_size[2] = 8;
break;
}
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
flags = SDL_OPENGL;
#else //!USE_OPENGL_2D
SDL_VideoInfo *videoInfo = const_cast<SDL_VideoInfo*>(SDL_GetVideoInfo());
flags = SDL_DOUBLEBUF|SDL_HWPALETTE;
2002-11-21 05:40:49 +00:00
//check capabilities and use what we can//
if(videoInfo->hw_available)
flags |= SDL_HWSURFACE;
else
flags |= SDL_SWSURFACE;
if(videoInfo->blit_hw)
flags |= SDL_HWACCEL;
2002-11-28 23:15:52 +00:00
#endif //USE_OPENGL_2D
2002-11-21 05:40:49 +00:00
//Window Manager settings//
if(!icon.length())
SDL_WM_SetCaption(title.c_str(),NULL);
else
{
SDL_WM_SetCaption(title.c_str(),icon.c_str());
iconImg = LoadImage(icon);
SDL_WM_SetIcon(iconImg.image,NULL);
FreeImage(iconImg);
}
2002-11-28 23:15:52 +00:00
//create SDL screen and update settings based on returned screen//
2002-11-21 05:40:49 +00:00
if(mFullscreen)
flags |= SDL_FULLSCREEN;
mScreen = SDL_SetVideoMode(mWidth, mHeight, mBPP, flags);
2002-11-28 23:15:52 +00:00
mWidth = mScreen->w;
mHeight = mScreen->h;
mBPP = mScreen->format->BitsPerPixel;
#ifdef USE_OPENGL_2D
//OpenGL code from SDL project testgl.c//
glViewport(0,0,mWidth,mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
/* This allows alpha blending of 2D textures with the scene*/
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, (GLdouble)mWidth, (GLdouble)mHeight, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
#endif //USE_OPENGL_2D
2002-11-21 05:40:49 +00:00
if(!mScreen)
{
LogError(FormatStr("Unable to set video mode %dx%d (%dBpp): %s",mWidth,mHeight,mBPP,SDL_GetError()));
2002-11-28 23:15:52 +00:00
CloseDisplay();
2002-11-21 05:40:49 +00:00
}
mKeyPressed = SDL_GetKeyState(NULL);
#ifdef USE_SDL_TTF
TTF_Init();
#endif
mLastTime = mPausedTime = SDL_GetTicks();
mActive = true;
}
2002-11-28 23:15:52 +00:00
void ZEngine::CloseDisplay()
2002-11-21 05:40:49 +00:00
{
#ifdef USE_SDL_TTF
TTF_Quit();
#endif
#ifdef USE_SDL_MIXER
Mix_CloseAudio();
#endif
#ifdef USE_PHYSFS
PHYSFS_deinit();
#endif
SDL_Quit();
}
2002-11-28 23:15:52 +00:00
SDL_Surface *ZEngine::Display()
2002-11-21 05:40:49 +00:00
{
return mScreen;
}
void ZEngine::UpdateScreen()
{
2002-11-28 23:15:52 +00:00
#ifdef USE_OPENGL_2D
SDL_GL_SwapBuffers();
#else //!USE_OPENGL_2D
2002-11-21 05:40:49 +00:00
SDL_Flip(mScreen);
2002-11-28 23:15:52 +00:00
#endif //USE_OPENGL_2D
2002-11-21 05:40:49 +00:00
mSecPerFrame = (GetTime()-mLastTime)/1000.0;
mLastTime = GetTime();
}
Uint32 ZEngine::MapColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return SDL_MapRGBA(mScreen->format,r,g,b,a);
}
void ZEngine::Clear(Uint32 color, SDL_Rect *rect)
{
SDL_FillRect(mScreen,rect,color);
}
2002-11-28 23:15:52 +00:00
void ZEngine::Delay(Uint32 milliseconds)
2002-11-21 05:40:49 +00:00
{
SDL_Delay(milliseconds);
}
Uint32 ZEngine::GetTime()
{
if(mPaused)
return SDL_GetTicks() - (mPausedTime + (SDL_GetTicks() - mLastPause));
else
return SDL_GetTicks() - mPausedTime;
}
void ZEngine::PauseTimer()
{
if(!mPaused)
{
mLastPause = SDL_GetTicks();
mPaused = true;
}
}
void ZEngine::UnpauseTimer()
{
if(mPaused)
{
mPausedTime += (SDL_GetTicks() - mLastPause);
mPaused = false;
}
}
double ZEngine::GetFrameTime()
{
return mSecPerFrame;
}
bool ZEngine::IsPaused()
{
return mPaused;
}
bool ZEngine::IsActive()
{
return mActive;
}
void ZEngine::RequestQuit()
{
mQuit = true; //simply request a quit, nothing more
}
bool ZEngine::QuitRequested()
{
return mQuit;
}
bool ZEngine::KeyIsPressed(SDLKey key)
{
return mKeyPressed[key] == 1;
}
void ZEngine::HideCursor()
{
SDL_ShowCursor(SDL_DISABLE);
}
void ZEngine::ShowCursor()
{
SDL_ShowCursor(SDL_ENABLE);
}
2002-11-28 23:15:52 +00:00
int ZEngine::MouseX()
2002-11-21 05:40:49 +00:00
{
return mMouseX;
}
2002-11-28 23:15:52 +00:00
int ZEngine::MouseY()
2002-11-21 05:40:49 +00:00
{
return mMouseY;
}
bool ZEngine::LButtonPressed()
{
return (mMouseB & SDL_BUTTON_LMASK) > 0;
}
bool ZEngine::RButtonPressed()
{
return (mMouseB & SDL_BUTTON_RMASK) > 0;
}
bool ZEngine::MouseInRect(SDL_Rect *rect)
{
return (mMouseX >= rect->x && mMouseX <= rect->x+rect->w &&
mMouseY >= rect->y && mMouseY <= rect->y+rect->h);
}
void ZEngine::CheckEvents()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_VIDEOEXPOSE:
case SDL_ACTIVEEVENT:
if(event.active.state & SDL_APPACTIVE || event.active.state & SDL_APPINPUTFOCUS)
{
if( (event.type == SDL_ACTIVEEVENT && event.active.gain == 1) || event.type == SDL_VIDEOEXPOSE)
{
mActive = true;
if(mUnpauseOnActive)
UnpauseTimer();
}
else
{
mActive = mUnpauseOnActive = false;
if(!mPaused)
{
mUnpauseOnActive = true;
PauseTimer();
}
else
mUnpauseOnActive = false;
}
}
break;
case SDL_QUIT:
mQuit = true;
break;
default:
break;
}
}
mKeyPressed = SDL_GetKeyState(NULL); //recommended but not needed (says Sam)
if(mKeyPressed[SDLK_F4] && (mKeyPressed[SDLK_LALT] || mKeyPressed[SDLK_RALT]))
mQuit = true;
mMouseB = SDL_GetMouseState(&mMouseX,&mMouseY);
}
#ifdef USE_PHYSFS
void ZEngine::InitPhysFS(string argv)
{
string::size_type pos;
PHYSFS_init(argv.c_str());
pos = argv.rfind(PHYSFS_getDirSeparator());
if(pos != string::npos)
AddPhysFSDir(argv.substr(0,pos));
}
void ZEngine::AddPhysFSDir(string dir)
{
PHYSFS_addToSearchPath(dir.c_str(),0);
}
#endif //USE_PHYSFS
ImageData ZEngine::LoadImage(string filename)
{
ImageData img;
//using physfs//
#ifdef USE_PHYSFS
SDL_RWops *rw;
rw = PHYSFSRWOPS_openRead(filename.c_str());
if(!rw)
LogError(FormatStr("PhysFS RWops failed: %s",SDL_GetError()));
#ifdef USE_SDL_IMAGE
img.image = IMG_Load_RW(rw,0);
#else
img.image = SDL_LoadBMP_RW(rw,0);
#endif //USE_SDL_IMAGE
SDL_FreeRW(rw);
//end using physfs//
//Just SDL//
#else
#ifdef USE_SDL_IMAGE
img.image = IMG_Load(filename.c_str());
#else
img.image = SDL_LoadBMP(filename.c_str());
#endif //USE_SDL_IMAGE
#endif //USE_PHYSFS
if(!img.image)
{
img.filename = FormatStr("LoadImage could not load %s.",filename.c_str());
LogError(img.filename);
}
else
img.filename = filename;
return img;
}
void ZEngine::FreeImage(ImageData &image)
{
if(image.image)
{
SDL_FreeSurface(image.image);
image.image = NULL;
image.filename = "free";
}
}
#ifdef USE_SDL_MIXER
SoundData ZEngine::LoadSound(string filename)
{
SoundData snd;
#ifdef USE_PHYSFS
SDL_RWops *rw;
rw = PHYSFSRWOPS_openRead(filename.c_str());
snd.sound = Mix_LoadWAV_RW(rw,0);
SDL_FreeRW(rw);
#else
snd.sound = Mix_LoadWAV(filename.c_str());
#endif //USE_PHYSFS
if(!snd.sound)
{
snd.filename = FormatStr("LoadSound could not load %s.",filename.c_str());
LogError(snd.filename);
}
else
snd.filename = filename;
return snd;
}
void ZEngine::FreeSound(SoundData &sound)
{
if(sound.sound)
{
Mix_FreeChunk(sound.sound);
sound.sound = NULL;
sound.filename = "free";
}
}
MusicData ZEngine::LoadMusic(string filename)
{
MusicData mus;
//Currently SDL_Mixer doesn't support Music from a RW
//#ifdef USE_PHYSFS
// SDL_RWops *rw;
// rw = PHYSFSRWOPS_openRead(filename.c_str());
// mus.music = Mix_LoadMUS_RW(filename.c_str(),0);
// SDL_FreeRW(rw);
//#else
mus.music = Mix_LoadMUS(filename.c_str());
//#endif //USE_PHYSFS
if(!mus.music)
{
mus.filename = FormatStr("LoadMusic could not load %s.",filename.c_str());
LogError(mus.filename);
}
else
mus.filename = filename;
return mus;
}
void ZEngine::FreeMusic(MusicData &music)
{
if(music.music)
{
Mix_FreeMusic(music.music);
music.music = NULL;
music.filename = "free";
}
}
#endif
#ifdef USE_SDL_TTF
FontData ZEngine::LoadFont(string filename, int size)
{
FontData fnt;
//Currently SDL_ttf doesn't support Fonts from a RW
//#ifdef USE_PHYSFS
// SDL_RWops *rw;
// rw = PHYSFSRWOPS_openRead(filename.c_str());
// fnt.font = TTF_OpenFontRW(rw,0);
// SDL_FreeRW(rw);
//#else
fnt.font = TTF_OpenFont(filename.c_str(),size);
//#endif //USE_PHYSFS
if(!fnt.font)
{
fnt.filename = FormatStr("LoadFont could not load %s.",filename.c_str());
LogError(fnt.filename);
}
else
fnt.filename = filename;
return fnt;
}
void ZEngine::FreeFont(FontData &font)
{
if(font.font)
{
TTF_CloseFont(font.font);
font.font = NULL;
font.filename = "free";
}
}
#endif
2002-11-28 23:15:52 +00:00
int ZEngine::Width()
2002-11-21 05:40:49 +00:00
{
return mWidth;
}
2002-11-28 23:15:52 +00:00
int ZEngine::Height()
2002-11-21 05:40:49 +00:00
{
return mHeight;
}
2002-11-28 23:15:52 +00:00
int ZEngine::BPP()
2002-11-21 05:40:49 +00:00
{
return mBPP;
}
bool ZEngine::IsFullscreen()
{
return mFullscreen;
}
}