class UIMsg{
var string text;
var string font;
var string soundOnStart;
var int msgView;
var int Line1View;
var int Line2View;
var int durTicks;
var int color;
var int next;
};
class UIMsgManager
{
var int first;
var int last;
var int count;
var int state;
var int timeTillEnd;
};
const int MsgManager_State_None = 0;//nothing visible
const int MsgManager_State_FadeIN = 1;//new msg fading in
const int MsgManager_State_Show = 2;//displaying msg, waiting for end of duration
const int MsgManager_State_FadeOut = 3;//msg fading out
const int MAX_MessagesTime = 10*8;//max. time that message queue can be showed (15 seconds)
const int Msg_FadeInFrames = 5;
const int Msg_FadeOutFrames = Msg_FadeInFrames;
const int Msg_FinishBGAlpha = 150;
const int Msg_PosY = 35 * 82;//82 -one percent 2870
const int Msg_PosX = 5 * 82;
const int MsgBox_SizeY = 55;//in px
const int MsgBox_SizeX = 250;
func int GetScreenSizeX() { Print_GetScreenSize(); return Print_Screen[PS_X]; };
func int GetScreenSizeY() { Print_GetScreenSize(); return Print_Screen[PS_Y]; };
func int CalcPixelPosX(var int x)
{
var int pos; pos = fracf(8196,GetScreenSizeX());
//printdebug_s_i("># px =",truncf(pos));
pos = mulf(pos,mkf(x));
//printdebug_s_i("># vsizex =",truncf(pos));
return truncf(pos);
};
func int CalcPixelPosY(var int y)
{
var int pos; pos = fracf(8196,GetScreenSizeY()); pos = mulf(pos,mkf(y));
return truncf(pos);
};
//global msg Manager needs reinit every game init
instance MsgManager(UIMsgManager);
instance Msg_1st(UIMsg);
instance Msg_2nd(UIMsg);
func void MsgManager_ReInit()
{
var int Mptr;
Mptr = MEM_Alloc(20);//16-size os MsgManager
MEM_AssignInst (MsgManager,Mptr);
MsgManager.first = 0;
MsgManager.last = 0;
MsgManager.count = 0;
MsgManager.state = 0;
MsgManager.timeTillEnd = 0;
};
func void MsgManager_Push(var int MsgPtr)//struct* UIMsg
{
var UIMsg LastMsg; var UIMsg Msg;
MEM_AssignInst (Msg,MsgPtr);
//time the list will be showed is more than 10s?
if(MsgManager.timeTillEnd+Msg.durTicks>=MAX_MessagesTime)
{ return; };//(Ignore next messages)
//if much msg are pushed try to decrease time of present messages:
if(MsgManager.count>2)
{
Msg_1st.durTicks-=MsgManager.count*8;
Msg_2nd.durTicks-=MsgManager.count*4;
};
if(MsgManager.last)
{
MEM_AssignInst (LastMsg,MsgManager.last);
MsgManager.last = MsgPtr;
LastMsg.next = MsgPtr;
//there was only one msg? update Msg_2nd!
if(MEM_InstToPtr(LastMsg)==MsgManager.first)
{
MEM_AssignInst (Msg_2nd,MsgPtr);
};
}
else//list was empty
{
MsgManager.first = MsgPtr;
MsgManager.last = MsgPtr;
MEM_AssignInst (Msg_1st,MsgPtr);
};
MsgManager.count+=1;
MsgManager.timeTillEnd=+Msg.durTicks;
};
func void MsgManager_Pop()
{
var int fMsg; var UIMsg hlp;
MEM_AssignInst (hlp,MsgManager.first);
if(MsgManager.first)//list wasn't empty
{
//save ptr to following MSG;
fMsg = hlp.next;
//free memory
hlp.msgView = 0;
hlp.Line1View = 0;
hlp.Line2View = 0;
MEM_Free(MEM_InstToPtr(hlp));
//make next first
MEM_AssignInst (hlp,fMsg);
MsgManager.first = MEM_InstToPtr(hlp);
if(MsgManager.first==0)
{
MsgManager.last = 0;
MEM_AssignInstNull (Msg_1st);
MsgManager.state = MsgManager_State_None; //Added lately
}
else
{
MEM_AssignInst (Msg_1st,MsgManager.first);
MEM_AssignInst (Msg_2nd,hlp.next);
MsgManager.state = MsgManager_State_FadeIN; //Added lately
};
MsgManager.count-=1;
};
};
func void UIMsg_FormatAndPrintText(var UIMsg Msg)
{
const int maxCharsInline = 32; //zmienione przez Adanosa 2012-04-30
const int xStartOfWindow = 5;
var int yStartOf1Line; yStartOf1Line = 1584 - CalcPixelPosY(8)/2;
var int yStartOf2Line; yStartOf2Line = 3800 - CalcPixelPosY(8)/2;
var int yStartOfOneLine; yStartOfOneLine = 2800 - CalcPixelPosY(8)/2;//4096 = 100%
var int secondLine; var int splitPos;
var string Line1;var string Line2;
var int label;
secondLine = false;
Line1 = ""; Line2 = "";
if(Str_Len(Msg.text)>=maxCharsInline)
{
//split string
secondLine = true;
//find first space at left
splitPos = maxCharsInline;
//loop
MEM_InitLabels ();
label = MEM_StackPos.position;
if(Hlp_StrCmp(STR_SubStr(Msg.text,splitPos,1)," "))
{
}
else if(splitPos>0)
{
splitPos-=1;
MEM_StackPos.position = label;
};
//end loop
if(splitPos==0)//if no space fouded, divide at last char
{
splitPos=maxCharsInline;
};
Line1 = STR_SubStr (Msg.text,0,splitPos);
Line2 = STR_SubStr (Msg.text,splitPos+1,Str_Len(Msg.text));
};
//One Line:
if(!secondLine)
{
CALL_zStringPtrParam(Msg.text);//zcview
if(MEM_InstToPtr(Msg)==MsgManager.first)//first msg
{
CALL_IntParam(yStartOfOneLine);//zcview
}
else//second
{
CALL_IntParam(yStartOfOneLine);//zcview
};
CALL_IntParam(Msg_PosX+xStartOfWindow);//x pixel
CALL__thiscall (Msg.msgView,zCView_CreateText_offset);
Msg.Line1View = CALL_RetValAsInt();
}
else//Zamiast create text, add line?
{
//Line 1
CALL_zStringPtrParam(Line1);//zcview
if(MEM_InstToPtr(Msg)==MsgManager.first)//first msg
{
CALL_IntParam(yStartOf1Line);//zcview
}
else//second
{
CALL_IntParam(yStartOf1Line);//zcview
};
CALL_IntParam(Msg_PosX+xStartOfWindow);//x pixel
CALL__thiscall (Msg.msgView,zCView_CreateText_offset);
Msg.Line1View = CALL_RetValAsInt();
//Line 2
CALL_zStringPtrParam(Line2);//zcview
if(MEM_InstToPtr(Msg)==MsgManager.first)//first msg
{
CALL_IntParam(yStartOf2Line);//zcview
}
else//second
{
CALL_IntParam(yStartOf2Line);//zcview
};
CALL_IntParam(Msg_PosX+xStartOfWindow);//x pixel
CALL__thiscall (Msg.msgView,zCView_CreateText_offset);
Msg.Line2View = CALL_RetValAsInt();
};
};
func void Msg_FadeIN(var UIMsg Msg)
{
var int posYFrameStep;var int y;
var int frame; var int alphaNow;
var int alphaStep;
MEM_Info("FadeIN: UIMSG MSGVIEW");
var zCView MsgView; MsgView = _^(Msg.msgView);
MEM_Info("FadeIN: UIMSG MSGVIEW: AssignInst");
alphaNow = MsgView.alpha;
alphaStep = (Msg_FinishBGAlpha-(Msg_FinishBGAlpha%Msg_FadeInFrames))/Msg_FadeInFrames;
y = MsgView.vposy;
posYFrameStep = (MsgView.vsizey-(MsgView.vsizey%Msg_FadeInFrames))/Msg_FadeInFrames;
frame = (Msg_PosY-y-((Msg_PosY-y)%posYFrameStep))/posYFrameStep;
frame = Msg_FadeInFrames-frame;
if(frame>Msg_FadeInFrames){return;};
if(frame==Msg_FadeInFrames)//last frame
{
CALL_IntParam(Msg_PosY);//zcview
CALL_IntParam(Msg_PosX);//zcview
CALL__thiscall (Msg.msgView,zCView_SetPos_offset);
CALL_IntParam(Msg_FinishBGAlpha);
CALL__thiscall (Msg.msgView,zCView_SetTransparency_offset);
MsgManager.state = MsgManager_State_Show;
MsgView = _^(Msg.Line1View); MsgView.color = Msg.color;
if(Msg.Line2View)
{
MsgView = _^(Msg.Line2View);MsgView.color = Msg.color;
};
}
else
{
CALL_IntParam(y+posYFrameStep);//zcview
CALL_IntParam(Msg_PosX);//zcview
CALL__thiscall (Msg.msgView,zCView_SetPos_offset);
MsgView = _^(Msg.msgView);
MsgView.vposy = y+posYFrameStep;
CALL_IntParam(alphaNow+alphaStep);
CALL__thiscall (Msg.msgView,zCView_SetTransparency_offset);
var int txtAlpha; var int hlp;
txtAlpha = fracf(frame,Msg_FadeInFrames);
hlp = mulf(txtAlpha,mkf(GetAlpha(Msg.color)));//*alpha
txtAlpha = truncf(hlp);
if(Msg.Line2View)
{
MsgView = _^(Msg.Line2View);
MsgView.color = RGBA(zColor_r(Msg.color),zColor_g(Msg.color),zColor_b(Msg.color),255);
};
};
};
func void Msg_FadeOut(var UIMsg Msg)
{
MEM_Info("FadeOut: UIMSG MSGVIEW");
var zCView MsgView; MsgView = _^(Msg.msgView);
MEM_Info("FadeOut: UIMSG MSGVIEW: ASSIGNINST");
var int posYFrameStep;var int y;
var int frame; var int alphaNow;
var int alphaStep;
//calculate fade in frame
alphaNow = MsgView.alpha;
alphaStep = (Msg_FinishBGAlpha-(Msg_FinishBGAlpha%Msg_FadeOutFrames))/Msg_FadeOutFrames;
y = MsgView.vposy;
PosYFrameStep = (MsgView.vsizey-(MsgView.vsizey%Msg_FadeOutFrames))/Msg_FadeOutFrames;msg_FadeOutFrames;
frame = (y-Msg_PosY)/posYFrameStep;
frame = frame;
if(frame==Msg_FadeOutFrames)//last frame
{
CALL_IntParam(Msg_PosY);//zcview
CALL_IntParam(Msg_PosX);//zcview
CALL__thiscall (Msg.msgView,zCView_SetPos_offset);
CALL_IntParam(0);
CALL__thiscall (Msg.msgView,zCView_SetTransparency_offset);
MsgView = _^(Msg.Line1View);MsgView.alpha = 0;
if(Msg.Line2View)
{
MsgView = _^(Msg.Line2View);MsgView.alpha = 0;
};
CALL__thiscall (Msg.msgView,zCView_Close_offset);
MsgManager_Pop();
printdebug("># POPPED!");
}
else
{
CALL_IntParam(y+posYFrameStep);//zcview
CALL_IntParam(Msg_PosX);//zcview
CALL__thiscall (Msg.msgView,zCView_SetPos_offset);
MEM_WriteInt(Msg.msgView+72,y+posYFrameStep);
CALL_IntParam(alphaNow-alphaStep);
CALL__thiscall (Msg.msgView,zCView_SetTransparency_offset);
var int txtAlpha; var int hlp;
txtAlpha = fracf(frame,Msg_FadeOutFrames);
hlp = mulf(txtAlpha,mkf(GetAlpha(Msg.color)));//*alpha
txtAlpha = 255-truncf(hlp);
MsgView = _^(Msg.Line1View);MsgView.color = RGBA(zColor_r(Msg.color),zColor_g(Msg.color),zColor_b(Msg.color),txtAlpha);
// printdebug_s_i("># txtAlpha:",txtAlpha);
if(Msg.Line2View)
{
MsgView = _^(Msg.Line2View);MsgView.color = RGBA(zColor_r(Msg.color),zColor_g(Msg.color),zColor_b(Msg.color),txtAlpha);
};
};
};
func void Msg_InitView(var UIMsg Msg)
{
//Remove old view if it was present:
if(Msg_2nd.msgView>0)
{
MEM_Free(Msg.msgView);
};
var int vptr;
vptr = MEM_Alloc(256);
Msg.msgView = vptr;
var zCView MsgView; MsgView = _^(Msg.msgView);
printdebug("># constructor");
CALL__thiscall (vptr,zCView_zCView_offset);
//Remove on close: TRUE!!!
MsgView.removeOnClose = true;
//zCView::FX(OPEN/CLOSE)
MsgView.fxOpen = 0;
MsgView.fxClose = 0;
//SetPos
var int x;var int y;
x = CalcPixelPosX(MsgBox_SizeX); y = CalcPixelPosY(MsgBox_SizeY);
CALL_IntParam(Msg_PosY-y);
CALL_IntParam(Msg_PosX);//zcview
CALL__thiscall (vptr,zCView_SetPos_offset);
//Manualy update pos:
MsgView.vposy = Msg_PosY-CalcPixelPosY(MsgBox_SizeY);
CALL_IntParam(CalcPixelPosY(MsgBox_SizeY));//S Y
CALL_IntParam(CalcPixelPosX(MsgBox_SizeX));//S X
CALL__thiscall (vptr,zCView_SetSize_offset);
//Set Alpha
CALL_IntParam(0);
CALL__thiscall (vptr,zCView_SetTransparency_offset);
//set BG tex
CALL_zStringPtrParam("UI_MSG_BG.TGA");//zcview
CALL__thiscall (vptr,zCView_InsertBack_offset);
//set font
CALL_zStringPtrParam(Msg.font);//zcview
CALL__thiscall (vptr,zCView_SetFont_offset);
//Open
CALL__thiscall (vptr,zCView_Open_offset);
//Add Text:
UIMsg_FormatAndPrintText(Msg);
//make Text opanque:
MsgView = _^(Msg.Line1View);MsgView.color = RGBA(255,255,255,0);
if(Msg.Line2View)
{
MsgView = _^(Msg.Line2View); MsgView.color = RGBA(255,255,255,0);
};
//Insert Item to screen
CALL_IntParam(2);//zcview
CALL_IntParam(vptr);//zcview
CALL__thiscall (screen_offset,zCView_InsertItem_offset);
};
func int Msg_Create(var string msg,var string font,var int zCCol,var int dur,var string wav)
{
var int Mptr; var UIMsg hlp;
Mptr = MEM_Alloc(76);
MEM_AssignInst (hlp,Mptr);
hlp.text = msg;
hlp.msgView = 0;
hlp.next = 0;
hlp.color = zCCol;
hlp.font = font;
hlp.durTicks= dur;
hlp.soundOnStart= wav;
return Mptr;
};
func void PutMsg(var string msg,var string font,var int zCCol,var int dur,var string wav)
{
MsgManager_Push(Msg_Create(msg,font,zCCol,dur,wav));
};
//called by POISON_TRIGGER
func void MsgManager_DoTick()
{
if(MEM_InstToPtr(Msg_1st))&&(MsgManager.state==MsgManager_State_Show)
{
Msg_1st.durTicks-=1;
MsgManager.timeTillEnd-=1;
};
};
func void MsgManager_RenderMsg()
{
if(MEM_InstToPtr(Msg_1st))//Normal rendering of zCView(s)
{
//printdebug_s_i("># rendering msg:",MEM_InstToPtr(Msg_1st));
CALL__thiscall (Msg_1st.msgView,zCView_Render_offset);
if(MEM_InstToPtr(Msg_2nd))&&(Msg_2nd.msgView)
{
printdebug_s_i("># rendering msg#2:",MEM_InstToPtr(Msg_2nd));
CALL__thiscall (Msg_2nd.msgView,zCView_Render_offset);
};
};
};
//called by PerFrameTrigger
func void MsgManager_DoFrame()
{
if(MsgManager.count)
{
printdebug_s_i("># MsgManager.count:",MsgManager.count);
if(MsgManager.state == MsgManager_State_None)&&(MsgManager.count)
{
//Init of Msg_1
var int vptr;
MsgManager.state = MsgManager_State_FadeIN;
printdebug("># Msg state = FADE IN");
Msg_InitView(Msg_1st);//opacity = 0%
}
else if(MsgManager.state == MsgManager_State_FadeIN)
{
printdebug("># frame: Msg_FadeIN(Msg_1st);");
Msg_FadeIN(Msg_1st);//opacity = 0%
}
else if(Msg_1st.durTicks<=0)&&(MsgManager.state == MsgManager_State_Show)//First msg time expired
{
MsgManager.state = MsgManager_State_FadeOUT;
printdebug("># Msg state = FADE OUT");
if(MEM_InstToPtr(Msg_2nd))
{
Msg_InitView(Msg_2nd);
};
//return;
}
else if(MsgManager.state == MsgManager_State_Show)&&(!Hlp_StrCmp(Msg_1st.soundOnStart,""))
{
introducechapter ("","","",Msg_1st.soundOnStart, 0);
Msg_1st.soundOnStart = "";//clear after play
}
else if(MsgManager.state == MsgManager_State_FadeOUT)
{
//Bugfix: Second message have to be first because FadingOut of first Msg can change object in Msg_2nd to next one
if(MEM_InstToPtr(Msg_2nd))
{
printdebug("># Fading in 2nd");
if(!Msg_2nd.msgView)//during fading out another msg was pushed...
{
Msg_InitView(Msg_2nd);
};
Msg_FadeIN(Msg_2nd);
};
printdebug("># Fading out 1st");
Msg_FadeOut(Msg_1st);
};
MsgManager_RenderMsg();
};
};
Zabezpieczenie przed kimś kto nie ogarnia ikarusa (nie ma adresów, bo nie są potrzebne)