mirror of
https://github.com/id-Software/Wolf3D-iOS.git
synced 2026-03-19 16:39:49 +01:00
Source release of Wolfenstein 3D Classic Platinum for iOS, 1.2
This commit is contained in:
478
wolf3d/code/iphone/iphone_mapselector.c
Normal file
478
wolf3d/code/iphone/iphone_mapselector.c
Normal file
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
Reference in New Issue
Block a user