- distributed the source code to more files - reduced some lines of source code git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@214 4df4b0f3-56ce-47cb-b001-ed939b7d65a6
387 lines
7.0 KiB
C++
387 lines
7.0 KiB
C++
/*
|
|
* CDialog.cpp
|
|
*
|
|
* Created on: 20.03.2009
|
|
* Author: gerstrong
|
|
*/
|
|
|
|
#include "CDialog.h"
|
|
|
|
#include <stdio.h> // Must be changed, when Graphics Class is implemented
|
|
#include "../funcdefs.h" // This class should not depend on those headers
|
|
#include <string.h>
|
|
|
|
#include "../keen.h"
|
|
#include "../sdl/CTimer.h"
|
|
#include "../include/gamedo.h"
|
|
#include "../CGraphics.h"
|
|
|
|
#include <iostream>
|
|
using namespace std;
|
|
|
|
|
|
#define FONT_TWIRL 9
|
|
#define FONT_UPARROW 15
|
|
#define FONT_DOWNARROW 19
|
|
#define TWIRL_TIME 25
|
|
#define TWIRL_NUM_FRAMES 5
|
|
|
|
CDialog::CDialog() {
|
|
x = y = w = h = 0;
|
|
|
|
number_of_options = 0;
|
|
selection = -1;
|
|
twirlframe = 0;
|
|
twirltime = 0;
|
|
scrollpos = 0;
|
|
|
|
isanimated = false;
|
|
isVisible = false;
|
|
|
|
OptionTextList = NULL;
|
|
}
|
|
|
|
CDialog::~CDialog() {
|
|
|
|
// If there is a list of optional text data, it must be freed!
|
|
if(OptionTextList != NULL)
|
|
freeTextListData();
|
|
}
|
|
void CDialog::freeTextListData(void)
|
|
{
|
|
stTextList* curTextptr;
|
|
stTextList* prevTextptr;
|
|
|
|
curTextptr = OptionTextList;
|
|
prevTextptr = NULL;
|
|
|
|
while(OptionTextList->nextElement)
|
|
{
|
|
if(curTextptr->nextElement == NULL)
|
|
{
|
|
delete curTextptr;
|
|
prevTextptr->nextElement = NULL;
|
|
curTextptr = OptionTextList;
|
|
}
|
|
else
|
|
{
|
|
prevTextptr = curTextptr;
|
|
curTextptr = (stTextList*)curTextptr->nextElement;
|
|
}
|
|
}
|
|
delete OptionTextList;
|
|
}
|
|
|
|
void CDialog::addSeparator(void)
|
|
{
|
|
addOptionText("");
|
|
}
|
|
|
|
void CDialog::addOptionText(const std::string& text)
|
|
{
|
|
std::string buf;
|
|
// This algorithm is similar to one pointer session and
|
|
// list implementation. TextList is the head.
|
|
if(OptionTextList == NULL)
|
|
{
|
|
OptionTextList = new stTextList;
|
|
OptionTextList->nextElement = NULL;
|
|
|
|
OptionTextList->text = "";
|
|
|
|
buf = text;
|
|
|
|
size_t length = buf.length();
|
|
|
|
// before the text is copied, check if that string is too long.
|
|
if(length > w-4)
|
|
{
|
|
OptionTextList->text = text.substr(0, w-7);
|
|
OptionTextList->text += "...";
|
|
}
|
|
else
|
|
{
|
|
OptionTextList->text = text;
|
|
}
|
|
|
|
number_of_options = 1;
|
|
selection = 0;
|
|
}
|
|
else
|
|
{
|
|
stTextList *curTextList;
|
|
|
|
curTextList = OptionTextList;
|
|
|
|
while (curTextList->nextElement != NULL)
|
|
{
|
|
curTextList = (stTextList*) curTextList->nextElement;
|
|
}
|
|
|
|
curTextList->nextElement = new stTextList;
|
|
|
|
curTextList = (stTextList*) curTextList->nextElement;
|
|
|
|
curTextList->text = "";
|
|
|
|
number_of_options++;
|
|
|
|
buf = text;
|
|
|
|
size_t length = buf.length();
|
|
|
|
// before the text is copied, check if that string is too long.
|
|
if(length > w-4)
|
|
{
|
|
curTextList->text = text.substr(0, w-7);
|
|
curTextList->text += "...";
|
|
}
|
|
else
|
|
{
|
|
curTextList->text = text;
|
|
}
|
|
curTextList->nextElement = NULL;
|
|
}
|
|
}
|
|
|
|
void CDialog::setOptionText(unsigned int pos, const std::string& text)
|
|
{
|
|
unsigned int i;
|
|
stTextList *curTextList = OptionTextList;
|
|
|
|
for(i=0 ; i<pos ; i++) {
|
|
if(!curTextList)
|
|
// TODO: print error
|
|
return;
|
|
curTextList = curTextList->nextElement;
|
|
}
|
|
|
|
curTextList->text = text;
|
|
}
|
|
|
|
void CDialog::setDimensions(int rectx, int recty, int rectw, int recth)
|
|
{
|
|
x = rectx;
|
|
y = recty,
|
|
w = rectw-1;
|
|
h = recth;
|
|
}
|
|
|
|
void CDialog::setVisible(bool value) { isVisible = value; }
|
|
|
|
void CDialog::renderDialog()
|
|
{
|
|
unsigned int i;
|
|
stTextList *curTextList;
|
|
|
|
if(!isVisible) return;
|
|
|
|
curTextList = OptionTextList;
|
|
|
|
// Open the Dialog animation
|
|
if(isanimated)
|
|
renderOpenDialogAnimation(x,y,w,h);
|
|
|
|
// draw the empty Dialog
|
|
drawDialogbox(x,y,w,h);
|
|
|
|
// draw the objects (text. items, etc.)
|
|
|
|
// scroll as many times necessary
|
|
for(i=0 ; i<scrollpos ; i++)
|
|
curTextList = (stTextList*) curTextList->nextElement;
|
|
|
|
i=0;
|
|
|
|
while(curTextList != NULL)
|
|
{
|
|
g_pGraphics->sb_font_draw(curTextList->text, (x+3)<<3, (y+i+1)<<3);
|
|
curTextList = (stTextList*) curTextList->nextElement;
|
|
i++;
|
|
if(i >= h-2)
|
|
break;
|
|
}
|
|
|
|
|
|
// Draw the twirl at the right position
|
|
// Render the smooth twirl
|
|
if(twirltime < TWIRL_TIME)
|
|
twirltime++;
|
|
else
|
|
{
|
|
twirlframe++;
|
|
twirltime=0;
|
|
}
|
|
|
|
if(twirlframe > TWIRL_NUM_FRAMES)
|
|
twirlframe=0;
|
|
|
|
g_pGraphics->sb_drawCharacter((x+1)<<3, (y+selection-scrollpos+1)<<3, FONT_TWIRL+twirlframe);
|
|
|
|
// Now draw the up and down arrows if the list is going to be scrolled
|
|
if(scrollpos > h-5)
|
|
g_pGraphics->sb_drawCharacter((x+w-1)<<3, (y+1)<<3, FONT_UPARROW);
|
|
|
|
if(scrollpos < (number_of_options-h+2) && number_of_options > (int)(h-2))
|
|
g_pGraphics->sb_drawCharacter((x+w-1)<<3, (y+h-2)<<3, FONT_DOWNARROW);
|
|
|
|
}
|
|
|
|
// The original Game had a open Dialog Animation. This is what that function does...
|
|
void CDialog::animateDialogBox(bool value){ isanimated = value; }
|
|
void CDialog::renderOpenDialogAnimation(int x,int y, int w, int h)
|
|
{
|
|
if(!isanimated || !isVisible)
|
|
return;
|
|
|
|
int timer=0;
|
|
|
|
int mx, my, mw, mh;
|
|
|
|
mw = mh = 0;
|
|
|
|
// Calculate the center
|
|
mx = x + (w>>1);
|
|
my = y + (h>>1);
|
|
|
|
do
|
|
{
|
|
if(timer == 10)
|
|
{
|
|
if(mx > x)
|
|
mx--;
|
|
if(my > y)
|
|
my--;
|
|
if(mh < h)
|
|
{
|
|
if(mh+1 == h)
|
|
mh++;
|
|
else
|
|
mh+=2;
|
|
}
|
|
if(mw < w)
|
|
{
|
|
if(mw+1 == w)
|
|
mw++;
|
|
else
|
|
mw+=2;
|
|
}
|
|
|
|
timer = 0;
|
|
}
|
|
|
|
|
|
if(mx <= x && my <= y && mh >= h && mw >= w)
|
|
break;
|
|
|
|
drawDialogbox(mx,my,mw,mh);
|
|
|
|
gamedo_AnimatedTiles();
|
|
gamedo_frameskipping();
|
|
g_pTimer->SpeedThrottle();
|
|
|
|
timer++;
|
|
}while(1);
|
|
|
|
isanimated = false;
|
|
}
|
|
|
|
std::string CDialog::getOptionString(unsigned int pos)
|
|
{
|
|
unsigned int i;
|
|
stTextList *curTextList;
|
|
|
|
curTextList = OptionTextList;
|
|
|
|
for(i=0 ; i<pos ; i++)
|
|
curTextList = (stTextList*) curTextList->nextElement;
|
|
|
|
return curTextList->text;
|
|
}
|
|
|
|
bool CDialog::setSelection(int value)
|
|
{
|
|
if(value < number_of_options && value >= 0)
|
|
{
|
|
selection = value;
|
|
|
|
if(selection < (int)scrollpos)
|
|
scrollpos = selection;
|
|
|
|
if(selection >= (int)(scrollpos+h-2) )
|
|
scrollpos = selection-h+3;
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int CDialog::getSelection(void)
|
|
{
|
|
return selection;
|
|
}
|
|
|
|
bool CDialog::setNextSelection()
|
|
{
|
|
int i=0;
|
|
if(selection+1 < number_of_options)
|
|
{
|
|
while(getOptionString(selection+i+1) == "")
|
|
i++;
|
|
|
|
selection += i;
|
|
}
|
|
else if(selection >= number_of_options-1)
|
|
selection = -1;
|
|
|
|
return setSelection(selection+1);
|
|
}
|
|
|
|
bool CDialog::setPrevSelection()
|
|
{
|
|
int i=0;
|
|
if(selection-1 > 0)
|
|
{
|
|
while(getOptionString(selection-i-1) == "")
|
|
i++;
|
|
|
|
selection -= i;
|
|
}
|
|
else if(selection-1 < 0)
|
|
selection = number_of_options;
|
|
|
|
return setSelection(selection-1);
|
|
}
|
|
|
|
void CDialog::drawDialogbox(int x1, int y1, int w, int h)
|
|
{
|
|
int px,py,pi,pj;
|
|
|
|
g_pGraphics->sb_drawCharacter(x1*8, y1*8, 1);
|
|
g_pGraphics->sb_drawCharacter((x1+w)*8, y1*8, 3);
|
|
for(px=(x1*8)+8,pi=0;pi<w-1;pi++)
|
|
{
|
|
g_pGraphics->sb_drawCharacter(px, y1*8, 2);
|
|
px+=8;
|
|
}
|
|
py=(y1+1)*8;
|
|
for(pj=0;pj<h-2;pj++)
|
|
{
|
|
for(px=(x1*8),pi=0;pi<=w;pi++)
|
|
{
|
|
if (pi==0) g_pGraphics->sb_drawCharacter(px, py, 4);
|
|
else if (pi==w) g_pGraphics->sb_drawCharacter(px, py, 5);
|
|
else g_pGraphics->sb_drawCharacter(px, py, ' ');
|
|
px+=8;
|
|
}
|
|
py+=8;
|
|
}
|
|
for(px=(x1*8),pi=0;pi<=w;pi++)
|
|
{
|
|
if (pi==0) g_pGraphics->sb_drawCharacter(px, py, 6);
|
|
else if (pi==w) g_pGraphics->sb_drawCharacter(px, py, 8);
|
|
else g_pGraphics->sb_drawCharacter(px, py, 7);
|
|
px+=8;
|
|
}
|
|
}
|