📄 menu.cpp
字号:
/*************************************************************************
"I Have No Tomatoes"
Copyright (c) 2004, Mika Halttunen
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Mika Halttunen <lsoft@mbnet.fi>
*************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "SDL.h"
#include "SDL_opengl.h"
#include "SDL_image.h"
#include "game.h"
#include "texture.h"
#include "init.h"
#include "timer.h"
#include "mymath.h"
#include "font.h"
#include "screenshot.h"
#include "soundmusic.h"
#include "bgrounds.h"
#include "mpak.h"
#include "menu.h"
#include "hiscore.h"
// Version
#define VERSION "v1.5"
// Menu textures
GLuint button_tex;
GLuint button_tex2;
GLuint menu_bg;
// Item colors
float col_selected[3] = { 1, 1, 0.5f };
float col_selected2[3] = { 1, 1, 1 };
float col_normal[3] = { .75f, .75f, .75f };
float col_normal2[3] = { 0.0f, 0.8f, 1 };
// Fading stuff (from game.cpp)
// Are we fading? (0 == no, 1 == fade in, 2 == fade out)
extern int fading;
extern float fade_amount;
// Hiscore/credits stuff
float mid_fade_amount;
int mid_fade_dir;
int mid_state; // 1 == single player hiscores, 2 == two player hiscores, 3 == credits
int mid_state_wait;
// Background animation
float back_anim;
float bx_roll, by_roll;
float bx_roll_dir, by_roll_dir;
// Key setting stuff
int whose_keys;
int *key_to_set;
int prev_key;
bool setting_key;
// Helper function which returns a key name in upper case
char *key_name(int key) {
if(key != -1) {
// Get the key name from SDL
static char buf[32];
#ifdef WIN32
_snprintf(buf, 32, "%s", SDL_GetKeyName((SDLKey)key));
#else
snprintf(buf, 32, "%s", SDL_GetKeyName((SDLKey)key));
#endif
if(strcmp(buf, "left") == 0)
return "LEFT ARROW";
else if(strcmp(buf, "right") == 0)
return "RIGHT ARROW";
else if(strcmp(buf, "up") == 0)
return "UP ARROW";
else if(strcmp(buf, "down") == 0)
return "DOWN ARROW";
// Convert it to upper case
for(unsigned int c=0; c<strlen(buf); c++) {
buf[c] = toupper(buf[c]);
}
return buf;
}
else
return "PRESS A KEY"; // This is displayed when we're setting
// a key.
}
// Helper function which draws the credits
void draw_credits(float fade) {
set_font_scale(0.8f,0.7f);
glColor4f(0.1f,1,1, fade);
glprintf_center(font1, 0, 0, 3.05f, -13, "CREDITS");
set_font_scale(0.6f, 0.6f);
glColor4f(0.7f,0.8f,1, fade);
glprintf_center(font1, 0, 0, 2.4f, -13, "GAME DESIGN");
glColor4f(1,1,1, fade);
glprintf_center(font1, 0, 0, 1.8f, -13, "TEEMU RUOKOLAINEN");
glColor4f(0.7f,0.8f,1, fade);
glprintf_center(font1, 0, 0, 0.8f, -13, "PROGRAMMING");
glColor4f(1,1,1, fade);
glprintf_center(font1, 0, 0, 0.2f, -13, "MIKA HALTTUNEN");
glColor4f(0.7f,0.8f,1, fade);
glprintf_center(font1, 0, 0, -0.8f, -13, "SOUND AND MUSIC");
glColor4f(1,1,1, fade);
glprintf_center(font1, 0, 0, -1.4f, -13, "TEEMU RUOKOLAINEN");
glColor4f(0.7f,0.8f,1, fade);
glprintf_center(font1, 0, 0, -2.4f, -13, "ARTWORK");
glColor4f(1,1,1, fade);
glprintf_center(font1, 0, 0, -3.0f, -13, "MIKA HALTTUNEN");
set_font_scale(1,1);
}
// Draw the menu
void draw_menu(int menu_id, int menu_item, int place, float fade, HISCORE_LIST *list) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//glClear(GL_DEPTH_BUFFER_BIT);
// Set up the viewport
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0f, 1.333333f, 1, 100);
glTranslatef(0,0,-32);
// Draw the background
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
BIND_TEXTURE(menu_bg);
glDepthMask(GL_FALSE);
float bx = bx_roll;
float by = by_roll;
glBegin(GL_TRIANGLE_STRIP);
glColor3f(.1f,1,1);
glTexCoord2f(-bx + 1,-by + 1); glVertex3f(14, 14, -2);
glTexCoord2f(-bx + 0,-by + 1); glVertex3f(-14, 14, -2);
glColor3f(0,0.4f,0.7f);
glTexCoord2f(-bx + 1,-by + 0); glVertex3f(14, -14, -2);
glTexCoord2f(-bx + 0,-by + 0); glVertex3f(-14, -14, -2);
glEnd();
float rot = -5.0f;
glEnable(GL_BLEND);
for(int f=0; f<5; f++) {
glRotatef(rot * SIN(back_anim), 0,0,1);
glBegin(GL_TRIANGLE_STRIP);
glColor4f(0.1f,1,1,.25f);
glTexCoord2f(-bx + 1,-by + 1); glVertex3f(14, 14, -2);
glTexCoord2f(-bx + 0,-by + 1); glVertex3f(-14, 14, -2);
glColor4f(0,0.4f,0.7f,.25f);
glTexCoord2f(-bx + 1,-by + 0); glVertex3f(14, -14, -2);
glTexCoord2f(-bx + 0,-by + 0); glVertex3f(-14, -14, -2);
glEnd();
rot += (1.0f * COS(back_anim));
}
glDepthMask(GL_TRUE);
// Begin font drawing
begin_fonts();
glLoadIdentity();
// Draw the logo
glEnable(GL_BLEND);
BIND_TEXTURE(logo_tex);
glPushMatrix();
glTranslatef(0,4.5f,-13);
glRotatef(20.0f * COS(back_anim), 1,0,0);
glColor3f(1,1,1);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,1); glVertex3f( 4, .5f, 0);
glTexCoord2f(0,1); glVertex3f(-4, .5f, 0);
glTexCoord2f(1,0); glVertex3f( 4,-.5f, 0);
glTexCoord2f(0,0); glVertex3f(-4,-.5f, 0);
glEnd();
glPopMatrix();
// Draw the hiscores/credits
if(menu_id == MENU_ID_MAIN || menu_id == MENU_ID_START) {
if(mid_state == 1)
hiscore_1.draw(-1, mid_fade_amount);
else if(mid_state == 2)
hiscore_2.draw(-1, mid_fade_amount);
else if(mid_state == 3)
draw_credits(mid_fade_amount);
}
// Draw the version number
set_font_scale(0.3f, 0.3f);
glColor4f(1,1,1,0.3f);
glprintf(font1, 0, -7.0f, -5.3f, -13, VERSION);
set_font_scale(1,1);
// Draw the hilighted hiscore list if we're typing a name
if(place != -1 && list != NULL)
list->draw(place, 1.0f);
// Draw the menuitem background stripe
BIND_TEXTURE(0);
glColor4f(0,0,0,0.1f);
glPushMatrix();
glTranslatef(0,-4.0f, -13);
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(10,.57f,0);
glVertex3f(-10,.57f,0);
glVertex3f(10,-.57f,0);
glVertex3f(-10,-.57f,0);
glEnd();
glPopMatrix();
// Draw the menuitems
if(menu_id == MENU_ID_MAIN) {
// START
if(menu_item == MENU_START)
glColor3fv(col_selected);
else
glColor3fv(col_normal);
BIND_TEXTURE(button_tex);
glPushMatrix();
glTranslatef(-4.0f, -4.0f, -13);
glRotatef(20.0f * SIN(back_anim), 1,0,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,1); glVertex3f( 2, .5f, 0);
glTexCoord2f(0,1); glVertex3f(-2, .5f, 0);
glTexCoord2f(1,.75f); glVertex3f( 2,-.5f, 0);
glTexCoord2f(0,.75f); glVertex3f(-2,-.5f, 0);
glEnd();
glPopMatrix();
// OPTIONS
if(menu_item == MENU_OPTIONS)
glColor3fv(col_selected);
else
glColor3fv(col_normal);
glPushMatrix();
glTranslatef(0, -4.0f, -13);
glRotatef(20.0f * SIN(back_anim), 1,0,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,.75f); glVertex3f( 2, .5f, 0);
glTexCoord2f(0,.75f); glVertex3f(-2, .5f, 0);
glTexCoord2f(1,.5f); glVertex3f( 2,-.5f, 0);
glTexCoord2f(0,.5f); glVertex3f(-2,-.5f, 0);
glEnd();
glPopMatrix();
// EXIT
if(menu_item == MENU_EXIT)
glColor3fv(col_selected);
else
glColor3fv(col_normal);
glPushMatrix();
glTranslatef(4.0f, -4.0f, -13);
glRotatef(20.0f * SIN(back_anim), 1,0,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,.5f); glVertex3f( 2, .5f, 0);
glTexCoord2f(0,.5f); glVertex3f(-2, .5f, 0);
glTexCoord2f(1,.25f); glVertex3f( 2,-.5f, 0);
glTexCoord2f(0,.25f); glVertex3f(-2,-.5f, 0);
glEnd();
glPopMatrix();
}
else if(menu_id == MENU_ID_START) {
// SINGLE PLAYER
if(menu_item == MENU_SINGLEPLAY)
glColor3fv(col_selected);
else
glColor3fv(col_normal);
BIND_TEXTURE(button_tex2);
glPushMatrix();
glTranslatef(-2.0f, -4.0f, -13);
glRotatef(20.0f * SIN(back_anim), 1,0,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,1); glVertex3f( 2, .85f, 0);
glTexCoord2f(0,1); glVertex3f(-2, .85f, 0);
glTexCoord2f(1,.5f); glVertex3f( 2,-.85f, 0);
glTexCoord2f(0,.5f); glVertex3f(-2,-.85f, 0);
glEnd();
glPopMatrix();
// TWO PLAYERS
if(menu_item == MENU_MULTIPLAY)
glColor3fv(col_selected);
else
glColor3fv(col_normal);
glPushMatrix();
glTranslatef(2.0f, -4.0f, -13);
glRotatef(20.0f * SIN(back_anim), 1,0,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1,.5f); glVertex3f( 2, .85f, 0);
glTexCoord2f(0,.5f); glVertex3f(-2, .85f, 0);
glTexCoord2f(1,0); glVertex3f( 2,-.85f, 0);
glTexCoord2f(0,0); glVertex3f(-2,-.85f, 0);
glEnd();
glPopMatrix();
}
else if(menu_id == MENU_ID_OPTIONS) {
int who = whose_keys;
// Settings for ...
set_font_scale(0.6f, 0.5f);
if(menu_item == MENU_WHOSEKEYS)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
glprintf(font1, 0, -5.0f, 3.0f, -13, "Settings for: %s", (whose_keys == 0) ? "PLAYER ONE" : "PLAYER TWO");
// Moving style
if(menu_item == MENU_MOVSTYLE)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
glprintf(font1, 0, -5.0f, 2.5f, -13, "Moving style: %s", (config.moving_style[who] == 1) ? "RELATIVE" : "ABSOLUTE");
// Key up
if(menu_item == MENU_KEYUP)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
if(config.moving_style[who] == 1)
glprintf(font1, 0, -5.0f, 2.0f, -13, "Move forward: %s", key_name(config.key_up[who]));
else
glprintf(font1, 0, -5.0f, 2.0f, -13, "Move up: %s", key_name(config.key_up[who]));
// Key down
if(menu_item == MENU_KEYDOWN)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
if(config.moving_style[who] == 1)
glprintf(font1, 0, -5.0f, 1.5f, -13, "Turn around: %s", key_name(config.key_down[who]));
else
glprintf(font1, 0, -5.0f, 1.5f, -13, "Move down: %s", key_name(config.key_down[who]));
// Key left
if(menu_item == MENU_KEYLEFT)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
if(config.moving_style[who] == 1)
glprintf(font1, 0, -5.0f, 1.0f, -13, "Turn left: %s", key_name(config.key_left[who]));
else
glprintf(font1, 0, -5.0f, 1.0f, -13, "Move left: %s", key_name(config.key_left[who]));
// Key right
if(menu_item == MENU_KEYRIGHT)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
if(config.moving_style[who] == 1)
glprintf(font1, 0, -5.0f, 0.5f, -13, "Turn right: %s", key_name(config.key_right[who]));
else
glprintf(font1, 0, -5.0f, 0.5f, -13, "Move right: %s", key_name(config.key_right[who]));
// Key bomb
if(menu_item == MENU_KEYBOMB)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
glprintf(font1, 0, -5.0f, 0.0f, -13, "Throw a bomb: %s", key_name(config.key_shoot[who]));
// Key special
if(menu_item == MENU_KEYSPECIAL)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
glprintf(font1, 0, -5.0f, -0.5f, -13, "Use a special: %s", key_name(config.key_special[who]));
// Sound volume slider
if(menu_item == MENU_SOUNDVOL)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
glprintf(font1, 0, -5.0f, -1.5f, -13, "Sound volume:");
glPushMatrix();
glTranslatef(2.0f, -1.5f, -13);
glColor3f(0,0,0.5f);
BIND_TEXTURE(0);
glBegin(GL_TRIANGLE_STRIP);
glColor3f(0,0,0);
glVertex2f(3, 0.55f);
glVertex2f(0, 0.55f);
glColor3f(0,0,0.5f);
glVertex2f(3, 0.0f);
glVertex2f(0, 0.0f);
glEnd();
glColor3f(0.5f,0.5f,1);
float vol = (float)config.sound_vol / 255.0f;
glBegin(GL_TRIANGLE_STRIP);
glColor3f(0.5f,0.5f,1);
glVertex2f(2.95f * vol, 0.50f);
glVertex2f(0.05f, 0.50f);
glColor3f(0.25f,0.25f,0.5f);
glVertex2f(2.95f * vol, 0.05f);
glVertex2f(0.05f, 0.05f);
glEnd();
glPopMatrix();
// Music volume slider
if(menu_item == MENU_MUSICVOL)
glColor3fv(col_selected2);
else
glColor3fv(col_normal2);
glprintf(font1, 0, -5.0f, -2.0f, -13, "Music volume:");
glPushMatrix();
glTranslatef(2.0f, -2.0f, -13);
BIND_TEXTURE(0);
glBegin(GL_TRIANGLE_STRIP);
glColor3f(0,0,0);
glVertex2f(3, 0.55f);
glVertex2f(0, 0.55f);
glColor3f(0,0,0.5f);
glVertex2f(3, 0.0f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -