Files
Wolf3D-iOS/wolf3d/code/iphone/iphone_mapselector.c

479 lines
12 KiB
C

/*
* iphone_mapselector.c
* wolf3d
*
* Created by Greg Hodges on 7/2/09.
* Copyright 2009 id software. All rights reserved.
*
*/
#include "../wolfiphone.h"
#include <dirent.h>
const char levelNames[][29] = {
"E1 level 1",
"E1 level 2",
"E1 level 3",
#ifndef LITE
"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",
#endif
};
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 );
#ifdef LITE
extern void GetMoreLevels( int x, int y );
#endif
//==========================================
// 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;
if (g_version-> value == SPEAROFDESTINY)
num = numMaps + 7;
num += numUserMaps + 1;
if (dragPosition < 320 - (height+spacing)*(num) - 20)
dragPosition < 320 - (height+spacing)*(num) - 20;
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;
//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
iphoneDrawPic( x,y+23, width, height, "iphone/kills_shadow.tga" ); x += width + spacing;
iphoneDrawPic( x,y+23, width, height, "iphone/secrets_shadow.tga" ); x += width + spacing;
iphoneDrawPic( x,y+23, width, height, "iphone/treasure_shadow.tga" ); x += width + spacing;
iphoneDrawPic( x,y+23, width, height, "iphone/partime_shadow.tga" ); //x += width + 5;
x = startX;
// draw awards
if ( (ch & MF_KILLS) || forceDrawRewards) {
iphoneDrawPic( x,y+23, width, height, "iphone/kills.tga" );
}
x += width + spacing;
if ( (ch & MF_SECRETS) || forceDrawRewards) {
iphoneDrawPic( x,y+23, width, height, "iphone/secrets.tga" );
}
x += width + spacing;
if ( (ch & MF_TREASURE) || forceDrawRewards) {
iphoneDrawPic( x,y+23, width, height, "iphone/treasure.tga" );
}
x += width + spacing;
if ( (ch & MF_TIME) || forceDrawRewards) {
iphoneDrawPic( x,y+23, width, height, "iphone/partime.tga" );
}
}
//==========================================
// 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");
while (ep = readdir (dp))
{
++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';
#ifdef LITE
int numMaps = 3;//5;
#else
int numMaps = 60;
if (g_version->value == SPEAROFDESTINY)
numMaps = 60 + 21;
#endif
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;
#ifdef LITE
//buy more episodes button
GetMoreLevels( 0, dragPosition + (height + spacing) * (m+1) );
#else
#if 0
//buy more episodes button
if (g_version->value != SPEAROFDESTINY)
GetSpearOfDestiny( 0, dragPosition + (height + spacing) * (m+6) );
#endif
//TODO: Draw user maps
numUserMaps = iphoneDrawUserMaps(y, height, spacing, skillValue);
#endif
//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)
}