- Added early implementation of CWindow System which easily can print dialogs, menus and much more!

- Youseeinyourmind and vorticonelder are now one function (showHintmessage)
- This also fixed the VorticonElder bug which made the system freeze, because dialog was printed a lot of times.

git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@194 4df4b0f3-56ce-47cb-b001-ed939b7d65a6
This commit is contained in:
gerstrong
2009-07-31 12:27:16 +00:00
parent 57c4d2a67f
commit 4c5616a585
9 changed files with 349 additions and 89 deletions

View File

@@ -312,6 +312,21 @@ unsigned char xa,ya;
}
}
void CGraphics::drawCharacter(float x, float y, int f)
{
assert(f >= 0 && f < 256);
unsigned char xa,ya;
for(ya=0;ya<8;ya++)
{
for(xa=0;xa<8;xa++)
{
g_pVideoDriver->setpixel((unsigned int)((x*320)+xa), (unsigned int)((y*200)+ya), (unsigned char)font[f][ya][xa]);
}
}
}
void CGraphics::sb_drawCharacter(int x, int y, int f)
{
unsigned char xa,ya;
@@ -605,7 +620,7 @@ unsigned int i,x=xoff,y;
if (c!=13)
{
if (highlight) c|=128;
drawCharacter(x, y, c);
drawCharacter((int)x, (int)y, c);
x+=8;
}
else
@@ -615,6 +630,14 @@ unsigned int i,x=xoff,y;
}
}
}
// font drawing functions (float version)
void CGraphics::drawFont(const std::string& text, float xoff, float yoff, int highlight)
{
drawFont(text, (int)(xoff*320), (int)(yoff*200), highlight);
}
void CGraphics::sb_font_draw(const std::string& text, int xoff, int yoff)
{
unsigned int i,x,y;

View File

@@ -31,6 +31,7 @@ public:
void drawSprite(int x, int y, unsigned int s, int objectnum);
void eraseSprite(int x, int y, unsigned int s, int objectnum);
void drawCharacter(int x, int y, int f);
void drawCharacter(float x, float y, int f);
void sb_drawCharacter(int x, int y, int f);
void sb_drawCharacterwithmask(int x, int y, int f, char mask);
void sb_drawColorcharacter(int x, int y, int f, unsigned short colour, unsigned short bgcolour);
@@ -46,6 +47,7 @@ public:
int getBitmapNumberFromName(const char *bmname);
void sb_drawCharacterinverse(int x, int y, int f);
void drawFont(const std::string& text, int xoff, int yoff, int highlight);
void drawFont(const std::string& text, float xoff, float yoff, int highlight);
void sb_font_draw(const std::string& text, int xoff, int yoff);
void sb_mask_font_draw(const std::string& text, int xoff, int yoff, char mask);
void sb_color_font_draw(const std::string& text, int xoff, int yoff, unsigned int colour, unsigned short bgcolour);

61
src/dialog/CTextBox.cpp Normal file
View File

@@ -0,0 +1,61 @@
/*
* CTextBox.cpp
*
* Created on: 30.07.2009
* Author: gerstrong
*/
#include "CTextBox.h"
#include "../CGraphics.h"
#include "../StringUtils.h"
CTextBox::CTextBox(float x, float y, float w, float h, float font_w, float font_h, const std::string& text) {
m_fontwidth = font_w;
m_fontheight = font_h;
m_x = x;
m_y = y;
m_w = w;
m_h = h;
m_String = text;
}
void CTextBox::format()
{
// This function format properly the text into a box (multiple lines),
// separating the strings by words.
std::string word;
std::string::iterator it = m_String.begin();
std::string oneline;
unsigned int i = 0;
while(m_String.length() > i)
{
word = GetNextWord(it, m_String);
if((oneline.length() + word.length()) > m_w/m_fontwidth)
{
if(*(oneline.end()-1) == ' ') oneline.erase(oneline.end()-1);
m_Textline.push_back(oneline);
oneline.clear();
}
oneline += word + " ";
it += word.length() + 1;
i += word.length() + 1;
}
// The last line might not be full, but must also be printed
m_Textline.push_back(oneline);
}
void CTextBox::draw()
{
// Draw Routine for the Textbox
for(unsigned int i=0 ; i<m_Textline.size() ; i++ )
{
g_pGraphics->drawFont(m_Textline[i], m_x, m_y+i*m_fontheight, 0); // 0 is blank colour
if( i*m_fontheight>m_h )
break;
}
}

29
src/dialog/CTextBox.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* CTextBox.h
*
* Created on: 30.07.2009
* Author: gerstrong
*/
#ifndef CTEXTBOX_H_
#define CTEXTBOX_H_
#include <string>
#include <vector>
class CTextBox {
public:
CTextBox(float x, float y, float w, float h, float font_w, float font_h, const std::string& text);
void format();
void draw();
private:
std::string m_String;
std::vector <std::string> m_Textline;
float m_x, m_y, m_w, m_h;
float m_fontwidth, m_fontheight;
};
#endif /* CTEXTBOX_H_ */

120
src/dialog/CWindow.cpp Normal file
View File

@@ -0,0 +1,120 @@
/*
* CWindow.cpp
*
* Created on: 29.07.2009
* Author: gerstrong
*/
#include "CWindow.h"
#include "../CGraphics.h"
CWindow::CWindow(float x, float y, float w, float h)
{
m_x = x;
m_y = y;
m_w = w;
m_h = h;
m_8x8tileheight = 8.0/200.0;
m_8x8tilewidth = 8.0/320.0;
}
CWindow::~CWindow() {
// Empty list ID, while also emptying
int textbox_ctr = 0;
while(!m_ID_List.empty())
{
switch(*m_ID_List.begin())
{
case OBJ_TYPE_TEXT:
delete m_TextBox[textbox_ctr++];
break;
}
m_ID_List.pop_front();
}
}
///////////////////////
// Creation Routines //
///////////////////////
void CWindow::addTextBox(float x, float y, float w, float h, const std::string& text, bool border_rel)
{
// Element coordinates are all relative and must go inside the borders if desired!
// if false it will be relative to the window itself and can be used as title border
if(border_rel)
{
x *= m_w;
x += (m_8x8tilewidth);
y *= m_h;
y += (m_8x8tileheight);
w -= 2*m_8x8tilewidth/(m_w);
h -= 2*m_8x8tileheight/(m_h);
}
CTextBox* ptr = new CTextBox(x + m_x,
y + m_y,
w*(m_w),
h*(m_h),
m_8x8tilewidth, m_8x8tileheight, text);
m_TextBox.push_back(ptr);
m_TextBox.back()->format();
m_ID_List.push_back(OBJ_TYPE_TEXT);
}
////////////////////////
// Rendering Routines //
////////////////////////
void CWindow::render()
{
// draw the window
drawWindow();
// Draw the window objects which are inside
// Process the ID-List and render every Element of the Window
std::list<int> :: iterator i;
int textbox_ctr = 0;
for( i = m_ID_List.begin() ; i != m_ID_List.end() ; i++ )
{
switch(*i)
{
case OBJ_TYPE_TEXT:
m_TextBox[textbox_ctr++]->draw();
break;
}
}
}
void CWindow::drawWindow()
{
// Use we use floating values, the drawing routine is very important to get a well sized window.
// first draw the blank rect
float i, j;
for(j = 0.0 ; j < m_h - m_8x8tileheight ; j+= (m_8x8tileheight*(7.0/8.0)) )
{
for(i = 0.0 ; i < m_w - m_8x8tilewidth ; i+= m_8x8tilewidth )
g_pGraphics->drawCharacter( m_x + i, m_y + j, 32); // 32 is blank tile
g_pGraphics->drawCharacter( m_x + m_w - m_8x8tilewidth, m_y + j, 32); // for the last tile
}
// then the borders
for( i = m_8x8tilewidth ; i < m_w-m_8x8tilewidth ; i+= m_8x8tilewidth )
{
g_pGraphics->drawCharacter( m_x + i, m_y, 2); // 2 is one upper-border
g_pGraphics->drawCharacter( m_x + i, m_y + m_h - m_8x8tileheight, 7); // 2 is also the lower-border
}
g_pGraphics->drawCharacter( m_x + m_w - m_8x8tilewidth, m_y, 2); // for the last tile
g_pGraphics->drawCharacter( m_x + m_w - m_8x8tilewidth, m_y + m_h - m_8x8tileheight, 2); // for the last tile
for( j = m_8x8tileheight ; j < m_h-m_8x8tileheight ; j+= (m_8x8tileheight*(7.0/8.0)) )
{
g_pGraphics->drawCharacter( m_x, m_y + j, 4); // 4 is one left-border
g_pGraphics->drawCharacter( m_x + m_w - m_8x8tilewidth, m_y + j, 5); // 4 is also the right-border
}
// At last the corners
g_pGraphics->drawCharacter( m_x, m_y , 1); // Upper-Left corner
g_pGraphics->drawCharacter( m_x + m_w - m_8x8tilewidth, m_y, 3); // Upper-Right corner
g_pGraphics->drawCharacter( m_x, m_y + m_h - m_8x8tileheight, 6); // Lower-Left corner
g_pGraphics->drawCharacter( m_x + m_w - m_8x8tilewidth, m_y + m_h - m_8x8tileheight, 8); // Lower-Right corner
}

44
src/dialog/CWindow.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* CWindow.h
*
* Created on: 29.07.2009
* Author: gerstrong
*/
#ifndef CWINDOW_H_
#define CWINDOW_H_
#include <list>
#include <vector>
#include <string>
#include "CTextBox.h"
enum{
OBJ_TYPE_TEXT
};
class CWindow {
public:
CWindow(float x, float y, float w, float h);
virtual ~CWindow();
void addTextBox(float x, float y, float w, float h, const std::string& text, bool border_rel);
void render();
private:
float m_x;
float m_y;
float m_h;
float m_w;
float m_8x8tileheight;
float m_8x8tilewidth;
std::list<int> m_ID_List;
std::vector<CTextBox*> m_TextBox;
void drawWindow();
};
#endif /* CWINDOW_H_ */

View File

@@ -1314,14 +1314,8 @@ void procgoodie(int t, int mpx, int mpy, int theplayer, stCloneKeenPlus *pCKP)
pCKP->Control.levelcontrol.tobonuslevel = 1;
break;
case YORPSTATUEHEAD:
if(pCKP->Control.levelcontrol.episode == 1)
{
youseeinyourmind(mpx, mpy, pCKP);
}
else if(pCKP->Control.levelcontrol.episode == 2)
if(!player[theplayer].blockedr && !player[theplayer].blockedl)
VorticonElder(mpx, mpy, pCKP);
case 22: // Game info block (Youseein your mind or vorticon elder...)
showGameHint(mpx, mpy, pCKP->Control.levelcontrol.episode, pCKP->Control.levelcontrol.curlevel);
break;
case 27:

View File

@@ -13,5 +13,6 @@ char gameiswon(stCloneKeenPlus *pCKP);
void game_save(char *fname, stCloneKeenPlus *pCKP);
int game_load(char *fname, stCloneKeenPlus *pCKP);
void showTextMB(int lines, char **text, stCloneKeenPlus *pCKP);
void showGameHint(int mpx, int mpy, int episode, int level);
unsigned int rnd(void);

View File

@@ -27,6 +27,8 @@
#include "StringUtils.h"
#include "FindFile.h"
#include "dialog/CWindow.h"
void banner(void)
{
@@ -153,98 +155,78 @@ void sb_dialogbox(int x1, int y1, int w, int h)
}
}
#define YORPSTATUEHEADUSED 485
void youseeinyourmind(int mpx, int mpy, stCloneKeenPlus *pCKP)
void showGameHint(int mpx, int mpy, int episode, int level)
{
int twirlframe, twirltimer;
char strname[80];
int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY;
std::string strname;
bool isgarg;
// First check, if the item has really been activated
if(!map_isanimated(mpx, mpy+(episode==2) ))
return;
int i;
isgarg = false;
if(episode == 1)
{
if(map.mapdata[mpx][mpy] >= 435 && map.mapdata[mpx][mpy] <= 438)
isgarg = true;
if (!isgarg)
{
if(!map_isanimated(mpx, mpy))
return;
}
// it's a garg statue
map_chgtile(mpx, mpy, 434);
else
{ // it's a garg statue
if(!map_isanimated(mpx, mpy))
return;
}
map_chgtile(mpx, mpy, 485);
for(i=0; i < 4 ; i++)
strname = "EP1_YSIYM_LVL" + itoa(level);
}
else if(episode == 2)
{
player[0].playcontrol[PA_JUMP+i] = 0;
// make the switch stop glowing
// There may be a bug. Be careful
map_chgtile(mpx, mpy+1, 432);
switch(level)
{
case 8:
strname = "EP2_VE_NOJUMPINDARK";
break;
case 10:
strname = "EP2_VE_EVILBELTS";
break;
}
}
map_deanimate(mpx, mpy+(episode==2));
const int twirl_speed = 100;
// In Episode 2 the floor must be deanimated, instead of the player, the player is at.?
// get the name of the string we need to display
sprintf(strname, "EP1_YSIYM_LVL%d", pCKP->Control.levelcontrol.curlevel);
CWindow *InfoTextWindow = new CWindow(0.2, 0.2, 0.6, 0.6);
InfoTextWindow->addTextBox(0.0f, 0.0f, 1.0f, 0.8f, getstring(strname), true);
InfoTextWindow->addTextBox(0.2f, 0.8f, 1.0f, 0.2f, "Okay!", true);
g_pInput->flushAll();
dlgX = GetStringAttribute(strname, "LEFT");
dlgY = GetStringAttribute(strname, "TOP");
dlgW = GetStringAttribute(strname, "WIDTH");
dlgH = GetStringAttribute(strname, "HEIGHT");
twirlX = GetStringAttribute(strname, "TWIRLX");
twirlY = GetStringAttribute(strname, "TWIRLY");
dialogbox(dlgX,dlgY,dlgW,dlgH);
g_pGraphics->drawFont(getstring(strname), (dlgX+1)<<3, (dlgY+1)<<3,0);
twirlframe = 0;
twirltimer = twirl_speed+1;
// wait for enter
do
{
if (twirltimer>twirl_speed)
{
g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe);
g_pVideoDriver->update_screen();
twirlframe++;
if (twirlframe>5) twirlframe=0;
twirltimer=0;
} else twirltimer++;
g_pInput->pollEvents();
g_pTimer->SpeedThrottle();
InfoTextWindow->render();
g_pVideoDriver->update_screen();
} while(!g_pInput->getPressedKey(KENTER) /*&& !immediate_keytable[KQUIT] && !getanyevent(pCKP)*/);
} while(!g_pInput->getPressedAnyCommand());
// make the statue head stop glowing
if (!isgarg)
{
map_chgtile(mpx, mpy, YORPSTATUEHEADUSED);
map_deanimate(mpx, mpy);
}
else
{ // it's a garg statue
map_chgtile(mpx, mpy, 434);
map_deanimate(mpx, mpy);
}
delete InfoTextWindow;
}
void VorticonElder(int mpx, int mpy, stCloneKeenPlus *pCKP)
{
CWindow *ElderTextWindow;
/*
int twirlframe, twirltimer;
int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY;
const int twirl_speed = 100;*/
const char *strName="";
const int twirl_speed = 100;
for(int i=0; i < 4 ; i++)
{
player[0].playcontrol[PA_JUMP+i] = 0;
}
// TODO: Pause the game, because CWindow won't do that
g_pInput->flushAll();
g_pSound->pauseSound();
ElderTextWindow = new CWindow(0.2, 0.2, 0.6, 0.6);
switch(pCKP->Control.levelcontrol.curlevel)
{
case 8:
@@ -260,35 +242,39 @@ void VorticonElder(int mpx, int mpy, stCloneKeenPlus *pCKP)
break;
}
dlgX = GetStringAttribute(strName, "LEFT");
/*dlgX = GetStringAttribute(strName, "LEFT");
dlgY = GetStringAttribute(strName, "TOP");
dlgW = GetStringAttribute(strName, "WIDTH");
dlgH = GetStringAttribute(strName, "HEIGHT");
twirlX = GetStringAttribute(strName, "TWIRLX");
twirlY = GetStringAttribute(strName, "TWIRLY");
twirlY = GetStringAttribute(strName, "TWIRLY");*/
dialogbox(dlgX, dlgY, dlgW, dlgH);
g_pGraphics->drawFont( getstring(strName), (dlgX+1)<<3, (dlgY+1)<<3,0);
//dialogbox(dlgX, dlgY, dlgW, dlgH);
//g_pGraphics->drawFont( getstring(strName), (dlgX+1)<<3, (dlgY+1)<<3,0);
// For what was pGraphics->drawFont
twirlframe = 0;
twirltimer = twirl_speed+1;
//twirlframe = 0;
//twirltimer = twirl_speed+1;
// wait for enter
do
{
if (twirltimer>twirl_speed)
/*if (twirltimer>twirl_speed)
{
g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe);
g_pVideoDriver->update_screen();
twirlframe++;
if (twirlframe>5) twirlframe=0;
twirltimer=0;
} else twirltimer++;
} else twirltimer++;*/
g_pInput->pollEvents();
g_pTimer->SpeedThrottle();
ElderTextWindow->render();
g_pVideoDriver->update_screen();
} while(!g_pInput->getPressedKey(KENTER) );
// make the switch stop glowing
// There may be a bug. Be careful
map_chgtile(mpx, mpy+1, 432);
map_deanimate(mpx, mpy+1);