2012-01-31 22:57:34 +00:00
|
|
|
/*
|
2012-01-31 23:08:50 +00:00
|
|
|
|
|
|
|
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
|
|
|
|
This file is part of the WOLF3D iOS v2.1 GPL Source Code.
|
|
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
2012-01-31 22:57:34 +00:00
|
|
|
*/
|
2012-01-31 23:08:50 +00:00
|
|
|
|
|
|
|
|
2012-01-31 22:57:34 +00:00
|
|
|
#include "../wolfiphone.h"
|
|
|
|
#include <dirent.h>
|
|
|
|
|
|
|
|
const char levelNames[][29] = {
|
|
|
|
"E1 level 1",
|
|
|
|
"E1 level 2",
|
|
|
|
"E1 level 3",
|
|
|
|
"E1 level 4",
|
|
|
|
"E1 level 5",
|
|
|
|
"E1 level 6",
|
|
|
|
"E1 level 7",
|
|
|
|
"E1 level 8",
|
|
|
|
"E1 Boss ",
|
|
|
|
"E1 Secret ",
|
|
|
|
"E2 level 1",
|
|
|
|
"E2 level 2",
|
|
|
|
"E2 level 3",
|
|
|
|
"E2 level 4",
|
|
|
|
"E2 level 5",
|
|
|
|
"E2 level 6",
|
|
|
|
"E2 level 7",
|
|
|
|
"E2 level 8",
|
|
|
|
"E2 Boss ",
|
|
|
|
"E2 Secret ",
|
|
|
|
"E3 level 1",
|
|
|
|
"E3 level 2",
|
|
|
|
"E3 level 3",
|
|
|
|
"E3 level 4",
|
|
|
|
"E3 level 5",
|
|
|
|
"E3 level 6",
|
|
|
|
"E3 level 7",
|
|
|
|
"E3 level 8",
|
|
|
|
"E3 Boss ",
|
|
|
|
"E3 Secret ",
|
|
|
|
"E4 level 1",
|
|
|
|
"E4 level 2",
|
|
|
|
"E4 level 3",
|
|
|
|
"E4 level 4",
|
|
|
|
"E4 level 5",
|
|
|
|
"E4 level 6",
|
|
|
|
"E4 level 7",
|
|
|
|
"E4 level 8",
|
|
|
|
"E4 Boss ",
|
|
|
|
"E4 Secret ",
|
|
|
|
"E5 level 1",
|
|
|
|
"E5 level 2",
|
|
|
|
"E5 level 3",
|
|
|
|
"E5 level 4",
|
|
|
|
"E5 level 5",
|
|
|
|
"E5 level 6",
|
|
|
|
"E5 level 7",
|
|
|
|
"E5 level 8",
|
|
|
|
"E5 Boss ",
|
|
|
|
"E5 Secret ",
|
|
|
|
"E5 level 1",
|
|
|
|
"E6 level 2",
|
|
|
|
"E6 level 3",
|
|
|
|
"E6 level 4",
|
|
|
|
"E6 level 5",
|
|
|
|
"E6 level 6",
|
|
|
|
"E6 level 7",
|
|
|
|
"E6 level 8",
|
|
|
|
"E6 Boss ",
|
|
|
|
"E6 Secret ",
|
|
|
|
"Floor 1: Tunnels 1 ",
|
|
|
|
"Floor 2: Tunnels 2 ",
|
|
|
|
"Floor 3: Tunnels 3 ",
|
|
|
|
"Floor 4: Tunnels 4 ",
|
|
|
|
"Floor 5: Tunnels Boss ",
|
|
|
|
"Floor 6: Dungeons 1 ",
|
|
|
|
"Floor 7: Dungeons 2 ",
|
|
|
|
"Floor 8: Dungeons 3 ",
|
|
|
|
"Floor 9: Dungeons 4 ",
|
|
|
|
"Floor 10: Dungeons Boss ",
|
|
|
|
"Floor 11: Castle 1 ",
|
|
|
|
"Floor 12: Castle 2 ",
|
|
|
|
"Floor 13: Castle 3 ",
|
|
|
|
"Floor 14: Castle 4 ",
|
|
|
|
"Floor 15: Castle 5 ",
|
|
|
|
"Floor 16: Castle Boss ",
|
|
|
|
"Floor 17: Ramparts ",
|
|
|
|
"Floor 18: Death Knight ",
|
|
|
|
"Floor 19: Secret 1 ",
|
|
|
|
"Floor 20: Secret 2 ",
|
|
|
|
"Floor 21: Angel of Death",
|
|
|
|
};
|
|
|
|
|
|
|
|
int dragVelocity = 0; //velocity for the scrolling maps
|
|
|
|
int dragPosition = 32; //position for the scrolling maps
|
|
|
|
|
|
|
|
extern int BackButton();
|
|
|
|
#ifdef SPEARSTOREKIT
|
|
|
|
extern void GetSpearOfDestiny( int x, int y );
|
|
|
|
#endif
|
|
|
|
extern int iphoneDrawPicWithTouchAndColor( int x, int y, int w, int h, const char *pic, colour4_t color );
|
|
|
|
extern void iphoneStartUserMap( int episodeNum, int mapNum, int skillLevel, char *mapName );
|
|
|
|
|
|
|
|
|
|
|
|
extern void GetMoreLevels( int x, int y );
|
|
|
|
|
|
|
|
//==========================================
|
|
|
|
// iphoneUpdateDrags()
|
|
|
|
// Updates the touches for the scrolling maps
|
|
|
|
//==========================================
|
|
|
|
void iphoneUpdateDrags(int numMaps, int skillSides, int height, int spacing, int numUserMaps)
|
|
|
|
{
|
|
|
|
//Update drag/touch info
|
|
|
|
int x = 64;
|
|
|
|
int w = 480 - skillSides - 64;
|
|
|
|
int y = 0;
|
|
|
|
int h = 320;
|
|
|
|
|
|
|
|
if (TouchDown(x, y, w, h))
|
|
|
|
{
|
|
|
|
if (!numPrevTouches)
|
|
|
|
prevTouches[0][1] = touches[0][1];
|
|
|
|
else if (numTouches == 1)
|
|
|
|
dragVelocity = prevTouches[0][1] - touches[0][1];
|
|
|
|
}
|
|
|
|
|
|
|
|
//boundary check the drags
|
|
|
|
int num = numMaps+1+6;
|
2012-01-31 23:08:50 +00:00
|
|
|
if (g_version->value == SPEAROFDESTINY)
|
2012-01-31 22:57:34 +00:00
|
|
|
num = numMaps + 7;
|
|
|
|
|
|
|
|
num += numUserMaps + 1;
|
|
|
|
|
|
|
|
if (dragPosition < 320 - (height+spacing)*(num) - 20)
|
2012-01-31 23:08:50 +00:00
|
|
|
dragPosition = 320 - (height+spacing)*(num) - 20;
|
2012-01-31 22:57:34 +00:00
|
|
|
else if (dragPosition > 40)
|
|
|
|
dragPosition = 40;
|
|
|
|
|
|
|
|
if (dragPosition < 320 - (height+spacing)*(num))
|
|
|
|
dragVelocity = -1;
|
|
|
|
else if (dragPosition > 32)
|
|
|
|
dragVelocity = 1;
|
|
|
|
|
|
|
|
//update the drags
|
|
|
|
dragPosition -= dragVelocity;
|
|
|
|
|
2012-01-31 23:08:50 +00:00
|
|
|
dragVelocity /= screenScale;
|
|
|
|
|
2012-01-31 22:57:34 +00:00
|
|
|
//retard the velocity
|
|
|
|
if (dragVelocity > 0)
|
|
|
|
--dragVelocity;
|
|
|
|
else if (dragVelocity < 0)
|
|
|
|
++dragVelocity;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================
|
|
|
|
// iphoneDrawRewards()
|
|
|
|
// Draws the rewards on each level
|
|
|
|
//==========================================
|
|
|
|
int forceDrawRewards = 0;
|
|
|
|
void iphoneDrawRewards(int m, int s, int x, int y)
|
|
|
|
{
|
|
|
|
int ch = currentMap.mapFlags[s][m];
|
|
|
|
// bit1 = attempted
|
|
|
|
// bit2 = completed
|
|
|
|
// bit3 = 100% kills
|
|
|
|
// bit4 = 100% secrets
|
|
|
|
// bit5 = 100% treasure
|
|
|
|
|
|
|
|
//ch = 4+8+16+32; //used for testing proper placement
|
|
|
|
|
|
|
|
x += 80;
|
|
|
|
int startX = x;
|
|
|
|
|
|
|
|
//x += 66;//375;
|
|
|
|
y -= 27;//10;
|
|
|
|
|
|
|
|
int width = 40;//22;
|
|
|
|
int height = 40;//22;
|
|
|
|
int spacing = -12;
|
|
|
|
// draw award shadows
|
2012-01-31 23:08:50 +00:00
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/kills_shadow.tga" ); x += width + spacing;
|
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/secrets_shadow.tga" ); x += width + spacing;
|
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/treasure_shadow.tga" ); x += width + spacing;
|
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/partime_shadow.tga" ); //x += width + 5;
|
2012-01-31 22:57:34 +00:00
|
|
|
|
|
|
|
x = startX;
|
|
|
|
|
|
|
|
// draw awards
|
|
|
|
if ( (ch & MF_KILLS) || forceDrawRewards) {
|
2012-01-31 23:08:50 +00:00
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/kills.tga" );
|
2012-01-31 22:57:34 +00:00
|
|
|
}
|
|
|
|
x += width + spacing;
|
|
|
|
if ( (ch & MF_SECRETS) || forceDrawRewards) {
|
2012-01-31 23:08:50 +00:00
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/secrets.tga" );
|
2012-01-31 22:57:34 +00:00
|
|
|
}
|
|
|
|
x += width + spacing;
|
|
|
|
if ( (ch & MF_TREASURE) || forceDrawRewards) {
|
2012-01-31 23:08:50 +00:00
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/treasure.tga" );
|
2012-01-31 22:57:34 +00:00
|
|
|
}
|
|
|
|
x += width + spacing;
|
|
|
|
if ( (ch & MF_TIME) || forceDrawRewards) {
|
2012-01-31 23:08:50 +00:00
|
|
|
iphoneDrawPicRect( MakeScaledRectFloat( x,y+23, width, height ), "iphone/partime.tga" );
|
2012-01-31 22:57:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================
|
|
|
|
// iphoneDrawUserMaps()
|
|
|
|
// This function scans through the custom maps
|
|
|
|
// and displays the ones on screen
|
|
|
|
//==========================================
|
|
|
|
int iphoneDrawUserMaps(int Yoffset, int height, int spacing, int skillValue)
|
|
|
|
{
|
|
|
|
int numMaps = 0;
|
|
|
|
|
|
|
|
DIR *dp;
|
|
|
|
struct dirent *ep;
|
|
|
|
char mapBuffer[1024];
|
|
|
|
|
|
|
|
int length = strlen(iphoneDocDirectory);
|
|
|
|
strcpy(mapBuffer, iphoneDocDirectory);
|
|
|
|
strcpy(mapBuffer + length, "/usermaps/");
|
|
|
|
|
|
|
|
dp = opendir (mapBuffer);
|
|
|
|
|
|
|
|
if (dp != NULL)
|
|
|
|
{
|
|
|
|
int y = Yoffset;
|
|
|
|
if (g_version->value != SPEAROFDESTINY) //make space for the purchase SOD button
|
|
|
|
y += height + spacing + spacing;
|
|
|
|
|
|
|
|
//draw the custom map spacing
|
|
|
|
y += height + spacing;
|
|
|
|
iphoneDrawPic( 0, y, 480-80, height, "iphone/button_epSOD.tga");
|
|
|
|
|
|
|
|
|
2012-01-31 23:08:50 +00:00
|
|
|
while ( ( ep = readdir (dp) ) )
|
2012-01-31 22:57:34 +00:00
|
|
|
{
|
|
|
|
++numMaps;
|
|
|
|
if (numMaps < 3) //skip the '.' and '..'
|
|
|
|
continue;
|
|
|
|
|
|
|
|
y += height + spacing;
|
|
|
|
Com_Printf("value y: %i\n", y);
|
|
|
|
|
|
|
|
//TODO: draw the names!
|
|
|
|
if ( y >= -height && y < 320 )
|
|
|
|
{
|
|
|
|
|
|
|
|
//draw maps and touch
|
|
|
|
int alpha = 128;
|
|
|
|
//colour4_t colorSecret = { 80, 0, 0, alpha };
|
|
|
|
colour4_t colorNoTry = { 0, 0, 0, alpha };
|
|
|
|
|
|
|
|
if ( iphoneDrawPicWithTouchAndColor( 0, y, 480-80, height, "iphone/menu_bar.tga", colorNoTry) && dragVelocity == 0 )//&& isSecretAvailable )
|
|
|
|
{
|
|
|
|
//reset the player to new
|
|
|
|
PL_NewGame( &Player );
|
|
|
|
|
|
|
|
//set episode and map numbers and load map
|
|
|
|
int e = 9; //9 will be used to show a custom map
|
|
|
|
Cvar_SetValue( episode->name, e );
|
|
|
|
iphonePreloadBeforePlay(); //This prevents crashes when loading SOD maps
|
|
|
|
iphoneStartUserMap( e, numMaps - 3, skillValue, ep->d_name );
|
|
|
|
}
|
|
|
|
|
|
|
|
iphoneDrawText( 100, y + 16, 16, 16, ep->d_name );
|
|
|
|
//iphoneCenterText( 160, y + 16, ep->d_name );
|
|
|
|
|
|
|
|
//draw the rewards
|
|
|
|
iphoneDrawRewards(numMaps-2+90, skillValue, 0, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir (dp);
|
|
|
|
|
|
|
|
--numMaps;
|
|
|
|
--numMaps;
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("numMaps: %i\n", numMaps);
|
|
|
|
|
|
|
|
return numMaps;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================
|
|
|
|
// iphoneSelectMapMenu()
|
|
|
|
// A doom classic style map selector
|
|
|
|
//==========================================
|
|
|
|
void iphoneSelectMapMenu()
|
|
|
|
{
|
|
|
|
int s; //skill
|
|
|
|
char str[64];
|
|
|
|
|
|
|
|
// highlight the current skill selection
|
|
|
|
int skillValue = (int)skill->value;
|
|
|
|
if (skillValue < 0)
|
|
|
|
skillValue = 0;
|
|
|
|
if (skillValue > 3)
|
|
|
|
skillValue = 3;
|
|
|
|
|
|
|
|
int skillSides = 80;
|
|
|
|
|
|
|
|
int e = 0; //episode
|
|
|
|
|
|
|
|
int m, map; //mission/map
|
|
|
|
int height = 48;
|
|
|
|
int spacing = 10;
|
|
|
|
int y = 0;
|
|
|
|
|
|
|
|
char strMission[80];
|
|
|
|
strMission[79] = '\0';
|
|
|
|
|
|
|
|
int numMaps = 60;
|
|
|
|
if (g_version->value == SPEAROFDESTINY)
|
|
|
|
numMaps = 60 + 21;
|
|
|
|
|
|
|
|
iphoneDrawPic(0, 0, 480, 320, "iphone/submenus_background_image.tga");
|
|
|
|
|
|
|
|
//check for BackButton touches
|
|
|
|
if ( BackButton() ) {
|
|
|
|
menuState = IPM_MAIN;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//we want to use the menu selector bar
|
|
|
|
my_snprintf( str, sizeof( str ), "iphone/menu_bar.tga" );
|
|
|
|
|
|
|
|
//iterate through the maps... drawing only the visible maps
|
|
|
|
for (m = 0; m < numMaps; m++)
|
|
|
|
{
|
|
|
|
|
|
|
|
//Draws the spacing between each episode
|
|
|
|
e = m/10;
|
|
|
|
if (e < 6)
|
|
|
|
{
|
|
|
|
y = dragPosition + ((height + spacing) * e*11);// + ((height + spacing) * (e+1));
|
|
|
|
if ( y >= -height && y < 320 )
|
|
|
|
{
|
|
|
|
my_snprintf( str, sizeof( str ), "iphone/button_ep%i.tga", e+1 );
|
|
|
|
iphoneDrawPic( 0, y, 480-80, height, str);
|
|
|
|
}
|
|
|
|
|
|
|
|
y = dragPosition + ((height + spacing) * m) + ((height + spacing) * (e+1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
y = dragPosition + ((height + spacing) * 6*11);
|
|
|
|
if ( y >= -height && y < 320 )
|
|
|
|
{
|
|
|
|
my_snprintf( str, sizeof( str ), "iphone/button_epSOD.tga");
|
|
|
|
iphoneDrawPic( 0, y, 480-80, height, str);
|
|
|
|
}
|
|
|
|
y = dragPosition + ((height + spacing) * m) + ((height + spacing) * 7);
|
|
|
|
}
|
|
|
|
|
|
|
|
//we want to use the menu selector bar
|
|
|
|
my_snprintf( str, sizeof( str ), "iphone/menu_bar.tga" );
|
|
|
|
|
|
|
|
//only draw the maps that are currently viewable
|
|
|
|
if ( y >= -height && y < 320 )
|
|
|
|
{
|
|
|
|
e = m/10;
|
|
|
|
map = m%10;
|
|
|
|
|
|
|
|
//color maps
|
|
|
|
int ch = currentMap.mapFlags[skillValue][m];
|
|
|
|
|
|
|
|
int alpha = 128;
|
|
|
|
colour4_t colorSecret = { 80, 0, 0, alpha };
|
|
|
|
colour4_t colorNoTry = { 0, 0, 0, alpha };
|
|
|
|
colour4_t colorTried = { 80, 80, 0, alpha };
|
|
|
|
colour4_t colorCompleted = { 0, 80, 0, alpha };
|
|
|
|
colour4_t colorBlink = { 80, 80, 80, alpha };
|
|
|
|
|
|
|
|
unsigned char *color = colorNoTry;
|
|
|
|
bool isSecretAvailable = true;
|
|
|
|
|
|
|
|
if ( map == 9 && !( ch & MF_TRIED ) && e < 6) //if it's the 9th and not SOD
|
|
|
|
{
|
|
|
|
color = colorSecret;
|
|
|
|
isSecretAvailable = false;
|
|
|
|
}
|
|
|
|
else if ( (m == 79 || m == 78) && !(ch & MF_TRIED) ) //if it's the secret SOD levels
|
|
|
|
{
|
|
|
|
color = colorSecret;
|
|
|
|
isSecretAvailable = false;
|
|
|
|
} else if ( ch & MF_COMPLETED ) {
|
|
|
|
color = colorCompleted;
|
|
|
|
} else if ( ch & MF_TRIED ) {
|
|
|
|
color = colorTried;
|
|
|
|
} else {
|
|
|
|
color = colorNoTry;
|
|
|
|
}
|
|
|
|
|
|
|
|
//blink the level you're currently on
|
|
|
|
if ( ( iphoneFrameNum & 8 ) && map == currentMap.map && e == currentMap.episode )
|
|
|
|
color = colorBlink;
|
|
|
|
|
|
|
|
//draw maps and touch
|
|
|
|
if ( iphoneDrawPicWithTouchAndColor( 0, y, 480-80, height, str, color) && dragVelocity == 0 && isSecretAvailable )
|
|
|
|
{
|
|
|
|
//reset the player to new
|
|
|
|
PL_NewGame( &Player );
|
|
|
|
|
|
|
|
//set episode and map numbers and load map
|
|
|
|
Cvar_SetValue( episode->name, e );
|
|
|
|
iphonePreloadBeforePlay(); //This prevents crashes when loading SOD maps
|
|
|
|
iphoneStartMap( e, map, skillValue );
|
|
|
|
}
|
|
|
|
|
|
|
|
//draw the rewards
|
|
|
|
iphoneDrawRewards(m, skillValue, 0, y);
|
|
|
|
|
|
|
|
//draw the episode and map over the selection bar
|
|
|
|
my_snprintf( strMission, sizeof( strMission ), "%s", levelNames[m] );
|
|
|
|
iphoneDrawText( 100, y + 16, 16, 16, strMission );
|
|
|
|
// iphoneCenterText( 160, y + 16, strMission );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int numUserMaps = 0;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
//buy more episodes button
|
|
|
|
if (g_version->value != SPEAROFDESTINY)
|
|
|
|
GetSpearOfDestiny( 0, dragPosition + (height + spacing) * (m+6) );
|
|
|
|
#endif
|
|
|
|
//TODO: Draw user maps
|
2012-01-31 23:08:50 +00:00
|
|
|
numUserMaps = iphoneDrawUserMaps(y, height, spacing, skillValue);
|
2012-01-31 22:57:34 +00:00
|
|
|
|
|
|
|
//Update the scrolling drags
|
|
|
|
iphoneUpdateDrags(numMaps, skillSides, height, spacing, numUserMaps);
|
|
|
|
|
|
|
|
|
|
|
|
//Draw/choose the skills on the right side of the screen
|
|
|
|
for ( s = 0 ; s < 4 ; s++ )
|
|
|
|
{
|
|
|
|
my_snprintf( str, sizeof( str ), "iphone/button_skill%i.tga", s+1 );
|
|
|
|
|
|
|
|
if ( s != (int)skill->value ) {
|
|
|
|
pfglColor3f( 0.5, 0.5, 0.5 );
|
|
|
|
}
|
|
|
|
if ( iphoneDrawPicWithTouch( 480 - skillSides, skillSides*s, skillSides, skillSides, str ) ) {
|
|
|
|
Cvar_SetValue( skill->name, s );
|
|
|
|
skillValue = s;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pfglColor3f( 1, 1, 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Draw a bar that covers empty space
|
|
|
|
iphoneDrawPic(0, 0, 480-80, 32, "iphone/menu_bar.tga");
|
|
|
|
|
|
|
|
//levels header
|
|
|
|
iphoneDrawPic(240-64, 0, 128, 32, "iphone/header_levels.tga");
|
|
|
|
|
|
|
|
BackButton(); //this is kinda cheap...
|
|
|
|
//we want the back button to render on top
|
|
|
|
//but we also want it to check for touches before the maps
|
|
|
|
//so we call this function twice
|
|
|
|
//(at the beginning for touches; the end for rendering)
|
|
|
|
}
|