02061d74c2
(as received from Jonas Echterhoff)
1206 lines
37 KiB
C++
1206 lines
37 KiB
C++
#include <OpenGL/gl.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include "gamemem.h"
|
|
#include "textures.h"
|
|
#include "gametime.h"
|
|
#include "interface.h"
|
|
#include "interfaceutil.h"
|
|
#include "vectors.h"
|
|
#include "text.h"
|
|
#include "controls.h"
|
|
#include "screen.h"
|
|
#include "carphysics.h"
|
|
#include "gamesystem.h"
|
|
#include "gamesound.h"
|
|
#include "random.h"
|
|
#include "interfacemultiplayer.h"
|
|
#include "log.h"
|
|
#include "reg_tool_3.h"
|
|
#include "initexit.h"
|
|
#include "ASWRegistrationCarbonAPI.h"
|
|
|
|
int gJoinFlag=false;
|
|
int gInterfaceType=false;
|
|
char gJoinHost[256];
|
|
char gLastMenuChar;
|
|
float gStartIdleTime=0;
|
|
|
|
/*
|
|
#define kNumEasterEggStrings 3
|
|
char gEasterEggStrings[kNumEasterEggStrings][256]={
|
|
"Easter Egg not yet implemented...",
|
|
"Bla Bla",
|
|
"Insert Funny Stuff here"
|
|
};
|
|
|
|
/*/
|
|
#define kNumEasterEggStrings 10
|
|
char gEasterEggStrings[kNumEasterEggStrings][256]={
|
|
"You better respect me, 'cos I'm the man with the car with the star",
|
|
"It's a long way to the top (if you wanna rock'n'roll!)",
|
|
"There's no replacement for displacement",
|
|
"echo \"carsOnSpeed 1\" >> ~/Library/Preferences/Redline\ Preferences",
|
|
"Moof!",
|
|
"All your horsepower are belong to us",
|
|
"Frog blast the vent core!",
|
|
"\255#w\255Everyone likes \255#r\255c\255#y\255o\255#g\255l\255#c\255o\255#b\255r\255#w\255 tags: \\255#r\\255",
|
|
"In Soviet Russia, car drives you!",
|
|
"out of errors."
|
|
};
|
|
|
|
#define kEasterEggScrollSpeed 0.8
|
|
|
|
#define kMenuFPS 75.0
|
|
#define kMenuFrameTime (1/kMenuFPS)
|
|
#define kMenuSuspendedFPS 0.5
|
|
#define kMenuSuspendedFrameTime (1/kMenuSuspendedFPS)
|
|
|
|
void InterfaceDrawBackgroundFade(float opacity,int showtop)
|
|
{
|
|
gTexturesQualityModifier=-255;
|
|
if(opacity==0)
|
|
return;
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_TEXTURE_BIT+GL_CURRENT_BIT);
|
|
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
|
glColor4f(1,1,1,opacity);
|
|
TexturesSelectTex(FileGetReference(kInterfaceBackgroundTexture));
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
|
|
|
if(showtop)
|
|
{
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch,kBackgroundYStretch);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch);
|
|
glEnd();
|
|
|
|
TexturesSelectTex(FileGetReference("menustripe.tif"));
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch, 0.7*kScreenYPos);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch, 1.0*kScreenYPos);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,0.7*kScreenYPos);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch,1.0*kScreenYPos);
|
|
glEnd();
|
|
}
|
|
else
|
|
{
|
|
if(ScreenSupportsBlendColor())
|
|
{
|
|
glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE_MINUS_CONSTANT_ALPHA);
|
|
glBlendColor(1,1,1,opacity);
|
|
}
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glTexCoord2d(1,0.15); glVertex2f(kBackgroundXStretch,kBackgroundYStretch-0.3*kBackgroundXStretch);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glTexCoord2d(0,0.15); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-0.3*kBackgroundXStretch);
|
|
glEnd();
|
|
}
|
|
glDisable(GL_TEXTURE_2D);
|
|
glColor4f(0,0,0,opacity);
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glVertex2f(-kBackgroundXStretch,kBackgroundYStretch);
|
|
glVertex2f(-2*kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glVertex2f(-2*kBackgroundXStretch,kBackgroundYStretch);
|
|
glEnd();
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glVertex2f(2*kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glVertex2f(2*kBackgroundXStretch,kBackgroundYStretch);
|
|
glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glVertex2f(kBackgroundXStretch,kBackgroundYStretch);
|
|
glEnd();
|
|
glPopAttrib();
|
|
gTexturesQualityModifier=0;
|
|
}
|
|
|
|
void InterfaceDrawBackground(tFileRef background,tFileRef image,float imageXScale,float imageYScale,float imageXPos,float imageYPos,float alpha)
|
|
{
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
gTexturesQualityModifier=-255;
|
|
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_CURRENT_BIT);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
if(background!=kFileErr)
|
|
TexturesSelectTex(background);
|
|
else
|
|
TexturesSelectTex(FileGetReference(kInterfaceBackgroundTexture));
|
|
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
|
|
|
|
|
/*
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch,-kBackgroundYStretch);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch,kBackgroundYStretch);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,-kBackgroundYStretch);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch);
|
|
glEnd();
|
|
*/
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch,kBackgroundYStretch);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch);
|
|
glEnd();
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
TexturesSelectTex(FileGetReference("menustripe.tif"));
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch, 0.7*kScreenYPos);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch, 1.0*kScreenYPos);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,0.7*kScreenYPos);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch,1.0*kScreenYPos);
|
|
glEnd();
|
|
|
|
if(image!=kFileErr)
|
|
{
|
|
glColor4f(1,1,1,alpha);
|
|
TexturesSelectTex(image);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(imageXPos+imageXScale,imageYPos-imageYScale);
|
|
glTexCoord2d(1,0); glVertex2f(imageXPos+imageXScale,imageYPos+imageYScale);
|
|
glTexCoord2d(0,1); glVertex2f(imageXPos-imageXScale,imageYPos-imageYScale);
|
|
glTexCoord2d(0,0); glVertex2f(imageXPos-imageXScale,imageYPos+imageYScale);
|
|
glEnd();
|
|
}
|
|
|
|
glPopAttrib();
|
|
gTexturesQualityModifier=0;
|
|
}
|
|
|
|
void InterfaceFadeInImageFromBlack(float xSize,float ySize,tFileRef image,float maxTime)
|
|
{
|
|
gTexturesQualityModifier=-255;
|
|
TexturesSelectTex(image);
|
|
float startTime=TimeGetSeconds();
|
|
float time=0;
|
|
int exit=false;
|
|
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
while(!exit)
|
|
{
|
|
time=TimeGetSeconds()-startTime;
|
|
float alpha=(time/maxTime);
|
|
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_COLOR_BUFFER_BIT+GL_LIGHTING_BIT+GL_TEXTURE_BIT+GL_CURRENT_BIT);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
glColor4f(1,1,1,alpha);
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch*xSize,-kBackgroundYStretch*ySize);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch*xSize,kBackgroundYStretch*ySize);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch*xSize,-kBackgroundYStretch*ySize);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch*xSize,kBackgroundYStretch*ySize);
|
|
glEnd();
|
|
|
|
glPopAttrib();
|
|
|
|
ScreenBlit();
|
|
if(time>=maxTime)
|
|
exit=true;
|
|
}
|
|
gTexturesQualityModifier=0;
|
|
}
|
|
|
|
void InterfaceFadeInImageFromImage(float xSize,float ySize,tFileRef image,float xSize2,float ySize2,tFileRef image2,float maxTime)
|
|
{
|
|
gTexturesQualityModifier=-255;
|
|
float startTime=TimeGetSeconds();
|
|
float time=0;
|
|
int exit=false;
|
|
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
while(!exit)
|
|
{
|
|
time=TimeGetSeconds()-startTime;
|
|
float alpha=(time/maxTime);
|
|
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_COLOR_BUFFER_BIT+GL_LIGHTING_BIT+GL_TEXTURE_BIT+GL_CURRENT_BIT);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
TexturesSelectTex(image);
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch*xSize,-kBackgroundYStretch*ySize);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch*xSize,kBackgroundYStretch*ySize);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch*xSize,-kBackgroundYStretch*ySize);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch*xSize,kBackgroundYStretch*ySize);
|
|
glEnd();
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
glColor4f(1,1,1,alpha);
|
|
TexturesSelectTex(image2);
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch*xSize2,-kBackgroundYStretch*ySize2);
|
|
glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch*xSize2,kBackgroundYStretch*ySize2);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch*xSize2,-kBackgroundYStretch*ySize2);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch*xSize2,kBackgroundYStretch*ySize2);
|
|
glEnd();
|
|
|
|
glPopAttrib();
|
|
|
|
ScreenBlit();
|
|
if(time>=maxTime)
|
|
exit=true;
|
|
}
|
|
gTexturesQualityModifier=0;
|
|
}
|
|
|
|
void InterfaceFadeInInterfaceFromImage(tFileRef image,float maxTime)
|
|
{
|
|
float startTime=TimeGetSeconds();
|
|
float time=0;
|
|
int exit=false;
|
|
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
while(!exit)
|
|
{
|
|
time=TimeGetSeconds()-startTime;
|
|
float alpha=1-(time/maxTime);
|
|
InterfaceDrawBackground(-1,image,kBackgroundXStretch,kBackgroundYStretch,0,0,alpha);
|
|
ScreenBlit();
|
|
if(time>=maxTime)
|
|
exit=true;
|
|
}
|
|
}
|
|
|
|
void InterfaceDrawStrings(char *stringBuffer,char *secondaryStringBuffer,tFileRef background)
|
|
{
|
|
InterfaceDrawBackground(background,-1,0,0,0,0,1);
|
|
TextPrintfToBufferFormated(Vector(kTitlePosX,kTitlePosY),0.08,kTextAlignLeft,stringBuffer);
|
|
TextPrintfToBufferFormated(Vector(-0.9,0.5),0.05,kTextAlignLeft,secondaryStringBuffer);
|
|
// TextPrintfToBufferFormated(Vector(-1,0.97),0.03,kTextAlignLeft,gInterfaceMenuPath);
|
|
TextPrintBuffer(1,false);
|
|
TextClearBuffer();
|
|
ScreenBlit();
|
|
}
|
|
|
|
void InterfaceDrawStatusBar(char *stringBuffer,char *secondaryStringBuffer,float status)
|
|
{
|
|
InterfaceDrawBackground(-1,-1,0,0,0,0,1);
|
|
TextPrintfToBufferFormated(Vector(kTitlePosX,kTitlePosY),0.08,kTextAlignLeft,stringBuffer);
|
|
TextPrintfToBufferFormated(Vector(-0.9,0.5),0.05,kTextAlignLeft,secondaryStringBuffer);
|
|
// TextPrintfToBufferFormated(Vector(-1,0.97),0.03,kTextAlignLeft,gInterfaceMenuPath);
|
|
TextPrintBuffer(1,false);
|
|
TextClearBuffer();
|
|
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_CURRENT_BIT);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
gTexturesQualityModifier=-255;
|
|
TexturesSelectTex(FileGetReference("progress.pct"));
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(status,1); glVertex2f(-kBackgroundXStretch*0.8+kBackgroundXStretch*1.6*status,-kBackgroundYStretch*0.1);
|
|
glTexCoord2d(status,0); glVertex2f(-kBackgroundXStretch*0.8+kBackgroundXStretch*1.6*status,kBackgroundYStretch*0.1);
|
|
glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch*0.8,-kBackgroundYStretch*0.1);
|
|
glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch*0.8,kBackgroundYStretch*0.1);
|
|
glEnd();
|
|
|
|
glPopAttrib();
|
|
|
|
ScreenBlit();
|
|
gTexturesQualityModifier=0;
|
|
}
|
|
|
|
void MenuSubTitleCallback(char *text,int selection,void *menu)
|
|
{
|
|
TextPrintfToBufferFormated(Vector(-0.85,0.6),0.05,kTextAlignLeft|kTextAutoWrap,text);
|
|
}
|
|
|
|
|
|
int InterfaceGetUserConfirmation(char *title,char *text)
|
|
{
|
|
tInterfaceMenuDescribtion menu;
|
|
InterfaceInitMenu(&menu,2,title);
|
|
|
|
menu.RenderCallback=(void(*)(void*,int,void*))MenuSubTitleCallback;
|
|
menu.userData=text;
|
|
menu.itemsYPos=0.2;
|
|
|
|
char itemStrings[][32]={"OK","Cancel"};
|
|
for(int i=0;i<menu.numItems;i++)
|
|
strcpy(menu.items[i].label,itemStrings[i]);
|
|
|
|
InterfaceMenuZoomAnimation(&menu,0,true);
|
|
int result=!InterfaceGetUserMenuSelection(&menu);
|
|
InterfaceDisposeMenu(&menu);
|
|
return result;
|
|
}
|
|
|
|
int InterfaceGetUserInputString(char *prompt,char *stringBuffer,int bufferSize,int fullCharSet,int hideType)
|
|
{
|
|
*stringBuffer='\0';
|
|
char ch;
|
|
int len=0;
|
|
|
|
tInterfaceMenuDescribtion menu;
|
|
InterfaceInitMenu(&menu,0,"");
|
|
gInterfaceType=true;
|
|
|
|
do
|
|
{
|
|
//InterfaceDrawBackground(-1,-1,0,0,0,0,1);
|
|
InterfaceRenderReplay(NULL,0,&menu);
|
|
|
|
TextPrintfToBufferFormated(Vector(kTitlePosX,kTitlePosY),0.08,kTextAlignLeft,prompt);
|
|
if(!hideType)
|
|
TextPrintfToBufferFormated(Vector(-0.9,0.5),0.05,kTextAlignLeft,"%s%s",stringBuffer,(int)(TimeGetSeconds()*4.0)%2?"_":"");
|
|
else
|
|
{
|
|
char hiddenType[256];
|
|
int ch;
|
|
for(ch=0;ch<strlen(stringBuffer);ch++)
|
|
hiddenType[ch]='*';
|
|
hiddenType[ch]='\0';
|
|
TextPrintfToBufferFormated(Vector(-0.9,0.5),0.05,kTextAlignLeft,"%s%s",hiddenType,(int)(TimeGetSeconds()*4.0)%2?"_":"");
|
|
}
|
|
// TextPrintfToBufferFormated(Vector(-1,0.97),0.03,kTextAlignLeft,gInterfaceMenuPath);
|
|
TextPrintBuffer(1,false);
|
|
TextClearBuffer();
|
|
/* if(!anim)
|
|
{
|
|
InterfaceTextBufferZoomAnimation(-1,true);
|
|
anim=true;
|
|
}*/
|
|
ScreenBlit();
|
|
SystemPoll(false);
|
|
SystemYieldTime(TimeGetSeconds()+(gSystemSuspended?1.0:0.05));
|
|
|
|
ch=GetKeyInput(NULL);
|
|
if((ch==0x7f||ch==0x08)&&len>0)
|
|
stringBuffer[--len]='\0';
|
|
if(ch>=(fullCharSet?' ':'-')&&ch<='z'&&len<bufferSize-1)
|
|
{
|
|
PlayInterfaceSound(FileGetReference("type.wav"));
|
|
stringBuffer[len++]=ch;
|
|
stringBuffer[len]='\0';
|
|
}
|
|
/* if((ch=='\r'||ch==0x1b))
|
|
InterfaceTextBufferZoomAnimation(-1,false);*/
|
|
TextClearBuffer();
|
|
}
|
|
while(ch!='\r'&&ch!=0x1b);//wait until return or esc is pressed
|
|
|
|
gInterfaceType=false;
|
|
|
|
return(ch=='\r');
|
|
}
|
|
|
|
void InterfaceDisplayMessage(tFileRef background,char *stringBuffer,char *secondaryStringBuffer)
|
|
{
|
|
while(GetInterfaceKey(kInterfaceKeyReturn)||GetInterfaceKey(kInterfaceKeyEnter)||GetInterfaceKey(kInterfaceKeyEsc));
|
|
TextPrintfToBufferFormated(Vector(kTitlePosX,kTitlePosY),0.08,kTextAlignLeft,stringBuffer);
|
|
TextPrintfToBufferFormated(Vector(-0.9,0.5),0.05,kTextAlignLeft|kTextAutoWrap,secondaryStringBuffer);
|
|
// TextPrintfToBufferFormated(Vector(-1,0.97),0.03,kTextAlignLeft,gInterfaceMenuPath);
|
|
InterfaceTextBufferZoomAnimation(background,true);
|
|
InterfaceDrawBackground(background,-1,0,0,0,0,1);
|
|
TextPrintBuffer(1,false);
|
|
ScreenBlit();
|
|
int exit=false;
|
|
while(!GetKeyInput(NULL)){
|
|
SystemPoll(false);
|
|
SystemYieldTime(TimeGetSeconds()+(gSystemSuspended?1.0:0.1));
|
|
}
|
|
InterfaceTextBufferZoomAnimation(background,false);
|
|
TextClearBuffer();
|
|
FlushKeys();
|
|
}
|
|
|
|
void CashString(int cash, char *str)
|
|
{
|
|
if(cash>=1000000)
|
|
sprintf(str,"$%d,%03d,%03d",cash/1000000,(cash/1000)%1000,cash%1000);
|
|
else if(cash>=1000)
|
|
sprintf(str,"$%d,%03d",cash/1000,cash%1000);
|
|
else
|
|
sprintf(str,"$%d",cash);
|
|
}
|
|
|
|
void MakeNumString(int i,char *str)
|
|
{
|
|
if((i%10)==1&&i!=11)
|
|
sprintf(str,"1st");
|
|
else if((i%10)==2&&i!=12)
|
|
sprintf(str,"2nd");
|
|
else if((i%10)==3&&i!=13)
|
|
sprintf(str,"3rd");
|
|
else
|
|
sprintf(str,"%dth",i);
|
|
}
|
|
|
|
void InterfaceInitMenu(tInterfaceMenuDescribtion *menu,int numItems,char *title)
|
|
{
|
|
menu->items=(tInterfaceMenuItemDescribtion*)MemoryAllocateBlock(sizeof(tInterfaceMenuItemDescribtion)*numItems);
|
|
|
|
strcpy(menu->title,title);
|
|
menu->initialSelection=0;
|
|
menu->numItems=numItems;
|
|
menu->image=-1;
|
|
menu->background=FileGetReference(kInterfaceBackgroundTexture);
|
|
menu->scrollEnable=false;
|
|
menu->joinDisable=false;
|
|
menu->enterAlwaysOK=false;
|
|
menu->easterEggEnable=false;
|
|
menu->menuTypeable=false;
|
|
menu->easterEggScrollPos=-10;
|
|
menu->easterEggString=0;
|
|
menu->imageXScale=kBackgroundXStretch;
|
|
menu->imageYScale=kBackgroundYStretch;
|
|
menu->imageAlpha=1.0;
|
|
menu->imageXPos=0;
|
|
menu->imageYPos=0;
|
|
menu->itemsXPos=-0.9;
|
|
menu->itemsYPos=0.55;
|
|
menu->minScroll=-0.75;
|
|
menu->type[0]='\0';
|
|
menu->returnOnSpace=false;
|
|
|
|
menu->cursorShowPos=10000;
|
|
menu->cursorPos=0;
|
|
menu->descPos=Vector(0.3,0.55);
|
|
menu->mousePos=GetMousePos();
|
|
menu->RenderCallback=NULL;
|
|
menu->TimerCallback=NULL;
|
|
menu->userData=NULL;
|
|
for(int i=0;i<numItems;i++)
|
|
{
|
|
menu->items[i].sel=0;
|
|
menu->items[i].label[0]='\0';
|
|
menu->items[i].describtion[0]='\0';
|
|
menu->items[i].type[0]='\0';
|
|
menu->items[i].size=0.05;
|
|
menu->items[i].lineSpacing=0.15;
|
|
menu->items[i].maxTypeXPos=0.95;
|
|
menu->items[i].maxTypeLength=255;
|
|
menu->items[i].sliderPos=0;
|
|
menu->items[i].sliderTransparency=0;
|
|
menu->items[i].r=1;
|
|
menu->items[i].g=1;
|
|
menu->items[i].b=1;
|
|
menu->items[i].flags=0;
|
|
}
|
|
}
|
|
|
|
void InterfaceDisposeMenu(tInterfaceMenuDescribtion *menu)
|
|
{
|
|
MemoryFreeBlock((tInterfaceMenuItemDescribtion*)menu->items);
|
|
}
|
|
|
|
void InterfaceMenuRender(tInterfaceMenuDescribtion *menu,int selection,float backgroundAlpha)
|
|
{
|
|
static float lt=0;
|
|
float t=TimeGetSeconds();
|
|
float dt=t-lt;
|
|
lt=t;
|
|
|
|
gTexturesQualityModifier=-255;
|
|
if(menu->background!=kFileErr)
|
|
InterfaceDrawBackground(menu->background,menu->image,menu->imageXScale,menu->imageYScale,menu->imageXPos,menu->imageYPos,menu->imageAlpha*backgroundAlpha);
|
|
|
|
gTexturesQualityModifier=0;
|
|
if(menu->RenderCallback)
|
|
menu->RenderCallback(menu->userData,selection,menu);
|
|
gTexturesQualityModifier=-255;
|
|
|
|
|
|
float line=menu->itemsYPos;
|
|
float selOffset=line;
|
|
|
|
if(selection!=-1&&menu->scrollEnable)
|
|
{
|
|
for(int i=0;i<selection;i++)
|
|
if(!(menu->items[i].flags&kInterfaceMenuItemFixedPos))
|
|
selOffset-=menu->items[i].lineSpacing;
|
|
float lastOffset=selOffset;
|
|
for(int i=selection;i<menu->numItems;i++)
|
|
if(!(menu->items[i].flags&kInterfaceMenuItemFixedPos))
|
|
lastOffset-=menu->items[i].lineSpacing;
|
|
|
|
if(lastOffset<menu->minScroll)
|
|
line+=((menu->itemsYPos-selOffset)/(menu->itemsYPos-lastOffset))*((menu->itemsYPos-lastOffset)-(menu->itemsYPos-menu->minScroll));
|
|
}
|
|
|
|
for(int i=0;i<menu->numItems;i++)
|
|
{
|
|
if((line<=menu->itemsYPos+menu->items[i].lineSpacing*0.5&&line>=menu->minScroll)||(!menu->scrollEnable)||menu->items[i].flags&kInterfaceMenuItemFixedPos)
|
|
{
|
|
char hiddenType[256];
|
|
int ch;
|
|
for(ch=0;ch<strlen(menu->items[i].type);ch++)
|
|
hiddenType[ch]='*';
|
|
hiddenType[ch]='\0';
|
|
|
|
char str[256];
|
|
int j=0;
|
|
int img=false;
|
|
if(menu->items[i].flags&kInterfaceMenuItemTypeable)
|
|
do
|
|
{
|
|
char *type=(menu->items[i].flags&kInterfaceMenuItemTypeHidden?hiddenType:menu->items[i].type)+j;
|
|
sprintf(str,"%s\255#a\255%s",menu->items[i].label,type);
|
|
if(j)
|
|
if(type[-1]=='\255')
|
|
img=!img;
|
|
j++;
|
|
}
|
|
while((TextWidth(str,menu->items[i].size*(1+0.1*menu->items[i].sel))+menu->itemsXPos*kTextXPos>kTextXPos*menu->items[i].maxTypeXPos||img)&&j!=strlen(menu->items[i].type));
|
|
else
|
|
strcpy(str,menu->items[i].label);
|
|
float fullLength=TextWidth(str,menu->items[i].size*(1+0.1*menu->items[i].sel));
|
|
float visRatio=fullLength/(kTextXPos*(menu->items[i].maxTypeXPos-menu->itemsXPos));
|
|
float textshift=0;
|
|
if(visRatio>1)
|
|
{
|
|
float scroll=menu->items[i].scroll/1.5f;
|
|
if(selection==i)
|
|
menu->items[i].scroll+=dt;
|
|
else if(menu->items[i].scroll>2)
|
|
menu->items[i].scroll=0;
|
|
else if(menu->items[i].scroll>1)
|
|
menu->items[i].scroll=2-menu->items[i].scroll;
|
|
else
|
|
menu->items[i].scroll-=dt;
|
|
|
|
float scrollsize;
|
|
if(scroll<1)
|
|
scrollsize=fullLength*(1-(1-(1/(visRatio+0.1)))*scroll);
|
|
else if(scroll<2)
|
|
scrollsize=fullLength*(1-(1-(1/(visRatio+0.1)))*(2-scroll));
|
|
else
|
|
scrollsize=fullLength;
|
|
char tmp[256];
|
|
strcpy(tmp,str);
|
|
j=0;
|
|
img=false;
|
|
char color=-1;
|
|
do
|
|
{
|
|
strcpy(str,tmp+j);
|
|
if(j)
|
|
if(tmp[j-1]=='\255')
|
|
{
|
|
img=!img;
|
|
if(img&&tmp[j]=='#')
|
|
color=tmp[j+1];
|
|
}
|
|
j++;
|
|
}
|
|
while((TextWidth(str,menu->items[i].size*(1+0.1*menu->items[i].sel))>scrollsize||img)&&j!=strlen(tmp));
|
|
textshift=scrollsize-TextWidth(str,menu->items[i].size*(1+0.1*menu->items[i].sel));
|
|
if(color!=-1)
|
|
{
|
|
strcpy(tmp,str);
|
|
sprintf(str,"\255#%c\255%s",color,tmp);
|
|
}
|
|
/* int scrollpos=0;
|
|
|
|
if(scroll<1)
|
|
scrollpos=(1-(1/visRatio))*strlen(str)*scroll;
|
|
else if(scroll<2)
|
|
scrollpos=(1-(1/visRatio))*strlen(str)*(2-scroll);
|
|
memmove(str,str+scrollpos,strlen(str+scrollpos)+1);*/
|
|
}
|
|
if(menu->items[i].scroll<0)
|
|
menu->items[i].scroll=0;
|
|
img=false;
|
|
int l=strlen(str);
|
|
while((TextWidth(str,menu->items[i].size*(1+0.1*menu->items[i].sel))+menu->itemsXPos*kTextXPos>kTextXPos*menu->items[i].maxTypeXPos||img)&&*str)
|
|
{
|
|
if(str[l-1]=='\255')
|
|
img=!img;
|
|
str[l-1]='\0';
|
|
l--;
|
|
}
|
|
|
|
|
|
|
|
if(menu->items[i].flags&kInterfaceMenuItemTypeable&&selection==i&&(int)(TimeGetSeconds()*4)%2)
|
|
sprintf(str,"%s%s",str,"_");
|
|
|
|
float a=(menu->items[i].flags&kInterfaceMenuItemDisabled?0.5:1)*(0.8+(0.2*menu->items[i].sel*0.5*(sin(TimeGetSeconds()*8)+1) ));
|
|
if(menu->items[i].flags&kInterfaceMenuItemFixedPos)
|
|
TextPrintfToBufferFormatedColored(Vector(menu->items[i].fixedX,menu->items[i].fixedY+menu->items[i].size*0.1*menu->items[i].sel)
|
|
,menu->items[i].size*(1+0.1*menu->items[i].sel)
|
|
,kTextAlignLeft
|
|
,menu->items[i].r
|
|
,menu->items[i].g
|
|
,menu->items[i].b
|
|
,a
|
|
,str
|
|
);
|
|
else
|
|
TextPrintfToBufferFormatedColored(Vector(menu->itemsXPos+textshift,line+menu->items[i].size*0.1*menu->items[i].sel)
|
|
,menu->items[i].size*(1+0.1*menu->items[i].sel)
|
|
,kTextAlignLeft
|
|
,menu->items[i].r
|
|
,menu->items[i].g
|
|
,menu->items[i].b
|
|
,a
|
|
,str
|
|
);
|
|
if(selection==i)
|
|
if(menu->items[i].flags&kInterfaceMenuItemFixedPos)
|
|
menu->cursorPos=(menu->items[i].fixedY-menu->items[i].size*1.3)*kScreenYPos;
|
|
else
|
|
menu->cursorPos=(line-menu->items[i].size*1.3)*kScreenYPos;
|
|
|
|
if(menu->items[i].flags&kInterfaceMenuItemSlider)
|
|
{
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_CURRENT_BIT);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
float y=(line-0.05)*kScreenYPos;
|
|
|
|
glColor4f(1,1,1,(1-menu->items[i].sliderTransparency)*backgroundAlpha);
|
|
TexturesSelectTex(FileGetReference(kInterfaceMenuSlideBarTexture));
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+kInterfaceMenuSlideBarStart+kInterfaceMenuSlideBarWidth, y-kInterfaceMenuSlideBarHeight);
|
|
glTexCoord2d(1,0); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+kInterfaceMenuSlideBarStart+kInterfaceMenuSlideBarWidth, y+kInterfaceMenuSlideBarHeight);
|
|
glTexCoord2d(0,1); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+kInterfaceMenuSlideBarStart, y-kInterfaceMenuSlideBarHeight);
|
|
glTexCoord2d(0,0); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+kInterfaceMenuSlideBarStart, y+kInterfaceMenuSlideBarHeight);
|
|
glEnd();
|
|
|
|
TexturesSelectTex(FileGetReference(kInterfaceMenuSliderTexture));
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
glTexCoord2d(1,1); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+menu->items[i].sliderPos*kInterfaceMenuSlideBarWidth+kInterfaceMenuSlideBarStart+kInterfaceMenuSliderSize, y-kInterfaceMenuSliderSize);
|
|
glTexCoord2d(1,0); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+menu->items[i].sliderPos*kInterfaceMenuSlideBarWidth+kInterfaceMenuSlideBarStart+kInterfaceMenuSliderSize, y+kInterfaceMenuSliderSize);
|
|
glTexCoord2d(0,1); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+menu->items[i].sliderPos*kInterfaceMenuSlideBarWidth+kInterfaceMenuSlideBarStart-kInterfaceMenuSliderSize, y-kInterfaceMenuSliderSize);
|
|
glTexCoord2d(0,0); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+menu->items[i].sliderPos*kInterfaceMenuSlideBarWidth+kInterfaceMenuSlideBarStart-kInterfaceMenuSliderSize, y+kInterfaceMenuSliderSize);
|
|
glEnd();
|
|
|
|
glPopAttrib();
|
|
}
|
|
}
|
|
if(!(menu->items[i].flags&kInterfaceMenuItemFixedPos))
|
|
line-=menu->items[i].lineSpacing;
|
|
}
|
|
TextPrintfToBufferFormated(Vector(kTitlePosX,kTitlePosY),0.08,kTextAlignLeft,menu->title);
|
|
|
|
float a=2-(TimeGetSeconds()-giTunesLastStatusUpdate)*0.4;
|
|
if(a>0)
|
|
{
|
|
char str[1024];
|
|
if(giTunesPlaying==kITunesPlaying)
|
|
sprintf(str,"%s - %s",giTunesArtist,giTunesSong);
|
|
else if(giTunesPlaying==kITunesPaused)
|
|
strcpy(str,"Paused");
|
|
else
|
|
strcpy(str,"Stopped");
|
|
float screenRatio=(float)gConfig->screenXSize/(float)gConfig->screenYSize;
|
|
float maxWidth=(0.1+screenRatio/(4.0/3.0))*kTextXPos;
|
|
float scale=1;
|
|
while(TextWidth(str,0.04*scale)>maxWidth)
|
|
scale*=0.9;
|
|
//printf("%f,%f/%f\n",size,TextWidth(str,size),maxWidth);
|
|
TextPrintfToBufferFormatedColored(Vector(-0.1,0.95+0.05*scale),0.04*scale,kTextAlignLeft,1,1,1,a,str);
|
|
}
|
|
|
|
glLoadIdentity();
|
|
glTranslatef(0.0f,0.0f,-1.0f);
|
|
|
|
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_CURRENT_BIT);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
glColor4f(1,1,1,backgroundAlpha*(menu->menuTypeable&&*menu->type)?0.5:1);
|
|
TexturesSelectTex(FileGetReference(kInterfaceMenuPointerTexture));
|
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
float y=menu->cursorShowPos;
|
|
glTexCoord2d(1,1); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+kInterfaceMenuPointerSize,y-kInterfaceMenuPointerSize);
|
|
glTexCoord2d(1,0); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos+kInterfaceMenuPointerSize,y+kInterfaceMenuPointerSize);
|
|
glTexCoord2d(0,1); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos-kInterfaceMenuPointerSize,y-kInterfaceMenuPointerSize);
|
|
glTexCoord2d(0,0); glVertex2f((menu->itemsXPos-0.05)*kScreenXPos-kInterfaceMenuPointerSize,y+kInterfaceMenuPointerSize);
|
|
glEnd();
|
|
|
|
|
|
glPopAttrib();
|
|
|
|
if(selection!=-1)
|
|
TextPrintfToBufferFormatedColored(menu->descPos,0.03,kTextAlignLeft|kTextAutoWrap
|
|
,1,1,1,menu->items[selection].flags&kInterfaceMenuItemDisabled?0.45:1
|
|
,menu->items[selection].describtion);
|
|
|
|
|
|
|
|
TextPrintfToBufferFormatedColoredTilted(Vector(0+sin(menu->easterEggScrollPos*5)*0.1,-menu->easterEggScrollPos),0.05,kTextAlignMiddle,-cos(menu->easterEggScrollPos*5)*0.3,1,0.5,0,1,gEasterEggStrings[menu->easterEggString]);
|
|
|
|
TextPrintBuffer(backgroundAlpha,false);
|
|
TextClearBuffer();
|
|
ScreenBlit();
|
|
gTexturesQualityModifier=0;
|
|
}
|
|
|
|
#define kMenuAnimationTime 0.2
|
|
#define kMenuAnimationMaxXZoom 2.5
|
|
#define kMenuAnimationMaxYZoom 0.5
|
|
|
|
void InterfaceTextBufferZoomAnimation(tFileRef background,int in)
|
|
{
|
|
float startTime=TimeGetSeconds();
|
|
float time=0;
|
|
while(time<kMenuAnimationTime)
|
|
{
|
|
time=TimeGetSeconds()-startTime;
|
|
float f=time/kMenuAnimationTime;
|
|
gTextBufferScale.x=1+(in?1-f:f)*kMenuAnimationMaxXZoom;
|
|
gTextBufferScale.y=1+(in?1-f:f)*kMenuAnimationMaxYZoom;
|
|
InterfaceDrawBackground(background,-1,0,0,0,0,1);
|
|
TextPrintBuffer(0.5+0.5*(in?1-f:f),false);
|
|
SystemPoll(false);
|
|
ScreenBlit();
|
|
}
|
|
gTextBufferScale=Vector(1,1);
|
|
ScreenBlit();
|
|
}
|
|
|
|
void InterfaceMenuZoomAnimation(tInterfaceMenuDescribtion *menu,int selection,int in)
|
|
{
|
|
InterfaceMenuRender(menu,selection,(in?0:1));
|
|
float startTime=TimeGetSeconds();
|
|
float time=0;
|
|
while(time<kMenuAnimationTime)
|
|
{
|
|
time=TimeGetSeconds()-startTime;
|
|
float f=time/kMenuAnimationTime;
|
|
// gTextBufferScale.x=1+(in?1-f:f)*kMenuAnimationMaxXZoom;
|
|
// gTextBufferScale.y=1+(in?1-f:f)*kMenuAnimationMaxYZoom;
|
|
SystemPoll(false);
|
|
InterfaceMenuRender(menu,selection,(in?f:1-f));
|
|
}
|
|
gTextBufferScale=Vector(1,1);
|
|
ScreenBlit();
|
|
}
|
|
|
|
extern int gReggieConnected;
|
|
|
|
int InterfaceMenuInput(tInterfaceMenuDescribtion *menu,int *selection)
|
|
{
|
|
if(gSystemSuspended)
|
|
return false;
|
|
/*
|
|
tVector2 mousePos=GetMousePos();
|
|
int mouseSel=false;
|
|
float mouseBar=-1;
|
|
float y=menu->itemsYPos;
|
|
float minDist=1000;
|
|
for(int i=0;i<menu->numItems;i++)
|
|
{
|
|
float dist=fabs(y-menu->items[i].size-mousePos.y);
|
|
if(mousePos.x<menu->itemsXPos)
|
|
dist+=fabs(mousePos.x-menu->itemsXPos);
|
|
if(menu->items[i].flags&kInterfaceMenuItemSlider)
|
|
{
|
|
if(mousePos.x>menu->itemsXPos+(kInterfaceMenuSlideBarStart+kInterfaceMenuSlideBarWidth)/kScreenXPos)
|
|
dist+=fabs(mousePos.x-(menu->itemsXPos+(kInterfaceMenuSlideBarStart+kInterfaceMenuSlideBarWidth)/kScreenXPos));
|
|
}
|
|
else
|
|
if(mousePos.x>menu->itemsXPos+TextWidth(menu->items[i].label,menu->items[i].size)/kScreenXPos)
|
|
dist+=fabs(mousePos.x-(menu->itemsXPos+TextWidth(menu->items[i].label,menu->items[i].size)/kScreenXPos));
|
|
if(dist<minDist)
|
|
{
|
|
minDist=dist;
|
|
if(dist<0.2)
|
|
{
|
|
if(!VectorEqual(mousePos,menu->mousePos))
|
|
*selection=i;
|
|
mouseSel=true;
|
|
}
|
|
}
|
|
|
|
y-=menu->items[i].lineSpacing;
|
|
|
|
}
|
|
if(mousePos.x>menu->itemsXPos+kInterfaceMenuSlideBarStart/kScreenXPos&&mousePos.x<menu->itemsXPos+(kInterfaceMenuSlideBarStart+kInterfaceMenuSlideBarWidth)/kScreenXPos)
|
|
mouseBar=(mousePos.x-(menu->itemsXPos+kInterfaceMenuSlideBarStart/kScreenXPos))/(kInterfaceMenuSlideBarWidth/kScreenXPos)+0.08;
|
|
menu->mousePos=mousePos;
|
|
*/
|
|
int key;
|
|
char ch=GetKeyInput(&key);
|
|
gLastMenuChar=ch;
|
|
if(ch||key)
|
|
gStartIdleTime=TimeGetSeconds();
|
|
|
|
/* if(key==kInterfaceMouseDown&&mouseSel)
|
|
if(menu->items[*selection].flags&kInterfaceMenuItemSlider)
|
|
{
|
|
if(mouseBar>menu->items[*selection].sliderPos)
|
|
key=kInterfaceKeyRight;
|
|
else
|
|
key=kInterfaceKeyLeft;
|
|
}
|
|
else if(menu->items[*selection].flags&kInterfaceMenuItemArrowInput)
|
|
key=kInterfaceKeyRight;
|
|
else if(!(menu->items[*selection].flags&kInterfaceMenuItemTypeable))
|
|
key=kInterfaceKeyEnter;
|
|
*/
|
|
switch(key)
|
|
{
|
|
//cursor up/down movement
|
|
case kInterfaceKeyDown:
|
|
PlayInterfaceSound(FileGetReference("menu.wav"));
|
|
(*selection)++;
|
|
if(*selection>=menu->numItems)
|
|
*selection=0;
|
|
break;
|
|
|
|
case kInterfaceKeyUp:
|
|
PlayInterfaceSound(FileGetReference("menu.wav"));
|
|
(*selection)--;
|
|
if(*selection<0)
|
|
*selection=menu->numItems-1;
|
|
break;
|
|
|
|
//cursor left/right movement (if enabled)
|
|
case kInterfaceKeyLeft:
|
|
if(menu->items[*selection].flags&kInterfaceMenuItemArrowInput&&!(menu->items[*selection].flags&kInterfaceMenuItemDisabled))
|
|
{
|
|
PlayInterfaceSound(FileGetReference("toggle.wav"));
|
|
*selection|=kInterfaceMenuLeftArrow;
|
|
if(GetInterfaceKey(kInterfaceKeyEasterEgg))
|
|
*selection|=kInterfaceMenuEasterEgg;
|
|
return true;
|
|
}
|
|
break;
|
|
|
|
case kInterfaceKeyRight:
|
|
if(menu->items[*selection].flags&kInterfaceMenuItemArrowInput&&!(menu->items[*selection].flags&kInterfaceMenuItemDisabled))
|
|
{
|
|
PlayInterfaceSound(FileGetReference("toggle.wav"));
|
|
*selection|=kInterfaceMenuRightArrow;
|
|
if(GetInterfaceKey(kInterfaceKeyEasterEgg))
|
|
*selection|=kInterfaceMenuEasterEgg;
|
|
return true;
|
|
}
|
|
break;
|
|
|
|
//esc key
|
|
case kInterfaceKeyDelete:
|
|
if((menu->items[*selection].flags&kInterfaceMenuItemTypeable)||(menu->menuTypeable))
|
|
break;
|
|
case kInterfaceKeyEsc:
|
|
PlayInterfaceSound(FileGetReference("esc.wav"));
|
|
if(menu->menuTypeable&&*menu->type)
|
|
{
|
|
*menu->type='\0';
|
|
break;
|
|
}
|
|
InterfaceMenuZoomAnimation(menu,*selection,false);
|
|
*selection=kInterfaceMenuEsc;
|
|
return true;
|
|
|
|
case kInterfaceKeyEasterEgg:
|
|
if(menu->easterEggEnable)
|
|
menu->easterEggScrollPos=1.0;
|
|
menu->easterEggString=RandomInt(0,kNumEasterEggStrings);
|
|
break;
|
|
|
|
case kInterfaceKeyR:
|
|
if(menu->easterEggEnable)
|
|
{
|
|
InterfaceMenuZoomAnimation(menu,*selection,false);
|
|
*selection=kInterfaceMenuReplayKey;
|
|
return true;
|
|
}
|
|
break;
|
|
|
|
//enter key
|
|
case kInterfaceKeyReturn:
|
|
case kInterfaceKeyEnter:
|
|
if(menu->menuTypeable&&*menu->type)
|
|
return true;
|
|
PlayInterfaceSound(FileGetReference("select.wav"));
|
|
if(menu->enterAlwaysOK)
|
|
{
|
|
InterfaceMenuZoomAnimation(menu,*selection,false);
|
|
*selection=kInterfaceMenuOK;
|
|
return true;
|
|
}
|
|
if(!(menu->items[*selection].flags&(kInterfaceMenuItemTypeable|kInterfaceMenuItemDisabled|kInterfaceMenuItemArrowInput)))
|
|
InterfaceMenuZoomAnimation(menu,*selection,false);
|
|
if(!(menu->items[*selection].flags&kInterfaceMenuItemDisabled))
|
|
return true;
|
|
|
|
case kInterfaceKeySpace:
|
|
if(menu->returnOnSpace)
|
|
{
|
|
InterfaceMenuZoomAnimation(menu,*selection,false);
|
|
*selection|=kInterfaceMenuSpaceFlag;
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(menu->items[*selection].flags&kInterfaceMenuItemTypeable||menu->menuTypeable&&!(menu->menuTypeable==kMenuTypeableReggie&&!gReggieConnected))
|
|
{
|
|
gInterfaceType=true;
|
|
if(ch)
|
|
{
|
|
int len=strlen((menu->items[*selection].flags&kInterfaceMenuItemTypeable)?menu->items[*selection].type:menu->type);
|
|
if((ch==0x7f||ch==0x08)&&len>0)
|
|
if(menu->items[*selection].flags&kInterfaceMenuItemTypeable)
|
|
menu->items[*selection].type[--len]='\0';
|
|
else
|
|
menu->type[--len]='\0';
|
|
if(ch>=' '&&ch<='z'&&ch!='%'&&len<menu->items[*selection].maxTypeLength)
|
|
{
|
|
PlayInterfaceSound(FileGetReference("type.wav"));
|
|
if(menu->items[*selection].flags&kInterfaceMenuItemTypeable)
|
|
{
|
|
menu->items[*selection].type[len++]=ch;
|
|
menu->items[*selection].type[len]='\0';
|
|
}
|
|
else
|
|
{
|
|
menu->type[len++]=ch;
|
|
menu->type[len]='\0';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
gInterfaceType=menu->items[*selection].flags&kInterfaceMenuItemTypeable;
|
|
return false;
|
|
}
|
|
|
|
#define kMenuSelFadeTime 0.2
|
|
|
|
void InterfaceFadeMenuSelection(tInterfaceMenuDescribtion *menu,float dt,int selection)
|
|
{
|
|
for(int i=0;i<menu->numItems;i++)
|
|
{
|
|
menu->items[i].sel-=dt/kMenuSelFadeTime;
|
|
if(menu->items[i].sel<0)
|
|
menu->items[i].sel=0;
|
|
}
|
|
if( menu->items[selection].sel<1)
|
|
menu->items[selection].sel=1;
|
|
if(menu->cursorShowPos>10)
|
|
menu->cursorShowPos=menu->cursorPos;
|
|
|
|
if(menu->cursorShowPos>menu->cursorPos)
|
|
{
|
|
menu->cursorShowPos-=dt+dt*10*fabs(menu->cursorShowPos-menu->cursorPos);
|
|
if(menu->cursorShowPos<menu->cursorPos)
|
|
menu->cursorShowPos=menu->cursorPos;
|
|
}
|
|
else
|
|
{
|
|
menu->cursorShowPos+=dt+dt*10*fabs(menu->cursorShowPos-menu->cursorPos);
|
|
if(menu->cursorShowPos>menu->cursorPos)
|
|
menu->cursorShowPos=menu->cursorPos;
|
|
}
|
|
}
|
|
|
|
int InterfaceGetUserMenuSelection(tInterfaceMenuDescribtion *menu)
|
|
{
|
|
float lastTime=TimeGetSeconds();
|
|
int selection=menu->initialSelection;
|
|
int count=0;
|
|
do{
|
|
if(selection>=menu->numItems||selection<0)
|
|
selection=0;
|
|
|
|
if(gJoinFlag)
|
|
if(!menu->joinDisable)
|
|
{
|
|
gJoinFlag=false;
|
|
DirectJoinGame(gJoinHost);
|
|
}
|
|
else
|
|
return kInterfaceMenuEsc;
|
|
|
|
if(!gSystemSuspended||(count++%100==0))
|
|
InterfaceMenuRender(menu,selection,1);
|
|
SystemPoll(false);
|
|
SystemYieldTime(kMenuFrameTime+lastTime);
|
|
|
|
float time=TimeGetSeconds();
|
|
|
|
InterfaceFadeMenuSelection(menu,time-lastTime,selection);
|
|
menu->easterEggScrollPos-=kEasterEggScrollSpeed*(time-lastTime);
|
|
lastTime=time;
|
|
if(menu->TimerCallback)
|
|
{
|
|
int val=menu->TimerCallback(menu->userData);
|
|
if(val!=-1)
|
|
return val;
|
|
}
|
|
}while(!InterfaceMenuInput(menu,&selection));
|
|
return selection;
|
|
}
|
|
|
|
#define kScrollTextSize 0.05
|
|
|
|
int TextPrintFile(tFileRef fileId,float yStart)
|
|
{
|
|
float y=yStart;
|
|
char *fileData=(char*)FileGetDataPtr(fileId);
|
|
char *filePos=fileData;
|
|
int fileLenght=FileGetSize(fileId);
|
|
int linedrawn=false;
|
|
while(filePos<fileData+fileLenght)
|
|
{
|
|
char line[128];
|
|
GetLine(line,&filePos,fileData+fileLenght,128);
|
|
float a=1-((fabs(y)-0.55)/0.45);
|
|
if(a<0)a=0;
|
|
if(a>1)a=1;
|
|
|
|
if(y<=1+3*kScrollTextSize&&y>=-1-3*kScrollTextSize)
|
|
{
|
|
if(line[0]=='\255'&&line[1]!='#')
|
|
TextPrintfToBufferFormatedColored(Vector(0,y),kScrollTextSize*5,kTextAlignMiddle,1,1,1,a,line);
|
|
else
|
|
TextPrintfToBufferFormatedColored(Vector(0,y),kScrollTextSize,kTextAlignMiddle,1,1,1,a,line);
|
|
linedrawn=true;
|
|
}
|
|
y-=kScrollTextSize*3;
|
|
}
|
|
// InterfaceDrawBackground(-1,-1,0,0,0,0,1);
|
|
InterfaceRenderReplay(NULL,0,NULL);
|
|
TextPrintBuffer(1,false);
|
|
TextClearBuffer();
|
|
|
|
ScreenBlit();
|
|
return linedrawn;
|
|
}
|
|
|
|
void TextScrollFile(tFileRef fileId)
|
|
{
|
|
while(GetInterfaceKey(kInterfaceKeyReturn)||GetInterfaceKey(kInterfaceKeyEnter)||GetInterfaceKey(kInterfaceKeyEsc));
|
|
float startTime=TimeGetSeconds();
|
|
int start=false;
|
|
int done=false;
|
|
while(!(GetInterfaceKey(kInterfaceKeyReturn)||GetInterfaceKey(kInterfaceKeyEnter)||GetInterfaceKey(kInterfaceKeyEsc)||GetInterfaceKey(kInterfaceKeyDelete)||done))
|
|
{
|
|
SystemPoll(false);
|
|
float time=TimeGetSeconds()-startTime;
|
|
float y=-1.2+time*0.2;
|
|
if(!TextPrintFile(fileId,y)){
|
|
if(start)
|
|
done=true;
|
|
}
|
|
else
|
|
start=true;
|
|
SystemPoll(false);
|
|
}
|
|
FlushKeys();
|
|
}
|
|
|
|
void TeaserScreen()
|
|
{
|
|
if(RT3_IsRegistered())
|
|
return;
|
|
|
|
tInterfaceMenuDescribtion menu;
|
|
InterfaceInitMenu(&menu,2,"Get the full version now!");
|
|
|
|
// menu.userData=text;
|
|
menu.image=FileGetReference("teaser.png");
|
|
menu.imageXScale=0.2;
|
|
menu.imageYScale=0.2;
|
|
menu.imageXPos+=0.2;
|
|
menu.imageYPos+=0.1;
|
|
|
|
char itemStrings[][32]={"Later...","Buy It Now!"};
|
|
for(int i=0;i<menu.numItems;i++)
|
|
{
|
|
strcpy(menu.items[i].label,itemStrings[i]);
|
|
menu.items[i].flags=kInterfaceMenuItemDisabled;
|
|
}
|
|
|
|
InterfaceMenuZoomAnimation(&menu,0,true);
|
|
InterfaceMenuRender(&menu,0,1);
|
|
tFileRef logs[kMaxLogs];
|
|
int logCount;
|
|
GetLogs(logs,&logCount);
|
|
if(!LogLoad(logs[RandomInt(0,logCount)],gGameInfo))
|
|
LogLoad(FileGetReference("bullit.redlog"),gGameInfo);
|
|
|
|
StartBackgroundReplay();
|
|
menu.RenderCallback=(void(*)(void*,int,void*))InterfaceRenderReplay;
|
|
menu.background=kFileErr;
|
|
for(int i=0;i<menu.numItems;i++)
|
|
menu.items[i].flags=0;
|
|
|
|
if(InterfaceGetUserMenuSelection(&menu))
|
|
{
|
|
if(gConfig->fullscreen)
|
|
{
|
|
gConfig->fullscreen=false;
|
|
ScreenReInit();
|
|
gConfig->fullscreen=true;
|
|
}
|
|
ASWReg_Initialization();
|
|
ASWReg_ShowDialog(true);
|
|
if(gConfig->fullscreen)
|
|
ScreenReInit();
|
|
|
|
// RT3_LaunchRegisterApp();
|
|
// Exit();
|
|
}
|
|
InterfaceDisposeMenu(&menu);
|
|
} |