492 lines
15 KiB
C++
492 lines
15 KiB
C++
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// BitmapTextDisplay
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
#include "CKAll.h"
|
|
|
|
#include "CKBitmapFont.h"
|
|
|
|
#define LEFT 1
|
|
#define RIGHT 2
|
|
#define CENTER 3
|
|
|
|
CKObjectDeclaration *FillBehaviorBitmapTextDisplayDecl();
|
|
CKERROR CreateBitmapTextDisplayProto(CKBehaviorPrototype **pproto);
|
|
int BitmapTextDisplay(const CKBehaviorContext& behcontext);
|
|
CKERROR BitmapTextDisplayCallBackObject(const CKBehaviorContext& behcontext);
|
|
//void BitmapTextRender(CKRenderContext *rc, void *arg);
|
|
void BitmapTextRender(CKRenderContext *context, void *arg);
|
|
|
|
|
|
|
|
CKObjectDeclaration *FillBehaviorBitmapTextDisplayDecl()
|
|
{
|
|
CKObjectDeclaration *od = CreateCKObjectDeclaration("BitmapText Display");
|
|
od->SetDescription("Displays a Bitmap Text on top of the 3D environment");
|
|
/* rem:
|
|
<SPAN CLASS=in>On/Reset : </SPAN>activates the behavior, updates the displayed text and reset the inserted lines.<BR>
|
|
<SPAN CLASS=in>Off : </SPAN>deactivates the behavior.<BR>
|
|
<SPAN CLASS=in>Carriage Return : </SPAN>Add a new line to the text to be displayed
|
|
<BR>
|
|
<SPAN CLASS=out>Exit On : </SPAN>is activated when the behavior was triggered by 'On' input.<BR>
|
|
<SPAN CLASS=out>Exit Off : </SPAN>is activated when the behavior was triggered by 'Off' input.<BR>
|
|
<SPAN CLASS=out>Line Added : </SPAN>is activated when a new line is added.<BR>
|
|
<BR>
|
|
<SPAN CLASS=pin>Position : </SPAN>x,y position for the text on the screen, in pixels. It represents the top margin in Y and the left margin in X
|
|
for the align left mode, the right margin in X for the right aligned mode and the center of the text for center align mode.<BR>
|
|
<SPAN CLASS=pin>Character Spacing : </SPAN>Choose the number of pixel between each characters. Default is 1.<BR>
|
|
<SPAN CLASS=pin>Scale : </SPAN>Choose the horizontal and vertical scaling of the font. Warning values greater than 2 and smaller than 0.5 lead to disgracious visual effects (Moreover, values < 1 may crash some machines...).<BR>
|
|
<SPAN CLASS=pin>Alignment : </SPAN> Choose the justification of the text : either left justified, centered on the position or right justified.<BR>
|
|
<SPAN CLASS=pin>Vertical Spacing : </SPAN>When printing several lines with the carriage return input, you can choose here the space (in pixels) to leave between each line.<BR>
|
|
<SPAN CLASS=pin>Text : </SPAN>Text you want to display. You can change the type of this parameter to display something else.<BR>
|
|
<BR>
|
|
<SPAN CLASS=setting>Font : </SPAN>The chosen font to be used for displaying the string. The fonc is a 2DSprite with
|
|
a fixed set of characters drawn in it, each character separed by vertical lines. The bitmap must start by a vertical line of a
|
|
color, followed by some spaces (representing the typical pixels to let for 'space' character) and another vertical
|
|
lines + all the other characters.
|
|
The characters used are :<BR>
|
|
<FONT SIZE=2><pre>!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</pre></FONT>
|
|
Look at the 2DSprite/ArialFont.bmp in the "General_Resources" for an example of font designing....<BR>
|
|
Enter the character "|" if you want a carriage return in your string.<BR>
|
|
If you want to change dynamically the parameters printed in the string, you'll need to loop
|
|
the behavior in the "On" input. <BR>
|
|
You must provide input parameters (e.g. : the string to be displayed )<BR>
|
|
You can add any input parameters (of any type) as you want and they'll be printed, separated by a space.<BR>
|
|
*/
|
|
od->SetType( CKDLL_BEHAVIORPROTOTYPE);
|
|
od->SetGuid(CKGUID(0x49d487b,0x57565345));
|
|
od->SetAuthorGuid(VIRTOOLS_GUID);
|
|
od->SetAuthorName("Virtools");
|
|
od->SetVersion(0x00010000);
|
|
od->SetCreationFunction(CreateBitmapTextDisplayProto);
|
|
od->SetCompatibleClassId(CKCID_BEOBJECT);
|
|
od->SetCategory("Interface/Text");
|
|
return od;
|
|
}
|
|
|
|
|
|
CKERROR CreateBitmapTextDisplayProto(CKBehaviorPrototype **pproto)
|
|
{
|
|
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("BitmapText Display");
|
|
if(!proto) return CKERR_OUTOFMEMORY;
|
|
|
|
proto->DeclareInput("On/Reset");
|
|
proto->DeclareInput("Off");
|
|
proto->DeclareInput("Carriage Return");
|
|
|
|
proto->DeclareOutput("Exit On");
|
|
proto->DeclareOutput("Exit Off");
|
|
proto->DeclareOutput("Line Added");
|
|
|
|
proto->DeclareInParameter("Position", CKPGUID_2DVECTOR );
|
|
proto->DeclareInParameter("Character Spacing", CKPGUID_INT ,"1");
|
|
proto->DeclareInParameter("Scale", CKPGUID_2DVECTOR ,"1.0,1.0");
|
|
proto->DeclareInParameter("Alignment", CKGUID(0x11223faf,0x1a9315f9) ,"Left");
|
|
proto->DeclareInParameter("Vertical Spacing",CKPGUID_INT,"20");
|
|
proto->DeclareInParameter("Text", CKPGUID_STRING);
|
|
|
|
proto->DeclareSetting("Font", CKPGUID_SPRITE );
|
|
proto->DeclareLocalParameter(NULL, CKPGUID_STRING ); // "String"
|
|
proto->DeclareLocalParameter(NULL, CKPGUID_VOIDBUF ); // "BitmapFont" (MAC ok)
|
|
|
|
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
|
|
proto->SetFunction(BitmapTextDisplay);
|
|
proto->SetBehaviorFlags(CKBEHAVIOR_VARIABLEPARAMETERINPUTS);
|
|
|
|
proto->SetBehaviorCallbackFct(BitmapTextDisplayCallBackObject);
|
|
|
|
*pproto = proto;
|
|
return CK_OK;
|
|
|
|
}
|
|
|
|
|
|
int BitmapTextDisplay(const CKBehaviorContext& behcontext)
|
|
{
|
|
CKBehavior *beh = behcontext.Behavior;
|
|
|
|
BOOL update = FALSE;
|
|
if(beh->IsInputActive(1)) { //________/ OFF
|
|
behcontext.CurrentRenderContext->RemovePostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
|
|
beh->ActivateInput(1, FALSE);
|
|
beh->ActivateInput(0, FALSE);
|
|
beh->ActivateOutput(1);
|
|
return CKBR_OK;
|
|
}
|
|
|
|
if(beh->IsInputActive(0)) { //________/ ON
|
|
update = TRUE;
|
|
behcontext.CurrentRenderContext->AddPostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
|
|
beh->ActivateInput(0,FALSE);
|
|
beh->ActivateOutput(0);
|
|
char buffer = (char)0;
|
|
beh->SetLocalParameterValue(1,&buffer,sizeof(buffer));
|
|
}
|
|
|
|
XString buffer;
|
|
|
|
CKParameterIn* pin;
|
|
CKParameter* pout;
|
|
CKGUID guid;
|
|
if( !beh->GetInput(2) ){ // old version
|
|
// we construct the string
|
|
int pinc = beh->GetInputParameterCount();
|
|
int i;
|
|
for(i=4;i<pinc;i++) {
|
|
pin = beh->GetInputParameter(i);
|
|
pout = pin->GetRealSource();
|
|
if(!pout) continue;
|
|
|
|
int paramsize = pout->GetStringValue(NULL);
|
|
if (paramsize) {
|
|
XAP<char> paramstring(new char[paramsize]);
|
|
pout->GetStringValue(paramstring,FALSE);
|
|
|
|
if (i!=4) buffer << " ";
|
|
buffer << (char*)paramstring;
|
|
}
|
|
}
|
|
} else {
|
|
if( beh->IsInputActive(2) || update ){ // we need to read the input
|
|
// we construct the string
|
|
int pinc = beh->GetInputParameterCount();
|
|
int i;
|
|
for(i=5;i<pinc;i++) {
|
|
pin = beh->GetInputParameter(i);
|
|
pout = pin->GetRealSource();
|
|
if(!pout) continue;
|
|
|
|
int paramsize = pout->GetStringValue(NULL);
|
|
if (paramsize) {
|
|
XAP<char> paramstring(new char[paramsize]);
|
|
pout->GetStringValue(paramstring,FALSE);
|
|
|
|
char* foundcr = paramstring;
|
|
while(foundcr = strchr(foundcr,'|')) {
|
|
*foundcr = '\n';
|
|
}
|
|
|
|
if (i!=5) buffer << " ";
|
|
buffer << (char*)paramstring;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
char* finalstring = buffer.Str();
|
|
if(beh->IsInputActive(2)) { // we enter by concatenate
|
|
beh->ActivateInput(2,FALSE);
|
|
beh->ActivateOutput(2);
|
|
|
|
char* oldstring = (char*)beh->GetLocalParameterReadDataPtr(1);
|
|
if(oldstring) {
|
|
finalstring = new char[buffer.Length()+strlen(oldstring)+2];
|
|
sprintf(finalstring,"%s\n%s",oldstring,buffer.Str());
|
|
}
|
|
update = TRUE;
|
|
}
|
|
|
|
if(update) beh->SetLocalParameterValue(1,finalstring,strlen(finalstring)+1);
|
|
if (buffer != finalstring) delete [] finalstring;
|
|
|
|
return CKBR_ACTIVATENEXTFRAME;
|
|
}
|
|
|
|
CKERROR
|
|
BitmapTextDisplayCallBackObject(const CKBehaviorContext& behcontext)
|
|
{
|
|
CKBehavior *beh = behcontext.Behavior;
|
|
CKContext *ctx = behcontext.Context;
|
|
|
|
switch( behcontext.CallbackMessage )
|
|
{
|
|
case CKM_BEHAVIORCREATE:
|
|
{
|
|
CKBitmapFont* bf = new CKBitmapFont;
|
|
beh->SetLocalParameterValue(2,bf,sizeof(CKBitmapFont));
|
|
delete bf;
|
|
}
|
|
case CKM_BEHAVIORSETTINGSEDITED:
|
|
{
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
CKSprite* sprite = (CKSprite*)beh->GetLocalParameterObject(0);
|
|
if(sprite) {
|
|
sprite->Show(CKHIDE);
|
|
if(bf->GetFont(behcontext.Context) != sprite) {
|
|
bf->CreateFont(CKOBJID(sprite), ctx);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CKM_BEHAVIORLOAD:
|
|
{
|
|
CKSprite* sprite = (CKSprite*)beh->GetLocalParameterObject(0);
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
CKParameterLocal* p=beh->GetLocalParameter(2);
|
|
if (p->GetDataSize()!=sizeof(CKBitmapFont)) {
|
|
CKBitmapFont temp=*bf;
|
|
temp.m_SeparationColor =0xFFFF00FF;
|
|
temp.m_FillColor =0xFF000000;
|
|
p->SetValue(&temp,sizeof(CKBitmapFont));
|
|
bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
}
|
|
if (!bf) {
|
|
CKBitmapFont temp;
|
|
beh->SetLocalParameterValue(2,&temp,sizeof(CKBitmapFont));
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
if (sprite) bf->CreateFont(CKOBJID(sprite), ctx);
|
|
} else {
|
|
// When loading on a Big-Endian processor
|
|
// CKPGUID_VOIDBUF Parameters need to be converted
|
|
// only the owner knows the format of the underlying variables
|
|
#if defined(macintosh) && defined(__ppc__)
|
|
CKConvertEndianArray32(&bf->m_FontBitmap,sizeof(CKBitmapFont)>>2);
|
|
#endif
|
|
}
|
|
|
|
if(sprite) {
|
|
sprite->Show(CKHIDE);
|
|
bf->SetFont(CKOBJID(sprite));
|
|
} else bf->m_FontBitmap=0;
|
|
}
|
|
break;
|
|
case CKM_BEHAVIORDETACH:
|
|
{
|
|
if (behcontext.CurrentRenderContext) behcontext.CurrentRenderContext->RemovePostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
} break;
|
|
case CKM_BEHAVIORDEACTIVATESCRIPT:
|
|
case CKM_BEHAVIORPAUSE:
|
|
case CKM_BEHAVIORRESET:
|
|
{
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
if (bf) bf->MaskSeparationLines(FALSE, ctx);
|
|
|
|
if(beh->IsActive()) {
|
|
behcontext.CurrentRenderContext->RemovePostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
}
|
|
} break;
|
|
case CKM_BEHAVIORACTIVATESCRIPT:
|
|
case CKM_BEHAVIORRESUME:
|
|
{
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
if (bf) bf->MaskSeparationLines(TRUE, ctx);
|
|
|
|
CKScene *scene = behcontext.CurrentScene;
|
|
if( beh->IsParentScriptActiveInScene(scene)){
|
|
if(beh->IsActive()) {
|
|
behcontext.CurrentRenderContext->AddPostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CKM_BEHAVIORNEWSCENE:
|
|
{
|
|
CKBeObject *owner = beh->GetOwner();
|
|
CKScene *scene = behcontext.CurrentScene;
|
|
if( beh->IsParentScriptActiveInScene(scene)){
|
|
if(beh->IsInputActive(0)) {
|
|
behcontext.CurrentRenderContext->AddPostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
}
|
|
} else {
|
|
behcontext.CurrentRenderContext->RemovePostSpriteRenderCallBack(BitmapTextRender,beh);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
return CKBR_OK;
|
|
}
|
|
|
|
/*
|
|
void
|
|
BitmapTextRender(CKRenderContext *rc, void *arg)
|
|
{
|
|
CKRenderContext *context=VxDeviceToCKRenderContext(Vxdev);
|
|
|
|
CKBehavior* beh = (CKBehavior*)arg;
|
|
char *string = (char*) beh->GetLocalParameterReadDataPtr(1);
|
|
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
if (!bf) return;
|
|
if (!bf->HasFont()) return;
|
|
|
|
Vx2DVector off;
|
|
beh->GetInputParameterValue(0, &off);
|
|
int spacing;
|
|
beh->GetInputParameterValue(1, &spacing);
|
|
Vx2DVector scale(1.0f,1.0f);
|
|
beh->GetInputParameterValue(2, &scale);
|
|
int align=LEFT;
|
|
beh->GetInputParameterValue(3, &align);
|
|
int vspacing=20;
|
|
if(beh->GetOutput(2)) {
|
|
beh->GetInputParameterValue(4, &vspacing);
|
|
}
|
|
|
|
switch(align) {
|
|
case LEFT:
|
|
{
|
|
string = strdup(string);
|
|
char* substring = string;
|
|
char* newline;
|
|
while(substring) {
|
|
newline = strchr(substring,'\n');
|
|
if(newline) {
|
|
*newline = '\0';
|
|
newline++;
|
|
}
|
|
bf->DrawString(context,substring,(int)off.x,(int)off.y,spacing,scale);
|
|
off.y += vspacing;
|
|
if(newline) {
|
|
if(*newline!='\0') substring = newline;
|
|
else substring = NULL;
|
|
} else substring = NULL;
|
|
}
|
|
free(string);
|
|
}
|
|
break;
|
|
case CENTER:
|
|
{
|
|
string = strdup(string);
|
|
char* substring = string;
|
|
char* newline;
|
|
while(substring) {
|
|
newline = strchr(substring,'\n');
|
|
if(newline) {
|
|
*newline = '\0';
|
|
newline++;
|
|
}
|
|
int sw = bf->StringWidth(substring,spacing,scale);
|
|
bf->DrawString(context,substring,(int)off.x-(sw>>1),(int)off.y,spacing,scale);
|
|
off.y += vspacing;
|
|
if(newline) {
|
|
if(*newline!='\0') substring = newline;
|
|
else substring = NULL;
|
|
} else substring = NULL;
|
|
}
|
|
free(string);
|
|
}
|
|
break;
|
|
case RIGHT:
|
|
{
|
|
string = strdup(string);
|
|
char* substring = string;
|
|
char* newline;
|
|
while(substring) {
|
|
newline = strchr(substring,'\n');
|
|
if(newline) {
|
|
*newline = '\0';
|
|
newline++;
|
|
}
|
|
int sw = bf->StringWidth(substring,spacing,scale);
|
|
bf->DrawString(context,substring,(int)off.x-sw,(int)off.y,spacing,scale);
|
|
off.y += vspacing;
|
|
if(newline) {
|
|
if(*newline!='\0') substring = newline;
|
|
else substring = NULL;
|
|
} else substring = NULL;
|
|
}
|
|
free(string);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
*/
|
|
|
|
void BitmapTextRender(CKRenderContext *context, void *arg)
|
|
{
|
|
CKBehavior* beh = (CKBehavior*)arg;
|
|
CKContext *ctx = beh->GetCKContext();
|
|
|
|
char* string = (char*) beh->GetLocalParameterReadDataPtr(1);
|
|
|
|
CKBitmapFont* bf = (CKBitmapFont*)beh->GetLocalParameterReadDataPtr(2);
|
|
if (!bf) return;
|
|
if (!bf->HasFont(ctx)) return;
|
|
|
|
Vx2DVector off;
|
|
beh->GetInputParameterValue(0, &off);
|
|
int spacing;
|
|
beh->GetInputParameterValue(1, &spacing);
|
|
Vx2DVector scale(1.0f,1.0f);
|
|
beh->GetInputParameterValue(2, &scale);
|
|
int align=LEFT;
|
|
beh->GetInputParameterValue(3, &align);
|
|
int vspacing=20;
|
|
if(beh->GetOutput(2)) {
|
|
beh->GetInputParameterValue(4, &vspacing);
|
|
}
|
|
|
|
switch(align) {
|
|
case LEFT:
|
|
{
|
|
VxScratchString sstring(string);
|
|
char* substring = sstring->Str();
|
|
char* newline;
|
|
while(substring) {
|
|
newline = strchr(substring,'\n');
|
|
if(newline) {
|
|
*newline = '\0';
|
|
newline++;
|
|
}
|
|
bf->DrawString(context,substring,(int)off.x,(int)off.y,spacing,scale);
|
|
off.y += vspacing;
|
|
if(newline) {
|
|
if(*newline!='\0') substring = newline;
|
|
else substring = NULL;
|
|
} else substring = NULL;
|
|
}
|
|
}
|
|
break;
|
|
case CENTER:
|
|
{
|
|
VxScratchString sstring(string);
|
|
char* substring = sstring->Str();
|
|
char* newline;
|
|
while(substring) {
|
|
newline = strchr(substring,'\n');
|
|
if(newline) {
|
|
*newline = '\0';
|
|
newline++;
|
|
}
|
|
int sw = bf->StringWidth(substring,spacing,scale);
|
|
bf->DrawString(context,substring,(int)off.x-(sw>>1),(int)off.y,spacing,scale);
|
|
off.y += vspacing;
|
|
if(newline) {
|
|
if(*newline!='\0') substring = newline;
|
|
else substring = NULL;
|
|
} else substring = NULL;
|
|
}
|
|
}
|
|
break;
|
|
case RIGHT:
|
|
{
|
|
VxScratchString sstring(string);
|
|
char* substring = sstring->Str();
|
|
char* newline;
|
|
while(substring) {
|
|
newline = strchr(substring,'\n');
|
|
if(newline) {
|
|
*newline = '\0';
|
|
newline++;
|
|
}
|
|
int sw = bf->StringWidth(substring,spacing,scale);
|
|
bf->DrawString(context,substring,(int)off.x-sw,(int)off.y,spacing,scale);
|
|
off.y += vspacing;
|
|
if(newline) {
|
|
if(*newline!='\0') substring = newline;
|
|
else substring = NULL;
|
|
} else substring = NULL;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|