7848 lines
186 KiB
C++
7848 lines
186 KiB
C++
//
|
||
// frontend.cpp
|
||
//
|
||
// matthew rosenfeld 8 july 99
|
||
//
|
||
// this is our new front end thingy to replace the hideous startscr.cpp
|
||
//
|
||
|
||
|
||
//#define BIN_STUFF_PLEASE_BOB I have been defined
|
||
//#define FORCE_STUFF_PLEASE_BOB I have been defined
|
||
#ifdef DEBUG
|
||
//#define BIN_BACKGROUNDS_PLEASE_BOB I have been defined
|
||
#else
|
||
//#define BIN_BACKGROUNDS_PLEASE_BOB I have been defined
|
||
#endif
|
||
|
||
#ifndef TARGET_DC
|
||
// On a PC, you need an exit. On a console, you don't.
|
||
#define WANT_AN_EXIT_MENU_ITEM defined
|
||
// Keyboard not currently supported on DC - might be in future.
|
||
#define WANT_A_KEYBOARD_ITEM define
|
||
// On DC, the "Start" button is not allowed to be remapped.
|
||
#define WANT_A_START_JOYSTICK_ITEM defined
|
||
|
||
#else
|
||
|
||
// On the DC, we need a title & language selection screen.
|
||
#define WANT_A_TITLE_SCREEN defined
|
||
|
||
#endif
|
||
|
||
#ifndef PSX
|
||
|
||
#include "demo.h"
|
||
#include "DDLib.h"
|
||
#include "frontend.h"
|
||
#include "xlat_str.h"
|
||
#include "menufont.h"
|
||
#include "font2d.h"
|
||
#include "env.h"
|
||
#include "drive.h"
|
||
#include "snd_type.h"
|
||
#include "sound.h"
|
||
#include "MFX.h"
|
||
#include "MFX_Miles.h"
|
||
#include "music.h"
|
||
#include "poly.h"
|
||
#include "drawxtra.h"
|
||
#include "fmatrix.h"
|
||
#include "C:\fallen\DDLibrary\headers\D3DTexture.h"
|
||
#include "C:\fallen\DDLibrary\headers\GDisplay.h"
|
||
#include "C:\fallen\DDEngine\headers\polypage.h"
|
||
#include "io.h"
|
||
#include "truetype.h"
|
||
#include "c:\fallen\ddlibrary\headers\dclowlevel.h"
|
||
#include "panel.h"
|
||
|
||
#ifdef TARGET_DC
|
||
#include <platutil.h>
|
||
#include <ceddcdrm.h>
|
||
#include <segagdrm.h>
|
||
#endif
|
||
|
||
#include "interfac.h"
|
||
extern BOOL allow_debug_keys;
|
||
|
||
|
||
#ifndef TARGET_DC
|
||
UBYTE build_dc = TRUE; // Set to TRUE to save out all the dreamcast DAD files.
|
||
UBYTE build_dc_mission;
|
||
#endif
|
||
|
||
//----------------------------------------------------------------------------
|
||
// EXTERNS
|
||
//
|
||
|
||
extern SLONG FontPage;
|
||
extern UBYTE InkeyToAscii[];
|
||
extern UBYTE InkeyToAsciiShift[];
|
||
extern CBYTE STARTSCR_mission[_MAX_PATH];
|
||
extern DIJOYSTATE the_state;
|
||
|
||
extern void init_joypad_config(void);
|
||
|
||
void DreamCastCredits ( void );
|
||
void FRONTEND_display ( void );
|
||
|
||
//----------------------------------------------------------------------------
|
||
// DEFINES
|
||
//
|
||
|
||
#define ALLOW_JOYPAD_IN_FRONTEND
|
||
|
||
|
||
// font sizes, where 256 is "normal".
|
||
#define BIG_FONT_SCALE (192)
|
||
#define BIG_FONT_SCALE_FRENCH ( 176 );
|
||
|
||
#ifdef TARGET_DC
|
||
#define BIG_FONT_SCALE_SELECTED (256)
|
||
#endif
|
||
#define SMALL_FONT_SCALE (256)
|
||
// small font being larger DOES make sense because they're different bitmaps.
|
||
|
||
// In milliseconds.
|
||
#ifdef DEBUG
|
||
// For debugging the looper
|
||
#define AUTOPLAY_FMV_DELAY (1000 * 10)
|
||
#else
|
||
#define AUTOPLAY_FMV_DELAY (1000 * 60 * 2)
|
||
#endif
|
||
|
||
// #define ALLOW_DANGEROUS_OPTIONS
|
||
|
||
//#define MISSION_SCRIPT "data\\urban.sty"
|
||
// see below...
|
||
|
||
#if 0
|
||
#define STARTS_START 1
|
||
#define STARTS_EDITOR 2
|
||
#define STARTS_LOAD 3
|
||
#define STARTS_EXIT 4
|
||
#define STARTS_LANGUAGE_CHANGE 10
|
||
#else
|
||
#include "startscr.h"
|
||
#endif
|
||
|
||
// just know someone's gonna want me to take it back out again soooo.....
|
||
#ifndef VERSION_DEMO
|
||
// ^^^^ see, i was right
|
||
#define ANNOYING_HACK_FOR_SIMON 1
|
||
#endif
|
||
|
||
|
||
#define FE_MAINMENU ( 1)
|
||
#define FE_MAPSCREEN ( 2)
|
||
#define FE_MISSIONSELECT ( 3)
|
||
#define FE_MISSIONBRIEFING ( 4)
|
||
#define FE_LOADSCREEN ( 5)
|
||
#define FE_SAVESCREEN ( 6)
|
||
#define FE_CONFIG ( 7)
|
||
#define FE_CONFIG_VIDEO ( 8)
|
||
#define FE_CONFIG_AUDIO ( 9)
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
#define FE_CONFIG_INPUT_KB (10)
|
||
#endif
|
||
#define FE_CONFIG_INPUT_JP (11)
|
||
#define FE_CONFIG_OPTIONS (13)
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
#define FE_QUIT (12)
|
||
#endif
|
||
#define FE_SAVE_CONFIRM (14)
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
#define FE_TITLESCREEN (15)
|
||
#define FE_LANGUAGESCREEN (16)
|
||
#define FE_CHANGE_LANGUAGE (17)
|
||
#endif
|
||
#ifdef TARGET_DC
|
||
#define FE_VMU_SELECT (18)
|
||
#endif
|
||
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
#define FE_NO_REALLY_QUIT (-1)
|
||
#endif
|
||
#define FE_BACK (-2)
|
||
#define FE_START (-3)
|
||
#define FE_EDITOR (-4)
|
||
#define FE_CREDITS (-5)
|
||
#ifdef TARGET_DC
|
||
#define FE_CHANGE_JOYPAD (-6)
|
||
#endif
|
||
|
||
#define OT_BUTTON ( 1)
|
||
#define OT_BUTTON_L ( 2)
|
||
#define OT_SLIDER ( 3)
|
||
#define OT_MULTI ( 4)
|
||
#define OT_KEYPRESS ( 5)
|
||
#define OT_LABEL ( 6)
|
||
#define OT_PADPRESS ( 7)
|
||
#define OT_RESET ( 8)
|
||
#define OT_PADMOVE ( 9)
|
||
|
||
#define MC_YN (CBYTE*)( 1)
|
||
#define MC_SCANNER (CBYTE*)( 2)
|
||
#ifdef TARGET_DC
|
||
#define MC_JOYPAD_MODE (CBYTE*)( 3)
|
||
#define MC_ANALOGUE_MODE (CBYTE*)( 4)
|
||
#endif
|
||
|
||
//----------------------------------------------------------------------------
|
||
// STRUCTS
|
||
//
|
||
|
||
struct MissionData {
|
||
SLONG ObjID, GroupID, ParentID, ParentIsGroup;
|
||
SLONG District;
|
||
SLONG Type, Flags;
|
||
CBYTE fn[255], ttl[255], brief[4096];
|
||
};
|
||
|
||
struct RawMenuData {
|
||
UBYTE Menu;
|
||
UBYTE Type;
|
||
// CBYTE* Label;
|
||
SWORD Label;
|
||
CBYTE* Choices;
|
||
SLONG Data;
|
||
};
|
||
|
||
struct MenuData {
|
||
UBYTE Type;
|
||
UBYTE LabelID;
|
||
CBYTE* Label;
|
||
CBYTE* Choices;
|
||
SLONG Data;
|
||
UWORD X,Y;
|
||
};
|
||
|
||
struct MenuStack {
|
||
UBYTE mode;
|
||
UBYTE selected;
|
||
SWORD scroll;
|
||
CBYTE* title;
|
||
};
|
||
|
||
struct MenuState {
|
||
UBYTE items;
|
||
UBYTE selected;
|
||
SWORD scroll;
|
||
MenuStack stack[10];
|
||
UBYTE stackpos;
|
||
SBYTE mode;
|
||
SWORD base;
|
||
CBYTE* title;
|
||
};
|
||
|
||
struct Kibble {
|
||
SLONG page;
|
||
SLONG x, y;
|
||
SWORD dx,dy;
|
||
SWORD r, t, p, rd, td, pd;
|
||
UBYTE type, size;
|
||
ULONG rgb;
|
||
};
|
||
|
||
struct MissionCache {
|
||
CBYTE name[255];
|
||
UBYTE id;
|
||
UBYTE district;
|
||
};
|
||
|
||
|
||
|
||
//
|
||
// This is the order we recommend the missions be played in...
|
||
//
|
||
|
||
CBYTE *suggest_order[] =
|
||
{
|
||
"testdrive1a.ucm",
|
||
"FTutor1.ucm",
|
||
"Assault1.ucm",
|
||
"police1.ucm",
|
||
"police2.ucm",
|
||
"Bankbomb1.ucm",
|
||
"police3.ucm",
|
||
"Gangorder2.ucm",
|
||
"police4.ucm",
|
||
"bball2.ucm",
|
||
"wstores1.ucm",
|
||
"e3.ucm",
|
||
"westcrime1.ucm",
|
||
"carbomb1.ucm",
|
||
"botanicc.ucm",
|
||
"Semtex.ucm",
|
||
"AWOL1.ucm",
|
||
"mission2.ucm",
|
||
"park2.ucm",
|
||
"MIB.ucm",
|
||
"skymiss2.ucm",
|
||
"factory1.ucm",
|
||
"estate2.ucm",
|
||
"Stealtst1.ucm",
|
||
"snow2.ucm",
|
||
"Gordout1.ucm",
|
||
"Baalrog3.ucm",
|
||
"Finale1.ucm",
|
||
|
||
"Gangorder1.ucm",
|
||
"FreeCD1.ucm",
|
||
"jung3.ucm",
|
||
|
||
"fight1.ucm",
|
||
"fight2.ucm",
|
||
"testdrive2.ucm",
|
||
"testdrive3.ucm",
|
||
|
||
"Album1.ucm",
|
||
|
||
"!"
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
// The script... biggest one at the moment is 17k
|
||
//
|
||
|
||
#define SCRIPT_MEMORY (20 * 1024)
|
||
|
||
CBYTE loaded_in_script[SCRIPT_MEMORY];
|
||
CBYTE *loaded_in_script_read_upto;
|
||
|
||
void CacheScriptInMemory(CBYTE *script_fname)
|
||
{
|
||
//FILE *handle = MF_Fopen(script_fname, "rb");
|
||
// Er... it's a TEXT FILE
|
||
FILE *handle = MF_Fopen(script_fname, "rt");
|
||
|
||
ASSERT(handle);
|
||
|
||
if (handle)
|
||
{
|
||
int iLoaded = fread(loaded_in_script, 1, SCRIPT_MEMORY, handle);
|
||
ASSERT ( iLoaded < sizeof(loaded_in_script) );
|
||
// Stupid thing doesn't always terminate with a
|
||
// zero, and sometimes writes crap past the end.
|
||
loaded_in_script[iLoaded] = '\0';
|
||
|
||
MF_Fclose(handle);
|
||
}
|
||
}
|
||
|
||
void FileOpenScript(void)
|
||
{
|
||
loaded_in_script_read_upto = loaded_in_script;
|
||
}
|
||
|
||
CBYTE *LoadStringScript(CBYTE *txt) {
|
||
CBYTE *ptr=txt;
|
||
|
||
ASSERT(loaded_in_script_read_upto);
|
||
|
||
*ptr=0;
|
||
while (1) {
|
||
|
||
*ptr = *loaded_in_script_read_upto++;
|
||
|
||
if (*ptr == 0) {
|
||
return txt;
|
||
};
|
||
if (*ptr==10) break;
|
||
ptr++;
|
||
}
|
||
*(++ptr)=0;
|
||
return txt;
|
||
}
|
||
|
||
void FileCloseScript(void)
|
||
{
|
||
loaded_in_script_read_upto = NULL;
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------------
|
||
// CONSTANTS
|
||
//
|
||
|
||
|
||
|
||
|
||
RawMenuData raw_menu_data[] = {
|
||
{ FE_MAINMENU, OT_BUTTON, X_START, 0, FE_MAPSCREEN },
|
||
#ifndef VERSION_DEMO
|
||
{ 0, OT_BUTTON, X_LOAD_GAME, 0, FE_LOADSCREEN },
|
||
{ 0, OT_BUTTON, X_SAVE_GAME, (CBYTE*)1, FE_SAVESCREEN },
|
||
#endif
|
||
{ 0, OT_BUTTON, X_OPTIONS, 0, FE_CONFIG },
|
||
#if !defined(NDEBUG) && !defined(TARGET_DC)
|
||
// sheer MADNESS!
|
||
{ 0, OT_BUTTON, X_LOAD_UCM, 0, FE_START },
|
||
{ 0, OT_BUTTON, X_EDITOR, 0, FE_EDITOR },
|
||
#endif
|
||
#ifndef VERSION_DEMO
|
||
{ 0, OT_BUTTON, X_CREDITS, 0, FE_CREDITS },
|
||
#endif
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
{ 0, OT_BUTTON, X_EXIT, 0, FE_QUIT },
|
||
#endif
|
||
#ifdef TARGET_DC
|
||
{ FE_LOADSCREEN, OT_BUTTON, X_VMU_SELECT, 0, FE_VMU_SELECT },
|
||
{ 0, OT_BUTTON, X_CANCEL, 0, FE_BACK },
|
||
|
||
{ FE_SAVESCREEN, OT_BUTTON, X_VMU_SELECT, 0, FE_VMU_SELECT },
|
||
{ 0, OT_BUTTON, X_CANCEL, 0, FE_MAPSCREEN },
|
||
|
||
{ FE_VMU_SELECT, OT_BUTTON, X_CANCEL, 0, FE_BACK },
|
||
#else
|
||
{ FE_LOADSCREEN, OT_BUTTON, X_CANCEL, 0, FE_BACK },
|
||
{ FE_SAVESCREEN, OT_BUTTON, X_CANCEL, 0, FE_MAPSCREEN },
|
||
#endif
|
||
#ifdef TARGET_DC
|
||
{ FE_SAVE_CONFIRM, OT_LABEL, X_OVERWRITE_SURE,0, 0 },
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_MAPSCREEN },
|
||
{ 0, OT_BUTTON, X_CANCEL, 0, FE_BACK },
|
||
#else
|
||
{ FE_SAVE_CONFIRM, OT_LABEL, X_ARE_YOU_SURE ,0, 0 },
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_MAPSCREEN },
|
||
{ 0, OT_BUTTON, X_CANCEL, 0, FE_BACK },
|
||
#endif
|
||
|
||
#ifdef TARGET_DC
|
||
{ FE_CONFIG, OT_BUTTON, X_GENERAL, 0, FE_CONFIG_OPTIONS },
|
||
#else
|
||
{ FE_CONFIG, OT_BUTTON, X_OPTIONS, 0, FE_CONFIG_OPTIONS },
|
||
#endif
|
||
{ 0, OT_BUTTON, X_GRAPHICS, 0, FE_CONFIG_VIDEO },
|
||
{ 0, OT_BUTTON, X_SOUND, 0, FE_CONFIG_AUDIO },
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
{ 0, OT_BUTTON, X_KEYBOARD, 0, FE_CONFIG_INPUT_KB },
|
||
#endif
|
||
{ 0, OT_BUTTON, X_JOYPAD, 0, FE_CONFIG_INPUT_JP },
|
||
#ifdef TARGET_DC
|
||
{ 0, OT_BUTTON, X_CHANGE_JOYPAD,0, FE_CHANGE_JOYPAD },
|
||
#endif
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK },
|
||
{ FE_CONFIG_AUDIO, OT_SLIDER, X_VOLUME, 0, 128 },
|
||
{ 0, OT_SLIDER, X_AMBIENT, 0, 128 },
|
||
{ 0, OT_SLIDER, X_MUSIC, 0, 128 },
|
||
#ifdef TARGET_DC
|
||
{ 0, OT_MULTI, X_STEREO, MC_YN, 1 },
|
||
#endif
|
||
#ifdef M_SOUND
|
||
#ifdef ALLOW_DANGEROUS_OPTIONS
|
||
{ 0, OT_MULTI, X_DRIVERS, 0, 128 },
|
||
#endif
|
||
#endif
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK },
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
{FE_CONFIG_INPUT_KB, OT_KEYPRESS, X_LEFT, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_RIGHT, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_FORWARDS, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_BACKWARDS, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_PUNCH, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_KICK, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_ACTION, 0, 0, },
|
||
// { 0, OT_KEYPRESS, X_RUN, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_JUMP, 0, 0, },
|
||
#ifdef WANT_A_START_JOYSTICK_ITEM
|
||
{ 0, OT_KEYPRESS, X_START, 0, 0, },
|
||
#endif
|
||
{ 0, OT_KEYPRESS, X_SELECT, 0, 0, },
|
||
{ 0, OT_LABEL, X_CAMERA, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_JUMP, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_LEFT, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_RIGHT, 0, 0, },
|
||
{ 0, OT_KEYPRESS, X_LOOK_AROUND, 0, 0, },
|
||
{ 0, OT_RESET, X_RESET_DEFAULT,0, 0, },
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK, },
|
||
#endif
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
|
||
{FE_CONFIG_INPUT_JP, OT_MULTI, X_PAD_MODE, MC_JOYPAD_MODE, 0, },
|
||
{ 0, OT_LABEL, X_PAD_CUSTOM, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_PUNCH, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_KICK, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_JUMP, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_ACTION, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_PAD_WALK, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_SELECT, 0, 0, },
|
||
{ 0, OT_LABEL, X_CAMERA, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_PAD_MODE, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_LEFT, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_RIGHT, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_LOOK_AROUND, 0, 0, },
|
||
{ 0, OT_RESET, X_RESET_DEFAULT,0, 0, },
|
||
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK, },
|
||
|
||
#else //#ifdef TARGET_DC
|
||
|
||
{FE_CONFIG_INPUT_JP, OT_PADPRESS, X_KICK, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_PUNCH, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_JUMP, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_ACTION, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_RUN, 0, 0, },
|
||
#ifdef WANT_A_START_JOYSTICK_ITEM
|
||
{ 0, OT_PADPRESS, X_START, 0, 0, },
|
||
#endif
|
||
{ 0, OT_PADPRESS, X_SELECT, 0, 0, },
|
||
{ 0, OT_LABEL, X_CAMERA, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_JUMP_CAM, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_LEFT, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_RIGHT, 0, 0, },
|
||
{ 0, OT_PADPRESS, X_LOOK_AROUND, 0, 0, },
|
||
{ 0, OT_RESET, X_RESET_DEFAULT,0, 0, },
|
||
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK, },
|
||
|
||
#endif //#else //#ifdef TARGET_DC
|
||
|
||
|
||
// { FE_CONFIG_VIDEO, OT_SLIDER, X_DETAIL, 0, 128, },
|
||
#ifdef ALLOW_DANGEROUS_OPTIONS
|
||
{ FE_CONFIG_VIDEO, OT_LABEL, X_GRAPHICS, 0, 1, },
|
||
{ 0, OT_MULTI, X_RESOLUTION, 0, 1, },
|
||
{ 0, OT_MULTI, X_DRIVERS, 0, 1, },
|
||
{ 0, OT_MULTI, X_COLOUR_DEPTH, 0, 1, },
|
||
#endif
|
||
// { 0, OT_LABEL, X_DETAIL, 0, 1, },
|
||
#ifdef TARGET_DC
|
||
{ FE_CONFIG_VIDEO, OT_MULTI, X_SHADOWS, MC_YN, 1, },
|
||
// { 0, OT_MULTI, X_PUDDLES, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_DIRT, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_MIST, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_RAIN, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_SKYLINE, MC_YN, 1, },
|
||
// { 0, OT_MULTI, X_CRINKLES, MC_YN, 1, },
|
||
// { 0, OT_LABEL, X_REFLECTIONS ,0, 0 },
|
||
// { 0, OT_MULTI, X_MOON, MC_YN, 1, },
|
||
// { 0, OT_MULTI, X_PEOPLE, MC_YN, 1, },
|
||
// { 0, OT_LABEL, X_TEXTURE_MAP ,0, 0, },
|
||
// { 0, OT_MULTI, X_PERSPECTIVE,MC_YN,1, },
|
||
// { 0, OT_MULTI, X_BILINEAR, MC_YN, 1, },
|
||
// { 0, OT_SLIDER, "Gamma", 0, 128, },
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK, },
|
||
#else
|
||
{ FE_CONFIG_VIDEO, OT_MULTI, X_STARS, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_SHADOWS, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_PUDDLES, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_DIRT, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_MIST, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_RAIN, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_SKYLINE, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_CRINKLES, MC_YN, 1, },
|
||
{ 0, OT_LABEL, X_REFLECTIONS ,0, 0 },
|
||
{ 0, OT_MULTI, X_MOON, MC_YN, 1, },
|
||
{ 0, OT_MULTI, X_PEOPLE, MC_YN, 1, },
|
||
{ 0, OT_LABEL, X_TEXTURE_MAP ,0, 0, },
|
||
{ 0, OT_MULTI, X_PERSPECTIVE,MC_YN,1, },
|
||
{ 0, OT_MULTI, X_BILINEAR, MC_YN, 1, },
|
||
// { 0, OT_SLIDER, "Gamma", 0, 128, },
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK, },
|
||
#endif
|
||
#ifdef TARGET_DC
|
||
{ FE_CONFIG_OPTIONS, OT_MULTI, X_TRACK,MC_SCANNER, 0 },
|
||
{ 0, OT_MULTI, X_CONTROLS,MC_ANALOGUE_MODE, 0 },
|
||
{ 0, OT_MULTI, X_VIBRATION,MC_YN, 0 },
|
||
{ 0, OT_MULTI, X_VIBRATION_ENG,MC_YN, 0 },
|
||
{ 0, OT_PADMOVE, X_PANEL, 0, 0 },
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
{ 0, OT_BUTTON, X_LANGUAGE, 0, FE_LANGUAGESCREEN },
|
||
#endif
|
||
#else
|
||
{ FE_CONFIG_OPTIONS, OT_LABEL, X_SCANNER, 0, 0 },
|
||
{ 0, OT_MULTI, X_TRACK,MC_SCANNER, 0 },
|
||
#endif
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_BACK, },
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
{ FE_QUIT, OT_LABEL, X_ARE_YOU_SURE ,0, 0 },
|
||
{ 0, OT_BUTTON, X_OKAY, 0, FE_NO_REALLY_QUIT },
|
||
{ 0, OT_BUTTON, X_CANCEL, 0, FE_BACK },
|
||
#endif
|
||
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
{ FE_LANGUAGESCREEN, OT_BUTTON, X_ENGLISH, 0, FE_CHANGE_LANGUAGE },
|
||
{ 0, OT_BUTTON, X_FRENCH, 0, FE_CHANGE_LANGUAGE },
|
||
{ FE_TITLESCREEN, OT_BUTTON, X_GAME_NAME, 0, FE_MAINMENU },
|
||
#endif
|
||
|
||
{ -1, 0, 0, 0 },
|
||
};
|
||
|
||
CBYTE menu_choice_yesno[20];// = { "no\0yes" };
|
||
CBYTE menu_choice_scanner[255];
|
||
#ifdef TARGET_DC
|
||
CBYTE menu_choice_joypad_mode[50];
|
||
CBYTE menu_choice_analogue_mode[50];
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
CBYTE menu_choice_language[50];
|
||
#endif
|
||
#endif
|
||
|
||
#if TARGET_DC
|
||
// Underlines, not spaces.
|
||
CBYTE* menu_back_names[] = { "title_leaves1.tga", "title_rain1.tga",
|
||
"title_snow1.tga", "title_blood1.tga" };
|
||
CBYTE* menu_map_names[] = { "map_leaves_darci.tga", "map_rain_darci.tga",
|
||
"map_snow_darci.tga", "map_blood_darci.tga" };
|
||
CBYTE* menu_brief_names[]= { "briefing_leaves_darci.tga", "briefing_rain_darci.tga",
|
||
"briefing_snow_darci.tga", "briefing_blood_darci.tga" };
|
||
CBYTE* menu_config_names[]= { "config_leaves.tga", "config_rain.tga",
|
||
"config_snow.tga", "config_blood.tga" };
|
||
#else
|
||
CBYTE* menu_back_names[] = { "title leaves1.tga", "title rain1.tga",
|
||
"title snow1.tga", "title blood1.tga" };
|
||
CBYTE* menu_map_names[] = { "map leaves darci.tga", "map rain darci.tga",
|
||
"map snow darci.tga", "map blood darci.tga" };
|
||
CBYTE* menu_brief_names[]= { "briefing leaves darci.tga", "briefing rain darci.tga",
|
||
"briefing snow darci.tga", "briefing blood darci.tga" };
|
||
CBYTE* menu_config_names[]= { "config leaves.tga", "config rain.tga",
|
||
"config snow.tga", "config blood.tga" };
|
||
#endif
|
||
|
||
CBYTE frontend_fonttable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!\":;'#$*-()[]\\/?<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||
|
||
/*ULONG FRONTEND_leaf_colours[4] =
|
||
{
|
||
0x332d1d,
|
||
0x243224,
|
||
0x123320,
|
||
0x332f07
|
||
};*/
|
||
ULONG FRONTEND_leaf_colours[4] =
|
||
{
|
||
0x665a3a,
|
||
0x486448,
|
||
0x246640,
|
||
0x665E0E
|
||
};
|
||
|
||
|
||
|
||
//----------------------------------------------------------------------------
|
||
// GLOBALS
|
||
//
|
||
|
||
MenuData menu_data[50]; // max menu items...
|
||
MenuState menu_state;
|
||
CBYTE menu_buffer[2048];
|
||
BOOL grabbing_key=0;
|
||
BOOL grabbing_pad=0;
|
||
BOOL m_bMovingPanel = FALSE;
|
||
#ifdef TARGET_DC
|
||
// Dynamically allocated instead.
|
||
Kibble *kibble = NULL;
|
||
#else
|
||
Kibble kibble[512];
|
||
#endif
|
||
UBYTE kibble_off[512];
|
||
SLONG fade_state=0;
|
||
UBYTE fade_mode=1;
|
||
SLONG fade_rgb=0x000000;
|
||
SBYTE menu_mode_queued=0;
|
||
UBYTE menu_theme=1;
|
||
UBYTE menu_thrash=0; // cunningly thrash the stack...
|
||
SWORD districts[40][3]; // x, y, id
|
||
SWORD district_count=0;
|
||
SWORD district_selected=0;
|
||
SWORD district_flash=0;
|
||
UBYTE district_valid[40];
|
||
SWORD mission_count=0;
|
||
SWORD mission_selected=0;
|
||
UBYTE mission_hierarchy[60];
|
||
MissionCache mission_cache[60];
|
||
#ifdef NDEBUG
|
||
UBYTE complete_point=0;
|
||
#else
|
||
UBYTE complete_point=0;
|
||
#endif
|
||
UBYTE mission_launch=0;
|
||
UBYTE previous_mission_launch=0;
|
||
BOOL ragepro_sucks=0;
|
||
BOOL cheating=0;
|
||
SLONG MidX=0, MidY;
|
||
float ScaleX, ScaleY; // bwahahaha... and lo! the floats creep in! see the extent of my evil powers! muahahaha! *cough* er...
|
||
#ifdef DEBUG
|
||
// Allow saves from init, just so I can test the damn things.
|
||
UBYTE AllowSave=1;
|
||
#else
|
||
UBYTE AllowSave=0;
|
||
#endif
|
||
SLONG CurrentVidMode=0;
|
||
UBYTE CurrentBitDepth=16;
|
||
UBYTE save_slot;
|
||
UBYTE bonus_this_turn = 0;
|
||
UBYTE bonus_state = 0;
|
||
|
||
CBYTE the_script_file[MAX_PATH];
|
||
#define MISSION_SCRIPT the_script_file
|
||
|
||
UBYTE IsEnglish=0;
|
||
|
||
char *pcSpeechLanguageDir = "talk2\\";
|
||
|
||
DWORD dwAutoPlayFMVTimeout = 0;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
int iNextSuggestedMission = 0;
|
||
int g_iLevelNumber;
|
||
#endif
|
||
|
||
// Kludge!
|
||
SLONG GammaIndex;
|
||
|
||
// That's not a kludge. THIS is a kludge.
|
||
bool m_bGoIntoSaveScreen = FALSE;
|
||
|
||
|
||
BOOL bCanChangeJoypadButtons = FALSE;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
#define QUICK_INFO_MAX_LEN 40
|
||
char pcQuickInfo[QUICK_INFO_MAX_LEN+1] = "";
|
||
DWORD dwQuickInfotimeGetTimeExpires = 0;
|
||
bool bQuickInfoReplaceWithSegasMadMessage = FALSE;
|
||
#endif
|
||
|
||
|
||
//
|
||
// The three screen images for each theme are now preloaded.
|
||
//
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// If you're short of memory, ditch one.
|
||
//#define ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB defined
|
||
#endif
|
||
|
||
|
||
#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
CompressedBackground screenfull_back = NULL;
|
||
CompressedBackground screenfull_map = NULL;
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
CompressedBackground screenfull_config = NULL;
|
||
#endif
|
||
CompressedBackground screenfull_brief = NULL;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
CompressedBackground screenfull_title = NULL;
|
||
#endif
|
||
|
||
|
||
//
|
||
// The surface we use to do swipes\fades.
|
||
//
|
||
|
||
CompressedBackground screenfull = NULL;
|
||
|
||
#else
|
||
|
||
LPDIRECTDRAWSURFACE4 screenfull_back = NULL;
|
||
LPDIRECTDRAWSURFACE4 screenfull_map = NULL;
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
LPDIRECTDRAWSURFACE4 screenfull_config = NULL;
|
||
#endif
|
||
LPDIRECTDRAWSURFACE4 screenfull_brief = NULL;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
LPDIRECTDRAWSURFACE4 screenfull_title = NULL;
|
||
#endif
|
||
|
||
//
|
||
// The surface we use to do swipes\fades.
|
||
//
|
||
|
||
LPDIRECTDRAWSURFACE4 screenfull = NULL;
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//----------------------------------------------------------------------------
|
||
// FUNCTIONS
|
||
//
|
||
|
||
//--- tools ---
|
||
|
||
#ifdef TARGET_DC
|
||
|
||
// TRUE = normal behaviour - reset on door open.
|
||
// FALSE = ignore door resets.
|
||
void ChangeDoorResetStatus ( bool bAllowReset )
|
||
{
|
||
// And unlock the disk door reset thingie.
|
||
HANDLE handle = CreateFile(TEXT("\\Device\\CDROM0"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
|
||
if ( handle == INVALID_HANDLE_VALUE )
|
||
{
|
||
ASSERT ( FALSE );
|
||
return;
|
||
}
|
||
|
||
DWORD dwDummy;
|
||
SEGACD_DOOR_BEHAVIOR sdb;
|
||
if ( bAllowReset )
|
||
{
|
||
sdb.dwBehavior = SEGACD_DOOR_REBOOT;
|
||
}
|
||
else
|
||
{
|
||
sdb.dwBehavior = SEGACD_DOOR_NOTIFY_APP;
|
||
}
|
||
DeviceIoControl ( handle, IOCTL_SEGACD_SET_DOOR_BEHAVIOR,
|
||
&sdb, sizeof ( sdb ),
|
||
NULL, 0,
|
||
&dwDummy, NULL );
|
||
|
||
CloseHandle ( handle );
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
#ifndef TARGET_DC
|
||
// define this to save backgrounds out again in DC file format.
|
||
#define SAVE_MY_BACKGROUNDS_PLEASE_BOB defined
|
||
#endif
|
||
|
||
|
||
#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
void FRONTEND_scr_add(CompressedBackground *screen, UBYTE *image_data)
|
||
{
|
||
// First convert to 565 format.
|
||
WORD *pwTemp = (WORD *)MemAlloc ( 640 * 480 * 2 );
|
||
ASSERT ( pwTemp != NULL );
|
||
UBYTE *pbSrc = image_data;
|
||
|
||
for ( int i = 0; i < 640*480; i++ )
|
||
{
|
||
// From 24-bit RGB to 565.
|
||
*pwTemp = ( ( *pbSrc++ ) & 0xf8 ) << 8;
|
||
*pwTemp |= ( ( *pbSrc++ ) & 0xfc ) << 3;
|
||
*pwTemp |= ( ( *pbSrc++ ) & 0xf8 ) >> 3;
|
||
pwTemp++;
|
||
}
|
||
|
||
// See how big it is, compressed.
|
||
int iSize = PackBackground ( NULL, pwTemp );
|
||
|
||
TRACE ( "FRONTEND_scr_add: Original 565 0x%x, now 0x%x, saving of %i percent\n", 640*480*2, iSize, (100*iSize)/(640*480*2) );
|
||
|
||
if (*screen)
|
||
{
|
||
MemFree ( *screen );
|
||
*screen = NULL;
|
||
}
|
||
|
||
*screen = MemAlloc ( iSize );
|
||
|
||
PackBackground ( (UBYTE *)*screen, pwTemp );
|
||
|
||
// And free the 565 version.
|
||
MemFree ( (void *)pwTemp );
|
||
}
|
||
|
||
#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
void FRONTEND_scr_add(LPDIRECTDRAWSURFACE4 *screen, UBYTE *image_data)
|
||
{
|
||
DDSURFACEDESC2 back;
|
||
DDSURFACEDESC2 mine;
|
||
|
||
// Remember this if we have to reload.
|
||
|
||
// Create a mirror surface to the back buffer.
|
||
|
||
InitStruct(back);
|
||
|
||
the_display.lp_DD_BackSurface->GetSurfaceDesc(&back);
|
||
|
||
|
||
|
||
//
|
||
// Create the mirror surface in system memory.
|
||
//
|
||
|
||
InitStruct(mine);
|
||
|
||
mine.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||
mine.dwWidth = back.dwWidth;
|
||
mine.dwHeight = back.dwHeight;
|
||
mine.ddpfPixelFormat = back.ddpfPixelFormat;
|
||
#ifdef TARGET_DC
|
||
// No software blits on DC, but I'll do it myself.
|
||
mine.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||
#else
|
||
mine.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||
|
||
|
||
|
||
#ifdef SAVE_MY_BACKGROUNDS_PLEASE_BOB
|
||
// Force the format to be 640x480x565, because that's what the DC needs.
|
||
mine.dwWidth = 640;
|
||
mine.dwHeight = 480;
|
||
mine.ddpfPixelFormat.dwRBitMask = 0xf800;
|
||
mine.ddpfPixelFormat.dwGBitMask = 0x07e0;
|
||
mine.ddpfPixelFormat.dwBBitMask = 0x001f;
|
||
#endif
|
||
|
||
|
||
#endif
|
||
|
||
HRESULT result = the_display.lp_DD4->CreateSurface(&mine, screen, NULL);
|
||
|
||
|
||
if (FAILED(result))
|
||
{
|
||
// Probably out of memory.
|
||
ASSERT ( FALSE );
|
||
*screen = NULL;
|
||
return;
|
||
}
|
||
|
||
// Copy the image into the surface...
|
||
|
||
extern void CopyBackground(UBYTE* image_data, IDirectDrawSurface4* surface);
|
||
|
||
CopyBackground(image_data, *screen);
|
||
|
||
return;
|
||
}
|
||
#endif //#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
|
||
|
||
|
||
|
||
#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
#ifndef TARGET_DC
|
||
#error Compressed backgrounds only work on the DC at the moment.
|
||
#endif
|
||
|
||
void FRONTEND_scr_img_load_into_screenfull(CBYTE *name, CompressedBackground *screen)
|
||
{
|
||
MFFileHandle image_file;
|
||
SLONG height;
|
||
CBYTE fname[200];
|
||
UBYTE* image;
|
||
UBYTE *image_data;
|
||
|
||
//if (screenfull) FRONTEND_scr_del();
|
||
|
||
if ( *screen != NULL )
|
||
{
|
||
MemFree ( *screen );
|
||
*screen = NULL;
|
||
}
|
||
|
||
// Look for the preprocessed version.
|
||
sprintf(fname,"%sdata\\%s",DATA_DIR,name);
|
||
// Change the extension.
|
||
char *pchTemp = fname + strlen ( fname ) - 4;
|
||
ASSERT ( pchTemp[0] == '.' );
|
||
ASSERT ( pchTemp[1] == 't' );
|
||
ASSERT ( pchTemp[2] == 'g' );
|
||
ASSERT ( pchTemp[3] == 'a' );
|
||
pchTemp[1] = 'b';
|
||
pchTemp[2] = 'g';
|
||
pchTemp[3] = 's';
|
||
|
||
// .BGS - BackGroundScreen.
|
||
|
||
MFFileHandle handle = FileOpen ( fname );
|
||
if ( handle == FILE_OPEN_ERROR )
|
||
{
|
||
ASSERT ( FALSE );
|
||
}
|
||
else
|
||
{
|
||
SLONG slSize = FileSize ( handle );
|
||
|
||
*screen = MemAlloc ( slSize );
|
||
if ( *screen == NULL )
|
||
{
|
||
// Out of memory
|
||
TRACE ( "Out of memory for screen %s\n", fname );
|
||
return;
|
||
}
|
||
|
||
SLONG res = FileRead ( handle, *screen, slSize );
|
||
ASSERT ( res == slSize );
|
||
|
||
FileClose ( handle );
|
||
}
|
||
}
|
||
|
||
#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
void FRONTEND_scr_img_load_into_screenfull(CBYTE *name, LPDIRECTDRAWSURFACE4 *screen)
|
||
{
|
||
MFFileHandle image_file;
|
||
SLONG height;
|
||
CBYTE fname[200];
|
||
UBYTE* image;
|
||
UBYTE *image_data;
|
||
|
||
//if (screenfull) FRONTEND_scr_del();
|
||
|
||
*screen = NULL;
|
||
|
||
|
||
sprintf(fname,"%sdata\\%s",DATA_DIR,name);
|
||
|
||
image_data = (UBYTE*)MemAlloc(640*480*3);
|
||
|
||
if(image_data)
|
||
{
|
||
|
||
image_file = FileOpen(fname);
|
||
if(image_file>0)
|
||
{
|
||
TRACE ( "Loading background <%s>\n", fname );
|
||
FileSeek(image_file,SEEK_MODE_BEGINNING,18);
|
||
image = image_data +(640*479*3);
|
||
for(height=480;height;height--,image-=(640*3))
|
||
{
|
||
FileRead(image_file,image,640*3);
|
||
}
|
||
FileClose(image_file);
|
||
}
|
||
else
|
||
{
|
||
TRACE ( "Unable to load background <%s>\n", fname );
|
||
}
|
||
|
||
FRONTEND_scr_add(screen, image_data);
|
||
|
||
MemFree(image_data);
|
||
|
||
|
||
#ifndef TARGET_DC
|
||
#ifdef SAVE_MY_BACKGROUNDS_PLEASE_BOB
|
||
// Save the screen out - should already be in 565.
|
||
|
||
|
||
// First see if we need to make a copy, or if it already exists.
|
||
sprintf(fname,"%sdata\\%s",DATA_DIR,name);
|
||
// Change the extension.
|
||
char *pchTemp = fname + strlen ( fname ) - 4;
|
||
ASSERT ( pchTemp[0] == '.' );
|
||
ASSERT ( pchTemp[1] == 't' );
|
||
ASSERT ( pchTemp[2] == 'g' );
|
||
ASSERT ( pchTemp[3] == 'a' );
|
||
pchTemp[1] = 'b';
|
||
pchTemp[2] = 'g';
|
||
pchTemp[3] = 's';
|
||
// .BGS - BackGroundScreen. Wank, eh? But there's no format, it's just 640x480, 565 pixels, raw.
|
||
|
||
|
||
// If it already exists, don't bother.
|
||
MFFileHandle handle = FileCreate ( fname, FALSE );
|
||
if ( handle == FILE_CREATION_ERROR )
|
||
{
|
||
// Probably already exists.
|
||
TRACE ( "Couldn't save Dreamcast background <%s> - might already exist\n", fname );
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
// First make a linear-mem copy.
|
||
WORD *pwTemp = (WORD *)MemAlloc ( 640 * 480 * 2 );
|
||
ASSERT ( pwTemp != NULL );
|
||
|
||
DDSURFACEDESC2 mine;
|
||
InitStruct(mine);
|
||
HRESULT result = (*screen)->Lock ( NULL, &mine, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL );
|
||
ASSERT ( result == DD_OK );
|
||
|
||
char *src = (char *)( mine.lpSurface );
|
||
char *dst = (char *)pwTemp;
|
||
for ( int i = 0; i < 480; i++ )
|
||
{
|
||
memcpy ( dst, src, 640 * 2 );
|
||
src += mine.lPitch;
|
||
dst += 640 * 2;
|
||
}
|
||
|
||
(*screen)->Unlock ( NULL );
|
||
|
||
|
||
|
||
// See how big it is, compressed.
|
||
extern int PackBackground ( UBYTE* image_data, WORD *surface );
|
||
int iSize = PackBackground ( NULL, pwTemp );
|
||
|
||
TRACE ( "FRONTEND_scr_img_load_into_screenfull: Original 565 0x%x, now 0x%x, saving of %i percent\n", 640*480*2, iSize, (100*iSize)/(640*480*2) );
|
||
|
||
void *pvCompressed = MemAlloc ( iSize );
|
||
ASSERT ( pvCompressed != NULL );
|
||
|
||
PackBackground ( (UBYTE *)pvCompressed, pwTemp );
|
||
|
||
// And free the linear version.
|
||
MemFree ( (void *)pwTemp );
|
||
|
||
|
||
|
||
int res = FileWrite ( handle, pvCompressed, iSize );
|
||
ASSERT ( res == iSize );
|
||
FileClose ( handle );
|
||
|
||
TRACE ( "Saved Dreamcast background <%s>\n", fname );
|
||
|
||
MemFree ( pvCompressed );
|
||
|
||
#endif
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
TRACE ( "No memory to load background <%s>\n", fname );
|
||
}
|
||
}
|
||
|
||
|
||
#endif //#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
|
||
|
||
|
||
void FRONTEND_scr_unload_theme()
|
||
{
|
||
the_display.lp_DD_Background_use_instead = NULL;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Recover moderately gracefully from having your bollocks stamped on.
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if ( ( screenfull_title != NULL ) && ( screenfull_title == screenfull_back ) )
|
||
{
|
||
ASSERT ( FALSE );
|
||
screenfull_title = NULL;
|
||
}
|
||
#endif
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
if ( ( screenfull_config != NULL ) && ( screenfull_config == screenfull_back ) )
|
||
{
|
||
ASSERT ( FALSE );
|
||
screenfull_config = NULL;
|
||
}
|
||
#endif
|
||
if ( ( screenfull_brief != NULL ) && ( screenfull_brief == screenfull_map ) )
|
||
{
|
||
ASSERT ( FALSE );
|
||
screenfull_brief = NULL;
|
||
}
|
||
if ( ( screenfull_map != NULL ) && ( screenfull_map == screenfull_back ) )
|
||
{
|
||
ASSERT ( FALSE );
|
||
screenfull_map = NULL;
|
||
}
|
||
#endif
|
||
|
||
|
||
#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
if (screenfull_back ) {MemFree(screenfull_back) ; screenfull_back = NULL;}
|
||
if (screenfull_map ) {MemFree(screenfull_map) ; screenfull_map = NULL;}
|
||
if (screenfull_brief ) {MemFree(screenfull_brief) ; screenfull_brief = NULL;}
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
if (screenfull_config) {MemFree(screenfull_config); screenfull_config = NULL;}
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if (screenfull_title) {MemFree(screenfull_title); screenfull_title = NULL;}
|
||
#endif
|
||
|
||
|
||
#else
|
||
|
||
if (screenfull_back ) {screenfull_back ->Release(); screenfull_back = NULL;}
|
||
if (screenfull_map ) {screenfull_map ->Release(); screenfull_map = NULL;}
|
||
if (screenfull_brief ) {screenfull_brief ->Release(); screenfull_brief = NULL;}
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
if (screenfull_config) {screenfull_config->Release(); screenfull_config = NULL;}
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if (screenfull_title) {screenfull_title->Release(); screenfull_title = NULL;}
|
||
#endif
|
||
|
||
#endif
|
||
|
||
screenfull = NULL;
|
||
|
||
}
|
||
|
||
|
||
void FRONTEND_scr_new_theme(
|
||
CBYTE *fname_back,
|
||
CBYTE *fname_map,
|
||
CBYTE *fname_brief,
|
||
CBYTE *fname_config)
|
||
{
|
||
SLONG last = 1;
|
||
|
||
// Stop all music while we load stuff from disk.
|
||
stop_all_fx_and_music(TRUE);
|
||
|
||
|
||
|
||
|
||
if (the_display.lp_DD_Background_use_instead == screenfull_back ) {last = 1;}
|
||
if (the_display.lp_DD_Background_use_instead == screenfull_map ) {last = 2;}
|
||
if (the_display.lp_DD_Background_use_instead == screenfull_brief ) {last = 3;}
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
if (the_display.lp_DD_Background_use_instead == screenfull_config) {last = 4;}
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if (the_display.lp_DD_Background_use_instead == screenfull_title) {last = 5;}
|
||
#endif
|
||
|
||
|
||
FRONTEND_scr_unload_theme();
|
||
|
||
FRONTEND_scr_img_load_into_screenfull(fname_back , &screenfull_back );
|
||
FRONTEND_scr_img_load_into_screenfull(fname_map , &screenfull_map );
|
||
FRONTEND_scr_img_load_into_screenfull(fname_brief , &screenfull_brief );
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
FRONTEND_scr_img_load_into_screenfull(fname_config, &screenfull_config);
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
|
||
// Always the same - doesn't change with theme.
|
||
// Does change with nationality though!
|
||
extern LPSTR lpszGlobalArgs;
|
||
if ( NULL != strstr ( lpszGlobalArgs, "NO_PAL" ) )
|
||
{
|
||
// An NTSC build, so load the Yank screen instead.
|
||
FRONTEND_scr_img_load_into_screenfull("DCtitlepage_us.tga", &screenfull_title);
|
||
}
|
||
else
|
||
{
|
||
FRONTEND_scr_img_load_into_screenfull("DCtitlepage_uk.tga", &screenfull_title);
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
if ( screenfull_map == NULL )
|
||
{
|
||
// Shit - out of memory. Panic.
|
||
ASSERT ( FALSE );
|
||
screenfull_map = screenfull_back;
|
||
}
|
||
if ( screenfull_brief == NULL )
|
||
{
|
||
// Shit - out of memory. Panic.
|
||
ASSERT ( FALSE );
|
||
screenfull_brief = screenfull_map;
|
||
}
|
||
#ifndef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
if ( screenfull_config == NULL )
|
||
{
|
||
// Shit - out of memory. Panic.
|
||
ASSERT ( FALSE );
|
||
screenfull_config = screenfull_back;
|
||
}
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if ( screenfull_title == NULL )
|
||
{
|
||
// Shit - out of memory. Panic.
|
||
ASSERT ( FALSE );
|
||
screenfull_title = screenfull_back;
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
switch(last)
|
||
{
|
||
case 1: the_display.lp_DD_Background_use_instead = screenfull_back; break;
|
||
case 2: the_display.lp_DD_Background_use_instead = screenfull_map; break;
|
||
case 3: the_display.lp_DD_Background_use_instead = screenfull_brief; break;
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
// On DC, use the normal background, then draw an alpha poly over it.
|
||
// FIXME - not actually drawing the alpha poly yet.
|
||
case 4: the_display.lp_DD_Background_use_instead = screenfull_back; break;
|
||
#else
|
||
case 4: the_display.lp_DD_Background_use_instead = screenfull_config; break;
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
case 5: the_display.lp_DD_Background_use_instead = screenfull_title; break;
|
||
#endif
|
||
default:
|
||
ASSERT ( FALSE );
|
||
break;
|
||
}
|
||
|
||
|
||
// And then restart the music.
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
|
||
}
|
||
|
||
|
||
void FRONTEND_restore_screenfull_surfaces(void)
|
||
{
|
||
FRONTEND_scr_new_theme(
|
||
menu_back_names [menu_theme],
|
||
menu_map_names [menu_theme],
|
||
menu_brief_names [menu_theme],
|
||
menu_config_names[menu_theme]);
|
||
}
|
||
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
|
||
|
||
|
||
VMU_Screen *pvmuscreenAmmo = NULL;
|
||
VMU_Screen *pvmuscreenMFLogo = NULL;
|
||
VMU_Screen *pvmuscreenPressStart = NULL;
|
||
VMU_Screen *pvmuscreenSaved = NULL;
|
||
VMU_Screen *pvmuscreenUCLogo = NULL;
|
||
VMU_Screen *pvmuscreenWait = NULL;
|
||
|
||
|
||
|
||
// Shows the given screen.
|
||
// If the screen is NULL, it shops the default screen.
|
||
// It will only show the default screen every two seconds or so,
|
||
// so a displayed screen will be replaced in two seconds by the default screen,
|
||
// or immediately by a non-default screen.
|
||
#define SEND_VMU_PICCIE_EVERY 3000
|
||
void FRONTEND_show_VMU_screen ( VMU_Screen *screen )
|
||
{
|
||
static DWORD dwLastTimeWeSentScreenToVMU = 0;
|
||
static int iLastDefaultScreen = 0;
|
||
|
||
if ( screen == NULL )
|
||
{
|
||
if ( ( timeGetTime() - dwLastTimeWeSentScreenToVMU ) < SEND_VMU_PICCIE_EVERY )
|
||
{
|
||
// Nope - don't do it yet.
|
||
return;
|
||
}
|
||
|
||
// Pick a default screen.
|
||
iLastDefaultScreen++;
|
||
if ( iLastDefaultScreen >= 2 )
|
||
{
|
||
iLastDefaultScreen = 0;
|
||
}
|
||
|
||
switch ( iLastDefaultScreen )
|
||
{
|
||
case 0:
|
||
screen = pvmuscreenMFLogo;
|
||
break;
|
||
case 1:
|
||
screen = pvmuscreenUCLogo;
|
||
break;
|
||
}
|
||
}
|
||
|
||
dwLastTimeWeSentScreenToVMU = timeGetTime();
|
||
|
||
WriteLCDScreenToCurrentController ( screen );
|
||
}
|
||
|
||
|
||
|
||
|
||
void FRONTEND_MakeQuickMessage ( char *pcText, int iMilliSecsToShowFor, bool bReplaceWithSegasMadMessage = FALSE )
|
||
{
|
||
strncpy ( pcQuickInfo, pcText, QUICK_INFO_MAX_LEN );
|
||
pcQuickInfo[QUICK_INFO_MAX_LEN] = '\0';
|
||
dwQuickInfotimeGetTimeExpires = timeGetTime() + iMilliSecsToShowFor;
|
||
bQuickInfoReplaceWithSegasMadMessage = bReplaceWithSegasMadMessage;
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
void FRONTEND_ParseMissionData(CBYTE *text, CBYTE version, MissionData *mdata) {
|
||
UWORD a,n;
|
||
switch(version) {
|
||
case 2:
|
||
sscanf(text,"%d : %d : %d : %d : %d : %s : *%d : %*d : %[^:] : %*s",
|
||
&mdata->ObjID, &mdata->GroupID, &mdata->ParentID, &mdata->ParentIsGroup,
|
||
&mdata->Type, mdata->fn, mdata->ttl);
|
||
mdata->Flags=0; mdata->District=-1; n=9;
|
||
break;
|
||
case 3:
|
||
sscanf(text,"%d : %d : %d : %d : %d : %d : %s : %[^:] : %*s",
|
||
&mdata->ObjID, &mdata->GroupID, &mdata->ParentID, &mdata->ParentIsGroup,
|
||
&mdata->Type, &mdata->District, mdata->fn, mdata->ttl);
|
||
mdata->Flags=0; n=8;
|
||
break;
|
||
case 4:
|
||
sscanf(text,"%d : %d : %d : %d : %d : %d : %d : %s : %[^:] : %*s",
|
||
&mdata->ObjID, &mdata->GroupID, &mdata->ParentID, &mdata->ParentIsGroup,
|
||
&mdata->Type, &mdata->Flags, &mdata->District, mdata->fn, mdata->ttl);
|
||
n=9;
|
||
break;
|
||
default:
|
||
sscanf(text,"%d : %d : %d : %d : %d : %s : %[^:] : %*s",
|
||
&mdata->ObjID, &mdata->GroupID, &mdata->ParentID, &mdata->ParentIsGroup,
|
||
&mdata->Type, mdata->fn, mdata->ttl);
|
||
mdata->Flags=0; mdata->District=-1; n=7;
|
||
}
|
||
for (a=0;a<n;a++)
|
||
{
|
||
text=strchr(text,':')+1;
|
||
}
|
||
strcpy(mdata->brief,text+1);
|
||
|
||
// Change all @ signs to \r (linefeeds). Are we ugly yet mummy?
|
||
char *pch = mdata->brief;
|
||
while ( *pch != '\0' )
|
||
{
|
||
if ( *pch == '@' )
|
||
{
|
||
*pch = '\r';
|
||
}
|
||
pch++;
|
||
}
|
||
|
||
text=mdata->brief+strlen(mdata->brief)-2;
|
||
if (*text==13) *text=0;
|
||
}
|
||
|
||
#ifndef TARGET_DC
|
||
CBYTE* FRONTEND_LoadString(MFFileHandle &file, CBYTE *txt) {
|
||
CBYTE *ptr=txt;
|
||
|
||
*ptr=0;
|
||
while (1) {
|
||
if (FileRead(file,ptr,1)==FILE_READ_ERROR) {
|
||
*ptr=0; return txt;
|
||
};
|
||
if (*ptr==10) break;
|
||
ptr++;
|
||
}
|
||
*(++ptr)=0;
|
||
return txt;
|
||
}
|
||
|
||
void FRONTEND_SaveString(MFFileHandle &file, CBYTE *txt) {
|
||
CBYTE *ptr=txt;
|
||
CBYTE crlf[] = { 13, 10};
|
||
|
||
FileWrite(file,txt,strlen(txt));
|
||
FileWrite(file,crlf,2);
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
SLONG FRONTEND_AlterAlpha(SLONG rgb, SWORD add, SBYTE shift) {
|
||
|
||
#ifdef TARGET_DC
|
||
// Instead of darker/lighter, we change size.
|
||
return rgb;
|
||
|
||
#else
|
||
|
||
SLONG alpha=rgb>>24;
|
||
alpha<<=shift;
|
||
alpha+=add;
|
||
if (alpha>0xff) alpha=0xff;
|
||
if (alpha<0) alpha=0;
|
||
rgb&=0xffffff;
|
||
return rgb|(alpha<<24);
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
// Recenters (vertically) whatever menu has been put down.
|
||
void FRONTEND_recenter_menu ( void )
|
||
{
|
||
MenuData *md=menu_data;
|
||
int iY = 0;
|
||
for ( int i = 0; i < menu_state.items; i++ )
|
||
{
|
||
md->Y = iY;
|
||
md++;
|
||
iY += 50;
|
||
}
|
||
|
||
menu_state.base = ( 480 - menu_state.items * 50 ) >> 1;
|
||
if ( menu_state.base < 100 )
|
||
{
|
||
menu_state.base = 100;
|
||
}
|
||
menu_state.scroll = 0;
|
||
}
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
ULONG FRONTEND_fix_rgb(ULONG rgb, BOOL sel)
|
||
{
|
||
rgb=fade_rgb;
|
||
if (sel) rgb=FRONTEND_AlterAlpha(rgb,0,1);
|
||
return rgb;
|
||
}
|
||
#else
|
||
ULONG FRONTEND_fix_rgb(ULONG rgb, BOOL sel)
|
||
{
|
||
if (ragepro_sucks) { // but the Rage Pro sucks, even if you don't have one in your machine
|
||
rgb>>=24;
|
||
if (sel) rgb<<=1;
|
||
rgb|=(rgb<<8)|(rgb<<16);
|
||
rgb|=0xff000000;
|
||
} else {
|
||
rgb=fade_rgb;
|
||
if (sel) rgb=FRONTEND_AlterAlpha(rgb,0,1);
|
||
}
|
||
return rgb;
|
||
}
|
||
#endif
|
||
|
||
//--- drawy stuff ---
|
||
|
||
#define RandStream(s) ((UWORD)((s = ((s*69069)+1) )>>7))
|
||
|
||
void FRONTEND_draw_title(SLONG x, SLONG y, SLONG cutx, CBYTE *str, BOOL wibble, BOOL r_to_l) {
|
||
#ifdef TARGET_DC
|
||
SLONG rgb=wibble?0xffffffff:0x70ffffff;
|
||
#else
|
||
SLONG rgb=wibble?(fade_rgb<<1)|0xffffff:fade_rgb|0xffffff;
|
||
#endif
|
||
SLONG seed=*str;
|
||
SWORD xo=0, yo=0;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Scan for the word "VMU".
|
||
// Mark the "U" as not to be drawn.
|
||
CBYTE *pDontDrawThisLetter = NULL;
|
||
if ( bWriteVMInsteadOfVMU )
|
||
{
|
||
pDontDrawThisLetter = strstr ( str, "VMU" );
|
||
if ( pDontDrawThisLetter != NULL )
|
||
{
|
||
// Point to the U
|
||
pDontDrawThisLetter += 2;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
|
||
for (;*str;str++) {
|
||
if (!wibble)
|
||
{
|
||
#ifdef TARGET_DC
|
||
// Ugh - don't like this wibble.
|
||
xo=4;
|
||
yo=4;
|
||
#else
|
||
xo=(RandStream(seed)&0x1f)-0xf;
|
||
yo=4;
|
||
#endif
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
if ( pDontDrawThisLetter == str )
|
||
{
|
||
// Ignore this letter.
|
||
ASSERT ( *str == 'U' );
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
if (((r_to_l)&&(x>cutx))||((!r_to_l)&&(x<cutx))) {
|
||
MENUFONT_Draw(x+xo,y+yo,BIG_FONT_SCALE+(wibble<<5),str,rgb,0,1);
|
||
}
|
||
x+=(MENUFONT_CharWidth(*str,BIG_FONT_SCALE))-2;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void FRONTEND_init_xition ( void ) {
|
||
MidX=RealDisplayWidth/2;
|
||
MidY=RealDisplayHeight/2;
|
||
ScaleX=MidX/64.0f;
|
||
ScaleY=MidY/64.0f;
|
||
switch (menu_state.mode) {
|
||
case FE_MAPSCREEN:
|
||
|
||
screenfull = screenfull_map;
|
||
|
||
//FRONTEND_scr_img(menu_map_names[menu_theme]);
|
||
break;
|
||
case FE_MAINMENU:
|
||
screenfull = screenfull_back;
|
||
|
||
//FRONTEND_scr_img(menu_map_names[menu_theme]);
|
||
break;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
case FE_TITLESCREEN:
|
||
case FE_LANGUAGESCREEN:
|
||
screenfull = screenfull_title;
|
||
break;
|
||
#endif
|
||
case FE_LOADSCREEN:
|
||
case FE_SAVESCREEN:
|
||
case FE_CONFIG:
|
||
#ifdef TARGET_DC
|
||
case FE_VMU_SELECT:
|
||
#endif
|
||
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
screenfull = screenfull_back;
|
||
#else
|
||
screenfull = screenfull_config;
|
||
#endif
|
||
|
||
//FRONTEND_scr_img(menu_config_names[menu_theme]);
|
||
break;
|
||
default:
|
||
if (menu_state.mode>=100)
|
||
{
|
||
screenfull = screenfull_brief;
|
||
|
||
//FRONTEND_scr_img(menu_brief_names[menu_theme]);
|
||
}
|
||
else
|
||
{
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
screenfull = screenfull_back;
|
||
#else
|
||
screenfull = screenfull_config;
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#if USE_COMPRESSED_BACKGROUNDS
|
||
CompressedBackground lpFRONTEND_show_xition_LastBlit = NULL;
|
||
#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
LPDIRECTDRAWSURFACE4 lpFRONTEND_show_xition_LastBlit = NULL;
|
||
#endif //#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
void FRONTEND_show_xition() {
|
||
RECT rc;
|
||
|
||
bool bDoBlit = FALSE;
|
||
|
||
if (menu_state.mode>=100)
|
||
{
|
||
rc.top=MidY-(fade_state*ScaleY); rc.bottom=MidY+(fade_state*ScaleY); // set to 3.75 ...
|
||
rc.left=MidX-(fade_state*ScaleX); rc.right=MidX+(fade_state*ScaleX); // set to 5...
|
||
if ( rc.left < rc.right )
|
||
{
|
||
bDoBlit = TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// This is a great switch statement!
|
||
//switch (menu_state.mode) {
|
||
//case FE_LOADSCREEN:
|
||
//case FE_SAVESCREEN:
|
||
//case FE_MAPSCREEN:
|
||
//case FE_CONFIG:
|
||
//case FE_MAINMENU:
|
||
//default:
|
||
rc.top=0; rc.bottom=RealDisplayHeight;
|
||
rc.left=0;
|
||
if (RealDisplayWidth==640)
|
||
{
|
||
rc.right=fade_state*10;
|
||
}
|
||
else
|
||
{
|
||
rc.right=fade_state*10*RealDisplayWidth/640;
|
||
}
|
||
if ( rc.right > 0 )
|
||
{
|
||
bDoBlit = TRUE;
|
||
}
|
||
//break;
|
||
//}
|
||
}
|
||
|
||
|
||
if ( bDoBlit )
|
||
{
|
||
#ifndef TARGET_DC
|
||
the_display.lp_DD_BackSurface->Blt(&rc,screenfull,&rc,DDBLT_WAIT,0);
|
||
#else
|
||
|
||
extern LPDIRECTDRAWSURFACE4 lpBackgroundCache2;
|
||
|
||
HRESULT result;
|
||
|
||
// Use a poly draw.
|
||
|
||
ASSERT ( lpBackgroundCache2 != NULL );
|
||
|
||
#if USE_COMPRESSED_BACKGROUNDS
|
||
if ( lpFRONTEND_show_xition_LastBlit != screenfull )
|
||
{
|
||
lpFRONTEND_show_xition_LastBlit = screenfull;
|
||
if ( screenfull != NULL )
|
||
{
|
||
UnpackBackground ( (UCHAR*)screenfull, lpBackgroundCache2 );
|
||
}
|
||
else
|
||
{
|
||
// Bum - black screen time :-(
|
||
ASSERT ( FALSE );
|
||
}
|
||
}
|
||
|
||
#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
if ( lpFRONTEND_show_xition_LastBlit != screenfull )
|
||
{
|
||
// Get the texture handle.
|
||
lpFRONTEND_show_xition_LastBlit = screenfull;
|
||
// Copy the data to the texture cache thingie.
|
||
RECT rect;
|
||
rect.top = 0;
|
||
rect.left = 0;
|
||
rect.right = 640;
|
||
rect.bottom = 480;
|
||
if ( screenfull == NULL )
|
||
{
|
||
// Nadgers. Black screen time.
|
||
ASSERT ( FALSE );
|
||
}
|
||
else
|
||
{
|
||
HRESULT hres = lpBackgroundCache2->Blt ( &rect, screenfull, &rect, DDBLT_WAIT, NULL );
|
||
VERIFY(SUCCEEDED(hres));
|
||
}
|
||
}
|
||
#endif //#else //#if USE_COMPRESSED_BACKGROUNDS
|
||
|
||
ASSERT ( lpFRONTEND_show_xition_LastBlit != NULL );
|
||
|
||
POLY_Point pp[4];
|
||
POLY_Point *quad[4] = { &pp[0], &pp[1], &pp[2], &pp[3] };
|
||
|
||
pp[0].colour=0xffffffff; pp[0].specular=0;
|
||
pp[1].colour=0xffffffff; pp[1].specular=0;
|
||
pp[2].colour=0xffffffff; pp[2].specular=0;
|
||
pp[3].colour=0xffffffff; pp[3].specular=0;
|
||
|
||
pp[0].X=rc.left; pp[0].Y=rc.top; pp[0].Z=0.0002f;
|
||
pp[0].u=rc.left / 1024.0f; pp[0].v=rc.top / 512.0f;
|
||
|
||
pp[1].X=rc.left; pp[1].Y=rc.bottom; pp[1].Z=0.0002f;
|
||
pp[1].u=rc.left / 1024.0f; pp[1].v=rc.bottom / 512.0f;
|
||
|
||
pp[2].X=rc.right; pp[2].Y=rc.top; pp[2].Z=0.0002f;
|
||
pp[2].u=rc.right / 1024.0f; pp[2].v=rc.top / 512.0f;
|
||
|
||
pp[3].X=rc.right; pp[3].Y=rc.bottom; pp[3].Z=0.0002f;
|
||
pp[3].u=rc.right / 1024.0f; pp[3].v=rc.bottom / 512.0f;
|
||
|
||
POLY_add_quad ( quad, POLY_PAGE_BACKGROUND_IMAGE2, FALSE, TRUE );
|
||
|
||
#endif
|
||
}
|
||
|
||
}
|
||
|
||
extern UBYTE* image_mem;
|
||
|
||
void FRONTEND_stop_xition()
|
||
{
|
||
switch(menu_state.mode)
|
||
{
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
case FE_QUIT:
|
||
#endif
|
||
case FE_MAINMENU:
|
||
UseBackSurface(screenfull_back);
|
||
break;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
case FE_TITLESCREEN:
|
||
case FE_LANGUAGESCREEN:
|
||
UseBackSurface(screenfull_title);
|
||
break;
|
||
#endif
|
||
case FE_CONFIG:
|
||
case FE_CONFIG_VIDEO:
|
||
case FE_CONFIG_AUDIO:
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
case FE_CONFIG_INPUT_KB:
|
||
#endif
|
||
case FE_CONFIG_INPUT_JP:
|
||
case FE_LOADSCREEN:
|
||
case FE_SAVESCREEN:
|
||
#ifdef TARGET_DC
|
||
case FE_VMU_SELECT:
|
||
#endif
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
UseBackSurface(screenfull_back);
|
||
#else
|
||
UseBackSurface(screenfull_config);
|
||
#endif
|
||
break;
|
||
case FE_MAPSCREEN:
|
||
UseBackSurface(screenfull_map);
|
||
break;
|
||
default:
|
||
if (menu_state.mode>=100)
|
||
{
|
||
UseBackSurface(screenfull_brief);
|
||
}
|
||
else
|
||
{
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
UseBackSurface(screenfull_back);
|
||
#else
|
||
UseBackSurface(screenfull_config);
|
||
#endif
|
||
}
|
||
break;
|
||
}
|
||
|
||
/*
|
||
|
||
if (screenfull) {
|
||
ResetBackImage();
|
||
the_display.lp_DD_Background=screenfull;
|
||
image_mem=screenimage;
|
||
screenfull=NULL; screenimage=NULL;
|
||
}
|
||
|
||
*/
|
||
|
||
/* if (menu_state.mode==FE_MAPSCREEN) InitBackImage("MAP SELECT LEAVES.tga");
|
||
if (menu_state.mode>=100) InitBackImage("MISSION BRIEF LEAVES.tga");
|
||
FRONTEND_scr_del();*/
|
||
}
|
||
|
||
|
||
void FRONTEND_draw_button(SLONG x, SLONG y, UBYTE which, UBYTE flash = FALSE) {
|
||
POLY_Point pp[4];
|
||
POLY_Point *quad[4] = { &pp[0], &pp[1], &pp[2], &pp[3] };
|
||
float u,v,w,h;
|
||
UBYTE size=(which<4)?64:32;
|
||
UBYTE grow;
|
||
|
||
if (flash)
|
||
{
|
||
grow = 8;
|
||
|
||
if (GetTickCount() & 0x200)
|
||
{
|
||
which = 7;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
grow = 0;
|
||
}
|
||
|
||
switch (which) {
|
||
case 0: case 4: u=0.0; v=0.0; w=0.5; h=0.5; break;
|
||
case 1: case 5: u=0.5; v=0.0; w=1.0; h=0.5; break;
|
||
case 2: case 6: u=0.0; v=0.5; w=0.5; h=1.0; break;
|
||
case 3: case 7: u=0.5; v=0.5; w=1.0; h=1.0; break;
|
||
}
|
||
|
||
pp[0].colour=(which<4)?0xffFFFFFF:(fade_rgb<<1)|0xffffff; pp[0].specular=0; pp[0].Z=0.5;
|
||
pp[1]=pp[2]=pp[3]=pp[0];
|
||
|
||
pp[0].X=x-(grow>>1); pp[0].Y=y-grow;
|
||
pp[0].u=u; pp[0].v=v;
|
||
|
||
pp[1].X=x+(grow>>1)+size; pp[1].Y=y-grow;
|
||
pp[1].u=w; pp[1].v=v;
|
||
|
||
pp[2].X=x; pp[2].Y=y+size;
|
||
pp[2].u=u; pp[2].v=h;
|
||
|
||
pp[3].X=x+size; pp[3].Y=y+size;
|
||
pp[3].u=w; pp[3].v=h;
|
||
|
||
POLY_add_quad(quad,(which<4)?POLY_PAGE_BIG_BUTTONS:POLY_PAGE_TINY_BUTTONS,FALSE,TRUE);
|
||
}
|
||
|
||
#define KIBBLE_Z 0.5
|
||
|
||
void FRONTEND_kibble_draw() {
|
||
UWORD c0;
|
||
Kibble*k;
|
||
POLY_Point pp[4];
|
||
POLY_Point *quad[4] = { &pp[0], &pp[1], &pp[2], &pp[3] };
|
||
SLONG matrix[9],x,y,z;
|
||
|
||
ASSERT ( kibble != NULL );
|
||
|
||
for (c0=0,k=kibble;c0<512;c0++,k++)
|
||
if (k->type>0) {
|
||
|
||
pp[0].colour=(k->rgb) | 0xff000000; pp[0].specular=0;
|
||
pp[1]=pp[2]=pp[3]=pp[0];
|
||
|
||
FMATRIX_calc(matrix, k->r, k->t, k->p);
|
||
|
||
x=- k->size;
|
||
y=- k->size;
|
||
z=0;
|
||
FMATRIX_MUL(matrix,x,y,z);
|
||
pp[0].X=(k->x>>8)+x; pp[0].Y=(k->y>>8)+y; pp[0].Z=KIBBLE_Z;
|
||
pp[0].u=0; pp[0].v=0;
|
||
|
||
x=+ k->size;
|
||
y=- k->size;
|
||
z=0;
|
||
FMATRIX_MUL(matrix,x,y,z);
|
||
pp[1].X=(k->x>>8)+x; pp[1].Y=(k->y>>8)+y; pp[1].Z=KIBBLE_Z;
|
||
pp[1].u=1; pp[1].v=0;
|
||
|
||
x=- k->size;
|
||
y=+ k->size;
|
||
z=0;
|
||
FMATRIX_MUL(matrix,x,y,z);
|
||
pp[2].X=(k->x>>8)+x; pp[2].Y=(k->y>>8)+y; pp[2].Z=KIBBLE_Z;
|
||
pp[2].u=0; pp[2].v=1;
|
||
|
||
x=+ k->size;
|
||
y=+ k->size;
|
||
z=0;
|
||
FMATRIX_MUL(matrix,x,y,z);
|
||
pp[3].X=(k->x>>8)+x; pp[3].Y=(k->y>>8)+y; pp[3].Z=KIBBLE_Z;
|
||
pp[3].u=1; pp[3].v=1;
|
||
|
||
POLY_add_quad(quad,k->page,FALSE,TRUE);
|
||
|
||
}
|
||
}
|
||
|
||
|
||
// Oh yuk this is pants - really could look better.
|
||
void FRONTEND_DrawSlider(MenuData *md) {
|
||
SLONG y;
|
||
ULONG rgb=FRONTEND_fix_rgb(fade_rgb,0);
|
||
y=md->Y+menu_state.base-menu_state.scroll;
|
||
DRAW2D_Box(320,y-2,610,y+2,rgb,0,192);
|
||
DRAW2D_Box(337,y-4,341,y+4,rgb,0,192);
|
||
DRAW2D_Box(337+255,y-4,341+255,y+4,rgb,0,192);
|
||
DRAW2D_Box(337+(md->Data),y-8,341+(md->Data),y+8,rgb,0,192);
|
||
}
|
||
|
||
void FRONTEND_DrawMulti(MenuData *md, ULONG rgb) {
|
||
SLONG x,y,dy,c0;
|
||
CBYTE *str;
|
||
//ULONG rgb=FRONTEND_fix_rgb(fade_rgb,0);
|
||
dy=md->Y+menu_state.base-menu_state.scroll;
|
||
str=md->Choices;
|
||
c0=md->Data&0xff;
|
||
|
||
if (!str) return;
|
||
|
||
while ((*str)&&c0--) {
|
||
str+=strlen(str)+1;
|
||
}
|
||
#ifndef TARGET_DC
|
||
if (IsEnglish)
|
||
#endif
|
||
{
|
||
MENUFONT_Dimensions(str,x,y,-1,BIG_FONT_SCALE);
|
||
if (320+x>630)
|
||
{
|
||
if (320+(x>>1)>630)
|
||
{
|
||
c0=MENUFONT_CharFit(str,310,128);
|
||
MENUFONT_Draw(320,dy-15,128,str,rgb,0,c0);
|
||
MENUFONT_Draw(320,dy+15,128,str+c0,rgb,0);
|
||
}
|
||
else
|
||
{
|
||
MENUFONT_Draw(620-(x>>1),dy,128,str,rgb,0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MENUFONT_Draw(620-x,dy,BIG_FONT_SCALE,str,rgb,0);
|
||
}
|
||
}
|
||
#ifndef TARGET_DC
|
||
else
|
||
{
|
||
rgb=FRONTEND_fix_rgb(fade_rgb,1);
|
||
FONT2D_DrawStringRightJustify(str,620,dy,rgb,SMALL_FONT_SCALE + 64,POLY_PAGE_FONT2D);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void FRONTEND_DrawKey(MenuData *md) {
|
||
SLONG x,y,dy,c0,rgb;
|
||
CBYTE key;
|
||
CBYTE str[25];
|
||
rgb=FRONTEND_fix_rgb(fade_rgb,(grabbing_key&&((menu_data+menu_state.selected==md)&&((GetTickCount()&0x7ff)<0x3ff))));
|
||
dy=md->Y+menu_state.base-menu_state.scroll;
|
||
/* switch (md->Data) {
|
||
case KB_LEFT:
|
||
c0=md->Data &~ 0x80;
|
||
c0<<=16;
|
||
c0|=1<<24;
|
||
GetKeyNameText(c0,str,20);
|
||
break;
|
||
// strcpy(str,"Left"); break;
|
||
case KB_RIGHT:
|
||
strcpy(str,"Right"); break;
|
||
case KB_UP:
|
||
strcpy(str,"Up"); break;
|
||
case KB_DOWN:
|
||
strcpy(str,"Down"); break;
|
||
case KB_ENTER:
|
||
strcpy(str,"Enter"); break;
|
||
case KB_SPACE:
|
||
strcpy(str,"Space"); break;
|
||
case KB_LSHIFT:
|
||
strcpy(str,"Left Shift"); break;
|
||
case KB_RSHIFT:
|
||
strcpy(str,"Right Shift"); break;
|
||
case KB_LALT:
|
||
strcpy(str,"Left Alt"); break;
|
||
case KB_RALT:
|
||
strcpy(str,"Right Alt"); break;
|
||
case KB_LCONTROL:
|
||
strcpy(str,"Left Ctrl"); break;
|
||
case KB_RCONTROL:
|
||
strcpy(str,"Right Ctrl");break;
|
||
case KB_TAB:
|
||
strcpy(str,"Tab"); break;
|
||
case KB_END:
|
||
strcpy(str,"End"); break;
|
||
case KB_HOME:
|
||
strcpy(str,"Home"); break;
|
||
case KB_DEL:
|
||
strcpy(str,"Delete"); break;
|
||
case KB_INS:
|
||
strcpy(str,"Insert"); break;
|
||
case KB_PGUP:
|
||
strcpy(str,"Page Up"); break;
|
||
case KB_PGDN:
|
||
strcpy(str,"Page Down"); break;
|
||
case 0:
|
||
strcpy(str,"Unused"); break;
|
||
default:
|
||
//key=InkeyToAscii[md->Data];
|
||
//str[0]=key; str[1]=0;
|
||
GetKeyNameText(md->Data<<16,str,20);
|
||
// if (!stricmp(str,"Circumflex")) strcpy(str,"^");
|
||
}*/
|
||
|
||
c0=md->Data;
|
||
if (c0&0x80)
|
||
{
|
||
c0=md->Data &~ 0x80;
|
||
c0<<=16;
|
||
c0|=1<<24;
|
||
} else {
|
||
c0<<=16;
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
strcpy ( str, "FixMePlease" );
|
||
#else
|
||
GetKeyNameText(c0,str,25);
|
||
#endif
|
||
|
||
if (IsEnglish)
|
||
{
|
||
MENUFONT_Dimensions(str,x,y,-1,BIG_FONT_SCALE);
|
||
MENUFONT_Draw(620-x,dy,BIG_FONT_SCALE,str,rgb,0);
|
||
}
|
||
else
|
||
{
|
||
FONT2D_DrawStringRightJustify(str,620,dy,rgb,SMALL_FONT_SCALE,POLY_PAGE_FONT2D);
|
||
}
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
|
||
void FRONTEND_DrawPad(MenuData *md) {
|
||
SLONG x,y,dy,c0,rgb;
|
||
CBYTE str[20];
|
||
rgb=FRONTEND_fix_rgb(fade_rgb,(grabbing_pad&&((menu_data+menu_state.selected==md)&&((GetTickCount()&0x3ff)<0x1ff))));
|
||
dy=md->Y+menu_state.base-menu_state.scroll;
|
||
if (md->Data==31)
|
||
{
|
||
// Unused.
|
||
sprintf(str,"%s",XLAT_str(X_EMPTY));
|
||
MENUFONT_Dimensions(str,x,y,-1,BIG_FONT_SCALE);
|
||
MENUFONT_Draw(620-x,dy,BIG_FONT_SCALE,str,rgb,0);
|
||
}
|
||
else
|
||
{
|
||
// Draw the button icon
|
||
DWORD dwPage = -1;
|
||
switch ( md->Data )
|
||
{
|
||
case DI_DC_BUTTON_A : dwPage = POLY_PAGE_JOYPAD_A; break;
|
||
case DI_DC_BUTTON_B : dwPage = POLY_PAGE_JOYPAD_B; break;
|
||
case DI_DC_BUTTON_C : dwPage = POLY_PAGE_JOYPAD_C; break;
|
||
case DI_DC_BUTTON_X : dwPage = POLY_PAGE_JOYPAD_X; break;
|
||
case DI_DC_BUTTON_Y : dwPage = POLY_PAGE_JOYPAD_Y; break;
|
||
case DI_DC_BUTTON_Z : dwPage = POLY_PAGE_JOYPAD_Z; break;
|
||
case DI_DC_BUTTON_RTRIGGER : dwPage = POLY_PAGE_JOYPAD_R; break;
|
||
case DI_DC_BUTTON_LTRIGGER : dwPage = POLY_PAGE_JOYPAD_L; break;
|
||
case DI_DC_BUTTON_UP : dwPage = POLY_PAGE_JOYPAD_PAD_U; break;
|
||
case DI_DC_BUTTON_DOWN : dwPage = POLY_PAGE_JOYPAD_PAD_D; break;
|
||
case DI_DC_BUTTON_LEFT : dwPage = POLY_PAGE_JOYPAD_PAD_L; break;
|
||
case DI_DC_BUTTON_RIGHT : dwPage = POLY_PAGE_JOYPAD_PAD_R; break;
|
||
default:
|
||
// Might be Start - don't have graphics, and shouldn't need them!
|
||
ASSERT ( FALSE );
|
||
break;
|
||
}
|
||
|
||
if ( dwPage == -1 )
|
||
{
|
||
// Button that we don't have the graphics for.
|
||
sprintf(str,"%s %d",XLAT_str(X_BUTTON),md->Data);
|
||
MENUFONT_Dimensions(str,x,y,-1,BIG_FONT_SCALE);
|
||
MENUFONT_Draw(620-x,dy,BIG_FONT_SCALE,str,rgb,0);
|
||
}
|
||
else
|
||
{
|
||
DWORD dwRGB = 0xffe0e0e0;
|
||
if ( grabbing_pad && ( menu_data + menu_state.selected == md ) && ( (GetTickCount()&0x3ff)<0x1ff ) )
|
||
{
|
||
// Flash it.
|
||
dwRGB = 0xff505050;
|
||
}
|
||
|
||
POLY_Point pp[4];
|
||
POLY_Point *quad[4] = { &pp[0], &pp[1], &pp[2], &pp[3] };
|
||
|
||
// The size of the button in pixels.
|
||
const float fSize = 48.0f * 0.5f;
|
||
|
||
pp[0].colour=dwRGB;
|
||
pp[0].specular=0;
|
||
pp[0].Z=0.7f;
|
||
pp[1]=pp[2]=pp[3]=pp[0];
|
||
|
||
pp[0].X=620 - fSize * 2.0f; pp[0].Y=dy - fSize;
|
||
pp[0].u=0.0f; pp[0].v=0.0f;
|
||
|
||
pp[1].X=620 - fSize * 2.0f; pp[1].Y=dy + fSize;
|
||
pp[1].u=0.0f; pp[1].v=1.0f;
|
||
|
||
pp[2].X=620; pp[2].Y=dy - fSize;
|
||
pp[2].u=1.0f; pp[2].v=0.0f;
|
||
|
||
pp[3].X=620; pp[3].Y=dy + fSize;
|
||
pp[3].u=1.0f; pp[3].v=1.0f;
|
||
|
||
POLY_add_quad(quad,dwPage,FALSE,TRUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
#else
|
||
|
||
void FRONTEND_DrawPad(MenuData *md) {
|
||
SLONG x,y,dy,c0,rgb;
|
||
CBYTE str[20];
|
||
rgb=FRONTEND_fix_rgb(fade_rgb,(grabbing_pad&&((menu_data+menu_state.selected==md)&&((GetTickCount()&0x7ff)<0x3ff))));
|
||
dy=md->Y+menu_state.base-menu_state.scroll;
|
||
if (md->Data<31) sprintf(str,"%s %d",XLAT_str(X_BUTTON),md->Data); else strcpy(str,"Unused");
|
||
MENUFONT_Dimensions(str,x,y,-1,BIG_FONT_SCALE);
|
||
MENUFONT_Draw(620-x,dy,BIG_FONT_SCALE,str,rgb,0);
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
//--- kibbly stuff ---
|
||
|
||
void FRONTEND_kibble_init_one(Kibble*k, UBYTE type) {
|
||
|
||
SLONG kibble_index = k - kibble;
|
||
|
||
ASSERT ( kibble != NULL );
|
||
|
||
ASSERT(WITHIN(kibble_index, 0, 511));
|
||
|
||
#ifndef FORCE_STUFF_PLEASE_BOB
|
||
if (kibble_off[kibble_index])
|
||
{
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
if (!(type&128)) {
|
||
if ((menu_state.mode==FE_MAPSCREEN)||(menu_state.mode>=100)) return;
|
||
}
|
||
switch(type&0x7f) {
|
||
case 1:
|
||
k->dx=(20+(Random()&15))<<5;
|
||
k->dy=0;
|
||
k->page=POLY_PAGE_BIG_LEAF;
|
||
k->rgb=FRONTEND_leaf_colours[Random()&3];
|
||
k->x=(-10-(Random()&0x1ff))<<8;
|
||
k->y=((Random()%520)-20)<<8;
|
||
k->size=35+(Random()&0x1f);
|
||
k->r=Random()&2047; k->t=Random()&2047; k->p=0;
|
||
k->rd=1+(Random()&7); k->td=1+(Random()&7); k->pd=0;
|
||
k->type=type;
|
||
break;
|
||
case 2:
|
||
k->dx=k->dy=(20+(Random()&15))<<5;
|
||
k->page=POLY_PAGE_BIG_RAIN;
|
||
k->rgb=0x3f7f7fff;
|
||
if (Random()&1) {
|
||
k->x=(-10-(Random()&0x1ff))<<8;
|
||
k->y=((Random()%520)-20)<<8;
|
||
} else {
|
||
k->x=((Random()%680)-20)<<8;
|
||
k->y=(-10-(Random()&0x1ff)-20)<<8;
|
||
}
|
||
k->size=25+(Random()&0x1f);
|
||
k->r=0; k->t=0; k->p=1792;
|
||
k->rd=0; k->td=0; k->pd=0;
|
||
k->type=type;
|
||
break;
|
||
case 3:
|
||
k->dx=(15+(Random()&15))<<5;
|
||
k->dy=(5+(Random()&15))<<5;
|
||
k->page=POLY_PAGE_SNOWFLAKE;
|
||
k->rgb=0xffafafff;
|
||
if (Random()&1) {
|
||
k->x=(-10-(Random()&0x1ff))<<8;
|
||
k->y=((Random()%520)-20)<<8;
|
||
} else {
|
||
k->x=((Random()%680)-20)<<8;
|
||
k->y=(-10-(Random()&0x1ff)-20)<<8;
|
||
}
|
||
k->size=25+(Random()&0x1f);
|
||
k->r=0; k->t=0; k->p=0;
|
||
k->rd=1; k->td=2; k->pd=0;
|
||
k->type=type;
|
||
break;
|
||
}
|
||
}
|
||
|
||
void FRONTEND_kibble_init() {
|
||
UWORD c0, densities[] = { 25, 255, 40, 10 };
|
||
Kibble*k;
|
||
|
||
#ifndef TARGET_DC
|
||
if (SOFTWARE)
|
||
{
|
||
densities[0] = 20;
|
||
densities[1] = 175;
|
||
densities[2] = 30;
|
||
densities[3] = 10;
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
densities[0] = 25;
|
||
densities[1] = 255;
|
||
densities[2] = 40;
|
||
densities[3] = 10;
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
// Allocate the kibble
|
||
if ( kibble == NULL )
|
||
{
|
||
kibble = (Kibble *)MemAlloc ( sizeof ( Kibble ) * 512 );
|
||
ASSERT ( kibble != NULL );
|
||
}
|
||
ZeroMemory(kibble,( sizeof ( Kibble ) * 512 ) );
|
||
#else
|
||
ZeroMemory(kibble,sizeof(kibble));
|
||
#endif
|
||
|
||
for (c0=0,k=kibble;c0<densities[menu_theme];c0++,k++) FRONTEND_kibble_init_one(k,menu_theme+1);
|
||
}
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
void FRONTEND_kibble_destroy()
|
||
{
|
||
// Bin the kibble.
|
||
if ( kibble != NULL )
|
||
{
|
||
MemFree ( kibble );
|
||
kibble = NULL;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
void FRONTEND_kibble_flurry() {
|
||
UWORD n, c0, densities[4];
|
||
Kibble*k;
|
||
|
||
ASSERT ( kibble != NULL );
|
||
|
||
#ifndef TARGET_DC
|
||
if (SOFTWARE)
|
||
{
|
||
densities[0] = 50;
|
||
densities[1] = 200;
|
||
densities[2] = 50;
|
||
densities[3] = 10;
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
densities[0] = 125;
|
||
densities[1] = 512;
|
||
densities[2] = 125;
|
||
densities[3] = 10;
|
||
}
|
||
|
||
n=densities[menu_theme];
|
||
|
||
for (c0=0,k=kibble;c0<n;c0++,k++)
|
||
if (!k->type) {
|
||
switch(menu_theme) {
|
||
case 0:
|
||
FRONTEND_kibble_init_one(k,1|128);
|
||
k->dx=(25+(Random()&15))<<5;
|
||
k->x=(-60-(Random()&0xff))<<8;
|
||
k->y=(Random()%480)<<8;
|
||
k->size=5+(Random()&0x1f);
|
||
k->r=Random()&2047; k->t=Random()&2047;
|
||
k->rd=1+(Random()&7); k->td=1+(Random()&7);
|
||
//k->type|=128;
|
||
break;
|
||
case 1:
|
||
FRONTEND_kibble_init_one(k,2|128);
|
||
//k->type|=128;
|
||
break;
|
||
case 2:
|
||
FRONTEND_kibble_init_one(k,3|128);
|
||
//k->type|=128;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void FRONTEND_kibble_process() {
|
||
SLONG c0;
|
||
Kibble*k;
|
||
|
||
static SLONG last = 0;
|
||
static SLONG now = 0;
|
||
|
||
ASSERT ( kibble != NULL );
|
||
|
||
now = GetTickCount();
|
||
|
||
if (last < now - 250)
|
||
{
|
||
last = now - 250;
|
||
}
|
||
|
||
#ifndef FORCE_STUFF_PLEASE_BOB
|
||
if (now > last + 100)
|
||
{
|
||
//
|
||
// Front-end running at less than 10 fps! Turn off a random kibble!
|
||
//
|
||
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
kibble_off[rand() & 0x1ff] = TRUE;
|
||
}
|
||
else
|
||
if (now < last + 50)
|
||
{
|
||
//
|
||
// More than 20 fps...
|
||
//
|
||
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
kibble_off[rand() & 0x1ff] = FALSE;
|
||
}
|
||
#endif
|
||
|
||
SLONG i;
|
||
SLONG num_on;
|
||
|
||
for (i = 0, num_on = 0; i < 512; i++) {if (!kibble_off[i]) {num_on += 1;}}
|
||
|
||
while(last < now)
|
||
{
|
||
//
|
||
// Process at 40 frames a second.
|
||
//
|
||
|
||
last += 1000 / 40;
|
||
|
||
for (c0=0,k=kibble;c0<512;c0++,k++)
|
||
if (k->type>0) {
|
||
k->x+=k->dx; k->y+=k->dy;
|
||
k->r+=k->rd; k->t+=k->td;
|
||
k->r&=2047; k->t&=2047;
|
||
switch (k->type) {
|
||
case 1:
|
||
k->dy++;
|
||
k->dx++;
|
||
if ((k->y>>8)>240) k->dy-=Random()%((k->y-240)>>14);
|
||
// if ((k->x>>8)+k->size<10) FRONTEND_kibble_init_one(k,1);
|
||
if ((k->x>>8)-k->size>650) FRONTEND_kibble_init_one(k,1);
|
||
break;
|
||
case 129:
|
||
// if ((k->x>>8)<10) k->type=0;
|
||
if ((k->x>>8)-k->size>650) k->type=0;
|
||
case 3:
|
||
case 131:
|
||
{
|
||
SWORD x=k->x>>8, y=k->y>>8;
|
||
k->dx++;
|
||
if ((x>320)&&(x<480)) k->dx-=Random()%((k->x-320)>>14);
|
||
if ((y>240)&&(y<280)) k->dy-=Random()%((k->y-240)>>14);
|
||
}
|
||
case 2:
|
||
case 130:
|
||
if ((((k->x>>8)-k->size)>640)||(((k->y>>8)-k->size)>480))
|
||
if (k->type<128)
|
||
FRONTEND_kibble_init_one(k,k->type&127);
|
||
else
|
||
k->type=0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//--- filing stuff ---
|
||
|
||
void FRONTEND_fetch_title_from_id(CBYTE *script, CBYTE *ttl, UBYTE id) {
|
||
CBYTE *text;
|
||
SLONG ver;
|
||
MissionData *mdata = MFnew<MissionData>();
|
||
|
||
*ttl=0;
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
|
||
// Default value = no valid mission.
|
||
// This can happen when saving a game that has been fully completed -
|
||
// no next suggested mission.
|
||
strcpy ( ttl, "Urban Chaos" );
|
||
|
||
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
break; // ignore them for the moment.
|
||
}
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else {
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
|
||
if (mdata->ObjID==id) {
|
||
strcpy(ttl,mdata->ttl);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
MemFree(text);
|
||
MFdelete(mdata);
|
||
|
||
// Bin any trailing spaces.
|
||
char *pEnd = ttl + strlen ( ttl ) - 1;
|
||
while ( *pEnd == ' ' )
|
||
{
|
||
*pEnd = '\0';
|
||
pEnd--;
|
||
}
|
||
|
||
}
|
||
|
||
UBYTE best_found[50][4];
|
||
void init_best_found(void)
|
||
{
|
||
memset(&best_found[0][0],50*4,0);
|
||
}
|
||
|
||
|
||
#ifndef TARGET_DC
|
||
|
||
|
||
bool FRONTEND_save_savegame(CBYTE *mission_name, UBYTE slot) {
|
||
CBYTE fn[_MAX_PATH];
|
||
MFFileHandle file;
|
||
UBYTE version=3;
|
||
|
||
CreateDirectory("saves",NULL);
|
||
|
||
sprintf(fn,"saves\\slot%d.wag",slot);
|
||
file=FileCreate(fn,1);
|
||
FRONTEND_SaveString(file,mission_name);
|
||
FileWrite(file,&complete_point,1);
|
||
FileWrite(file,&version,1);
|
||
FileWrite(file,&the_game.DarciStrength,1);
|
||
FileWrite(file,&the_game.DarciConstitution,1);
|
||
FileWrite(file,&the_game.DarciSkill,1);
|
||
FileWrite(file,&the_game.DarciStamina,1);
|
||
FileWrite(file,&the_game.RoperStrength,1);
|
||
FileWrite(file,&the_game.RoperConstitution,1);
|
||
FileWrite(file,&the_game.RoperSkill,1);
|
||
FileWrite(file,&the_game.RoperStamina,1);
|
||
FileWrite(file,&the_game.DarciDeadCivWarnings,1);
|
||
// mark, if you add stuff again, please remember to inc. the version number
|
||
FileWrite(file,mission_hierarchy,60);
|
||
|
||
FileWrite(file,&best_found[0][0],50*4);
|
||
|
||
FileClose(file);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
bool FRONTEND_load_savegame(UBYTE slot) {
|
||
CBYTE fn[_MAX_PATH];
|
||
MFFileHandle file;
|
||
UBYTE version=0;
|
||
|
||
sprintf(fn,"saves\\slot%d.wag",slot);
|
||
file=FileOpen(fn);
|
||
FRONTEND_LoadString(file,fn);
|
||
FileRead(file,&complete_point,1);
|
||
FileRead(file,&version,1); // yes, i know, strange place to have version number.
|
||
// it's for Historical Reasons(tm).
|
||
if (version) {
|
||
FileRead(file,&the_game.DarciStrength,1);
|
||
FileRead(file,&the_game.DarciConstitution,1);
|
||
FileRead(file,&the_game.DarciSkill,1);
|
||
FileRead(file,&the_game.DarciStamina,1);
|
||
FileRead(file,&the_game.RoperStrength,1);
|
||
FileRead(file,&the_game.RoperConstitution,1);
|
||
FileRead(file,&the_game.RoperSkill,1);
|
||
FileRead(file,&the_game.RoperStamina,1);
|
||
FileRead(file,&the_game.DarciDeadCivWarnings,1);
|
||
}
|
||
if (version>1)
|
||
{
|
||
FileRead(file,mission_hierarchy,60);
|
||
}
|
||
if (version>2)
|
||
{
|
||
FileRead(file,&best_found[0][0],50*4);
|
||
}
|
||
FileClose(file);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void FRONTEND_find_savegames ( bool bGreyOutEmpties=FALSE, bool bCheckSaveSpace=FALSE )
|
||
{
|
||
CBYTE dir[_MAX_PATH],ttl[_MAX_PATH];
|
||
WIN32_FIND_DATA data;
|
||
HANDLE handle;
|
||
BOOL ok;
|
||
SLONG c0;
|
||
MenuData *md=menu_data;
|
||
CBYTE *str=menu_buffer;
|
||
SLONG x,y,y2=0;
|
||
FILETIME time, high_time={0,0};
|
||
|
||
for (c0=1;c0<11;c0++)
|
||
{
|
||
md->Type=OT_BUTTON;
|
||
//md->Data=0;
|
||
md->Data=FE_SAVE_CONFIRM;
|
||
// Not greyed.
|
||
md->Choices = (CBYTE*)0;
|
||
|
||
MFFileHandle file;
|
||
sprintf(dir,"saves\\slot%d.wag",c0);
|
||
file = FileOpen(dir);
|
||
GetFileTime(file,NULL,NULL,&time);
|
||
if (file!=FILE_OPEN_ERROR)
|
||
{
|
||
FRONTEND_LoadString(file,ttl);
|
||
FileClose(file);
|
||
}
|
||
else
|
||
{
|
||
strcpy(ttl,XLAT_str(X_EMPTY));
|
||
if ( bGreyOutEmpties )
|
||
{
|
||
// Grey this out then.
|
||
md->Choices = (CBYTE*)1;
|
||
}
|
||
}
|
||
sprintf(dir,"%d: %s",c0,ttl);
|
||
md->Label=str;
|
||
strcpy(str,ttl);
|
||
str+=strlen(str)+1;
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,BIG_FONT_SCALE);
|
||
md->X=320-(x>>1);
|
||
md->Y=y2;
|
||
y2+=50;
|
||
if (CompareFileTime(&time,&high_time)>0)
|
||
{
|
||
high_time = time;
|
||
menu_state.selected=menu_state.items;
|
||
}
|
||
md++;
|
||
menu_state.items++;
|
||
}
|
||
}
|
||
|
||
|
||
#else //#ifndef TARGET_DC
|
||
|
||
|
||
|
||
#define MAX_SIZE_SAVEGAME_FILES 1024
|
||
char m_pcSaveData[MAX_SIZE_SAVEGAME_FILES];
|
||
|
||
|
||
bool m_bLoadedIconSavePic = FALSE;
|
||
BYTE m_pcIconSavePicData[32*16];
|
||
WORD m_pcIconSavePicPalette[16];
|
||
|
||
|
||
// Set to 1 for utter madness.
|
||
#define NEED_A_SAVING_LOADING_MESSAGE 1
|
||
|
||
bool FRONTEND_save_savegame ( int iMissionID, UBYTE slot )
|
||
{
|
||
CBYTE fn[_MAX_PATH];
|
||
UBYTE version=4;
|
||
|
||
|
||
#if NEED_A_SAVING_LOADING_MESSAGE
|
||
// Display a QuickMessage.
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_SAVING ), 3000 );
|
||
|
||
// Then fake up a screen cycling so it gets displayed.
|
||
the_display.Flip ( NULL, DDFLIP_WAIT );
|
||
FRONTEND_display();
|
||
the_display.Flip ( NULL, DDFLIP_WAIT );
|
||
FRONTEND_display();
|
||
|
||
// Mark the time - wait for a second.
|
||
DWORD dwTimeout = timeGetTime() + 1000;
|
||
#endif
|
||
|
||
|
||
if ( iMissionID == -1 )
|
||
{
|
||
iMissionID = 255;
|
||
}
|
||
ASSERT ( ( iMissionID <= 255 ) && ( iMissionID >= 0 ) );
|
||
|
||
//sprintf(fn,"URBAN_%02i.SAV",slot);
|
||
//MUST be this format, according to Sega.
|
||
sprintf(fn,"UR_CHAOS.%03i",slot);
|
||
|
||
|
||
|
||
char *pcCurPtr;
|
||
DWORD dwSize;
|
||
|
||
#define DC_FILE_WRITE(data,size) memcpy ( (void*)pcCurPtr, (void *)(data), size ); pcCurPtr += (size); dwSize += (size)
|
||
|
||
pcCurPtr = m_pcSaveData;
|
||
dwSize = 0;
|
||
|
||
|
||
//file=FileCreate(fn,1);
|
||
DC_FILE_WRITE(&version,1);
|
||
DC_FILE_WRITE(&iMissionID,1);
|
||
DC_FILE_WRITE(&complete_point,1);
|
||
DC_FILE_WRITE(&the_game.DarciStrength,1);
|
||
DC_FILE_WRITE(&the_game.DarciConstitution,1);
|
||
DC_FILE_WRITE(&the_game.DarciSkill,1);
|
||
DC_FILE_WRITE(&the_game.DarciStamina,1);
|
||
DC_FILE_WRITE(&the_game.RoperStrength,1);
|
||
DC_FILE_WRITE(&the_game.RoperConstitution,1);
|
||
DC_FILE_WRITE(&the_game.RoperSkill,1);
|
||
DC_FILE_WRITE(&the_game.RoperStamina,1);
|
||
DC_FILE_WRITE(&the_game.DarciDeadCivWarnings,1);
|
||
// mark, if you add stuff again, please remember to inc. the version number
|
||
DC_FILE_WRITE(mission_hierarchy,60);
|
||
|
||
DC_FILE_WRITE(&best_found[0][0],50*4);
|
||
|
||
// Version 4+ stuff.
|
||
// Env save.
|
||
int iEnvSize = ENV_save ( pcCurPtr );
|
||
pcCurPtr += iEnvSize;
|
||
dwSize += iEnvSize;
|
||
|
||
|
||
ASSERT ( dwSize < MAX_SIZE_SAVEGAME_FILES );
|
||
|
||
// Save to the current VMU.
|
||
MapleVMU *pVMU = FindCurrentStorageVMU ( FALSE );
|
||
if ( pVMU != NULL )
|
||
{
|
||
// Use the mission name as a comment.
|
||
CBYTE ttl[_MAX_PATH];
|
||
ttl[0] = '\0';
|
||
FRONTEND_fetch_title_from_id(MISSION_SCRIPT,ttl,iMissionID);
|
||
|
||
if ( ttl[0] == '\0' )
|
||
{
|
||
// Oops. Use something sensible.
|
||
strcpy ( ttl, "Urban Chaos" );
|
||
}
|
||
|
||
#if NEED_A_SAVING_LOADING_MESSAGE
|
||
// Lock out the reset-on-door-open thing.
|
||
ChangeDoorResetStatus ( FALSE );
|
||
#endif
|
||
|
||
|
||
bool bRes = pVMU->Flash_WriteFile ( fn, "Urban Chaos", ttl, m_pcSaveData, dwSize, (char *)m_pcIconSavePicPalette, (char *)m_pcIconSavePicData );
|
||
|
||
|
||
#if NEED_A_SAVING_LOADING_MESSAGE
|
||
// Now wait for a second
|
||
// so that the user has time to read the "saving" message that will be
|
||
// obsolete by the time they read it. Bloody standards.
|
||
while ( TRUE )
|
||
{
|
||
if ( ( ( dwTimeout - timeGetTime() ) & 0x80000000 ) != 0 )
|
||
{
|
||
break;
|
||
}
|
||
TRACE ( "w" );
|
||
Sleep(100);
|
||
}
|
||
TRACE ( "\n" );
|
||
|
||
// Lock out the reset-on-door-open thing.
|
||
ChangeDoorResetStatus ( TRUE );
|
||
#endif
|
||
|
||
|
||
|
||
|
||
if ( bRes )
|
||
{
|
||
FRONTEND_show_VMU_screen ( pvmuscreenSaved );
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_SAVED ), 3000 );
|
||
}
|
||
else
|
||
{
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_SAVE_FAILED ), 3000 );
|
||
}
|
||
return bRes;
|
||
}
|
||
else
|
||
{
|
||
// Save failed - VMU not present, or VMU full or something.
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_SAVE_FAILED ), 3000 );
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
#ifdef DEBUG
|
||
ASSERT (FALSE);
|
||
// This is a debug rout to fill the VMU with junk, so we can test the "full VMU" action.
|
||
pVMU = FindFirstVMUOnCurrentController();
|
||
if ( pVMU != NULL )
|
||
{
|
||
CBYTE ttl[_MAX_PATH];
|
||
bool bRes = TRUE;
|
||
int iCount = 1;
|
||
while ( bRes )
|
||
{
|
||
sprintf ( fn, "junk%04i.xxx", iCount );
|
||
strcpy ( ttl, "Urban Chaos" );
|
||
bRes = pVMU->Flash_WriteFile ( fn, "Urban Chaos", ttl, m_pcSaveData, dwSize, NULL, NULL );
|
||
iCount++;
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
bool FRONTEND_load_savegame(UBYTE slot)
|
||
{
|
||
CBYTE fn[_MAX_PATH];
|
||
UBYTE version=0;
|
||
int iMissionID;
|
||
|
||
|
||
|
||
#if NEED_A_SAVING_LOADING_MESSAGE
|
||
// Display a QuickMessage.
|
||
ChangeDoorResetStatus ( FALSE );
|
||
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_LOADING ), 3000 );
|
||
|
||
// Then fake up a few screen cycles so it gets displayed.
|
||
the_display.Flip ( NULL, DDFLIP_WAIT );
|
||
FRONTEND_display();
|
||
the_display.Flip ( NULL, DDFLIP_WAIT );
|
||
FRONTEND_display();
|
||
|
||
// Mark the time - wait for a second.
|
||
DWORD dwTimeout = timeGetTime() + 1000;
|
||
|
||
#endif
|
||
|
||
|
||
//sprintf(fn,"URBAN_%02i.SAV",slot);
|
||
//MUST be this format, according to Sega.
|
||
sprintf(fn,"UR_CHAOS.%03i",slot);
|
||
|
||
|
||
MapleVMU *pVMU = FindCurrentStorageVMU ( FALSE );
|
||
if ( pVMU == NULL )
|
||
{
|
||
// No VMUs. Nadgers.
|
||
ASSERT ( FALSE );
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_LOAD_FAILED ), 3000 );
|
||
return FALSE;
|
||
}
|
||
|
||
bool bRes = pVMU->Flash_ReadFile ( fn, m_pcSaveData, MAX_SIZE_SAVEGAME_FILES );
|
||
|
||
|
||
#if NEED_A_SAVING_LOADING_MESSAGE
|
||
// Now wait for a second
|
||
// so that the user has time to read the "saving" message that will be
|
||
// obsolete by the time they read it. Bloody standards.
|
||
|
||
// No, don't ask me why we need to ensure game _loads_ succeed before ... um ... resetting the machine.
|
||
// Just fucking do it.
|
||
while ( TRUE )
|
||
{
|
||
if ( ( ( dwTimeout - timeGetTime() ) & 0x80000000 ) != 0 )
|
||
{
|
||
break;
|
||
}
|
||
TRACE ( "w" );
|
||
Sleep(100);
|
||
}
|
||
TRACE ( "\n" );
|
||
|
||
ChangeDoorResetStatus ( TRUE );
|
||
#endif
|
||
|
||
|
||
if ( !bRes )
|
||
{
|
||
// File doesn't exist, or VMU's been removed or something.
|
||
// Happens if the user slects an (EMPTY) file (though they shouldn't be able to).
|
||
ASSERT ( FALSE );
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_LOAD_FAILED ), 3000 );
|
||
return FALSE;
|
||
}
|
||
|
||
char *pcCurPtr;
|
||
|
||
#define DC_FILE_READ(data,size) memcpy ( (void*)(data), (void *)(pcCurPtr), size ); pcCurPtr += (size)
|
||
|
||
pcCurPtr = m_pcSaveData;
|
||
|
||
|
||
DC_FILE_READ(&version,1);
|
||
// Only v3 and above should exist for DC!
|
||
ASSERT ( version >= 3 );
|
||
|
||
DC_FILE_READ(&iMissionID,1);
|
||
DC_FILE_READ(&complete_point,1);
|
||
|
||
if ( version >= 1 )
|
||
{
|
||
DC_FILE_READ(&the_game.DarciStrength,1);
|
||
DC_FILE_READ(&the_game.DarciConstitution,1);
|
||
DC_FILE_READ(&the_game.DarciSkill,1);
|
||
DC_FILE_READ(&the_game.DarciStamina,1);
|
||
DC_FILE_READ(&the_game.RoperStrength,1);
|
||
DC_FILE_READ(&the_game.RoperConstitution,1);
|
||
DC_FILE_READ(&the_game.RoperSkill,1);
|
||
DC_FILE_READ(&the_game.RoperStamina,1);
|
||
DC_FILE_READ(&the_game.DarciDeadCivWarnings,1);
|
||
}
|
||
if ( version >= 2 )
|
||
{
|
||
DC_FILE_READ(mission_hierarchy,60);
|
||
}
|
||
if ( version >= 3 )
|
||
{
|
||
DC_FILE_READ(&best_found[0][0],50*4);
|
||
}
|
||
if ( version >= 4 )
|
||
{
|
||
// Load the environment vars.
|
||
// But preserve the language setting!
|
||
BYTE bLanguage = ENV_get_value_number ( "lang_num", 0, "" );
|
||
pcCurPtr = ENV_load ( pcCurPtr );
|
||
ENV_set_value_number ( "lang_num", bLanguage, "" );
|
||
}
|
||
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_GAME_LOADED ), 3000 );
|
||
return TRUE;
|
||
|
||
}
|
||
|
||
|
||
#define SIZE_OF_VMU_SAVE_FILE_IN_BLOCKS 2
|
||
|
||
void FRONTEND_find_savegames ( bool bGreyOutEmpties=FALSE, bool bCheckSaveSpace=FALSE )
|
||
{
|
||
CBYTE dir[_MAX_PATH];
|
||
CBYTE ttl[_MAX_PATH];
|
||
WIN32_FIND_DATA data;
|
||
HANDLE handle;
|
||
BOOL ok;
|
||
SLONG c0;
|
||
MenuData *md=menu_data;
|
||
CBYTE *str=menu_buffer;
|
||
SLONG x,y,y2=0;
|
||
FILETIME time, high_time={0,0};
|
||
int iBestMissionIDSoFar = -2;
|
||
int iBestMissionIDSoFarPosition = -1;
|
||
|
||
menu_state.selected = 0;
|
||
|
||
|
||
int iBigFontScale = BIG_FONT_SCALE;
|
||
if ( !IsEnglish )
|
||
{
|
||
iBigFontScale = BIG_FONT_SCALE_FRENCH;
|
||
}
|
||
|
||
|
||
|
||
bool bSomethingChanged = TRUE;
|
||
while ( bSomethingChanged )
|
||
{
|
||
bSomethingChanged = RescanDevices();
|
||
if ( bSomethingChanged )
|
||
{
|
||
// Delete any removed devices.
|
||
DeleteInvalidDevice();
|
||
}
|
||
}
|
||
|
||
// Find the current VMU.
|
||
MapleVMU *pVMU = FindCurrentStorageVMU ( TRUE );
|
||
// And actually set whichever was found to be the current one.
|
||
SetCurrentStorageVMU ( pVMU );
|
||
|
||
bool bMarkEmptiesAsVMUFull = FALSE;
|
||
if ( bCheckSaveSpace && ( pVMU != NULL ) )
|
||
{
|
||
// Check how much space is on this VMU.
|
||
int iFreeBlocks = pVMU->Flash_GetFreeBlocks();
|
||
if ( iFreeBlocks < SIZE_OF_VMU_SAVE_FILE_IN_BLOCKS )
|
||
{
|
||
// No - not enough space - grey out the empty slots.
|
||
bMarkEmptiesAsVMUFull = TRUE;
|
||
}
|
||
}
|
||
|
||
int iFirstBlankSlot = -1;
|
||
|
||
// If pVMU is NULL, it will be dealt with below.
|
||
if ( pVMU == NULL )
|
||
{
|
||
md->Type=OT_BUTTON;
|
||
//md->Data=0;
|
||
md->Data=FE_SAVE_CONFIRM;
|
||
// Just one entry.
|
||
strcpy(str,XLAT_str(X_VMU_NOT_PRESENT));
|
||
// Grey this out.
|
||
md->Choices = (CBYTE*)1;
|
||
md->Label=str;
|
||
str+=strlen(str)+1;
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,iBigFontScale);
|
||
md->X=320-(x>>1);
|
||
md->Y=y2;
|
||
y2+=50;
|
||
|
||
md++;
|
||
menu_state.items++;
|
||
|
||
// And select the item _after_ which will be "select VMU"
|
||
menu_state.selected=menu_state.items;
|
||
}
|
||
else
|
||
{
|
||
bool bSetSelected = FALSE;
|
||
for (c0=1;c0<11;c0++)
|
||
{
|
||
md->Type=OT_BUTTON;
|
||
//md->Data=0;
|
||
md->Data=FE_SAVE_CONFIRM;
|
||
// Not greyed.
|
||
md->Choices = (CBYTE*)0;
|
||
md->LabelID = 0;
|
||
|
||
//sprintf(dir,"URBAN_%02i.SAV",c0);
|
||
//MUST be this format, according to Sega.
|
||
sprintf(dir,"UR_CHAOS.%03i",c0);
|
||
|
||
|
||
// NOTE! -1 is a perfectly good value - it means all missions have been done.
|
||
BYTE bMissionID = -2;
|
||
if ( pVMU != NULL )
|
||
{
|
||
bool bRes = pVMU->Flash_ReadFile ( dir, m_pcSaveData, MAX_SIZE_SAVEGAME_FILES );
|
||
if ( bRes )
|
||
{
|
||
char *pcCurPtr;
|
||
|
||
//#define DC_FILE_READ(data,size) memcpy ( (void*)(data), (void *)(pcCurPtr), size ); pcCurPtr += (size); dwSize += (size)
|
||
|
||
pcCurPtr = m_pcSaveData;
|
||
|
||
|
||
BYTE version;
|
||
DC_FILE_READ(&version,1);
|
||
// Only v3 and above should exist for DC!
|
||
ASSERT ( version >= 3 );
|
||
|
||
DC_FILE_READ(&bMissionID,1);
|
||
|
||
// Don't need the rest...
|
||
}
|
||
if ( bMissionID == (BYTE)-2 )
|
||
{
|
||
// Failed for some reason.
|
||
strcpy(ttl,XLAT_str(X_EMPTY));
|
||
|
||
// Indicate that there is no existing game.
|
||
md->Data=FE_MAPSCREEN;
|
||
|
||
if ( bGreyOutEmpties || bMarkEmptiesAsVMUFull )
|
||
{
|
||
// Grey this out then.
|
||
md->Choices = (CBYTE*)1;
|
||
if ( bMarkEmptiesAsVMUFull )
|
||
{
|
||
// And change the words to VMU FULL
|
||
strcpy(ttl,XLAT_str(X_VMU_FULL));
|
||
md->LabelID = X_VMU_FULL;
|
||
}
|
||
}
|
||
else if ( iFirstBlankSlot == -1 )
|
||
{
|
||
iFirstBlankSlot = menu_state.items;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FRONTEND_fetch_title_from_id(MISSION_SCRIPT,ttl,bMissionID);
|
||
if ( ttl[0] == '\0' )
|
||
{
|
||
// Oops. Use something sensible.
|
||
strcpy ( ttl, "Urban Chaos" );
|
||
}
|
||
}
|
||
}
|
||
|
||
//sprintf(dir,"%d: %s",c0,ttl);
|
||
md->Label=str;
|
||
strcpy(str,ttl);
|
||
str+=strlen(str)+1;
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,iBigFontScale);
|
||
md->X=320-(x>>1);
|
||
md->Y=y2;
|
||
y2+=50;
|
||
#if 0
|
||
if (CompareFileTime(&time,&high_time)>0)
|
||
{
|
||
high_time = time;
|
||
bSetSelected = TRUE;
|
||
menu_state.selected=menu_state.items;
|
||
}
|
||
#else
|
||
if ( bMissionID != (BYTE)-2 )
|
||
{
|
||
if ( bGreyOutEmpties )
|
||
{
|
||
// Loading, so pick the _highest_ mission number.
|
||
if ( ( bMissionID > iBestMissionIDSoFar ) || ( bMissionID == (BYTE)-1 ) )
|
||
{
|
||
iBestMissionIDSoFarPosition = menu_state.items;
|
||
iBestMissionIDSoFar = bMissionID;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Saving, so pick the _lowest_ mission number.
|
||
if ( bMissionID < iBestMissionIDSoFar )
|
||
{
|
||
iBestMissionIDSoFarPosition = menu_state.items;
|
||
iBestMissionIDSoFar = bMissionID;
|
||
}
|
||
}
|
||
bSetSelected = TRUE;
|
||
menu_state.selected=menu_state.items;
|
||
}
|
||
#endif
|
||
|
||
md++;
|
||
menu_state.items++;
|
||
}
|
||
if ( !bSetSelected )
|
||
{
|
||
// Nothing valid - select the "select VMU" option at the bottom that
|
||
// hasn't been added yet, but will be.
|
||
menu_state.selected=menu_state.items;
|
||
}
|
||
else
|
||
{
|
||
if ( iBestMissionIDSoFarPosition != -1 )
|
||
{
|
||
menu_state.selected = iBestMissionIDSoFarPosition;
|
||
}
|
||
}
|
||
|
||
if ( iFirstBlankSlot != -1 )
|
||
{
|
||
// There was a valid first blank slot, and we can select it. So do so by default.
|
||
menu_state.selected = iFirstBlankSlot;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// Hack hack hackety hack.
|
||
UBYTE m_ubVMUListCtrl[8];
|
||
UBYTE m_ubVMUListSlot[8];
|
||
|
||
|
||
// Build the menu of VMU slots.
|
||
void FRONTEND_find_VMUs ( void )
|
||
{
|
||
CBYTE ttl[_MAX_PATH];
|
||
WIN32_FIND_DATA data;
|
||
HANDLE handle;
|
||
BOOL ok;
|
||
SLONG c0;
|
||
MenuData *md=menu_data;
|
||
CBYTE *str=menu_buffer;
|
||
SLONG x,y,y2=0;
|
||
FILETIME time, high_time={0,0};
|
||
|
||
menu_state.selected = 0;
|
||
|
||
bool bSomethingChanged = TRUE;
|
||
while ( bSomethingChanged )
|
||
{
|
||
bSomethingChanged = RescanDevices();
|
||
if ( bSomethingChanged )
|
||
{
|
||
// Delete any removed devices.
|
||
DeleteInvalidDevice();
|
||
}
|
||
}
|
||
|
||
MapleVMU *pvmuCurrent = FindCurrentStorageVMU ( TRUE );
|
||
|
||
|
||
// Find the VMUs connected.
|
||
int iNumVMUsTotal = 0;
|
||
for ( int iCtrlNum = 0; iCtrlNum < 4; iCtrlNum++ )
|
||
{
|
||
for ( int iVMUNum = 0; iVMUNum < 2; iVMUNum++ )
|
||
{
|
||
// See if this VMU slot exists/is filled.
|
||
extern MapleVMU *FindMemoryVMUAt ( int iCtrlNum, int iVMUNum );
|
||
MapleVMU *pVMU = FindMemoryVMUAt ( iCtrlNum, iVMUNum );
|
||
|
||
if ( pVMU != NULL )
|
||
{
|
||
iNumVMUsTotal++;
|
||
|
||
md->Type=OT_BUTTON;
|
||
md->Data=FE_MAINMENU; // Special marker.
|
||
// Not greyed.
|
||
md->Choices = (CBYTE*)0;
|
||
md->Label=str;
|
||
|
||
strcpy(ttl,XLAT_str(X_VMU_CONTROLLER_SLOT));
|
||
sprintf ( str, ttl, "ABCD"[iCtrlNum], "12"[iVMUNum] );
|
||
str+=strlen(str)+1;
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,BIG_FONT_SCALE);
|
||
md->X=320-(x>>1);
|
||
md->Y=y2;
|
||
y2+=50;
|
||
|
||
if ( pvmuCurrent == pVMU )
|
||
{
|
||
// Set the current one.
|
||
menu_state.selected=menu_state.items;
|
||
}
|
||
|
||
m_ubVMUListCtrl[menu_state.items] = iCtrlNum;
|
||
m_ubVMUListSlot[menu_state.items] = iVMUNum;
|
||
|
||
md++;
|
||
menu_state.items++;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( iNumVMUsTotal == 0 )
|
||
{
|
||
// Tell the user that there are no vmus around.
|
||
md->Type=OT_BUTTON;
|
||
md->Data=FE_BACK;
|
||
// Greyed out.
|
||
md->Choices = (CBYTE*)1;
|
||
md->Label=str;
|
||
|
||
strcpy(str,XLAT_str(X_VMU_NOT_PRESENT));
|
||
str+=strlen(str)+1;
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,BIG_FONT_SCALE);
|
||
md->X=320-(x>>1);
|
||
md->Y=y2;
|
||
y2+=50;
|
||
|
||
md++;
|
||
menu_state.items++;
|
||
|
||
// Make the Cancel the default item.
|
||
menu_state.selected=menu_state.items;
|
||
|
||
|
||
}
|
||
|
||
FRONTEND_recenter_menu();
|
||
}
|
||
|
||
#endif //#else //#ifndef TARGET_DC
|
||
|
||
|
||
|
||
|
||
CBYTE* FRONTEND_MissionFilename(CBYTE *script, UBYTE i) {
|
||
MFFileHandle file;
|
||
CBYTE *text, *str=menu_buffer;
|
||
SLONG ver;
|
||
MissionData *mdata = MFnew<MissionData>();
|
||
MenuData *md=menu_data;
|
||
SLONG x,y,y2=0;
|
||
|
||
*str=0;
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
|
||
i++;
|
||
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
break; // ignore them for the moment.
|
||
}
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else {
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
|
||
if (mdata->District==districts[district_selected][2])
|
||
{
|
||
//
|
||
// Only missions available to play are put in the
|
||
// list nowadays...
|
||
//
|
||
|
||
if (mission_hierarchy[mdata->ObjID] & 4)
|
||
{
|
||
i--;
|
||
}
|
||
}
|
||
if (!i) {
|
||
strcpy(str,mdata->fn);
|
||
mission_launch=mdata->ObjID;
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
MemFree(text);
|
||
MFdelete(mdata);
|
||
|
||
return str;
|
||
|
||
}
|
||
|
||
void FRONTEND_MissionHierarchy(CBYTE *script) {
|
||
MFFileHandle file;
|
||
SLONG best_score;
|
||
CBYTE *text;
|
||
SLONG ver;
|
||
MissionData *mdata = MFnew<MissionData>();
|
||
MenuData *md=menu_data;
|
||
UBYTE i=0, j, flag;
|
||
UBYTE newtheme;
|
||
|
||
bonus_this_turn = 0;
|
||
|
||
// this is always called whenever the complete_point changes, soooo...
|
||
newtheme=3;
|
||
if (complete_point<24) newtheme=2;
|
||
if (complete_point<16) newtheme=1;
|
||
if (complete_point<8) newtheme=0;
|
||
if (newtheme!=menu_theme) {
|
||
|
||
menu_theme = newtheme;
|
||
|
||
FRONTEND_scr_new_theme(
|
||
menu_back_names [menu_theme],
|
||
menu_map_names [menu_theme],
|
||
menu_brief_names [menu_theme],
|
||
menu_config_names[menu_theme]);
|
||
|
||
switch(menu_state.mode) {
|
||
case FE_MAINMENU:
|
||
//InitBackImage(menu_back_names[menu_theme]);
|
||
|
||
UseBackSurface(screenfull_back);
|
||
|
||
break;
|
||
case FE_CONFIG:
|
||
case FE_CONFIG_VIDEO:
|
||
case FE_CONFIG_AUDIO:
|
||
case FE_CONFIG_OPTIONS:
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
case FE_CONFIG_INPUT_KB:
|
||
#endif
|
||
case FE_CONFIG_INPUT_JP:
|
||
case FE_LOADSCREEN:
|
||
case FE_SAVESCREEN:
|
||
#ifdef TARGET_DC
|
||
case FE_VMU_SELECT:
|
||
#endif
|
||
//InitBackImage(menu_config_names[menu_theme]);
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
UseBackSurface(screenfull_back);
|
||
#else
|
||
UseBackSurface(screenfull_config);
|
||
#endif
|
||
break;
|
||
case FE_MAPSCREEN:
|
||
//InitBackImage(menu_map_names[menu_theme]);
|
||
UseBackSurface(screenfull_map);
|
||
break;
|
||
default:
|
||
UseBackSurface(screenfull_brief);
|
||
//InitBackImage(menu_brief_names[menu_theme]);
|
||
}
|
||
FRONTEND_kibble_init();
|
||
}
|
||
|
||
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
|
||
// ZeroMemory(mission_hierarchy,sizeof(mission_hierarchy));
|
||
ZeroMemory(district_valid,sizeof(district_valid));
|
||
mission_hierarchy[1]=3; // the root; 1 - exists, 2 - complete, 4 - waiting
|
||
|
||
#ifdef ANNOYING_HACK_FOR_SIMON
|
||
|
||
// this hack does an end run around the hierarchy system
|
||
// it forces fight1, assault1, & testdrive1a (the bronze fighting, driving test and
|
||
// assault course) to be complete before allowing police1 to open up
|
||
|
||
SLONG fightID = -1, assaultID = -1, testdriveID = -1, policeID = -1, fight2ID = -1, testdrive3ID = -1;
|
||
SLONG bonusID1 = -1, bonusID2 = -1, bonusID3 = -1;
|
||
SLONG secretIDbreakout = -1, estateID = -1;
|
||
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') break;
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else
|
||
{
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
|
||
_strlwr(mdata->fn);
|
||
|
||
if (strstr(mdata->fn,"ftutor1.ucm"))
|
||
{
|
||
fightID=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"assault1.ucm"))
|
||
{
|
||
assaultID=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"testdrive1a.ucm"))
|
||
{
|
||
testdriveID=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"police1.ucm"))
|
||
{
|
||
policeID=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"fight2.ucm"))
|
||
{
|
||
fight2ID=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"testdrive3.ucm"))
|
||
{
|
||
testdrive3ID=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"gangorder1.ucm"))
|
||
{
|
||
bonusID1=mdata->ObjID;
|
||
}
|
||
if (strstr(mdata->fn,"gangorder2.ucm"))
|
||
{
|
||
bonusID2=mdata->ObjID;
|
||
}
|
||
if (strstr(mdata->fn,"bankbomb1.ucm"))
|
||
{
|
||
bonusID3=mdata->ObjID;
|
||
}
|
||
|
||
if (strstr(mdata->fn,"estate2.ucm"))
|
||
{
|
||
estateID=mdata->ObjID;
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
if (strstr(mdata->fn,"album1.ucm"))
|
||
{
|
||
// Breakout! - a secret mission.
|
||
secretIDbreakout = mdata->ObjID;
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
ASSERT(WITHIN(fightID , 0, 39));
|
||
ASSERT(WITHIN(fight2ID , 0, 39));
|
||
ASSERT(WITHIN(assaultID , 0, 39));
|
||
ASSERT(WITHIN(testdriveID , 0, 39));
|
||
ASSERT(WITHIN(testdrive3ID, 0, 39));
|
||
ASSERT(WITHIN(policeID , 0, 39));
|
||
ASSERT(WITHIN(bonusID1 , 0, 39));
|
||
ASSERT(WITHIN(bonusID2 , 0, 39));
|
||
ASSERT(WITHIN(bonusID3 , 0, 39));
|
||
ASSERT(WITHIN(estateID , 0, 39));
|
||
#ifdef TARGET_DC
|
||
ASSERT(WITHIN(secretIDbreakout, 0, 39));
|
||
#endif
|
||
|
||
#endif
|
||
|
||
#if 0
|
||
best_score = -INFINITY;
|
||
#else
|
||
best_score = 1000;
|
||
#endif
|
||
district_flash = -1;
|
||
district_selected = 0;
|
||
#ifdef TARGET_DC
|
||
iNextSuggestedMission = -1;
|
||
#endif
|
||
|
||
|
||
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
break; // ignore them for the moment.
|
||
}
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else {
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
|
||
flag=mission_hierarchy[mdata->ObjID]|1; // exists
|
||
|
||
// this dodgy method is no longer used, cos it sucks.
|
||
// if (mdata->ObjID<=complete_point) flag|=2; // complete
|
||
// instead, the entire hierarchy is preserved in savegames and
|
||
// completing a mission sets the appropriate flag. ie, the proper way.
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// If Estate of Emergency has been done, and the secret environment var is set, then
|
||
// expose Breakout to the world....
|
||
// Also, you have to be playing in English. Sorry.
|
||
if ( IsEnglish && ( ( mission_hierarchy[estateID] & 2 ) != 0 ) && ENV_get_value_number ( "cheat_driving_bronze", 0, "" ) )
|
||
{
|
||
// Hurrah!
|
||
mission_hierarchy[secretIDbreakout] |= 4;
|
||
}
|
||
else
|
||
{
|
||
// Nope - not yet.
|
||
mission_hierarchy[secretIDbreakout] = 0;
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
#ifndef VERSION_DEMO
|
||
if (mission_hierarchy[mdata->ParentID]&2)
|
||
#endif
|
||
{
|
||
#ifndef VERSION_DEMO
|
||
if (mdata->ObjID == fight2ID && menu_theme < 1)
|
||
{
|
||
//
|
||
// Ignore this mission until the first theme...
|
||
//
|
||
}
|
||
else
|
||
if (mdata->ObjID == testdrive3ID && menu_theme < 2)
|
||
{
|
||
//
|
||
// Ignore this mission until the last theme...
|
||
//
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
for (j=0;j<40;j++) {
|
||
if (districts[j][2]==mdata->District) {
|
||
district_valid[j]|=1;
|
||
if ( !(mission_hierarchy[mdata->ObjID]&2) &&
|
||
(mission_hierarchy[mdata->ObjID]&4) )
|
||
{
|
||
district_valid[j]|=2; // highlight zones with ready missions
|
||
}
|
||
|
||
/*
|
||
|
||
if ((!district_valid[district_selected])||(mdata->ObjID==complete_point+1))
|
||
{
|
||
district_flash=district_selected=j;
|
||
|
||
// there's a good chance this is the mission we wanna attempt now
|
||
}
|
||
|
||
*/
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
flag|=4; // available
|
||
}
|
||
}
|
||
|
||
#ifdef ANNOYING_HACK_FOR_SIMON
|
||
if (mdata->ObjID==policeID) {
|
||
if ( (mission_hierarchy[fightID]&2)
|
||
&&(mission_hierarchy[assaultID]&2)
|
||
&&(mission_hierarchy[testdriveID]&2))
|
||
flag|=4;
|
||
else
|
||
{
|
||
flag&=~4;
|
||
|
||
//
|
||
// Search for the district for this mission.
|
||
//
|
||
|
||
for (j = 0; j < 40; j++)
|
||
{
|
||
if (districts[j][2] == mdata->District)
|
||
{
|
||
district_valid[j] = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
if (complete_point>=40) // bodge!
|
||
flag|=2;
|
||
|
||
mission_hierarchy[mdata->ObjID]=flag;
|
||
|
||
if ((flag & 4) && !(flag & 2)) // 4 means available and 2 means complete
|
||
{
|
||
//
|
||
// This mission is active. Where abouts is it in the suggest_order[].
|
||
// The later it is in the suggest order, the later the mission is.
|
||
//
|
||
#ifndef VERSION_DEMO
|
||
if ((mdata->ObjID==bonusID1)&&!(bonus_state & 1))
|
||
{
|
||
bonus_state|=1;
|
||
bonus_this_turn = 1;
|
||
}
|
||
if ((mdata->ObjID==bonusID2)&&!(bonus_state & 2))
|
||
{
|
||
bonus_state|=2;
|
||
bonus_this_turn = 1;
|
||
}
|
||
if ((mdata->ObjID==bonusID3)&&!(bonus_state & 4))
|
||
{
|
||
bonus_state|=4;
|
||
bonus_this_turn = 1;
|
||
}
|
||
#endif
|
||
SLONG order = 0;
|
||
|
||
while(1)
|
||
{
|
||
if (stricmp(mdata->fn, suggest_order[order]) == 0)
|
||
{
|
||
//
|
||
// Found the mission!
|
||
//
|
||
|
||
#if 0
|
||
// No, this is selecting them in the wrong order.
|
||
if (order > best_score)
|
||
#else
|
||
if (order < best_score)
|
||
#endif
|
||
{
|
||
best_score = order;
|
||
#ifdef TARGET_DC
|
||
// For the savegame.
|
||
iNextSuggestedMission = mdata->ObjID;
|
||
#endif
|
||
|
||
//
|
||
// Find which district has this id.
|
||
//
|
||
|
||
for (j = 0; j < 40; j++)
|
||
{
|
||
if (districts[j][2] == mdata->District)
|
||
{
|
||
district_flash = j;
|
||
district_selected = j;
|
||
|
||
goto found_mission;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
order += 1;
|
||
|
||
if (suggest_order[order][0] == '!')
|
||
{
|
||
break;
|
||
}
|
||
|
||
found_mission:;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
|
||
#if 0
|
||
if ( !IsEnglish )
|
||
{
|
||
// Never show breakout in French.
|
||
mission_hierarchy[secretIDbreakout] = 0;
|
||
}
|
||
#else
|
||
|
||
// If Estate of Emergency has been done, and the secret environment var is set, then
|
||
// expose Breakout to the world....
|
||
// Also, you have to be playing in English. Sorry.
|
||
if ( IsEnglish && ( ( mission_hierarchy[estateID] & 2 ) != 0 ) && ENV_get_value_number ( "cheat_driving_bronze", 0, "" ) )
|
||
{
|
||
// Hurrah!
|
||
mission_hierarchy[secretIDbreakout] |= 4;
|
||
}
|
||
else
|
||
{
|
||
// Nope - not yet.
|
||
mission_hierarchy[secretIDbreakout] = 0;
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
MemFree(text);
|
||
MFdelete(mdata);
|
||
}
|
||
|
||
CBYTE *brief_wav[]=
|
||
{
|
||
"none", //0
|
||
"none", //1
|
||
"none", //2
|
||
"none", //3
|
||
"none", //4
|
||
"none", //5
|
||
"policem1.wav", //6
|
||
"policem.wav", //7
|
||
"policem.wav", //8
|
||
"policem2.wav", //9
|
||
"none", //10
|
||
"none", //11
|
||
"policem3.wav", //12
|
||
"none", //13
|
||
"policem4.wav", //14
|
||
"policem5.wav", //15
|
||
"policem6.wav", //16
|
||
"policem7.wav", //17
|
||
"policem8.wav", //18
|
||
"policem9.wav", //19
|
||
"policem10.wav", //20
|
||
"policem11.wav", //21
|
||
"policem12.wav", //22
|
||
"policem13.wav", //23
|
||
"policem14.wav", //24
|
||
"policem15.wav", //25
|
||
"policem16.wav", //26
|
||
"policem17.wav", //27
|
||
"policem18.wav", //28
|
||
"roperm19.wav", //29
|
||
"roperm20.wav", //30
|
||
"roperm21.wav", //31
|
||
// "roperm22.wav", //32
|
||
"roperm23.wav", //33
|
||
"roperm24.wav", //34
|
||
""
|
||
|
||
};
|
||
void FRONTEND_MissionBrief(CBYTE *script, UBYTE i) {
|
||
MFFileHandle file;
|
||
CBYTE *text, *str=menu_buffer;
|
||
SLONG ver;
|
||
MissionData *mdata = MFnew<MissionData>();
|
||
MenuData *md=menu_data;
|
||
SLONG x,y,y2=0;
|
||
|
||
*str=0;
|
||
i++;
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
|
||
MUSIC_mode(0);
|
||
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
break; // ignore them for the moment.
|
||
}
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else {
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
|
||
if (mdata->District==districts[district_selected][2])
|
||
{
|
||
//
|
||
// Only missions available to play are put in the
|
||
// list nowadays...
|
||
//
|
||
|
||
if (mission_hierarchy[mdata->ObjID] & 4)
|
||
{
|
||
i--;
|
||
}
|
||
}
|
||
|
||
if (!i) {
|
||
strcpy(str,mdata->brief);
|
||
str+=strlen(str)+1;
|
||
strcpy(str,mdata->ttl);
|
||
menu_state.title=str;
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
MemFree(text);
|
||
|
||
if ( ( mdata->ObjID ) && ( mdata->ObjID<34 ) &&
|
||
( 0 != strcmp ( brief_wav[mdata->ObjID], "none" ) ) )
|
||
{
|
||
CBYTE path[_MAX_PATH];
|
||
//MFX_QUICK_wait();
|
||
strcpy(path,GetSpeechPath());
|
||
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
strcat(path,pcSpeechLanguageDir);
|
||
#else
|
||
// On PC it's always talk2.
|
||
strcat ( path, "talk2\\" );
|
||
#endif
|
||
strcat(path,brief_wav[mdata->ObjID]);
|
||
|
||
MFX_QUICK_play(path, FALSE);
|
||
|
||
// And hang until the thing has actually started playing.
|
||
// Or five seconds, whichever is shorter.
|
||
// The seek time can be really quite high.
|
||
// NOTE! Some of them don't have briefings, so watch it!
|
||
// Things seem to hang nastily if we don't let the briefing happen.
|
||
// Fuck knows why, and I can't get it when debugging, only when
|
||
// emulating a real disk. Which sucks quite badly.
|
||
DWORD dwTimeout = timeGetTime() + 5000;
|
||
while ( TRUE )
|
||
{
|
||
extern bool DCLL_stream_has_started_streaming ( void );
|
||
if ( DCLL_stream_has_started_streaming() )
|
||
{
|
||
break;
|
||
}
|
||
if ( ( ( dwTimeout - timeGetTime() ) & 0x80000000 ) != 0 )
|
||
{
|
||
// Timeout!
|
||
TRACE ( "TIMEOUT!" );
|
||
break;
|
||
}
|
||
TRACE ( "w" );
|
||
Sleep(100);
|
||
}
|
||
TRACE ( "w\n" );
|
||
|
||
//
|
||
// Set the MEMSTREAM volume to the music volume.
|
||
//
|
||
|
||
//extern void MFX_play_at_stream_volume(UWORD, ULONG, ULONG);
|
||
|
||
//MFX_play_at_stream_volume(0, S_FRONT_END_LOOP_EDIT, MFX_LOOPED);
|
||
|
||
|
||
#if 1
|
||
// And then wait for half a second anyway, just in case.
|
||
dwTimeout = timeGetTime() + 500;
|
||
while ( TRUE )
|
||
{
|
||
if ( ( ( dwTimeout - timeGetTime() ) & 0x80000000 ) != 0 )
|
||
{
|
||
break;
|
||
}
|
||
TRACE ( "W" );
|
||
Sleep(100);
|
||
}
|
||
TRACE ( "W\n" );
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
// No briefing - stop the normal music.
|
||
MFX_QUICK_stop();
|
||
}
|
||
|
||
|
||
MFdelete(mdata);
|
||
|
||
|
||
DCLL_memstream_play();
|
||
|
||
}
|
||
|
||
|
||
void FRONTEND_MissionList(CBYTE *script, UBYTE district) {
|
||
/* MFFileHandle file;
|
||
CBYTE *text, *str=menu_buffer;
|
||
SLONG ver;
|
||
MissionData *mdata = MFnew<MissionData>();
|
||
// MenuData *md=menu_data;
|
||
// SLONG x,y,y2=0;
|
||
// UBYTE i=100;
|
||
|
||
//district--;
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
mission_count=mission_selected=0;
|
||
file = FileOpen(script);
|
||
while (1) {
|
||
FRONTEND_LoadString(file,text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
break; // ignore them for the moment.
|
||
}
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else {
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
if (mdata->District==district) {
|
||
*str=mdata->ObjID; str++;
|
||
strcpy(str,mdata->ttl);
|
||
str+=strlen(mdata->ttl)+1;
|
||
mission_count++;
|
||
}
|
||
|
||
}
|
||
}
|
||
FileClose(file);
|
||
|
||
MemFree(text);
|
||
MFdelete(mdata);
|
||
*/
|
||
UBYTE i=0;
|
||
CBYTE *str=menu_buffer;
|
||
|
||
mission_count=mission_selected=0;
|
||
|
||
while (*mission_cache[i].name)
|
||
{
|
||
if (mission_cache[i].district == district)
|
||
{
|
||
if (mission_hierarchy[mission_cache[i].id] & 4)
|
||
{
|
||
//
|
||
// This mission is available to play.
|
||
//
|
||
|
||
mission_selected = mission_count;
|
||
|
||
//
|
||
// First byte is the mission ID
|
||
//
|
||
|
||
*str++ = mission_cache[i].id;
|
||
|
||
//
|
||
// Then comes the mission name.
|
||
//
|
||
|
||
strcpy(str,mission_cache[i].name);
|
||
|
||
str+=strlen(mission_cache[i].name)+1;
|
||
|
||
mission_count++;
|
||
}
|
||
}
|
||
|
||
i++;
|
||
}
|
||
|
||
/*
|
||
|
||
//
|
||
// Default to selecting the last available mission.
|
||
//
|
||
|
||
mission_selected = mission_count - 1;
|
||
|
||
if (mission_selected < 0)
|
||
{
|
||
mission_selected = 0;
|
||
}
|
||
|
||
*/
|
||
}
|
||
|
||
void FRONTEND_CacheMissionList(CBYTE *script) {
|
||
MFFileHandle file;
|
||
CBYTE *text, *str;
|
||
SLONG ver;
|
||
MissionData *mdata = MFnew<MissionData>();
|
||
UBYTE i=0;
|
||
|
||
//district--;
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
break; // ignore them for the moment.
|
||
}
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
} else {
|
||
FRONTEND_ParseMissionData(text,ver,mdata);
|
||
mission_cache[i].district=mdata->District;
|
||
mission_cache[i].id=mdata->ObjID;
|
||
strcpy(mission_cache[i].name,mdata->ttl);
|
||
i++;
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
MemFree(text);
|
||
MFdelete(mdata);
|
||
|
||
//*mission_cache[i].name=0;
|
||
|
||
}
|
||
|
||
|
||
void FRONTEND_districts(CBYTE *script) {
|
||
MFFileHandle file;
|
||
CBYTE *text, *str=menu_buffer;
|
||
SLONG ver, mapx=0, mapy=0;
|
||
MenuData *md=menu_data;
|
||
SLONG x,y;
|
||
UBYTE i=0,ct,index=0;
|
||
SWORD temp_dist[40][3];
|
||
UBYTE crap_remap[640][10];
|
||
|
||
text = (CBYTE*)MemAlloc(4096);
|
||
memset(text,0,4096);
|
||
|
||
district_count=0;
|
||
//district_selected=0;
|
||
ZeroMemory(crap_remap,sizeof(crap_remap));
|
||
|
||
FileOpenScript();
|
||
while (1) {
|
||
LoadStringScript(text);
|
||
if (*text==0) break;
|
||
if (text[0]=='[') { // we've hit the districts
|
||
i=1;
|
||
} else {
|
||
if (i) {
|
||
ct=sscanf(text,"%[^=]=%d,%d",str,&mapx,&mapy);
|
||
if (strlen(str)&&mapx&&mapy&&(ct==3)) {
|
||
temp_dist[district_count][0]=mapx-16;
|
||
temp_dist[district_count][1]=mapy-32;
|
||
temp_dist[district_count][2]=index;
|
||
crap_remap[mapx][0]++;
|
||
crap_remap[mapx][ crap_remap[mapx][0] ]=district_count;
|
||
//districts[district_count][0]=mapx;
|
||
//districts[district_count][1]=mapy;
|
||
district_count++;
|
||
}
|
||
index++;
|
||
} else
|
||
if ((text[0]=='/')&&(text[1]=='/')) {
|
||
if (strstr(text,"Version")) sscanf(text,"%*s Version %d",&ver);
|
||
}
|
||
|
||
}
|
||
}
|
||
FileCloseScript();
|
||
|
||
if (district_count) {
|
||
i=0;
|
||
for (x=0;x<640;x++)
|
||
for (y=1;y<=crap_remap[x][0];y++) {
|
||
districts[i][0]=temp_dist[crap_remap[x][y]][0];
|
||
districts[i][1]=temp_dist[crap_remap[x][y]][1];
|
||
//districts[i][2]=crap_remap[x][y];
|
||
districts[i][2]=temp_dist[crap_remap[x][y]][2];
|
||
i++;
|
||
}
|
||
FRONTEND_MissionList(script,districts[district_selected][2]);
|
||
}
|
||
|
||
|
||
MemFree(text);
|
||
|
||
}
|
||
|
||
|
||
CBYTE* FRONTEND_gettitle(UBYTE mode, UBYTE selection) {
|
||
RawMenuData *pt=raw_menu_data;
|
||
while (pt->Menu!=mode) pt++;
|
||
for (;selection;selection--,pt++);
|
||
return XLAT_str_ptr(pt->Label);
|
||
}
|
||
|
||
void FRONTEND_easy(UBYTE mode) {
|
||
SLONG x,y,y2=0;
|
||
RawMenuData *pt=raw_menu_data;
|
||
MenuData *md=menu_data+menu_state.items;
|
||
|
||
if (menu_state.items) y2=(md-1)->Y+50;
|
||
|
||
|
||
int iBigFontScale = BIG_FONT_SCALE;
|
||
if ( !IsEnglish )
|
||
{
|
||
if ( ( menu_state.mode == FE_SAVESCREEN ) ||
|
||
( menu_state.mode == FE_LOADSCREEN ) ||
|
||
( menu_state.mode == FE_SAVE_CONFIRM ) )
|
||
{
|
||
// Reduce it a bit to fit long French words on screen.
|
||
iBigFontScale = BIG_FONT_SCALE_FRENCH;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
while (pt->Menu!=mode) pt++;
|
||
while ((pt->Menu==mode)||!pt->Menu) {
|
||
md->Type=pt->Type;
|
||
//XLAT_str(pt->Label,md->Label);
|
||
md->LabelID=pt->Label;
|
||
md->Label=XLAT_str_ptr(pt->Label);
|
||
md->Data=pt->Data;
|
||
switch (md->Type) {
|
||
case OT_BUTTON:
|
||
md->Choices=pt->Choices; // secret code... :P
|
||
// Fallthrough.
|
||
case OT_LABEL:
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,iBigFontScale);
|
||
md->X=320-(x>>1);
|
||
break;
|
||
case OT_MULTI:
|
||
md->X=30;
|
||
if (pt->Choices==MC_YN) {
|
||
md->Choices=menu_choice_yesno;
|
||
md->Data|=(2<<8);
|
||
}
|
||
else if (pt->Choices==MC_SCANNER) {
|
||
md->Choices=menu_choice_scanner;
|
||
md->Data|=(2<<8);
|
||
}
|
||
#ifdef TARGET_DC
|
||
else if (pt->Choices==MC_ANALOGUE_MODE) {
|
||
md->Choices=menu_choice_analogue_mode;
|
||
md->Data|=(2<<8);
|
||
}
|
||
else if (pt->Choices==MC_JOYPAD_MODE) {
|
||
md->Choices=menu_choice_joypad_mode;
|
||
md->Data|=((NUM_OF_JOYPAD_MODES+1)<<8);
|
||
}
|
||
#endif
|
||
break;
|
||
default:
|
||
md->X=30;
|
||
}
|
||
md->Y=y2;
|
||
y2+=50;
|
||
md++;
|
||
pt++;
|
||
menu_state.items++;
|
||
}
|
||
for (md=menu_data;md->Type==OT_LABEL;md++,menu_state.selected++);
|
||
#if 0
|
||
// Move to FRONTEND_recenter_menu.
|
||
menu_state.base=240-(menu_state.items*25);
|
||
if (menu_state.base<50) menu_state.base=50;
|
||
#endif
|
||
|
||
FRONTEND_recenter_menu();
|
||
}
|
||
|
||
//----------------------------------------------------------------------------
|
||
// STORE/RESTORE OPTIONS DATA
|
||
//
|
||
|
||
// Video
|
||
|
||
UBYTE LabelToIndex(SLONG label)
|
||
{
|
||
switch(label) {
|
||
case X_STARS: return 0;
|
||
case X_SHADOWS: return 1;
|
||
case X_PUDDLES: return 4;
|
||
case X_DIRT: return 5;
|
||
case X_MIST: return 6;
|
||
case X_RAIN: return 7;
|
||
case X_SKYLINE: return 8;
|
||
case X_CRINKLES: return 11;
|
||
case X_MOON: return 2;
|
||
case X_PEOPLE: return 3;
|
||
case X_BILINEAR: return 9;
|
||
case X_PERSPECTIVE: return 10;
|
||
}
|
||
return 19;
|
||
}
|
||
|
||
void FRONTEND_restore_video_data()
|
||
{
|
||
int data[20]; // int for compatability :P
|
||
UBYTE i,j;
|
||
#ifdef TARGET_DC
|
||
AENG_get_detail_levels( /*data,*/ data+1, /*data+2, data+3,*/ data+4, data+5, data+6, data+7, data+8, /*data+9, data+10,*/ data+11);
|
||
#else
|
||
AENG_get_detail_levels( data, data+1, data+2, data+3, data+4, data+5, data+6, data+7, data+8, data+9, data+10, data+11);
|
||
#endif
|
||
for (i=0;i<menu_state.items;i++)
|
||
switch(menu_data[i].LabelID)
|
||
{
|
||
/* case X_RESOLUTION:
|
||
CurrentVidMode=menu_data[i].Data&0xff;
|
||
ShellPauseOn();
|
||
switch(CurrentVidMode)
|
||
{
|
||
case 0:
|
||
SetDisplay(640,480,16);
|
||
break;
|
||
case 1:
|
||
SetDisplay(800,600,16);
|
||
break;
|
||
case 2:
|
||
SetDisplay(1024,768,16);
|
||
break;
|
||
}
|
||
ShellPauseOff();
|
||
break;
|
||
case X_DRIVERS:
|
||
// er...
|
||
break;*/
|
||
case X_STARS:
|
||
case X_SHADOWS:
|
||
case X_PUDDLES:
|
||
case X_DIRT:
|
||
case X_MIST:
|
||
case X_RAIN:
|
||
case X_SKYLINE:
|
||
case X_CRINKLES:
|
||
case X_MOON:
|
||
case X_PEOPLE:
|
||
case X_PERSPECTIVE:
|
||
case X_BILINEAR:
|
||
j=LabelToIndex(menu_data[i].LabelID);
|
||
data[j]|=menu_data[i].Data&0xff00;
|
||
menu_data[i].Data=data[j];
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
void FRONTEND_store_video_data()
|
||
{
|
||
int data[20], i, mode, bit_depth;
|
||
|
||
// Get the current ones.
|
||
#ifdef TARGET_DC
|
||
AENG_get_detail_levels( /*data,*/ data+1, /*data+2, data+3,*/ data+4, data+5, data+6, data+7, data+8, /*data+9, data+10,*/ data+11);
|
||
#else
|
||
AENG_get_detail_levels( data, data+1, data+2, data+3, data+4, data+5, data+6, data+7, data+8, data+9, data+10, data+11);
|
||
#endif
|
||
|
||
// Override with menu entries:
|
||
for (i=0;i<menu_state.items;i++)
|
||
switch(menu_data[i].LabelID)
|
||
{
|
||
case X_RESOLUTION:
|
||
mode=menu_data[i].Data&0xff;
|
||
break;
|
||
case X_COLOUR_DEPTH:
|
||
bit_depth=menu_data[i].Data&0xff ? 32 : 16;
|
||
break;
|
||
case X_DRIVERS:
|
||
// er...
|
||
break;
|
||
case X_STARS:
|
||
case X_SHADOWS:
|
||
case X_PUDDLES:
|
||
case X_DIRT:
|
||
case X_MIST:
|
||
case X_RAIN:
|
||
case X_SKYLINE:
|
||
case X_CRINKLES:
|
||
case X_MOON:
|
||
case X_PEOPLE:
|
||
case X_PERSPECTIVE:
|
||
case X_BILINEAR:
|
||
data[LabelToIndex(menu_data[i].LabelID)]=menu_data[i].Data&0xff;
|
||
break;
|
||
case X_LOW:
|
||
|
||
break;
|
||
}
|
||
#ifndef TARGET_DC
|
||
ENV_set_value_number("Mode",mode,"Video");
|
||
ENV_set_value_number("BitDepth",bit_depth,"Video");
|
||
#endif
|
||
#ifdef TARGET_DC
|
||
AENG_set_detail_levels(/*data[0],*/data[1],/*data[2],data[3],*/data[4],data[5],data[6],data[7],data[8],/*data[9],data[10],*/data[11] );
|
||
#else
|
||
AENG_set_detail_levels(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10],data[11] );
|
||
#endif
|
||
|
||
#ifdef ALLOW_DANGEROUS_OPTIONS
|
||
|
||
if ((mode!=CurrentVidMode)||(bit_depth!=CurrentBitDepth))
|
||
{
|
||
CurrentVidMode=mode;
|
||
CurrentBitDepth=bit_depth;
|
||
ShellPauseOn();
|
||
switch(CurrentVidMode)
|
||
{
|
||
case 0:
|
||
SetDisplay(640,480,bit_depth);
|
||
break;
|
||
case 1:
|
||
SetDisplay(800,600,bit_depth);
|
||
break;
|
||
case 2:
|
||
SetDisplay(1024,768,bit_depth);
|
||
break;
|
||
case 3:
|
||
SetDisplay(320,240,bit_depth);
|
||
break;
|
||
case 4:
|
||
SetDisplay(512,384,bit_depth);
|
||
break;
|
||
}
|
||
ShellPauseOff();
|
||
}
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
#ifdef M_SOUND
|
||
|
||
void set_miles_drivers() {
|
||
MFX_3D *prov;
|
||
UBYTE c0;
|
||
UWORD ct;
|
||
CBYTE *str=menu_buffer;
|
||
|
||
ct=Get3DProviderList(&prov);
|
||
menu_data[3].Data=Get3DProvider()|(ct<<8);
|
||
for (c0=0;c0<ct;c0++) {
|
||
strcpy(str,prov->name);
|
||
str+=strlen(str)+1;
|
||
prov++;
|
||
}
|
||
*str=0;
|
||
menu_data[3].Choices=menu_buffer;
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
#ifndef TARGET_DC
|
||
|
||
void FRONTEND_do_drivers() {
|
||
SLONG result, count=0, selected=0;
|
||
ChangeDDInfo *change_info;
|
||
DDDriverInfo *current_driver=0,
|
||
*driver_list;
|
||
GUID *DD_guid;
|
||
TCHAR szBuff[80];
|
||
CBYTE *str=menu_buffer, *str_tmp;
|
||
|
||
switch (RealDisplayWidth)
|
||
{
|
||
case 640:
|
||
CurrentVidMode=0;
|
||
break;
|
||
case 800:
|
||
CurrentVidMode=1;
|
||
break;
|
||
case 1024:
|
||
CurrentVidMode=2;
|
||
break;
|
||
case 320:
|
||
CurrentVidMode=3;
|
||
break;
|
||
case 512:
|
||
CurrentVidMode=4;
|
||
break;
|
||
|
||
default:
|
||
CurrentVidMode=0;
|
||
break;
|
||
}
|
||
CurrentBitDepth=DisplayBPP;
|
||
|
||
strcpy(str,"640x480");
|
||
str+=strlen(str)+1;
|
||
strcpy(str,"800x600");
|
||
str+=strlen(str)+1;
|
||
strcpy(str,"1024x768");
|
||
str+=strlen(str)+1;
|
||
strcpy(str,"320x240");
|
||
str+=strlen(str)+1;
|
||
strcpy(str,"512x384");
|
||
str+=strlen(str)+1;
|
||
str_tmp=str;
|
||
menu_data[1].Data=CurrentVidMode|(5<<8);
|
||
menu_data[1].Choices=menu_buffer;
|
||
|
||
strcpy(str,"16 bit");
|
||
str+=strlen(str)+1;
|
||
strcpy(str,"32 bit");
|
||
str+=strlen(str)+1;
|
||
menu_data[3].Data=((UBYTE)(CurrentBitDepth==32))|(2<<8);
|
||
menu_data[3].Choices=str_tmp;
|
||
str_tmp=str;
|
||
|
||
selected=0;
|
||
|
||
current_driver=the_manager.CurrDriver;
|
||
|
||
// Dump Driver list to Combo Box
|
||
driver_list = the_manager.DriverList;
|
||
while(driver_list)
|
||
{
|
||
if(driver_list->IsPrimary())
|
||
wsprintf(szBuff,TEXT("%s (Primary)"),driver_list->szName);
|
||
else
|
||
wsprintf(szBuff,TEXT("%s"),driver_list->szName);
|
||
|
||
// Add String to multi-choice
|
||
strcpy(str,szBuff);
|
||
str+=strlen(str)+1;
|
||
|
||
/* // Set up pointer to driver for this item
|
||
SendDlgItemMessage(hDlg, IDC_DRIVERS, CB_SETITEMDATA, (WPARAM)result, (LPARAM)(void *)driver_list);*/
|
||
|
||
// Is it the current Driver
|
||
if(current_driver==driver_list)
|
||
selected=count;
|
||
|
||
count++;
|
||
driver_list = driver_list->Next;
|
||
}
|
||
menu_data[2].Data=selected|(count<<8);
|
||
menu_data[2].Choices=str_tmp;
|
||
|
||
/* UBYTE c0;
|
||
UWORD ct;
|
||
CBYTE *str=menu_buffer;
|
||
|
||
ct=Get3DProviderList(&prov);
|
||
menu_data[3].Data=Get3DProvider()|(ct<<8);
|
||
for (c0=0;c0<ct;c0++) {
|
||
strcpy(str,prov->name);
|
||
str+=strlen(str)+1;
|
||
prov++;
|
||
}
|
||
*str=0;
|
||
menu_data[3].Choices=menu_buffer;*/
|
||
}
|
||
|
||
void FRONTEND_gamma_update() {
|
||
/* if ((menu_state.selected==11)||(menu_state.selected==12)) {
|
||
the_display.SetGamma(menu_data[11].Data, menu_data[12].Data);
|
||
}*/
|
||
if (menu_state.selected==GammaIndex)
|
||
the_display.SetGamma(menu_data[GammaIndex].Data&0xff, 256);
|
||
}
|
||
|
||
#else //#ifndef TARGET_DC
|
||
|
||
// Spoof them.
|
||
void FRONTEND_do_drivers() {
|
||
}
|
||
|
||
void FRONTEND_gamma_update() {
|
||
}
|
||
|
||
|
||
#endif //#else //#ifndef TARGET_DC
|
||
|
||
void FRONTEND_do_gamma() {
|
||
SLONG x,y,y2=0;
|
||
MenuData keepsafe;
|
||
MenuData *md=menu_data+menu_state.items-1;
|
||
|
||
keepsafe=*md; // we're going to insert the extra items before the last ("go back") item
|
||
|
||
md->Label=XLAT_str_ptr(X_GAMMA);
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,BIG_FONT_SCALE);
|
||
md->Type=OT_LABEL;
|
||
md->X=320-(x>>1);
|
||
y2=md->Y; md++; y2+=50;
|
||
|
||
md->Label=XLAT_str_ptr(X_LOW);
|
||
md->LabelID=X_LOW;
|
||
GammaIndex=md-menu_data;
|
||
MENUFONT_Dimensions(md->Label,x,y,-1,BIG_FONT_SCALE);
|
||
md->Type=OT_SLIDER;
|
||
md->X=30;
|
||
md->Y=y2; md++; y2+=50;
|
||
|
||
/* md->Label=XLAT_str_ptr(X_HIGH);
|
||
MENUFONT_Dimensions(md->Label,x,y);
|
||
md->Type=OT_SLIDER;
|
||
md->X=30;
|
||
md->Y=y2; md++; y2+=50;*/
|
||
|
||
*md=keepsafe;
|
||
md->Y=y2;
|
||
|
||
md++; y2+=50;
|
||
|
||
menu_state.items+=2; //3;
|
||
|
||
int a,b;
|
||
the_display.GetGamma(&a,&b);
|
||
menu_data[GammaIndex].Data=a;
|
||
// menu_data[12].Data=b;
|
||
|
||
}
|
||
|
||
void FRONTEND_mode(SBYTE mode, bool bDoTransition=TRUE) {
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
if ( mode == FE_MAINMENU )
|
||
{
|
||
// OK, we finally got to the main menu, so disable the immediate soft reset behaviour.
|
||
// From here on, it gets handled explicitely by some code elsewhere in frontend.cpp,
|
||
// rather than the code in interfac.cpp.
|
||
extern bool g_bDreamcastABXYStartShouldGoToBootRomImmediately;
|
||
g_bDreamcastABXYStartShouldGoToBootRomImmediately = FALSE;
|
||
}
|
||
#endif
|
||
|
||
|
||
if (menu_state.mode >= 100 && mode < 100)
|
||
{
|
||
//
|
||
// Moving from the briefing screen... reinitialise the music.
|
||
//
|
||
|
||
DCLL_memstream_stop();
|
||
|
||
//MFX_stop(0, S_FRONT_END_LOOP_EDIT);
|
||
|
||
#ifdef TARGET_DC
|
||
MFX_QUICK_play("data\\sfx\\1622DC\\GeneralMusic\\FrontLoopMONO.wav",TRUE,0,0,0);
|
||
#else
|
||
MFX_QUICK_play("data\\sfx\\1622\\GeneralMusic\\FrontLoopMONO.wav",TRUE,0,0,0);
|
||
#endif
|
||
}
|
||
|
||
|
||
// Reset this now.
|
||
dwAutoPlayFMVTimeout = timeGetTime() + AUTOPLAY_FMV_DELAY;
|
||
|
||
|
||
|
||
SBYTE last=menu_state.mode;
|
||
fade_mode=1;
|
||
ZeroMemory(menu_data,sizeof(menu_data));
|
||
menu_state.items=0;
|
||
if (mode==-2) {
|
||
if (menu_state.stackpos>0) {
|
||
menu_state.stackpos--;
|
||
mode=menu_state.stack[menu_state.stackpos].mode;
|
||
menu_state.scroll=menu_state.stack[menu_state.stackpos].scroll;
|
||
menu_state.selected=menu_state.stack[menu_state.stackpos].selected;
|
||
menu_state.title=menu_state.stack[menu_state.stackpos].title;
|
||
} else {
|
||
mode=menu_state.mode;
|
||
}
|
||
} else {
|
||
if (menu_thrash) {
|
||
menu_state.stack[menu_state.stackpos].mode=menu_thrash;
|
||
menu_state.stack[menu_state.stackpos].scroll=0;
|
||
menu_state.stack[menu_state.stackpos].selected=0;
|
||
menu_state.stack[menu_state.stackpos].title=0;
|
||
menu_state.stackpos++;
|
||
menu_thrash=0;
|
||
} else
|
||
if (menu_state.mode!=-1) {
|
||
menu_state.stack[menu_state.stackpos].mode=menu_state.mode;
|
||
menu_state.stack[menu_state.stackpos].scroll=menu_state.scroll;
|
||
menu_state.stack[menu_state.stackpos].selected=menu_state.selected;
|
||
menu_state.stack[menu_state.stackpos].title=menu_state.title;
|
||
menu_state.stackpos++;
|
||
}
|
||
menu_state.selected=0;
|
||
}
|
||
|
||
switch ( mode )
|
||
{
|
||
case FE_MAPSCREEN:
|
||
menu_state.title=XLAT_str_ptr(X_START);
|
||
break;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
case FE_TITLESCREEN:
|
||
case FE_LANGUAGESCREEN:
|
||
#endif
|
||
case FE_MAINMENU:
|
||
// No title.
|
||
menu_state.title=NULL;
|
||
break;
|
||
case FE_LOADSCREEN:
|
||
menu_state.title=XLAT_str_ptr(X_LOAD_GAME);
|
||
break;
|
||
case FE_SAVESCREEN:
|
||
menu_state.title=XLAT_str_ptr(X_SAVE_GAME);
|
||
break;
|
||
|
||
#ifdef TARGET_DC
|
||
case FE_VMU_SELECT:
|
||
menu_state.title=XLAT_str_ptr(X_VMU_SELECT);
|
||
break;
|
||
#endif
|
||
|
||
default:
|
||
if ( menu_state.stackpos && ( mode < 100 ) )
|
||
{
|
||
menu_state.title=FRONTEND_gettitle(menu_state.stack[menu_state.stackpos-1].mode,menu_state.stack[menu_state.stackpos-1].selected);
|
||
}
|
||
else
|
||
{
|
||
menu_state.title=0;
|
||
}
|
||
break;
|
||
}
|
||
|
||
menu_state.mode=mode;
|
||
|
||
if (mode>=100) {
|
||
//InitBackImage("TITLE LEAVES1.TGA");
|
||
FRONTEND_init_xition();
|
||
FRONTEND_MissionBrief(MISSION_SCRIPT,mode-100);
|
||
// MUSIC_mode(MUSIC_MODE_BRIEFING|MUSIC_MODE_FORCE);
|
||
return;
|
||
}
|
||
switch(mode) {
|
||
case FE_MAPSCREEN:
|
||
//InitBackImage("MAP SELECT LEAVES.TGA");
|
||
FRONTEND_init_xition();
|
||
FRONTEND_districts(MISSION_SCRIPT);
|
||
//FRONTEND_MissionList(MISSION_SCRIPT);
|
||
//MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
break;
|
||
case FE_MAINMENU:
|
||
//InitBackImage(menu_back_names[menu_theme]);
|
||
//UseBackSurface(screenfull_back);
|
||
|
||
|
||
FRONTEND_init_xition();
|
||
|
||
FRONTEND_easy(mode);
|
||
|
||
// Always reset the stack in the main menu.
|
||
menu_state.stackpos = 0;
|
||
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
if (AllowSave) menu_data[2].Choices=NULL;
|
||
break;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
case FE_TITLESCREEN:
|
||
FRONTEND_init_xition();
|
||
|
||
FRONTEND_easy(mode);
|
||
|
||
// Always reset the stack in the title screen.
|
||
menu_state.stackpos = 0;
|
||
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
|
||
// "Reset" the controller so that "Press Start Button" is displayed.
|
||
ClearPrimaryDevice();
|
||
break;
|
||
|
||
case FE_LANGUAGESCREEN:
|
||
//UseBackSurface(screenfull_title);
|
||
|
||
FRONTEND_init_xition();
|
||
|
||
FRONTEND_easy(mode);
|
||
|
||
// Always reset the stack in the title screen.
|
||
menu_state.stackpos = 0;
|
||
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
|
||
// Set the default selection to the current setting.
|
||
menu_state.selected = ENV_get_value_number ( "lang_num", 0, "" );
|
||
|
||
break;
|
||
#endif
|
||
case FE_SAVESCREEN:
|
||
AllowSave=1;
|
||
if (!menu_state.stackpos)
|
||
{
|
||
//InitBackImage(menu_config_names[menu_theme]);
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
UseBackSurface(screenfull_back);
|
||
#else
|
||
UseBackSurface(screenfull_config);
|
||
#endif
|
||
}
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_find_savegames ( FALSE, TRUE );
|
||
FRONTEND_easy(mode);
|
||
menu_state.title=XLAT_str_ptr(X_SAVE_GAME);
|
||
break;
|
||
case FE_LOADSCREEN:
|
||
FRONTEND_find_savegames ( TRUE, FALSE );
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
break;
|
||
#ifdef TARGET_DC
|
||
case FE_VMU_SELECT:
|
||
FRONTEND_find_VMUs();
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
break;
|
||
#endif
|
||
case FE_CONFIG:
|
||
FRONTEND_init_xition();
|
||
FRONTEND_easy(mode);
|
||
break;
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
case FE_QUIT:
|
||
FRONTEND_easy(mode);
|
||
menu_state.title=XLAT_str_ptr(X_EXIT);
|
||
break;
|
||
#endif
|
||
case FE_CONFIG_VIDEO:
|
||
{
|
||
int a,b,c,d,e,f,g,h,i,j,k; // <-- int for compatability with the prototype in aeng.h *shrug*
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
#ifndef TARGET_DC
|
||
#ifdef ALLOW_DANGEROUS_OPTIONS
|
||
FRONTEND_do_drivers();
|
||
#endif
|
||
#endif
|
||
if (the_display.IsGammaAvailable())
|
||
FRONTEND_do_gamma();
|
||
FRONTEND_restore_video_data();
|
||
}
|
||
break;
|
||
case FE_CONFIG_AUDIO:
|
||
{
|
||
SLONG fx,amb,mus;
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
// now put in correct values...
|
||
|
||
/*
|
||
|
||
#if defined(M_SOUND) || defined(DC_SOUND)
|
||
#else
|
||
fx = 127;
|
||
amb = 127;
|
||
mus = 127;
|
||
#endif
|
||
*/
|
||
|
||
MFX_get_volumes(&fx,&amb,&mus);
|
||
|
||
|
||
|
||
menu_data[0].Data=fx<<1;
|
||
menu_data[1].Data=amb<<1;
|
||
menu_data[2].Data=mus<<1;
|
||
#ifdef TARGET_DC
|
||
// Load this from the BOOT rom.
|
||
if ( FirmwareGetSoundMode() == SOUND_MODE_STEREO )
|
||
{
|
||
menu_data[3].Data = 1 | (2<<8);
|
||
}
|
||
else
|
||
{
|
||
menu_data[3].Data = 0 | (2<<8);
|
||
}
|
||
#endif
|
||
#ifdef M_SOUND
|
||
#ifdef ALLOW_DANGEROUS_OPTIONS
|
||
set_miles_drivers();
|
||
#endif
|
||
#endif
|
||
}
|
||
break;
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
case FE_CONFIG_INPUT_KB:
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
// now put in correct values...
|
||
menu_data[0].Data = ENV_get_value_number("keyboard_left", 203, "Keyboard");
|
||
menu_data[1].Data = ENV_get_value_number("keyboard_right", 205, "Keyboard");
|
||
menu_data[2].Data = ENV_get_value_number("keyboard_forward", 200, "Keyboard");
|
||
menu_data[3].Data = ENV_get_value_number("keyboard_back", 208, "Keyboard");
|
||
menu_data[4].Data = ENV_get_value_number("keyboard_punch", 44, "Keyboard");
|
||
menu_data[5].Data = ENV_get_value_number("keyboard_kick", 45, "Keyboard");
|
||
menu_data[6].Data = ENV_get_value_number("keyboard_action", 46, "Keyboard");
|
||
// menu_data[7].Data = ENV_get_value_number("keyboard_run", 47, "Keyboard");
|
||
menu_data[7].Data = ENV_get_value_number("keyboard_jump", 57, "Keyboard");
|
||
menu_data[8].Data = ENV_get_value_number("keyboard_start", 15, "Keyboard");
|
||
menu_data[9].Data = ENV_get_value_number("keyboard_select", 28, "Keyboard");
|
||
// gap for label
|
||
menu_data[11].Data = ENV_get_value_number("keyboard_camera", 207, "Keyboard");
|
||
menu_data[12].Data = ENV_get_value_number("keyboard_cam_left", 211, "Keyboard");
|
||
menu_data[13].Data= ENV_get_value_number("keyboard_cam_right", 209, "Keyboard");
|
||
menu_data[14].Data= ENV_get_value_number("keyboard_1stperson", 30, "Keyboard");
|
||
break;
|
||
#endif
|
||
case FE_CONFIG_INPUT_JP:
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
#ifndef TARGET_DC
|
||
menu_data[0].Data = ENV_get_value_number("joypad_kick", 4, "Joypad");
|
||
menu_data[1].Data = ENV_get_value_number("joypad_punch", 3, "Joypad");
|
||
menu_data[2].Data = ENV_get_value_number("joypad_jump", 0, "Joypad");
|
||
menu_data[3].Data = ENV_get_value_number("joypad_action", 1, "Joypad");
|
||
menu_data[4].Data = ENV_get_value_number("joypad_move", 7, "Joypad");
|
||
menu_data[5].Data = ENV_get_value_number("joypad_start", 8, "Joypad");
|
||
menu_data[6].Data = ENV_get_value_number("joypad_select", 2, "Joypad");
|
||
// gap for label
|
||
menu_data[8].Data = ENV_get_value_number("joypad_camera", 6, "Joypad");
|
||
menu_data[9].Data = ENV_get_value_number("joypad_cam_left", 9, "Joypad");
|
||
menu_data[10].Data = ENV_get_value_number("joypad_cam_right",10, "Joypad");
|
||
menu_data[11].Data =ENV_get_value_number("joypad_1stperson",5, "Joypad");
|
||
#else
|
||
// Set up the buttons from the environment.
|
||
{
|
||
int iMode = ENV_get_value_number("joypad_mode", 0, "Joypad");
|
||
INTERFAC_SetUpJoyPadButtons ( iMode );
|
||
// And set up the menu to match.
|
||
menu_data[0].Data = iMode | ((NUM_OF_JOYPAD_MODES+1)<<8);
|
||
// Gap for label.
|
||
menu_data[2].Data = joypad_button_use[JOYPAD_BUTTON_PUNCH];
|
||
menu_data[3].Data = joypad_button_use[JOYPAD_BUTTON_KICK];
|
||
menu_data[4].Data = joypad_button_use[JOYPAD_BUTTON_JUMP];
|
||
menu_data[5].Data = joypad_button_use[JOYPAD_BUTTON_ACTION];
|
||
menu_data[6].Data = joypad_button_use[JOYPAD_BUTTON_MOVE];
|
||
menu_data[7].Data = joypad_button_use[JOYPAD_BUTTON_SELECT];
|
||
// Gap for label.
|
||
menu_data[9].Data = joypad_button_use[JOYPAD_BUTTON_CAMERA];
|
||
menu_data[10].Data = joypad_button_use[JOYPAD_BUTTON_CAM_LEFT];
|
||
menu_data[11].Data = joypad_button_use[JOYPAD_BUTTON_CAM_RIGHT];
|
||
menu_data[12].Data = joypad_button_use[JOYPAD_BUTTON_1STPERSON];
|
||
}
|
||
#endif
|
||
break;
|
||
case FE_CONFIG_OPTIONS:
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
#ifdef TARGET_DC
|
||
menu_data[0].Data|=ENV_get_value_number("scanner_follows", 1, "Game");
|
||
menu_data[1].Data|=ENV_get_value_number("analogue_pad_mode", 0, "Game");
|
||
menu_data[2].Data|=ENV_get_value_number("vibration_mode", 1, "Game");
|
||
menu_data[3].Data|=ENV_get_value_number("vibration_engine", 1, "Game");
|
||
#else
|
||
menu_data[1].Data|=ENV_get_value_number("scanner_follows", 1, "Game");
|
||
#endif
|
||
break;
|
||
case FE_SAVE_CONFIRM:
|
||
if ( bDoTransition )
|
||
{
|
||
FRONTEND_init_xition();
|
||
}
|
||
FRONTEND_easy(mode);
|
||
menu_state.scroll=0;
|
||
menu_state.title=XLAT_str_ptr(X_SAVE_GAME);
|
||
break;
|
||
}
|
||
|
||
FRONTEND_recenter_menu();
|
||
}
|
||
|
||
|
||
|
||
|
||
void FRONTEND_draw_districts() {
|
||
UBYTE i,j,id;
|
||
SWORD x,y;
|
||
CBYTE *str;
|
||
UWORD fade;
|
||
ULONG rgb;
|
||
|
||
if (bonus_this_turn)
|
||
{
|
||
if (bonus_this_turn==1)
|
||
{
|
||
bonus_this_turn++;
|
||
MFX_play_stereo(0,S_TUNE_BONUS,0);
|
||
}
|
||
fade = (64 - fade_state) << 2;
|
||
if (IsEnglish)
|
||
{
|
||
str="Bonus mission unlocked!"; // XLAT_str(X_BONUS_MISSION_UNLOCKED)
|
||
FONT2D_DrawStringCentred(str,322,10,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#ifdef TARGET_DC
|
||
// A bit darker please.
|
||
FONT2D_DrawStringCentred(str,322,6,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawStringCentred(str,318,10,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawStringCentred(str,318,6,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#endif
|
||
FONT2D_DrawStringCentred(str,320,8,0xffffff,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
}
|
||
}
|
||
|
||
|
||
fade = (64 - fade_state) << 2;
|
||
|
||
{
|
||
CBYTE str2[200];
|
||
sprintf(str2,"%s: %03d %s: %03d %s: %03d %s: %03d\n",XLAT_str_ptr(X_CON_INCREASED),the_game.DarciConstitution,XLAT_str_ptr(X_STA_INCREASED),the_game.DarciStamina,XLAT_str_ptr(X_STR_INCREASED),the_game.DarciStrength,XLAT_str_ptr(X_REF_INCREASED),the_game.DarciSkill);
|
||
int iYpos;
|
||
if ( eDisplayType == DT_NTSC )
|
||
{
|
||
// Move it further up so it's on screen for the yanks.
|
||
iYpos = 434;
|
||
}
|
||
else
|
||
{
|
||
iYpos = 454;
|
||
}
|
||
FONT2D_DrawStringCentred(str2,320+2,iYpos+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#ifdef TARGET_DC
|
||
// A bit darker please.
|
||
FONT2D_DrawStringCentred(str2,320+2,iYpos-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawStringCentred(str2,320-2,iYpos-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawStringCentred(str2,320-2,iYpos+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#endif
|
||
FONT2D_DrawStringCentred(str2,320 ,iYpos ,0xffffff,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
}
|
||
|
||
for (i=0;i<district_count;i++) {
|
||
switch(district_valid[i]) {
|
||
case 1:
|
||
FRONTEND_draw_button(districts[i][0],districts[i][1],(UBYTE)(i==district_selected)|4,i==district_flash);
|
||
break;
|
||
case 2:
|
||
case 3:
|
||
FRONTEND_draw_button(districts[i][0],districts[i][1],(i==district_selected)?5:6,i==district_flash);
|
||
break;
|
||
}
|
||
|
||
/*
|
||
|
||
{
|
||
CBYTE num[16];
|
||
|
||
sprintf(num, "%d", i);
|
||
|
||
FONT2D_DrawString(num, districts[i][0],districts[i][1],0xffffff);
|
||
}
|
||
|
||
*/
|
||
|
||
if (i==district_selected)
|
||
{
|
||
y = districts[i][1];
|
||
x = districts[i][0];
|
||
|
||
str = menu_buffer;
|
||
|
||
for (j = 0; j < mission_count; j++)
|
||
{
|
||
id = *str++;
|
||
|
||
//
|
||
// What colour do we draw this bit of text?
|
||
//
|
||
|
||
if (j == mission_selected)
|
||
{
|
||
rgb = 0xffffff;
|
||
}
|
||
else
|
||
{
|
||
rgb = 0x667788;
|
||
}
|
||
|
||
/*
|
||
|
||
rgb=FRONTEND_fix_rgb(fade_rgb,j==mission_selected);
|
||
fade=(j==mission_selected)?0:127;
|
||
|
||
|
||
*/
|
||
|
||
|
||
fade = (64 - fade_state) << 2;
|
||
|
||
if (fade > 255) fade = 255;
|
||
|
||
if (mission_hierarchy[id] & 4) // 4 => available.
|
||
{
|
||
if (x>320)
|
||
{
|
||
FONT2D_DrawStringRightJustify(str,x+18+2,y+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#ifdef TARGET_DC
|
||
// A bit darker please.
|
||
FONT2D_DrawStringRightJustify(str,x+18-2,y+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawStringRightJustify(str,x+18-2,y-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawStringRightJustify(str,x+18+2,y-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#endif
|
||
FONT2D_DrawStringRightJustify(str,x+18,y,rgb,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
|
||
//
|
||
// Draw a line through completed missions!
|
||
//
|
||
|
||
// These are just tweaked values - dunno why they work/don't work. Just accept it.
|
||
#define STRIKETHROUGH_HANGOVER_L 5
|
||
#define STRIKETHROUGH_HANGOVER_R 25
|
||
|
||
if (mission_hierarchy[id] & 2) // 2 => complete
|
||
{
|
||
FONT2D_DrawStrikethrough(
|
||
FONT2D_leftmost_x + 2 - STRIKETHROUGH_HANGOVER_L,
|
||
x + 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y + 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, FALSE);
|
||
|
||
#ifdef TARGET_DC
|
||
// Darker.
|
||
FONT2D_DrawStrikethrough(
|
||
FONT2D_leftmost_x - 2 - STRIKETHROUGH_HANGOVER_L,
|
||
x - 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y + 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
FONT2D_DrawStrikethrough(
|
||
FONT2D_leftmost_x - 2 - STRIKETHROUGH_HANGOVER_L,
|
||
x - 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y - 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
FONT2D_DrawStrikethrough(
|
||
FONT2D_leftmost_x + 2 - STRIKETHROUGH_HANGOVER_L,
|
||
x + 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y - 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
#endif
|
||
|
||
FONT2D_DrawStrikethrough(
|
||
FONT2D_leftmost_x + 0 - STRIKETHROUGH_HANGOVER_L,
|
||
x + 0 + STRIKETHROUGH_HANGOVER_R,
|
||
y ,
|
||
rgb,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FONT2D_DrawString(str,x+32+2,y+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#ifdef TARGET_DC
|
||
// A bit darker please.
|
||
FONT2D_DrawString(str,x+32-2,y+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawString(str,x+32-2,y-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
FONT2D_DrawString(str,x+32+2,y-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
#endif
|
||
FONT2D_DrawString(str,x+32,y,rgb,SMALL_FONT_SCALE,POLY_PAGE_FONT2D, fade);
|
||
|
||
//
|
||
// Draw a line through completed missions!
|
||
//
|
||
|
||
#undef STRIKETHROUGH_HANGOVER_L
|
||
#undef STRIKETHROUGH_HANGOVER_R
|
||
// These are just tweaked values - dunno why they work/don't work. Just accept it.
|
||
#define STRIKETHROUGH_HANGOVER_L (-15)
|
||
#define STRIKETHROUGH_HANGOVER_R 30
|
||
|
||
if (mission_hierarchy[id] & 2) // 2 => complete
|
||
{
|
||
FONT2D_DrawStrikethrough(
|
||
x + 2 - STRIKETHROUGH_HANGOVER_L,
|
||
FONT2D_rightmost_x + 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y + 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, FALSE);
|
||
#ifdef TARGET_DC
|
||
// A bit darker please.
|
||
FONT2D_DrawStrikethrough(
|
||
x - 2 - STRIKETHROUGH_HANGOVER_L,
|
||
FONT2D_rightmost_x - 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y + 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
FONT2D_DrawStrikethrough(
|
||
x - 2 - STRIKETHROUGH_HANGOVER_L,
|
||
FONT2D_rightmost_x - 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y - 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
FONT2D_DrawStrikethrough(
|
||
x + 2 - STRIKETHROUGH_HANGOVER_L,
|
||
FONT2D_rightmost_x + 2 + STRIKETHROUGH_HANGOVER_R,
|
||
y - 2,
|
||
0x000000,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
#endif
|
||
|
||
FONT2D_DrawStrikethrough(
|
||
x - STRIKETHROUGH_HANGOVER_L,
|
||
FONT2D_rightmost_x + STRIKETHROUGH_HANGOVER_R,
|
||
y,
|
||
rgb,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
fade, TRUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
str+=strlen(str)+1;
|
||
#ifdef TRUETYPE
|
||
y += GetTextHeightTT() * 3/4;
|
||
#else
|
||
y+=20;
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void FRONTEND_shadowed_text ( char *pcString, int iX, int iY, DWORD dwColour )
|
||
{
|
||
FONT2D_DrawString(
|
||
pcString,
|
||
iX+2,
|
||
iY+2,
|
||
0,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
0);
|
||
|
||
FONT2D_DrawString(
|
||
pcString,
|
||
iX-1,
|
||
iY-1,
|
||
0,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
0);
|
||
|
||
FONT2D_DrawString(
|
||
pcString,
|
||
iX+1,
|
||
iY+1,
|
||
( dwColour & 0xfefefefe ) >> 1,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
0);
|
||
|
||
FONT2D_DrawString(
|
||
pcString,
|
||
iX,
|
||
iY,
|
||
dwColour,
|
||
256,
|
||
POLY_PAGE_FONT2D,
|
||
0);
|
||
}
|
||
|
||
|
||
void FRONTEND_display()
|
||
{
|
||
UBYTE i;
|
||
SLONG rgb, x,x2,y;
|
||
MenuData *md=menu_data;
|
||
UBYTE whichmap[]={2,0,1,3};
|
||
UBYTE arrow=0;
|
||
|
||
|
||
DumpTracies();
|
||
|
||
|
||
#if 1
|
||
LPDIRECT3DDEVICE3 dev = the_display.lp_D3D_Device;
|
||
HRESULT hres;
|
||
|
||
|
||
D3DVIEWPORT2 vp;
|
||
vp.dwSize = sizeof ( vp );
|
||
vp.dwX = the_display.ViewportRect.x1;
|
||
vp.dwY = the_display.ViewportRect.y1;
|
||
vp.dwWidth = the_display.ViewportRect.x2 - the_display.ViewportRect.x1;
|
||
vp.dwHeight = the_display.ViewportRect.y2 - the_display.ViewportRect.y1;
|
||
vp.dvClipX = (float)vp.dwX;
|
||
vp.dvClipY = (float)vp.dwY;
|
||
vp.dvClipWidth = (float)vp.dwWidth;
|
||
vp.dvClipHeight = (float)vp.dwHeight;
|
||
vp.dvMinZ = 0.0f;
|
||
vp.dvMaxZ = 1.0f;
|
||
hres = the_display.lp_D3D_Viewport->SetViewport2 ( &vp );
|
||
#endif
|
||
|
||
|
||
|
||
the_display.lp_D3D_Viewport->Clear(1, &the_display.ViewportRect, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET);
|
||
//#ifdef TARGET_DC
|
||
// Must do these inside a frame on DC!
|
||
//POLY_frame_init(FALSE, FALSE);
|
||
//#endif
|
||
ShowBackImage();
|
||
if ((fade_mode&3)==1) FRONTEND_show_xition();
|
||
#ifndef TARGET_DC
|
||
POLY_frame_init(FALSE, FALSE);
|
||
#endif
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if ( ( menu_state.mode == FE_TITLESCREEN ) || ( menu_state.mode == FE_LANGUAGESCREEN ) )
|
||
{
|
||
#if 0
|
||
// Title screen - draw misc copyright notices on screen.
|
||
FRONTEND_shadowed_text ( XLAT_str_ptr(X_COPYRIGHT_1), 32, 32+00, 0xffd0d0d0 );
|
||
FRONTEND_shadowed_text ( XLAT_str_ptr(X_COPYRIGHT_2), 32, 32+20, 0xffd0d0d0 );
|
||
FRONTEND_shadowed_text ( XLAT_str_ptr(X_COPYRIGHT_3), 32+20, 32+38, 0xffd0d0d0 );
|
||
FRONTEND_shadowed_text ( XLAT_str_ptr(X_COPYRIGHT_4), 32, 32+60, 0xffd0d0d0 );
|
||
#endif
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
FRONTEND_kibble_draw();
|
||
//POLY_frame_draw(FALSE, FALSE);
|
||
}
|
||
|
||
|
||
int iBigFontScale = BIG_FONT_SCALE;
|
||
if ( !IsEnglish )
|
||
{
|
||
if ( ( menu_state.mode == FE_SAVESCREEN ) ||
|
||
( menu_state.mode == FE_LOADSCREEN ) ||
|
||
( menu_state.mode == FE_SAVE_CONFIRM ) )
|
||
{
|
||
// Reduce it a bit to fit long French words on screen.
|
||
iBigFontScale = BIG_FONT_SCALE_FRENCH;
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// And a special kludge for the vibro pack options.
|
||
static bool bVibrationPackPresent = TRUE;
|
||
if ( menu_state.mode == FE_CONFIG_OPTIONS )
|
||
{
|
||
static int iVibroScanCountdown = 0;
|
||
if ( ( ( iVibroScanCountdown++ ) & 0xf ) == 0 )
|
||
{
|
||
// Flush the VMU device "cache".
|
||
RescanDevices();
|
||
// and rescan primary for a vibro pack.
|
||
if ( FindFirstVibratorOnCurrentController() == NULL )
|
||
{
|
||
bVibrationPackPresent = FALSE;
|
||
}
|
||
else
|
||
{
|
||
bVibrationPackPresent = TRUE;
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
//POLY_frame_init(FALSE, FALSE);
|
||
for (i=0;i<menu_state.items;i++,md++) {
|
||
y=md->Y+menu_state.base-menu_state.scroll;
|
||
if ((y>=100)&&(y<=400)) {
|
||
rgb=FRONTEND_fix_rgb(fade_rgb,i==menu_state.selected);
|
||
if ((md->Type==OT_BUTTON)&&(md->Choices==(CBYTE*)1)) // 'greyed out'
|
||
{
|
||
SLONG rgbtemp=rgb&0xff000000;
|
||
//rgb>>=25; //rgb<<=1;
|
||
rgb=(rgb&0xff)>>1;
|
||
rgb|=(rgb<<8)|(rgb<<16);
|
||
rgb|=rgbtemp;
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
if ( !bVibrationPackPresent &&
|
||
( ( md->LabelID == X_VIBRATION ) ||
|
||
( md->LabelID == X_VIBRATION_ENG ) ) )
|
||
{
|
||
// Grey this option out - no vibro pack.
|
||
SLONG rgbtemp=rgb&0xff000000;
|
||
//rgb>>=25; //rgb<<=1;
|
||
rgb=(rgb&0xff)>>1;
|
||
rgb|=(rgb<<8)|(rgb<<16);
|
||
rgb|=rgbtemp;
|
||
}
|
||
|
||
// Detect the (VMU full) message and alternate between that
|
||
// and (2 blocks required).
|
||
char *pString = md->Label;
|
||
int iXPos = md->X;
|
||
if ( ( md->LabelID == X_VMU_FULL ) && ( ( timeGetTime() & 2048 ) == 0 ) )
|
||
{
|
||
// Change it to the other one.
|
||
pString = XLAT_str ( X_VMU_X_BLOCKS_REQUIRED );
|
||
SLONG iX, iY;
|
||
MENUFONT_Dimensions(pString,iX,iY,-1,iBigFontScale);
|
||
iXPos=320-(iX>>1);
|
||
}
|
||
MENUFONT_Draw(iXPos,y,iBigFontScale,pString,rgb,0);
|
||
#else
|
||
MENUFONT_Draw(md->X,y,iBigFontScale,md->Label,rgb,0);
|
||
#endif
|
||
|
||
#ifdef TARGET_DC
|
||
if ( i==menu_state.selected )
|
||
{
|
||
// Draw a rectangle around the text.
|
||
MENUFONT_Draw_Selection_Box(md->X,y,iBigFontScale,md->Label,rgb,0);
|
||
}
|
||
#endif
|
||
switch (md->Type) {
|
||
case OT_SLIDER: FRONTEND_DrawSlider(md); break;
|
||
case OT_MULTI: FRONTEND_DrawMulti(md,rgb); break;
|
||
case OT_KEYPRESS: FRONTEND_DrawKey(md); break;
|
||
case OT_PADPRESS: FRONTEND_DrawPad(md); break;
|
||
}
|
||
} else {
|
||
if (i==menu_state.selected) { // better do some scrolling
|
||
#ifdef TARGET_DC
|
||
// As the man say, it's so slow I want to knaw out my own liver rather than wait for this.
|
||
if (y<100) menu_state.scroll-=20;
|
||
if (y>400) menu_state.scroll+=20;
|
||
#else
|
||
if (y<100) menu_state.scroll-=10;
|
||
if (y>400) menu_state.scroll+=10;
|
||
#endif
|
||
}
|
||
if (y<100) arrow|=1;
|
||
if (y>400) arrow|=2;
|
||
}
|
||
}
|
||
if (arrow&1) // draw a "more..." arrow at the top of the screen
|
||
{
|
||
DRAW2D_Tri(320,50, 335,65, 305,65,fade_rgb,0);
|
||
}
|
||
if (arrow&2) // draw a "more..." arrow at the bottom of the screen
|
||
{
|
||
DRAW2D_Tri(320,430, 335,415, 305,415,fade_rgb,0);
|
||
}
|
||
if (menu_state.title && (menu_state.mode != FE_MAINMENU)) {
|
||
BOOL dir;
|
||
x2=SIN(fade_state<<3)>>10;
|
||
switch(menu_state.mode) {
|
||
case FE_MAPSCREEN:
|
||
MENUFONT_Dimensions(menu_state.title,x,y,-1,BIG_FONT_SCALE);
|
||
x=560-x;
|
||
x2=(x2*10)-63;
|
||
dir=0;
|
||
break;
|
||
default:
|
||
x=80;
|
||
x2=642-(x2*10);
|
||
dir=1;
|
||
break;
|
||
}
|
||
FontPage=POLY_PAGE_NEWFONT;
|
||
FRONTEND_draw_title(x+2,44,x2,menu_state.title,0,dir);
|
||
#ifndef TARGET_DC
|
||
POLY_frame_draw(FALSE, FALSE);
|
||
POLY_frame_init(FALSE, FALSE);
|
||
#endif
|
||
FontPage=POLY_PAGE_NEWFONT_INVERSE;
|
||
FRONTEND_draw_title(x,40,x2,menu_state.title,1,dir);
|
||
#ifndef TARGET_DC
|
||
POLY_frame_draw(FALSE, FALSE);
|
||
POLY_frame_init(FALSE, FALSE);
|
||
#endif
|
||
FRONTEND_draw_button(x2,8,whichmap[menu_theme]);
|
||
}
|
||
if ((menu_state.mode==FE_MAPSCREEN)&&((fade_mode==2)||(fade_state==63))) FRONTEND_draw_districts();
|
||
if ((menu_state.mode>=100)&&*menu_buffer) {
|
||
//DRAW2D_Box(0,48,640,432,fade_rgb&0xff000000,1,127);
|
||
#ifndef TARGET_DC
|
||
POLY_frame_draw(FALSE, FALSE);
|
||
POLY_frame_init(FALSE, FALSE);
|
||
#endif
|
||
x=SIN(fade_state<<3)>>10;
|
||
FRONTEND_draw_button(642-(x*10),8,whichmap[menu_theme]);
|
||
FONT2D_DrawStringWrapTo(menu_buffer,20+2,100+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D,255-(fade_state<<2),402);
|
||
#ifdef TARGET_DC
|
||
// Darker Egor - MUCH darker!
|
||
FONT2D_DrawStringWrapTo(menu_buffer,20-2,100-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D,255-(fade_state<<2),398);
|
||
FONT2D_DrawStringWrapTo(menu_buffer,20-2,100+2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D,255-(fade_state<<2),398);
|
||
FONT2D_DrawStringWrapTo(menu_buffer,20+2,100-2,0x000000,SMALL_FONT_SCALE,POLY_PAGE_FONT2D,255-(fade_state<<2),402);
|
||
#endif
|
||
FONT2D_DrawStringWrapTo(menu_buffer,20,100,fade_rgb,SMALL_FONT_SCALE,POLY_PAGE_FONT2D,255-(fade_state<<2),400);
|
||
}
|
||
|
||
if ( m_bMovingPanel )
|
||
{
|
||
// Display the panel at the current position.
|
||
|
||
// REMEMBER THAT THESE NUMBERS ARE DIVIDED BY 4!
|
||
int iXPos = ENV_get_value_number ( "panel_x", 32 / 4, "" );
|
||
int iYPos = ENV_get_value_number ( "panel_y", (480 - 32) / 4, "" );
|
||
|
||
extern void PANEL_draw_quad( float left,float top,float right,float bottom,SLONG page,ULONG colour,
|
||
float u1,float v1,float u2,float v2);
|
||
|
||
PANEL_draw_quad(
|
||
(float)( iXPos * 4 + 0 ),
|
||
(float)( iYPos * 4 - 165 ),
|
||
(float)( iXPos * 4 + 212 ),
|
||
(float)( iYPos * 4 - 0 ),
|
||
POLY_PAGE_LASTPANEL_ALPHA,
|
||
0xffffffff,
|
||
0.0F,
|
||
90.0F / 256.0F,
|
||
212.0F / 256.0F,
|
||
1.0F);
|
||
}
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Draw a "quick info" text screen.
|
||
if ( pcQuickInfo[0] != '\0' )
|
||
{
|
||
|
||
#if 1
|
||
// This blows goats. But there you go.
|
||
if ( bQuickInfoReplaceWithSegasMadMessage )
|
||
{
|
||
// The big essay.
|
||
// Centre it on all sides.
|
||
SLONG iXSize[3], iYSize = 0;
|
||
char *pcString[3];
|
||
if ( !IsEnglish )
|
||
{
|
||
pcString[0] = "Une manette vient d'etre"; // NOTE! The E in etre should be <20>, but the font doesn't have it, and it's all in caps anyway.
|
||
if ( bWriteVMInsteadOfVMU )
|
||
{
|
||
pcString[1] = "retir<EFBFBD>e ou une VM est";
|
||
}
|
||
else
|
||
{
|
||
pcString[1] = "retir<EFBFBD>e ou une VMU est";
|
||
}
|
||
pcString[2] = "en cours de d<>tection";
|
||
}
|
||
else
|
||
{
|
||
pcString[0] = "The controller has been";
|
||
if ( bWriteVMInsteadOfVMU )
|
||
{
|
||
pcString[1] = "removed or a VM";
|
||
}
|
||
else
|
||
{
|
||
pcString[1] = "removed or a VMU";
|
||
}
|
||
pcString[2] = "is being recognised";
|
||
}
|
||
|
||
for ( int i = 0; i < 3; i++ )
|
||
{
|
||
SLONG iYTemp;
|
||
MENUFONT_Dimensions ( pcString[i], iXSize[i], iYTemp, 640, BIG_FONT_SCALE );
|
||
iYSize += iYTemp;
|
||
}
|
||
|
||
// Darken the whole damn screen.
|
||
PANEL_draw_quad(
|
||
0.0f,
|
||
0.0f,
|
||
640.0f,
|
||
480.0f,
|
||
POLY_PAGE_ALPHA,
|
||
0xc0000000,
|
||
0.0f,
|
||
0.0f,
|
||
0.0f,
|
||
0.0f);
|
||
|
||
MENUFONT_Draw ( (640-iXSize[0] ) >> 1, (480-iYSize ) >> 1, BIG_FONT_SCALE, pcString[0], 0xffffffff, 0 );
|
||
MENUFONT_Draw ( (640-iXSize[1] ) >> 1, (480-0 ) >> 1, BIG_FONT_SCALE, pcString[1], 0xffffffff, 0 );
|
||
MENUFONT_Draw ( (640-iXSize[2] ) >> 1, (480+iYSize ) >> 1, BIG_FONT_SCALE, pcString[2], 0xffffffff, 0 );
|
||
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
// Put at almost bottom centre - got to avoid the outer 16 pixels.
|
||
// Also avoid the ConStaStrRef stuff as well.
|
||
SLONG iXSize, iYSize;
|
||
MENUFONT_Dimensions ( pcQuickInfo, iXSize, iYSize, 640, BIG_FONT_SCALE );
|
||
|
||
// If on the title screen, move it to the top.
|
||
int iYpos;
|
||
if ( ( menu_state.mode == FE_TITLESCREEN ) || ( menu_state.mode == FE_LANGUAGESCREEN ) )
|
||
{
|
||
iYpos = 32+16;
|
||
}
|
||
else
|
||
{
|
||
iYpos = 480-32-16;
|
||
}
|
||
MENUFONT_Draw_Selection_Box ( (640-iXSize ) >> 1, iYpos, BIG_FONT_SCALE, pcQuickInfo, 0xffffffff, 0 );
|
||
MENUFONT_Draw ( (640-iXSize ) >> 1, iYpos, BIG_FONT_SCALE, pcQuickInfo, 0xffffffff, 0 );
|
||
}
|
||
|
||
if ( (signed)( timeGetTime() - dwQuickInfotimeGetTimeExpires ) > 0 )
|
||
{
|
||
pcQuickInfo[0] = '\0';
|
||
bQuickInfoReplaceWithSegasMadMessage = FALSE;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Just for non-final builds.
|
||
static CBYTE version_number[64] = "";
|
||
|
||
if ( version_number[0] == '\0' )
|
||
{
|
||
CBYTE ts[40] = __DATE__;
|
||
float vn;
|
||
|
||
CBYTE *month[12] =
|
||
{
|
||
"Jan",
|
||
"Feb",
|
||
"Mar",
|
||
"Apr",
|
||
"May",
|
||
"Jun",
|
||
"Jul",
|
||
"Aug",
|
||
"Sep",
|
||
"Oct",
|
||
"Nov",
|
||
"Dec"
|
||
};
|
||
|
||
SLONG i;
|
||
|
||
vn = 0.0F;
|
||
|
||
for (i = 0; i < 12; i++)
|
||
{
|
||
if (toupper(ts[0]) == toupper(month[i][0]) &&
|
||
toupper(ts[1]) == toupper(month[i][1]) &&
|
||
toupper(ts[2]) == toupper(month[i][2]))
|
||
{
|
||
vn = i - 8.0F;
|
||
}
|
||
}
|
||
|
||
SLONG day = atoi(ts + 4);
|
||
|
||
vn += day * 0.03F;
|
||
|
||
SLONG year = atoi(ts + 7);
|
||
|
||
vn += (year - 1999) * 12;
|
||
|
||
sprintf(version_number, "Version %.2f", vn );
|
||
}
|
||
|
||
|
||
static bool bShowVersionNumInFrontEnd = FALSE;
|
||
extern int g_iCheatNumber;
|
||
if ( g_iCheatNumber == 0x1a1a0002 )
|
||
{
|
||
bShowVersionNumInFrontEnd = TRUE;
|
||
g_iCheatNumber = 0;
|
||
}
|
||
|
||
if ( bShowVersionNumInFrontEnd )
|
||
{
|
||
FONT2D_DrawString(
|
||
version_number,
|
||
20,
|
||
20,
|
||
0xffffffff);
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
#ifndef TARGET_DC
|
||
POLY_frame_draw(FALSE, FALSE);
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
void FRONTEND_storedata() {
|
||
switch(menu_state.mode) {
|
||
case FE_CONFIG_VIDEO:
|
||
FRONTEND_store_video_data();
|
||
break;
|
||
case FE_CONFIG_AUDIO:
|
||
MFX_stop(WEATHER_REF,MFX_WAVE_ALL);
|
||
//MFX_stop(SIREN_REF,MFX_WAVE_ALL);
|
||
// MFX_stop(MFX_CHANNEL_ALL,MFX_WAVE_ALL);
|
||
// MFX_free_wave_list();
|
||
|
||
MFX_set_volumes(menu_data[0].Data>>1,menu_data[1].Data>>1,menu_data[2].Data>>1);
|
||
#ifdef TARGET_DC
|
||
if ( ( menu_data[3].Data & 0xff ) == 0 )
|
||
{
|
||
// Mono.
|
||
SetFirmwareValues ( DWORD_DONT_CHANGE, BYTE_DONT_CHANGE, BYTE_DONT_CHANGE, SOUND_MODE_MONO, BYTE_DONT_CHANGE );
|
||
}
|
||
else
|
||
{
|
||
// Stereo
|
||
SetFirmwareValues ( DWORD_DONT_CHANGE, BYTE_DONT_CHANGE, BYTE_DONT_CHANGE, SOUND_MODE_STEREO, BYTE_DONT_CHANGE );
|
||
}
|
||
#endif
|
||
|
||
#ifdef ALLOW_DANGEROUS_OPTIONS
|
||
Set3DProvider(menu_data[3].Data&0xff);
|
||
#endif
|
||
|
||
|
||
break;
|
||
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
case FE_CONFIG_INPUT_KB:
|
||
ENV_set_value_number("keyboard_left", menu_data[0].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_right", menu_data[1].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_forward", menu_data[2].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_back", menu_data[3].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_punch", menu_data[4].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_kick", menu_data[5].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_action", menu_data[6].Data, "Keyboard");
|
||
// ENV_set_value_number("keyboard_run", menu_data[7].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_jump", menu_data[7].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_start", menu_data[8].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_select", menu_data[9].Data, "Keyboard");
|
||
// gap for label
|
||
ENV_set_value_number("keyboard_camera", menu_data[11].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_cam_left", menu_data[12].Data, "Keyboard");
|
||
ENV_set_value_number("keyboard_cam_right", menu_data[13].Data , "Keyboard");
|
||
ENV_set_value_number("keyboard_1stperson", menu_data[14].Data, "Keyboard");
|
||
break;
|
||
#endif
|
||
|
||
case FE_CONFIG_INPUT_JP:
|
||
#ifdef TARGET_DC
|
||
// Save the preset mode.
|
||
ENV_set_value_number("joypad_mode", (menu_data[0].Data & 0xff) , "Joypad");
|
||
if ( ( menu_data[0].Data & 0xff ) == 0 )
|
||
{
|
||
// Custom mode. Save the custom buttons too.
|
||
ENV_set_value_number("joypad_punch", menu_data[2].Data, "Joypad");
|
||
ENV_set_value_number("joypad_kick", menu_data[3].Data, "Joypad");
|
||
ENV_set_value_number("joypad_jump", menu_data[4].Data, "Joypad");
|
||
ENV_set_value_number("joypad_action", menu_data[5].Data, "Joypad");
|
||
ENV_set_value_number("joypad_move", menu_data[6].Data, "Joypad");
|
||
ENV_set_value_number("joypad_select", menu_data[7].Data, "Joypad");
|
||
// gap for label
|
||
ENV_set_value_number("joypad_camera", menu_data[9].Data, "Joypad");
|
||
ENV_set_value_number("joypad_cam_left", menu_data[10].Data, "Joypad");
|
||
ENV_set_value_number("joypad_cam_right", menu_data[11].Data , "Joypad");
|
||
ENV_set_value_number("joypad_1stperson", menu_data[12].Data, "Joypad");
|
||
}
|
||
#else
|
||
ENV_set_value_number("joypad_kick", menu_data[0].Data, "Joypad");
|
||
ENV_set_value_number("joypad_punch", menu_data[1].Data, "Joypad");
|
||
ENV_set_value_number("joypad_jump", menu_data[2].Data, "Joypad");
|
||
ENV_set_value_number("joypad_action", menu_data[3].Data, "Joypad");
|
||
ENV_set_value_number("joypad_move", menu_data[4].Data, "Joypad");
|
||
ENV_set_value_number("joypad_start", menu_data[5].Data, "Joypad");
|
||
ENV_set_value_number("joypad_select", menu_data[6].Data, "Joypad");
|
||
// gap for label
|
||
ENV_set_value_number("joypad_camera", menu_data[8].Data, "Joypad");
|
||
ENV_set_value_number("joypad_cam_left", menu_data[9].Data, "Joypad");
|
||
ENV_set_value_number("joypad_cam_right", menu_data[10].Data , "Joypad");
|
||
ENV_set_value_number("joypad_1stperson", menu_data[11].Data, "Joypad");
|
||
#endif
|
||
break;
|
||
|
||
case FE_CONFIG_OPTIONS:
|
||
#ifdef TARGET_DC
|
||
ENV_set_value_number("scanner_follows", menu_data[0].Data&1, "Game");
|
||
ENV_set_value_number("analogue_pad_mode", menu_data[1].Data&1, "Game");
|
||
ENV_set_value_number("vibration_mode", menu_data[2].Data&1, "Game");
|
||
ENV_set_value_number("vibration_engine", menu_data[3].Data&1, "Game");
|
||
#else
|
||
ENV_set_value_number("scanner_follows", menu_data[1].Data&1, "Game");
|
||
#endif
|
||
break;
|
||
|
||
}
|
||
}
|
||
|
||
BOOL FRONTEND_ValidMission(SWORD sel) {
|
||
CBYTE *str=menu_buffer;
|
||
UBYTE id=*str;
|
||
|
||
while (sel) {
|
||
sel--;
|
||
str++;
|
||
str+=strlen(str)+1;
|
||
id=*str;
|
||
}
|
||
return (BOOL)(mission_hierarchy[id]&4);
|
||
}
|
||
|
||
|
||
|
||
|
||
UBYTE FRONTEND_input() {
|
||
UBYTE scan, any_button=0;
|
||
#ifndef TARGET_DC
|
||
// DC input system does this for us.
|
||
static SLONG last_input=0;
|
||
#endif
|
||
static UBYTE last_button=0;
|
||
static UBYTE first_pad=1;
|
||
|
||
SLONG input=0;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
if ( ( menu_state.mode == FE_SAVESCREEN ) || ( menu_state.mode == FE_LOADSCREEN ) || ( menu_state.mode == FE_VMU_SELECT ) )
|
||
{
|
||
// While these are shown, we much watch the VMUs and controllers.
|
||
// If any change state, the correct screen needs refreshing.
|
||
bool bSomethingChanged = RescanDevices();
|
||
if ( bSomethingChanged )
|
||
{
|
||
// Delete any removed devices.
|
||
DeleteInvalidDevice();
|
||
|
||
fade_mode=1;
|
||
// Re-enter this screen.
|
||
FRONTEND_mode ( menu_state.mode, FALSE );
|
||
// Pop the stack.
|
||
menu_state.stackpos--;
|
||
#if 0
|
||
switch ( menu_state.mode )
|
||
{
|
||
case FE_SAVESCREEN:
|
||
menu_state.title=XLAT_str_ptr(X_SAVE_GAME);
|
||
break;
|
||
case FE_LOADSCREEN:
|
||
menu_state.title=XLAT_str_ptr(X_LOAD_GAME);
|
||
break;
|
||
case FE_VMU_SELECT:
|
||
menu_state.title=XLAT_str_ptr(X_VMU_SELECT);
|
||
break;
|
||
default:
|
||
ASSERT ( FALSE );
|
||
break;
|
||
}
|
||
#endif
|
||
FRONTEND_kibble_flurry();
|
||
return ( 0 );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#ifdef TARGET_DC
|
||
extern DIDeviceInfo *primary_device;
|
||
extern BOOL AreAnyDevicesConnected ( void );
|
||
|
||
if ( primary_device == NULL )
|
||
{
|
||
if ( AreAnyDevicesConnected() )
|
||
{
|
||
// No current controller, but there is one connected. Tell them to press start.
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_CONTROLLER_REMOVED ), 100 );
|
||
}
|
||
else
|
||
{
|
||
// No controllers at all.
|
||
// Display Sega's mad message.
|
||
FRONTEND_MakeQuickMessage ( XLAT_str ( X_NO_CONTROLLER_CONNECTED ), 100, TRUE );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
if ( m_bMovingPanel )
|
||
{
|
||
// While the action button is held down, the analog stick or D-pad
|
||
// move the panel display around the screen.
|
||
// Wait until a new button goes down (not the one that just selected this option).
|
||
// Also need to remap so that we ignore the normal mappings, otherwise buttons that
|
||
// don't have any current mapping don't trigger anything!
|
||
DWORD dwInput = get_hardware_input ( INPUT_TYPE_JOY | INPUT_TYPE_REMAP_DPAD | INPUT_TYPE_REMAP_BUTTONS | INPUT_TYPE_REMAP_START_BUTTON );
|
||
|
||
if ( ( dwInput & INPUT_MASK_DOMENU ) == 0 )
|
||
{
|
||
// They stopped pressing the "do" button. Stop doing this.
|
||
m_bMovingPanel = FALSE;
|
||
}
|
||
else
|
||
{
|
||
// OK, still moving the panel.
|
||
// REMEMBER THAT THESE NUMBERS ARE DIVIDED BY 4!
|
||
int iXPos = ENV_get_value_number ( "panel_x", 32 / 4, "" );
|
||
int iYPos = ENV_get_value_number ( "panel_y", (480 - 32) / 4, "" );
|
||
|
||
// Move the panel
|
||
#define PANEL_MOVE_SHIFT 3
|
||
|
||
if ( dwInput & INPUT_MASK_LEFT )
|
||
{
|
||
int iHowMuch = 0x20 - ( ( dwInput >> 18 ) & 0x7f );
|
||
iHowMuch >>= PANEL_MOVE_SHIFT;
|
||
// Small possibility that it can be -ve (if digital stick is used, but analog centres slighty to right)
|
||
if ( iHowMuch < 0 )
|
||
{
|
||
iHowMuch = 0;
|
||
}
|
||
// Always at least 1 (also allows the digital stick to do slides).
|
||
iHowMuch++;
|
||
iXPos -= iHowMuch;
|
||
if ( iXPos < 0 )
|
||
{
|
||
iXPos = 0;
|
||
}
|
||
}
|
||
|
||
if ( dwInput & INPUT_MASK_RIGHT )
|
||
{
|
||
int iHowMuch = ( ( dwInput >> 18 ) & 0x7f ) - 0x5f;
|
||
iHowMuch >>= PANEL_MOVE_SHIFT;
|
||
// Small possibility that it can be -ve (if digital stick is used, but analog centres slighty to right)
|
||
if ( iHowMuch < 0 )
|
||
{
|
||
iHowMuch = 0;
|
||
}
|
||
// Always at least 1 (also allows the digital stick to do slides).
|
||
iHowMuch++;
|
||
iXPos += iHowMuch;
|
||
if ( iXPos > ( ( 640 - 212 ) / 4 ) )
|
||
{
|
||
iXPos = ( 640 - 212 ) / 4;
|
||
}
|
||
}
|
||
|
||
if ( dwInput & INPUT_MASK_FORWARDS )
|
||
{
|
||
int iHowMuch = 0x20 - ( ( dwInput >> 25 ) & 0x7f );
|
||
iHowMuch >>= PANEL_MOVE_SHIFT;
|
||
// Small possibility that it can be -ve
|
||
if ( iHowMuch < 0 )
|
||
{
|
||
iHowMuch = 0;
|
||
}
|
||
// Always at least 1 (also allows the digital stick to do slides).
|
||
iHowMuch++;
|
||
iYPos -= iHowMuch;
|
||
if ( iYPos < ( 165 / 4 ) )
|
||
{
|
||
iYPos = 165 / 4;
|
||
}
|
||
}
|
||
|
||
if ( dwInput & INPUT_MASK_BACKWARDS )
|
||
{
|
||
int iHowMuch = ( ( dwInput >> 25 ) & 0x7f ) - 0x5f;
|
||
iHowMuch >>= PANEL_MOVE_SHIFT;
|
||
// Small possibility that it can be -ve
|
||
if ( iHowMuch < 0 )
|
||
{
|
||
iHowMuch = 0;
|
||
}
|
||
// Always at least 1 (also allows the digital stick to do slides).
|
||
iHowMuch++;
|
||
iYPos += iHowMuch;
|
||
if ( iYPos > ( 480 / 4 ) )
|
||
{
|
||
iYPos = 480 / 4;
|
||
}
|
||
}
|
||
|
||
// Store the values back.
|
||
ASSERT ( ( iXPos >= 0 ) && ( iXPos < 256 ) );
|
||
ASSERT ( ( iYPos >= 0 ) && ( iYPos < 256 ) );
|
||
ENV_set_value_number ( "panel_x", iXPos, "" );
|
||
ENV_set_value_number ( "panel_y", iYPos, "" );
|
||
}
|
||
}
|
||
else
|
||
#endif
|
||
|
||
#ifdef TARGET_DC
|
||
if (grabbing_pad)
|
||
#else
|
||
if (grabbing_pad&&!last_input)
|
||
#endif
|
||
{
|
||
UBYTE i,j;
|
||
MenuData *item=menu_data+menu_state.selected;
|
||
#ifndef TARGET_DC
|
||
ReadInputDevice();
|
||
#else
|
||
// Wait until a new button goes down (not the one that just selected this option).
|
||
// Also need to remap so that we ignore the normal mappings, otherwise buttons that
|
||
// don't have any current mapping don't trigger anything!
|
||
input = get_hardware_input ( INPUT_TYPE_JOY | INPUT_TYPE_REMAP_DPAD | INPUT_TYPE_REMAP_BUTTONS | INPUT_TYPE_GONEDOWN | INPUT_TYPE_REMAP_START_BUTTON );
|
||
if ( input == 0 )
|
||
{
|
||
return 0;
|
||
}
|
||
#endif
|
||
#ifndef TARGET_DC
|
||
if (Keys[KB_ESC]||(input&INPUT_MASK_CANCEL))
|
||
#else
|
||
// On DC, use "start" as the cancel button, since we're not allowed to map anything onto it anyway.
|
||
if ( input & INPUT_MASK_START )
|
||
#endif
|
||
{
|
||
Keys[KB_ESC]=0;
|
||
#if 0
|
||
// Should we not just leave this as it is, rather than setting it to "unused"?
|
||
item->Data=31;
|
||
#endif
|
||
grabbing_pad=0;
|
||
}
|
||
else
|
||
{
|
||
for (i=0;i<32;i++)
|
||
{
|
||
if (the_state.rgbButtons[i] & 0x80)
|
||
{
|
||
for (j=0;j<menu_state.items;j++)
|
||
{
|
||
if (menu_data[j].Data==i)
|
||
{
|
||
menu_data[j].Data=31;
|
||
}
|
||
}
|
||
item->Data=i;
|
||
#ifndef TARGET_DC
|
||
last_button=1;
|
||
#else
|
||
last_button=0;
|
||
#endif
|
||
grabbing_pad=0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
} else {
|
||
|
||
#ifdef ALLOW_JOYPAD_IN_FRONTEND
|
||
|
||
|
||
// these are in interfac.cpp -- but the NOISE_TOLERANCE there, while appropriate for the game,
|
||
// is SHITTY for the menu. so here's a new one.
|
||
|
||
#define AXIS_CENTRE 32768
|
||
#define NOISE_TOLERANCE 4096
|
||
#define AXIS_MIN (AXIS_CENTRE-NOISE_TOLERANCE)
|
||
#define AXIS_MAX (AXIS_CENTRE+NOISE_TOLERANCE)
|
||
|
||
//extern ULONG get_hardware_input(UWORD type);
|
||
#ifdef TARGET_DC
|
||
input = get_hardware_input ( INPUT_TYPE_JOY | INPUT_TYPE_REMAP_DPAD | INPUT_TYPE_REMAP_BUTTONS | INPUT_TYPE_GONEDOWN | INPUT_TYPE_REMAP_START_BUTTON );
|
||
#else
|
||
input = get_hardware_input(INPUT_TYPE_JOY);
|
||
#endif
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// On the title screen, if there is a primary device,
|
||
// then we want to get onto the next screen immediately.
|
||
// So fake up a button A press. What a kludge!
|
||
if ( menu_state.mode == FE_TITLESCREEN )
|
||
{
|
||
if ( primary_device != NULL )
|
||
{
|
||
// The is a primary, so you must have pressed "Start",
|
||
// since the title screen resets the current device.
|
||
input = INPUT_MASK_DOMENU;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
// On the DC, the standard input is just fine.
|
||
#ifndef TARGET_DC
|
||
|
||
// TRACE("raw input: %d -- ",input);
|
||
input&=~(INPUT_MASK_LEFT|INPUT_MASK_RIGHT|INPUT_MASK_FORWARDS|INPUT_MASK_BACKWARDS);
|
||
if(the_state.lX>AXIS_MAX)
|
||
{
|
||
input |= INPUT_MASK_RIGHT;
|
||
}
|
||
else if(the_state.lX<AXIS_MIN)
|
||
{
|
||
input |= INPUT_MASK_LEFT;
|
||
}
|
||
|
||
// let's not allow diagonals, they're silly.
|
||
|
||
if(the_state.lY>AXIS_MAX)
|
||
{
|
||
input&=~(INPUT_MASK_LEFT|INPUT_MASK_RIGHT);
|
||
input|=INPUT_MASK_BACKWARDS;
|
||
}
|
||
else if(the_state.lY<AXIS_MIN)
|
||
{
|
||
input&=~(INPUT_MASK_LEFT|INPUT_MASK_RIGHT);
|
||
input|=INPUT_MASK_FORWARDS;
|
||
}
|
||
#endif //#ifndef TARGET_DC
|
||
|
||
#ifndef TARGET_DC
|
||
if (input==last_input) {
|
||
input=0;
|
||
any_button=0;
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
#ifndef TARGET_DC
|
||
last_input=input;
|
||
#endif
|
||
#ifndef TARGET_DC
|
||
for (scan=0;scan<8;scan++)
|
||
any_button |= the_state.rgbButtons[scan];
|
||
// Supress very first movement - PC joysticks have a
|
||
// strange habit of doing one movement on boot-up for some reason.
|
||
if (first_pad)
|
||
{
|
||
if (any_button)
|
||
first_pad=0;
|
||
else
|
||
if (input& (INPUT_MASK_LEFT|INPUT_MASK_RIGHT|INPUT_MASK_FORWARDS|INPUT_MASK_BACKWARDS)) {
|
||
first_pad=0;
|
||
input=0;
|
||
}
|
||
}
|
||
#else
|
||
// On DC, this has already been done - appropriate buttons are mapped to punch.
|
||
any_button = ( ( input & INPUT_MASK_DOMENU ) != 0 ) ? 1 : 0;
|
||
#endif
|
||
if (last_button)
|
||
{
|
||
if (!any_button)
|
||
last_button=0;
|
||
else
|
||
any_button=0;
|
||
}
|
||
}
|
||
// TRACE("proc'd input: %d\n",input);
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Sense ABXYStart
|
||
if ( g_bDreamcastABXYStartComboPressed )
|
||
{
|
||
g_bDreamcastABXYStartComboPressed = FALSE;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
// Go to the title screen instead of the menu screen.
|
||
if ( menu_state.mode != FE_TITLESCREEN )
|
||
{
|
||
// Go to the main menu.
|
||
menu_mode_queued=FE_TITLESCREEN;
|
||
fade_mode=2|4;
|
||
//FRONTEND_kibble_flurry();
|
||
return FE_TITLESCREEN;
|
||
}
|
||
#else
|
||
if ( menu_state.mode != FE_MAINMENU )
|
||
{
|
||
// Go to the main menu.
|
||
menu_mode_queued=FE_MAINMENU;
|
||
fade_mode=2|4;
|
||
FRONTEND_kibble_flurry();
|
||
return FE_MAINMENU;
|
||
}
|
||
#endif
|
||
else
|
||
{
|
||
// Already at main menu - bin everything and quit to BIOS boot screen.
|
||
ASSERT ( FALSE );
|
||
ResetToFirmware();
|
||
}
|
||
}
|
||
#endif
|
||
|
||
if (grabbing_key&&LastKey) {
|
||
MenuData *item=menu_data+menu_state.selected;
|
||
// CBYTE key=(Keys[KB_LSHIFT]||Keys[KB_RSHIFT]) ? InkeyToAsciiShift[LastKey] : InkeyToAscii[LastKey];
|
||
/* switch(LastKey){
|
||
case KB_LEFT: case KB_RIGHT: case KB_UP: case KB_DOWN: case KB_ENTER: case KB_SPACE:
|
||
case KB_LSHIFT: case KB_RSHIFT: case KB_LALT: case KB_RALT: case KB_LCONTROL: case KB_RCONTROL:
|
||
case KB_TAB: case KB_END: case KB_HOME: case KB_DEL: case KB_INS: case KB_PGUP: case KB_PGDN:
|
||
item->Data=LastKey;
|
||
Keys[LastKey]=0;
|
||
break;
|
||
case KB_ESC: break;
|
||
default:
|
||
item->Data=key;
|
||
}*/
|
||
if (LastKey!=KB_ESC) {
|
||
UBYTE j;
|
||
for (j=0;j<menu_state.items;j++)
|
||
if (menu_data[j].Data==LastKey) menu_data[j].Data=0;
|
||
item->Data=LastKey;
|
||
|
||
// CBYTE moo[20];
|
||
// GetKeyNameText(LastKey<<16,moo,20);
|
||
|
||
}
|
||
Keys[LastKey]=0;
|
||
grabbing_key=0;
|
||
//Keys[KB_ESC]=Keys[KB_UP]=Keys[KB_DOWN]=Keys[KB_LEFT]=Keys[KB_RIGHT]=Keys[KB_ENTER]=0;
|
||
return 0;
|
||
}
|
||
if(allow_debug_keys)
|
||
{
|
||
if (Keys[KB_1]||Keys[KB_2]||Keys[KB_3]||Keys[KB_4])
|
||
{
|
||
if (Keys[KB_1]) { Keys[KB_1]=0; menu_theme=0; }
|
||
if (Keys[KB_2]) { Keys[KB_2]=0; menu_theme=1; }
|
||
if (Keys[KB_3]) { Keys[KB_3]=0; menu_theme=2; }
|
||
if (Keys[KB_4]) { Keys[KB_4]=0; menu_theme=3; }
|
||
//InitBackImage(menu_back_names[menu_theme]);
|
||
UseBackSurface(screenfull_back);
|
||
|
||
FRONTEND_kibble_init();
|
||
}
|
||
}
|
||
|
||
#ifndef TARGET_DC
|
||
if (Keys[KB_END])
|
||
{
|
||
Keys[KB_END]=0;
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
menu_state.selected=menu_state.items-1;
|
||
if (menu_state.mode==FE_MAPSCREEN) mission_selected=mission_count-1;
|
||
while (((menu_data+menu_state.selected)->Type==OT_LABEL)||(((menu_data+menu_state.selected)->Type==OT_BUTTON)&&((menu_data+menu_state.selected)->Choices==(CBYTE*)1)))
|
||
menu_state.selected--;
|
||
}
|
||
if (Keys[KB_HOME])
|
||
{
|
||
Keys[KB_HOME]=0;
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
menu_state.selected=0;
|
||
if (menu_state.mode==FE_MAPSCREEN) mission_selected=0;
|
||
while (((menu_data+menu_state.selected)->Type==OT_LABEL)||(((menu_data+menu_state.selected)->Type==OT_BUTTON)&&((menu_data+menu_state.selected)->Choices==(CBYTE*)1)))
|
||
menu_state.selected++;
|
||
}
|
||
#endif
|
||
if (Keys[KB_UP]||(input&INPUT_MASK_FORWARDS)) {
|
||
Keys[KB_UP]=0;
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
if (menu_state.selected>0) menu_state.selected--;
|
||
else menu_state.selected=menu_state.items-1;
|
||
while (((menu_data+menu_state.selected)->Type==OT_LABEL)||(((menu_data+menu_state.selected)->Type==OT_BUTTON)&&((menu_data+menu_state.selected)->Choices==(CBYTE*)1))) {
|
||
if (menu_state.selected>0) menu_state.selected--;
|
||
else menu_state.selected=menu_state.items-1;
|
||
}
|
||
if ((menu_state.mode==FE_MAPSCREEN)&&mission_selected) mission_selected--;
|
||
}
|
||
if (Keys[KB_DOWN]||(input&INPUT_MASK_BACKWARDS)) {
|
||
Keys[KB_DOWN]=0;
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
if (menu_state.selected<menu_state.items-1) menu_state.selected++;
|
||
else menu_state.selected=0;
|
||
while (((menu_data+menu_state.selected)->Type==OT_LABEL)||(((menu_data+menu_state.selected)->Type==OT_BUTTON)&&((menu_data+menu_state.selected)->Choices==(CBYTE*)1))) {
|
||
if (menu_state.selected<menu_state.items-1) menu_state.selected++;
|
||
else menu_state.selected--;
|
||
}
|
||
if ((menu_state.mode==FE_MAPSCREEN)&&(mission_selected<mission_count-1)&&(FRONTEND_ValidMission(mission_selected+1))) mission_selected++;
|
||
}
|
||
|
||
if (Keys[KB_ENTER ] ||
|
||
Keys[KB_SPACE ] ||
|
||
Keys[KB_PENTER] ||
|
||
any_button
|
||
)
|
||
{
|
||
Keys[KB_ENTER ] = 0;
|
||
Keys[KB_SPACE ] = 0;
|
||
Keys[KB_PENTER] = 0;
|
||
MenuData *item=menu_data+menu_state.selected;
|
||
|
||
if (fade_mode!=2) MFX_play_stereo(0,S_MENU_CLICK_END,MFX_REPLACE);
|
||
FRONTEND_stop_xition();
|
||
#ifdef TARGET_DC
|
||
// Only go here if we are overwriting a file.
|
||
if ((menu_state.mode==FE_SAVESCREEN)&&(item->Data==FE_SAVE_CONFIRM))
|
||
#else
|
||
if ((menu_state.mode==FE_SAVESCREEN)&&(item->Data!=FE_BACK))
|
||
#endif
|
||
{
|
||
save_slot=menu_state.selected+1;
|
||
// item->LabelID=X_SAVE_GAME;
|
||
/* menu_mode_queued=FE_SAVE_CONFIRM;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
return 0;*/
|
||
}
|
||
#ifdef TARGET_DC
|
||
if ((menu_state.mode==FE_VMU_SELECT)&&(item->Data==FE_MAINMENU))
|
||
{
|
||
// Set this VMU to be the current one.
|
||
MapleVMU *pVMU = FindMemoryVMUAt ( m_ubVMUListCtrl[menu_state.selected], m_ubVMUListSlot[menu_state.selected] );
|
||
SetCurrentStorageVMU ( pVMU );
|
||
item->Data = FE_BACK;
|
||
}
|
||
|
||
if ((menu_state.mode==FE_CONFIG_OPTIONS)&&(item->LabelID==X_VIBRATION))
|
||
{
|
||
// Remember, this is the state it is currently, so we are turning it on.
|
||
if ( ( item->Data & 0x1 ) == 0 )
|
||
{
|
||
// Set off a vibration.
|
||
SetVibrationEnable ( TRUE );
|
||
Vibrate ( 10.0f, 1.0f, 0.5f );
|
||
}
|
||
else
|
||
{
|
||
//Turn the Engine Vibration off as well.
|
||
item[1].Data &= ~1;
|
||
}
|
||
}
|
||
if ((menu_state.mode==FE_CONFIG_OPTIONS)&&(item->LabelID==X_VIBRATION_ENG))
|
||
{
|
||
// Remember, this is the state it is currently, so we are turning it on.
|
||
if ( ( item->Data & 0x1 ) == 0 )
|
||
{
|
||
//Turn all vibrations on as well.
|
||
item[-1].Data |= 1;
|
||
// Set off a vibration.
|
||
SetVibrationEnable ( TRUE );
|
||
Vibrate ( 10.0f, 1.0f, 0.5f );
|
||
}
|
||
}
|
||
|
||
#endif
|
||
if ((menu_state.mode==FE_SAVESCREEN)&&(item->Data==FE_MAPSCREEN))
|
||
{
|
||
menu_mode_queued=FE_MAPSCREEN;
|
||
menu_state.stackpos=0;
|
||
menu_thrash=FE_MAINMENU;
|
||
}
|
||
#ifdef TARGET_DC
|
||
// If not overwriting a file, we come straight here without a confirm.
|
||
if ( ( (menu_state.mode==FE_SAVESCREEN)&&(item->Data==FE_MAPSCREEN) )
|
||
||( (menu_state.mode==FE_SAVE_CONFIRM)&&(item->Data==FE_MAPSCREEN) ) )
|
||
#else
|
||
if ((menu_state.mode==FE_SAVE_CONFIRM)&&(item->Data==FE_MAPSCREEN))
|
||
#endif
|
||
{
|
||
if ( item->LabelID == X_CANCEL )
|
||
{
|
||
// Cancel was pressed - just exit.
|
||
menu_mode_queued=FE_MAPSCREEN;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
menu_state.stackpos=0;
|
||
menu_thrash=FE_MAINMENU;
|
||
return 0;
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
if ( menu_state.mode==FE_SAVESCREEN )
|
||
{
|
||
// Which slot was it?
|
||
save_slot=menu_state.selected+1;
|
||
}
|
||
|
||
// Find the next "recommended" mission.
|
||
FRONTEND_MissionHierarchy(MISSION_SCRIPT);
|
||
bool bSuccess = FRONTEND_save_savegame(iNextSuggestedMission,save_slot);
|
||
#else
|
||
CBYTE ttl[_MAX_PATH];
|
||
FRONTEND_fetch_title_from_id(MISSION_SCRIPT,ttl,mission_launch);
|
||
bool bSuccess = FRONTEND_save_savegame(ttl,save_slot);
|
||
#endif
|
||
if ( bSuccess )
|
||
{
|
||
menu_mode_queued=FE_MAPSCREEN;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
menu_state.stackpos=0;
|
||
menu_thrash=FE_MAINMENU;
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
// Failed. Just buzz and return to the main menu.
|
||
// I hope this "no" sound is a decent one - sound doesn't work yet!
|
||
MFX_play_stereo(0,S_MENU_CLICK_END,MFX_REPLACE);
|
||
menu_mode_queued=FE_MAPSCREEN;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
menu_state.stackpos=0;
|
||
menu_thrash=FE_MAINMENU;
|
||
return 0;
|
||
}
|
||
}
|
||
if (menu_state.mode==FE_MAPSCREEN) {
|
||
if (mission_count>0) {
|
||
menu_mode_queued=100+mission_selected;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
if (menu_state.mode>=100)
|
||
{
|
||
// Starting a mission.
|
||
// Stop any briefing.
|
||
MFX_QUICK_stop(TRUE);
|
||
return FE_START;
|
||
}
|
||
if ((menu_state.mode==FE_LOADSCREEN)&&(item->Data==FE_SAVE_CONFIRM))
|
||
{
|
||
bool bSuccess = FRONTEND_load_savegame(menu_state.selected+1);
|
||
if ( bSuccess )
|
||
{
|
||
FRONTEND_MissionHierarchy(MISSION_SCRIPT);
|
||
menu_mode_queued=FE_MAPSCREEN;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
// Failed the load. For now, do nothing.
|
||
// For example, can be if they select an "(EMPTY)" slot.
|
||
// I hope this "no" sound is a decent one - sound doesn't work yet!
|
||
MFX_play_stereo(0,S_MENU_CLICK_END,MFX_REPLACE);
|
||
// Quit back to the main menu.
|
||
menu_mode_queued=FE_MAINMENU;
|
||
fade_mode=2;
|
||
FRONTEND_kibble_flurry();
|
||
return 0;
|
||
}
|
||
}
|
||
switch (item->Type) {
|
||
case OT_MULTI:
|
||
// Cycle through all options.
|
||
item->Data = ( item->Data & ~0xff ) | ( ( item->Data & 0xff ) + 1 );
|
||
if ( ( item->Data & 0xff ) >= ( item->Data >> 8 ) )
|
||
{
|
||
item->Data &= ~0xff;
|
||
}
|
||
break;
|
||
case OT_KEYPRESS:
|
||
grabbing_key=1;
|
||
LastKey=0;
|
||
break;
|
||
case OT_PADPRESS:
|
||
if ( bCanChangeJoypadButtons )
|
||
{
|
||
grabbing_pad=1;
|
||
//LastKey=0;
|
||
#ifndef TARGET_DC
|
||
last_input = 0;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
// Can't change button - using a predefined setup.
|
||
// I hope this "no" sound is a decent one - sound doesn't work yet!
|
||
MFX_play_stereo(0,S_MENU_CLICK_END,MFX_REPLACE);
|
||
}
|
||
break;
|
||
case OT_PADMOVE:
|
||
// Enter pad-move mode.
|
||
m_bMovingPanel = TRUE;
|
||
break;
|
||
case OT_BUTTON:
|
||
case OT_BUTTON_L:
|
||
if (menu_state.mode==FE_START) return FE_LOADSCREEN;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
|
||
#if 0
|
||
if (menu_state.mode==FE_TITLESCREEN)
|
||
{
|
||
}
|
||
#endif
|
||
if (menu_state.mode==FE_LANGUAGESCREEN)
|
||
{
|
||
// Select the language based on button press, and go to the main menu.
|
||
switch ( item->LabelID )
|
||
{
|
||
case X_ENGLISH:
|
||
ENV_set_value_number ( "lang_num", 0, "" );
|
||
break;
|
||
case X_FRENCH:
|
||
ENV_set_value_number ( "lang_num", 1, "" );
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
mission_launch = 0;
|
||
return FE_CHANGE_LANGUAGE;
|
||
}
|
||
#endif
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
//if (item->Data==-1) return -1;
|
||
if (item->Data==FE_NO_REALLY_QUIT) return -1;
|
||
#endif
|
||
//if (item->Data==-2) FRONTEND_storedata();
|
||
if (item->Data==FE_BACK) FRONTEND_storedata();
|
||
if (item->Data==FE_START) return FE_LOADSCREEN;
|
||
// temp thingy:
|
||
//if (item->Data==FE_MAPSCREEN) return FE_START;
|
||
if (item->Data==FE_EDITOR) return FE_EDITOR;
|
||
if (item->Data==FE_CREDITS) return FE_CREDITS;
|
||
#ifdef TARGET_DC
|
||
if (item->Data==FE_CHANGE_JOYPAD)
|
||
{
|
||
// Wait until the button goes back up, or this joypad
|
||
// will immediately be selected again!
|
||
while ( 0 != ( INPUT_MASK_ALL_BUTTONS & get_hardware_input ( INPUT_TYPE_JOY | INPUT_TYPE_REMAP_DPAD | INPUT_TYPE_REMAP_BUTTONS | INPUT_TYPE_REMAP_START_BUTTON ) ) )
|
||
{
|
||
}
|
||
|
||
// Change the active joypad.
|
||
ClearPrimaryDevice();
|
||
// And pretend it did an "FE_BACK".
|
||
menu_mode_queued=FE_BACK;
|
||
FRONTEND_storedata();
|
||
fade_mode=2|4;
|
||
FRONTEND_kibble_flurry();
|
||
return 0;
|
||
}
|
||
#endif
|
||
|
||
FRONTEND_kibble_flurry();
|
||
|
||
//FRONTEND_mode(item->Data);
|
||
menu_mode_queued=item->Data;
|
||
fade_mode=2|((item->Data==FE_BACK)?4:0);
|
||
break;
|
||
case OT_RESET:
|
||
switch(menu_state.mode){
|
||
#ifdef WANT_A_KEYBOARD_ITEM
|
||
case FE_CONFIG_INPUT_KB:
|
||
menu_data[0].Data = 203;
|
||
menu_data[1].Data = 205;
|
||
menu_data[2].Data = 200;
|
||
menu_data[3].Data = 208;
|
||
menu_data[4].Data = 44;
|
||
menu_data[5].Data = 45;
|
||
menu_data[6].Data = 46;
|
||
//menu_data[7].Data = 47;
|
||
menu_data[7].Data = 57;
|
||
menu_data[8].Data = 15;
|
||
menu_data[9].Data = 28;
|
||
// gap for label
|
||
menu_data[11].Data = 207;
|
||
menu_data[12].Data = 211;
|
||
menu_data[13].Data= 209;
|
||
menu_data[14].Data= 30;
|
||
break;
|
||
#endif
|
||
case FE_CONFIG_INPUT_JP:
|
||
#ifdef TARGET_DC
|
||
menu_data[0].Data = 1 | (5<<8);
|
||
// gap for label
|
||
menu_data[2].Data = 9;
|
||
menu_data[3].Data = 10;
|
||
menu_data[4].Data = 7;
|
||
menu_data[5].Data = 1;
|
||
menu_data[6].Data = 3;
|
||
menu_data[7].Data = 0;
|
||
// gap for label
|
||
menu_data[9].Data = 4;
|
||
menu_data[10].Data = 5;
|
||
menu_data[11].Data = 6;
|
||
menu_data[12].Data = 8;
|
||
#else
|
||
menu_data[0].Data = 4;
|
||
menu_data[1].Data = 3;
|
||
menu_data[2].Data = 0;
|
||
menu_data[3].Data = 1;
|
||
menu_data[4].Data = 7;
|
||
menu_data[5].Data = 8;
|
||
menu_data[6].Data = 2;
|
||
// gap for label
|
||
// menu_data[7].Data = 99;
|
||
menu_data[8].Data = 6;
|
||
menu_data[9].Data = 9;
|
||
menu_data[10].Data = 10;
|
||
menu_data[11].Data = 5;
|
||
#endif
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if (Keys[KB_LEFT]||(input&INPUT_MASK_LEFT)) {
|
||
Keys[KB_LEFT]=0;
|
||
MenuData *item=menu_data+menu_state.selected;
|
||
if ((item->Type==OT_SLIDER)&&(item->Data>0))
|
||
{
|
||
#ifdef TARGET_DC
|
||
// Analogue slidyness!
|
||
// The analog stuff has been masked out for GONEDOWN, so get it again.
|
||
DWORD dwInput = get_last_input ( 0 );
|
||
int iHowMuch = 0x20 - ( ( dwInput >> 18 ) & 0x7f );
|
||
iHowMuch >>= 3;
|
||
// Small possibility that it can be -ve (if digital stick is used, but analog centres slighty to right)
|
||
if ( iHowMuch < 0 )
|
||
{
|
||
iHowMuch = 0;
|
||
}
|
||
// Always at least 1 (also allows the digital stick to do slides).
|
||
iHowMuch++;
|
||
if ( item->Data > iHowMuch )
|
||
{
|
||
item->Data -= iHowMuch;
|
||
}
|
||
else
|
||
{
|
||
item->Data = 0;
|
||
}
|
||
// And allow this to autorepeat.
|
||
allow_input_autorepeat();
|
||
#else
|
||
item->Data--;
|
||
if (item->Data>0)
|
||
{
|
||
item->Data--;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
if ((menu_state.mode==FE_MAPSCREEN)&&district_selected) {
|
||
scan=district_selected-1;
|
||
while ((scan>0)&&!district_valid[scan]) scan--;
|
||
if (district_valid[scan]) {
|
||
district_selected=scan;
|
||
FRONTEND_MissionList(MISSION_SCRIPT,districts[district_selected][2]);
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
}
|
||
}
|
||
|
||
|
||
// No normal options can be changed by left/right - too easy to do on DC joypads.
|
||
#ifndef TARGET_DC
|
||
|
||
#ifdef TARGET_DC
|
||
if ((menu_state.mode==FE_CONFIG_OPTIONS)&&(item->LabelID==X_VIBRATION))
|
||
{
|
||
// Remember, this is the state it is currently, so we are turning it off.
|
||
if ( ( item->Data & 0x1 ) == 1 )
|
||
{
|
||
// Turn the Engine Vibration off as well.
|
||
item[1].Data &= ~1;
|
||
}
|
||
}
|
||
#endif
|
||
if ((item->Type==OT_MULTI)&&((item->Data&0xff)>0)) {
|
||
item->Data--;
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
}
|
||
#endif
|
||
|
||
if (menu_state.mode==FE_CONFIG_VIDEO) FRONTEND_gamma_update();
|
||
if ((menu_state.mode==FE_CONFIG_AUDIO)&&!menu_state.selected) {
|
||
MFX_play_stereo(1,S_TRAFFIC_CONE,0);
|
||
//MFX_set_gain(1,S_TRAFFIC_CONE,255);
|
||
}
|
||
|
||
}
|
||
if (Keys[KB_RIGHT]||(input&INPUT_MASK_RIGHT)) {
|
||
Keys[KB_RIGHT]=0;
|
||
MenuData *item=menu_data+menu_state.selected;
|
||
if ((item->Type==OT_SLIDER)&&(item->Data<255))
|
||
{
|
||
#ifdef TARGET_DC
|
||
// Analogue slidyness!
|
||
// The analog stuff has been masked out for GONEDOWN, so get it again.
|
||
DWORD dwInput = get_last_input ( 0 );
|
||
int iHowMuch = ( ( dwInput >> 18 ) & 0x7f ) - 0x5f;
|
||
iHowMuch >>= 3;
|
||
// Small possibility that it can be -ve (if digital stick is used, but analog centres slighty to right)
|
||
if ( iHowMuch < 0 )
|
||
{
|
||
iHowMuch = 0;
|
||
}
|
||
// Always at least 1 (also allows the digital stick to do slides).
|
||
iHowMuch++;
|
||
if ( item->Data < ( 256 - iHowMuch ) )
|
||
{
|
||
item->Data += iHowMuch;
|
||
}
|
||
else
|
||
{
|
||
item->Data = 255;
|
||
}
|
||
// And allow this to autorepeat.
|
||
allow_input_autorepeat();
|
||
#else
|
||
item->Data++;
|
||
if (item->Data<255)
|
||
{
|
||
item->Data++;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
if ((menu_state.mode==FE_MAPSCREEN)&&(district_selected<district_count-1)) {
|
||
scan=district_selected+1;
|
||
while ((scan<district_count-1)&&!district_valid[scan]) scan++;
|
||
if (district_valid[scan]) {
|
||
district_selected=scan;
|
||
FRONTEND_MissionList(MISSION_SCRIPT,districts[district_selected][2]);
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
}
|
||
}
|
||
|
||
|
||
// No normal options can be changed by left/right - too easy to do on DC joypads.
|
||
#ifndef TARGET_DC
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
if ((menu_state.mode==FE_CONFIG_OPTIONS)&&(item->LabelID==X_VIBRATION))
|
||
{
|
||
// Remember, this is the state it is currently, so we are turning it on.
|
||
if ( ( item->Data & 0x1 ) == 0 )
|
||
{
|
||
// Set off a vibration.
|
||
SetVibrationEnable ( TRUE );
|
||
Vibrate ( 10.0f, 1.0f, 0.5f );
|
||
}
|
||
}
|
||
if ((menu_state.mode==FE_CONFIG_OPTIONS)&&(item->LabelID==X_VIBRATION_ENG))
|
||
{
|
||
// Remember, this is the state it is currently, so we are turning it on.
|
||
if ( ( item->Data & 0x1 ) == 0 )
|
||
{
|
||
// Turn on general vibrations as well.
|
||
item[-1].Data |= 0x1;
|
||
}
|
||
}
|
||
#endif
|
||
if ((item->Type==OT_MULTI)&&((item->Data&0xff)<(item->Data>>8)-1)) {
|
||
item->Data++;
|
||
MFX_play_stereo(1,S_MENU_CLICK_START,MFX_REPLACE);
|
||
}
|
||
#endif
|
||
|
||
if (menu_state.mode==FE_CONFIG_VIDEO) FRONTEND_gamma_update();
|
||
if ((menu_state.mode==FE_CONFIG_AUDIO)&&!menu_state.selected) {
|
||
MFX_play_stereo(1,S_TRAFFIC_CONE,0);
|
||
//MFX_set_gain(1,S_TRAFFIC_CONE,255);
|
||
}
|
||
|
||
}
|
||
if (Keys[KB_ESC]||(input&INPUT_MASK_CANCEL)) {
|
||
Keys[KB_ESC]=0;
|
||
// if (menu_state.mode>=100)
|
||
// MFX_QUICK_stop();
|
||
if (fade_mode!=6) MFX_play_stereo(1,S_MENU_CLICK_END,MFX_REPLACE);
|
||
if (fade_mode==2) // cancel a transition
|
||
{
|
||
fade_mode=1;
|
||
menu_mode_queued=menu_state.mode;
|
||
return 0;
|
||
}
|
||
//FRONTEND_scr_del();
|
||
if (menu_state.stackpos)
|
||
{
|
||
switch(menu_state.mode)
|
||
{
|
||
case FE_CONFIG_VIDEO: // eidos want ESC to store opts
|
||
FRONTEND_store_video_data();
|
||
break;
|
||
case FE_CONFIG_AUDIO:
|
||
MFX_stop(WEATHER_REF,MFX_WAVE_ALL);
|
||
//MFX_stop(SIREN_REF,MFX_WAVE_ALL);
|
||
MFX_set_volumes(menu_data[0].Data>>1,menu_data[1].Data>>1,menu_data[2].Data>>1);
|
||
break;
|
||
}
|
||
|
||
// Store any options settings.
|
||
FRONTEND_storedata();
|
||
|
||
menu_mode_queued=FE_BACK;
|
||
}
|
||
else
|
||
{
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
menu_mode_queued=FE_QUIT;
|
||
#else
|
||
menu_mode_queued=FE_MAINMENU;
|
||
#endif
|
||
}
|
||
|
||
if ((menu_state.mode==FE_SAVESCREEN)&&!menu_state.stackpos) {
|
||
menu_thrash=FE_MAINMENU;
|
||
menu_mode_queued=FE_MAPSCREEN;
|
||
}
|
||
fade_mode=6;
|
||
|
||
FRONTEND_kibble_flurry();
|
||
}
|
||
|
||
#ifdef TARGET_DC
|
||
// Fudge for the joypad stuff.
|
||
if ( menu_state.mode == FE_CONFIG_INPUT_JP )
|
||
{
|
||
MenuData *item=menu_data+menu_state.selected;
|
||
if ( item->Type == OT_MULTI )
|
||
{
|
||
// There is only one MULTI on this screen - the "Mode" one.
|
||
|
||
if ( ( item->Data & 0xff ) == 0 )
|
||
{
|
||
// The custom mode - they can edit joypad settings.
|
||
bCanChangeJoypadButtons = TRUE;
|
||
}
|
||
else
|
||
{
|
||
// A predefined mode - they can't edit joypad settings.
|
||
bCanChangeJoypadButtons = FALSE;
|
||
}
|
||
|
||
|
||
// See if the mode has changed.
|
||
static int iLastMode = -1;
|
||
|
||
if ( iLastMode != ( item->Data & 0xff ) )
|
||
{
|
||
iLastMode = ( item->Data & 0xff );
|
||
|
||
// Update the shown joypad settings with the selected mode.
|
||
INTERFAC_SetUpJoyPadButtons ( iLastMode );
|
||
// Gap for label.
|
||
menu_data[2].Data = joypad_button_use[JOYPAD_BUTTON_PUNCH];
|
||
menu_data[3].Data = joypad_button_use[JOYPAD_BUTTON_KICK];
|
||
menu_data[4].Data = joypad_button_use[JOYPAD_BUTTON_JUMP];
|
||
menu_data[5].Data = joypad_button_use[JOYPAD_BUTTON_ACTION];
|
||
menu_data[6].Data = joypad_button_use[JOYPAD_BUTTON_MOVE];
|
||
menu_data[7].Data = joypad_button_use[JOYPAD_BUTTON_SELECT];
|
||
// Gap for label.
|
||
menu_data[9].Data = joypad_button_use[JOYPAD_BUTTON_CAMERA];
|
||
menu_data[10].Data = joypad_button_use[JOYPAD_BUTTON_CAM_LEFT];
|
||
menu_data[11].Data = joypad_button_use[JOYPAD_BUTTON_CAM_RIGHT];
|
||
menu_data[12].Data = joypad_button_use[JOYPAD_BUTTON_1STPERSON];
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
//--- externally accessible ---
|
||
|
||
|
||
void FRONTEND_init ( bool bGoToTitleScreen )
|
||
{
|
||
|
||
static bool bFirstTime = TRUE;
|
||
|
||
|
||
dwAutoPlayFMVTimeout = timeGetTime() + AUTOPLAY_FMV_DELAY;
|
||
|
||
// Stop the music while loading stuff.
|
||
stop_all_fx_and_music(TRUE);
|
||
//MFX_QUICK_stop();
|
||
|
||
// These two are so that when a mission ends with a camera still active, the music
|
||
// stuff actually works properly. Obscure or what?
|
||
extern UBYTE EWAY_conv_active;
|
||
extern SLONG EWAY_cam_active;
|
||
EWAY_conv_active = FALSE;
|
||
EWAY_cam_active = FALSE;
|
||
|
||
TICK_RATIO = (1 << TICK_SHIFT);
|
||
|
||
// Set up the current language
|
||
switch ( ENV_get_value_number ( "lang_num", 0, "" ) )
|
||
{
|
||
case 0:
|
||
pcSpeechLanguageDir = "talk2\\";
|
||
break;
|
||
case 1:
|
||
pcSpeechLanguageDir = "talk2_french\\";
|
||
break;
|
||
default:
|
||
ASSERT ( FALSE );
|
||
break;
|
||
}
|
||
|
||
|
||
// Reset the transition buffer's contents.
|
||
lpFRONTEND_show_xition_LastBlit = NULL;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
|
||
|
||
// Load the icon pic data if it hasn't already been done.
|
||
// Yes, this isn't the _best_ place to put it... :-)
|
||
if ( !m_bLoadedIconSavePic )
|
||
{
|
||
TGA_Pixel pPixelData[32*32];
|
||
|
||
// Load the savegame icon from disk.
|
||
extern TGA_Info TGA_load_from_file(const CBYTE *file, SLONG max_width, SLONG max_height, TGA_Pixel* data, BOOL bCanShrink);
|
||
TGA_Info tga_info = TGA_load_from_file ( "server\\textures\\extras\\dc\\saved_data_icon2.tga", 32, 32, pPixelData, FALSE );
|
||
if ( tga_info.valid )
|
||
{
|
||
// Convert to 16 colours. There MUST only be 16 colours!
|
||
int iNumColours = 0;
|
||
|
||
TGA_Pixel *pcSrc = pPixelData;
|
||
BYTE *pcDest = m_pcIconSavePicData;
|
||
for ( int y = 0; y < 32; y++ )
|
||
{
|
||
// Convert a line into bytes first.
|
||
BYTE pcLine[32];
|
||
BYTE *pcDest1 = pcLine;
|
||
for ( int x = 0; x < 32; x++ )
|
||
{
|
||
// Find the 4444 colour (set alpha to full).
|
||
WORD wColour = 0xf000;
|
||
// Read the colours.
|
||
wColour |= ( ( pcSrc->red ) & 0xf0 ) << 4;
|
||
wColour |= ( ( pcSrc->green ) & 0xf0 );
|
||
wColour |= ( ( pcSrc->blue ) & 0xf0 ) >> 4;
|
||
pcSrc++;
|
||
|
||
// Search for it.
|
||
for ( int i = 0; i < iNumColours; i++ )
|
||
{
|
||
if ( wColour == m_pcIconSavePicPalette[i] )
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if ( i == iNumColours )
|
||
{
|
||
// Didn't find it - add it.
|
||
ASSERT ( iNumColours < 16 );
|
||
m_pcIconSavePicPalette[iNumColours] = wColour;
|
||
iNumColours++;
|
||
}
|
||
|
||
*pcDest1++ = i;
|
||
}
|
||
|
||
// Now pack into 4bpp.
|
||
pcDest1 = pcLine;
|
||
for ( x = 0; x < 16; x++ )
|
||
{
|
||
*pcDest = (*pcDest1++) << 4;
|
||
*pcDest++ |= (*pcDest1++);
|
||
}
|
||
}
|
||
|
||
m_bLoadedIconSavePic = TRUE;
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Need to reinit the frontend stuff.
|
||
FRONTEND_scr_new_theme(
|
||
menu_back_names [menu_theme],
|
||
menu_map_names [menu_theme],
|
||
menu_brief_names [menu_theme],
|
||
menu_config_names[menu_theme]);
|
||
|
||
#ifdef ONLY_USE_THREE_BACKGROUNDS_PLEASE_BOB
|
||
UseBackSurface(screenfull_back);
|
||
screenfull = screenfull_back;
|
||
#else
|
||
UseBackSurface(screenfull_config);
|
||
screenfull = screenfull_config;
|
||
#endif
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef SAVE_MY_BACKGROUNDS_PLEASE_BOB
|
||
// Convert _all_ the screens used, to make sure we don't miss any.
|
||
// The act of loading them also converts them.
|
||
InitBackImage("e3load.tga");
|
||
InitBackImage("deadcivs.tga");
|
||
InitBackImage("DCtitlepage_uk.tga");
|
||
InitBackImage("DCtitlepage_us.tga");
|
||
|
||
InitBackImage("briefing blood darci.tga");
|
||
InitBackImage("map blood darci.tga");
|
||
InitBackImage("config blood.tga");
|
||
InitBackImage("title blood1.tga");
|
||
|
||
InitBackImage("briefing leaves darci.tga");
|
||
InitBackImage("map leaves darci.tga");
|
||
InitBackImage("config leaves.tga");
|
||
InitBackImage("title leaves1.tga");
|
||
|
||
InitBackImage("briefing rain darci.tga");
|
||
InitBackImage("map rain darci.tga");
|
||
InitBackImage("config rain.tga");
|
||
InitBackImage("title rain1.tga");
|
||
|
||
InitBackImage("briefing snow darci.tga");
|
||
InitBackImage("map snow darci.tga");
|
||
InitBackImage("config snow.tga");
|
||
InitBackImage("title snow1.tga");
|
||
#endif
|
||
|
||
|
||
|
||
#if 0
|
||
#ifndef FORCE_STUFF_PLEASE_BOB
|
||
//
|
||
// Turn off every even kibble.
|
||
//
|
||
|
||
for (SLONG kib = 0; kib < 512; kib += 2)
|
||
{
|
||
kibble_off[kib] = TRUE;
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
|
||
CBYTE *str, *lang=ENV_get_value_string("language");
|
||
|
||
#ifdef VERSION_FRENCH
|
||
// Kludge for the DC converter
|
||
if (!lang) lang="text\\lang_french.txt";
|
||
#else
|
||
if (!lang) lang="text\\lang_english.txt";
|
||
#endif
|
||
XLAT_load(lang);
|
||
XLAT_init();
|
||
|
||
IsEnglish=!stricmp(XLAT_str(X_THIS_LANGUAGE_IS),"English");
|
||
|
||
str=menu_choice_yesno;
|
||
strcpy(str,XLAT_str(X_NO));
|
||
str+=strlen(str)+1;
|
||
strcpy(str,XLAT_str(X_YES));
|
||
|
||
strcpy(MISSION_SCRIPT,"data\\");
|
||
lang=XLAT_str(X_THIS_LANGUAGE_IS);
|
||
if (strcmp(lang,"English")==0)
|
||
strcat(MISSION_SCRIPT,"urban");
|
||
else
|
||
strcat(MISSION_SCRIPT,lang);
|
||
strcat(MISSION_SCRIPT,".sty");
|
||
|
||
//
|
||
// Load the mission script into memory so we don't have
|
||
// to scan a file all the time!
|
||
//
|
||
|
||
CacheScriptInMemory(MISSION_SCRIPT);
|
||
|
||
#ifdef TARGET_DC
|
||
MENUFONT_Load("olyfont2dc.tga",POLY_PAGE_NEWFONT_INVERSE,frontend_fonttable);
|
||
#else
|
||
MENUFONT_Load("olyfont2.tga",POLY_PAGE_NEWFONT_INVERSE,frontend_fonttable);
|
||
#endif
|
||
|
||
void MENUFONT_MergeLower(void);
|
||
MENUFONT_MergeLower();
|
||
|
||
menu_theme = 0;
|
||
|
||
//InitBackImage(menu_back_names[menu_theme]);
|
||
UseBackSurface(screenfull_back);
|
||
|
||
#ifndef TARGET_DC
|
||
// Er... we call FRONTEND_kibble_init just below. Whatever....
|
||
ZeroMemory(kibble,sizeof(kibble));
|
||
#endif
|
||
ZeroMemory(&menu_state,sizeof(menu_state));
|
||
if (!complete_point) ZeroMemory(mission_hierarchy,60);
|
||
menu_state.mode=-1;
|
||
|
||
FRONTEND_CacheMissionList(MISSION_SCRIPT);
|
||
|
||
the_display.lp_D3D_Viewport->Clear(1, &the_display.ViewportRect, D3DCLEAR_ZBUFFER);
|
||
|
||
ragepro_sucks=!the_display.GetDeviceInfo()->ModulateAlphaSupported();
|
||
|
||
ZeroMemory(menu_choice_scanner,255);
|
||
XLAT_str(X_CAMERA,menu_choice_scanner);
|
||
lang=menu_choice_scanner+strlen(menu_choice_scanner)+1;
|
||
XLAT_str(X_CHARACTER,lang);
|
||
|
||
#ifdef TARGET_DC
|
||
// Joypad mode looks like "Custom A B C D" etc.
|
||
ZeroMemory(menu_choice_joypad_mode,50);
|
||
XLAT_str(X_PAD_CUSTOM,menu_choice_joypad_mode);
|
||
char *pchar = menu_choice_joypad_mode + strlen ( menu_choice_joypad_mode ) + 1;
|
||
for ( int iCount = 0; iCount < NUM_OF_JOYPAD_MODES; iCount++ )
|
||
{
|
||
*pchar++ = 'A' + iCount;
|
||
*pchar++ = '\0';
|
||
}
|
||
|
||
ZeroMemory(menu_choice_analogue_mode,50);
|
||
XLAT_str(X_TURN,menu_choice_analogue_mode);
|
||
lang=menu_choice_analogue_mode+strlen(menu_choice_analogue_mode)+1;
|
||
XLAT_str(X_MOVE,lang);
|
||
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
ZeroMemory(menu_choice_language,50);
|
||
XLAT_str(X_ENGLISH,menu_choice_language);
|
||
lang=menu_choice_language+strlen(menu_choice_language)+1;
|
||
XLAT_str(X_FRENCH,lang);
|
||
#endif
|
||
#endif
|
||
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
|
||
FRONTEND_scr_new_theme(
|
||
menu_back_names [menu_theme],
|
||
menu_map_names [menu_theme],
|
||
menu_brief_names [menu_theme],
|
||
menu_config_names[menu_theme]);
|
||
|
||
if ( !bFirstTime )
|
||
{
|
||
UseBackSurface(screenfull_back);
|
||
}
|
||
|
||
//#if defined(M_SOUND) || defined(DC_SOUND)
|
||
SLONG fx,amb,mus;
|
||
MFX_get_volumes(&fx,&amb,&mus);
|
||
MUSIC_gain(mus);
|
||
//#endif
|
||
|
||
FRONTEND_districts(MISSION_SCRIPT);
|
||
FRONTEND_MissionHierarchy(MISSION_SCRIPT);
|
||
FRONTEND_kibble_init();
|
||
|
||
|
||
//extern bool g_bGoToCreditsPleaseGameHasFinished;
|
||
|
||
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if ( bGoToTitleScreen )
|
||
{
|
||
// Start off in the title screen instead.
|
||
FRONTEND_mode(FE_TITLESCREEN);
|
||
}
|
||
else if ( bFirstTime )
|
||
{
|
||
// Start off in the language screen instead.
|
||
FRONTEND_mode(FE_LANGUAGESCREEN);
|
||
}
|
||
else
|
||
#endif
|
||
if ( m_bGoIntoSaveScreen )
|
||
{
|
||
// Just won a mission - going into save game.
|
||
FRONTEND_mode(FE_SAVESCREEN);
|
||
m_bGoIntoSaveScreen = FALSE;
|
||
}
|
||
else
|
||
{
|
||
// Frontend menu.
|
||
FRONTEND_mode(FE_MAINMENU);
|
||
}
|
||
|
||
|
||
|
||
// Stop all the music - about to start it again, properly.
|
||
stop_all_fx_and_music();
|
||
MUSIC_reset();
|
||
MUSIC_mode(0);
|
||
MUSIC_mode_process();
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
|
||
|
||
if (mission_launch)
|
||
{
|
||
// Just won a mission - going into save game.
|
||
return;
|
||
}
|
||
|
||
{
|
||
CBYTE fname[256];
|
||
|
||
//
|
||
// Load in the front-end specific sound
|
||
//
|
||
|
||
#ifdef TARGET_DC
|
||
sprintf(fname, "Data\\Sfx\\1622DC\\%s", sound_list[S_FRONT_END_LOOP_EDIT]);
|
||
#else
|
||
sprintf(fname, "Data\\Sfx\\1622\\%s", sound_list[S_FRONT_END_LOOP_EDIT]);
|
||
#endif
|
||
|
||
DCLL_memstream_load(fname);
|
||
|
||
//
|
||
// Start playing the music!
|
||
//
|
||
|
||
#ifdef TARGET_DC
|
||
MFX_QUICK_play("data\\sfx\\1622DC\\GeneralMusic\\FrontLoopMONO.wav",TRUE,0,0,0);
|
||
#else
|
||
MFX_QUICK_play("data\\sfx\\1622\\GeneralMusic\\FrontLoopMONO.wav",TRUE,0,0,0);
|
||
#endif
|
||
}
|
||
|
||
bFirstTime = FALSE;
|
||
}
|
||
|
||
void FRONTEND_level_lost()
|
||
{
|
||
mission_launch=previous_mission_launch;
|
||
// Start up the kibble again.
|
||
FRONTEND_kibble_init();
|
||
ZeroMemory(&menu_state,sizeof(menu_state));
|
||
menu_state.mode=-1;
|
||
// FRONTEND_MissionHierarchy(MISSION_SCRIPT);
|
||
FRONTEND_mode(FE_MAINMENU);
|
||
}
|
||
|
||
void FRONTEND_level_won()
|
||
{
|
||
|
||
ASSERT(mission_launch<50);
|
||
|
||
|
||
// update hierarchy data.
|
||
mission_hierarchy[mission_launch]|=2; // complete
|
||
|
||
|
||
|
||
extern bool g_bPunishMePleaseICheatedOnThisLevel;
|
||
if ( !g_bPunishMePleaseICheatedOnThisLevel )
|
||
{
|
||
// time to update roper/darci doohickeys
|
||
if (1)//NET_PERSON(0)->Genus.Person->PersonType==PERSON_DARCI)
|
||
{
|
||
SLONG found;
|
||
found=NET_PLAYER(0)->Genus.Player->Constitution - the_game.DarciConstitution;
|
||
ASSERT(found>=0);
|
||
|
||
if(found>best_found[mission_launch][0])
|
||
{
|
||
the_game.DarciConstitution+=found-best_found[mission_launch][0];
|
||
best_found[mission_launch][0]=found;
|
||
}
|
||
|
||
found=NET_PLAYER(0)->Genus.Player->Strength - the_game.DarciStrength;
|
||
ASSERT(found>=0);
|
||
|
||
if(found>best_found[mission_launch][1])
|
||
{
|
||
the_game.DarciStrength+=found-best_found[mission_launch][1];
|
||
best_found[mission_launch][1]=found;
|
||
}
|
||
|
||
found=NET_PLAYER(0)->Genus.Player->Stamina - the_game.DarciStamina;
|
||
ASSERT(found>=0);
|
||
|
||
if(found>best_found[mission_launch][2])
|
||
{
|
||
the_game.DarciStamina+=found-best_found[mission_launch][2];
|
||
best_found[mission_launch][2]=found;
|
||
}
|
||
|
||
found=NET_PLAYER(0)->Genus.Player->Skill - the_game.DarciSkill;
|
||
ASSERT(found>=0);
|
||
|
||
if(found>best_found[mission_launch][3])
|
||
{
|
||
the_game.DarciSkill+=found-best_found[mission_launch][3];
|
||
best_found[mission_launch][3]=found;
|
||
}
|
||
/*
|
||
the_game.DarciConstitution=NET_PLAYER(0)->Genus.Player->Constitution;
|
||
the_game.DarciStrength=NET_PLAYER(0)->Genus.Player->Strength;
|
||
the_game.DarciStamina=NET_PLAYER(0)->Genus.Player->Stamina;
|
||
the_game.DarciSkill=NET_PLAYER(0)->Genus.Player->Skill;
|
||
*/
|
||
}
|
||
else
|
||
{
|
||
#ifdef TARGET_DC
|
||
// Not used.
|
||
ASSERT ( FALSE );
|
||
#else
|
||
the_game.RoperConstitution=NET_PLAYER(0)->Genus.Player->Constitution;
|
||
the_game.RoperStrength=NET_PLAYER(0)->Genus.Player->Strength;
|
||
the_game.RoperStamina=NET_PLAYER(0)->Genus.Player->Stamina;
|
||
the_game.RoperSkill=NET_PLAYER(0)->Genus.Player->Skill;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
// Start up the kibble again.
|
||
FRONTEND_kibble_init();
|
||
ZeroMemory(&menu_state,sizeof(menu_state));
|
||
menu_state.mode=-1;
|
||
if (complete_point<mission_launch) complete_point=mission_launch;
|
||
//mission_launch++;
|
||
FRONTEND_MissionHierarchy(MISSION_SCRIPT);
|
||
/* hierarchy does both of these now
|
||
InitBackImage(menu_back_names[menu_theme]);
|
||
FRONTEND_kibble_init();*/
|
||
FRONTEND_mode(FE_SAVESCREEN);
|
||
m_bGoIntoSaveScreen = TRUE;
|
||
}
|
||
|
||
void FRONTEND_playambient3d(SLONG channel, SLONG wave_id, SLONG flags, UBYTE height = 0)
|
||
{
|
||
SLONG angle = Random() & 2047;
|
||
|
||
SLONG x = (COS(angle) << 4);
|
||
SLONG y = 0;
|
||
SLONG z = (SIN(angle) << 4);
|
||
|
||
if (height == 1) y += (512 + (Random() & 1023)) << 8;
|
||
|
||
MFX_play_xyz(channel, wave_id, 0, x, y, z);
|
||
// MFX_set_gain(channel, wave_id,255);
|
||
}
|
||
|
||
|
||
void FRONTEND_sound() {
|
||
static SLONG siren_time=100;
|
||
SLONG wave_id;
|
||
|
||
MFX_play_ambient(WEATHER_REF,S_WIND_START,MFX_LOOPED|MFX_QUEUED);
|
||
// MFX_play_ambient(MUSIC_REF,S_TUNE_DRIVING,MFX_LOOPED);
|
||
MFX_set_gain(WEATHER_REF,S_AMBIENCE_END,255);
|
||
// MFX_set_gain(MUSIC_REF,S_TUNE_FRONTEND,menu_data[2].Data>>1);
|
||
MUSIC_gain(menu_data[2].Data>>1);
|
||
//#if defined(M_SOUND) || defined(DC_SOUND)
|
||
MFX_set_volumes(menu_data[0].Data>>1,menu_data[1].Data>>1,menu_data[2].Data>>1);
|
||
//#endif
|
||
|
||
// Update the music volume.
|
||
//extern void DCLL_stream_volume(float volume);
|
||
// DCLL_stream_volume ( 1.0f );
|
||
|
||
|
||
siren_time--;
|
||
if(siren_time<0)
|
||
{
|
||
wave_id = S_SIREN_START + (Random() % 4);
|
||
siren_time = 300 + ((Random() & 0xFFFF) >> 5);
|
||
FRONTEND_playambient3d(SIREN_REF, wave_id, 0, 1);
|
||
}
|
||
MFX_set_listener(0,0,0,0,0,0);
|
||
MFX_render();
|
||
}
|
||
|
||
|
||
void FRONTEND_diddle_stats()
|
||
{
|
||
#ifndef FINAL
|
||
#ifndef TARGET_DC
|
||
SWORD stat_up = ENV_get_value_number("stat_up", 0, "Secret");
|
||
stat_up*=(mission_launch-1);
|
||
|
||
the_game.DarciConstitution=stat_up;
|
||
the_game.DarciStrength=stat_up;
|
||
the_game.DarciStamina=stat_up;
|
||
the_game.DarciSkill=stat_up;
|
||
the_game.RoperConstitution=stat_up;
|
||
the_game.RoperStrength=stat_up;
|
||
the_game.RoperStamina=stat_up;
|
||
the_game.RoperSkill=stat_up;
|
||
#endif
|
||
#endif
|
||
|
||
}
|
||
|
||
void FRONTEND_diddle_music()
|
||
{
|
||
TRACE("STARTSCR_mission: %s\n",STARTSCR_mission);
|
||
MUSIC_bodge_code=0;
|
||
if (strstr(STARTSCR_mission,"levels\\fight")||strstr(STARTSCR_mission,"levels\\FTutor"))
|
||
MUSIC_bodge_code=1;
|
||
else
|
||
if (strstr(STARTSCR_mission,"levels\\Assault"))
|
||
MUSIC_bodge_code=2;
|
||
else
|
||
if (strstr(STARTSCR_mission,"levels\\testdrive"))
|
||
MUSIC_bodge_code=3;
|
||
else
|
||
if (strstr(STARTSCR_mission,"levels\\Finale1"))
|
||
MUSIC_bodge_code=4;
|
||
|
||
|
||
}
|
||
|
||
UBYTE this_level_has_the_balrog;
|
||
UBYTE this_level_has_bane;
|
||
UBYTE is_semtex=0;
|
||
|
||
SBYTE FRONTEND_loop() {
|
||
SBYTE res;
|
||
|
||
static SLONG last = 0;
|
||
static SLONG now = 0;
|
||
|
||
SLONG millisecs;
|
||
|
||
now = GetTickCount();
|
||
|
||
if (last < now - 250)
|
||
{
|
||
last = now - 250;
|
||
}
|
||
|
||
millisecs = now - last;
|
||
last = now;
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Display the default VMU screen.
|
||
FRONTEND_show_VMU_screen ( NULL );
|
||
#endif
|
||
|
||
//
|
||
// How fast should the fade state fade?
|
||
//
|
||
|
||
SLONG fade_speed = (millisecs >> 3);
|
||
|
||
if (fade_speed < 1)
|
||
{
|
||
fade_speed = 1;
|
||
}
|
||
|
||
switch(fade_mode&3)
|
||
{
|
||
case 1:
|
||
if (fade_state<63)
|
||
{
|
||
fade_state += fade_speed;
|
||
|
||
if (fade_state > 63)
|
||
{
|
||
fade_state = 63;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FRONTEND_stop_xition();
|
||
|
||
fade_mode = 0;
|
||
}
|
||
break;
|
||
|
||
case 2:
|
||
if (fade_state>0)
|
||
{
|
||
fade_state -= fade_speed;
|
||
|
||
if (fade_state < 0)
|
||
{
|
||
fade_state = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FRONTEND_mode(menu_mode_queued);
|
||
}
|
||
break;
|
||
}
|
||
#ifdef TARGET_DC
|
||
// We don't fade, we change size.
|
||
fade_rgb=0xFFFFFFFF;
|
||
#else
|
||
fade_rgb=(((SLONG)fade_state*2)<<24)|0xFFFFFF;
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
if ( menu_state.mode == FE_TITLESCREEN )
|
||
{
|
||
// Handle the auto-playing of the FMV.
|
||
// Also disable the screensaver by prodding it
|
||
// every time.
|
||
|
||
if ( ( ( dwAutoPlayFMVTimeout - timeGetTime() ) & 0x80000000 ) != 0 )
|
||
{
|
||
// Timed out.
|
||
stop_all_fx_and_music();
|
||
the_display.RunCutscene( 0, ENV_get_value_number("lang_num", 0, "" ) );
|
||
|
||
// Clear the controler again (in case they pressed a button).
|
||
|
||
|
||
// Start the music again.
|
||
MFX_QUICK_play("data\\sfx\\1622DC\\GeneralMusic\\FrontLoopMONO.wav",TRUE,0,0,0);
|
||
|
||
// Start the music again.
|
||
// Doesn't seem to work.
|
||
//MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
|
||
// "Reset" the controller so that "Press Start Button" is displayed.
|
||
ClearPrimaryDevice();
|
||
|
||
// Two minutes wait on the title screen.
|
||
dwAutoPlayFMVTimeout = timeGetTime() + AUTOPLAY_FMV_DELAY;
|
||
}
|
||
|
||
// Pretend the screensaver got an input to disable it.
|
||
extern DWORD g_dwLastInputChangeTime;
|
||
g_dwLastInputChangeTime = timeGetTime();
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
// No kibble on the title screen.
|
||
if ( ( menu_state.mode == FE_TITLESCREEN ) || ( menu_state.mode == FE_LANGUAGESCREEN ) )
|
||
{
|
||
// Remove any existing kibble.
|
||
FRONTEND_kibble_init();
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
FRONTEND_kibble_process();
|
||
}
|
||
|
||
#ifndef TARGET_DC
|
||
PolyPage::DisableAlphaSort();
|
||
#endif
|
||
FRONTEND_display();
|
||
if ((menu_state.mode==FE_CONFIG_AUDIO)&&(fade_mode==0))
|
||
{
|
||
FRONTEND_sound();
|
||
}
|
||
else
|
||
{
|
||
MFX_set_listener(0,0,0,0,0,0);
|
||
MFX_render();
|
||
}
|
||
#ifndef TARGET_DC
|
||
PolyPage::EnableAlphaSort();
|
||
#endif
|
||
res=FRONTEND_input();
|
||
//MUSIC_process();
|
||
// This was commented out - why????
|
||
// Aha - because otherwise, after a briefing, the music starts up over the memstream music.
|
||
MUSIC_mode_process();
|
||
|
||
|
||
// dodgy hidden keys
|
||
|
||
#ifndef VERSION_DEMO
|
||
|
||
#ifndef TARGET_DC
|
||
//#ifndef NDEBUG
|
||
if(ControlFlag && ShiftFlag)
|
||
{
|
||
if (Keys[KB_PPLUS])
|
||
{ Keys[KB_PPLUS]=0; complete_point++; FRONTEND_MissionHierarchy(MISSION_SCRIPT); cheating=1; }
|
||
if (Keys[KB_ASTERISK])
|
||
{ Keys[KB_ASTERISK]=0; complete_point=40; FRONTEND_MissionHierarchy(MISSION_SCRIPT); cheating=1; }
|
||
}
|
||
//#endif
|
||
|
||
#else
|
||
|
||
|
||
#ifdef DEBUG
|
||
// Just for Tom's debugging.
|
||
if (
|
||
(the_state.rgbButtons[DI_DC_BUTTON_A])&&
|
||
(the_state.rgbButtons[DI_DC_BUTTON_B])&&
|
||
(the_state.rgbButtons[DI_DC_BUTTON_X])&&
|
||
(the_state.rgbButtons[DI_DC_BUTTON_Y]))
|
||
{
|
||
if (the_state.rgbButtons[DI_DC_BUTTON_RTRIGGER])
|
||
{ complete_point++; FRONTEND_MissionHierarchy(MISSION_SCRIPT); cheating=1; }
|
||
if (the_state.rgbButtons[DI_DC_BUTTON_LTRIGGER])
|
||
{ complete_point=40; FRONTEND_MissionHierarchy(MISSION_SCRIPT); cheating=1; }
|
||
}
|
||
#endif
|
||
|
||
// Proper harder to find cheat.
|
||
extern int g_iCheatNumber;
|
||
if ( g_iCheatNumber == 0x1a1a0001 )
|
||
{
|
||
// Expose all missions.
|
||
g_iCheatNumber = 0;
|
||
if (the_state.rgbButtons[DI_DC_BUTTON_LTRIGGER])
|
||
{ complete_point=40; FRONTEND_MissionHierarchy(MISSION_SCRIPT); cheating=1; }
|
||
}
|
||
|
||
#endif
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
#ifdef WANT_AN_EXIT_MENU_ITEM
|
||
if (res==FE_NO_REALLY_QUIT) return STARTS_EXIT;
|
||
#endif
|
||
if (res==FE_EDITOR) return STARTS_EDITOR;
|
||
if (res==FE_LOADSCREEN) return STARTS_START;
|
||
#ifdef WANT_A_TITLE_SCREEN
|
||
if (res==FE_CHANGE_LANGUAGE) return STARTS_LANGUAGE_CHANGE;
|
||
#endif
|
||
#ifndef TARGET_DC
|
||
if (res==FE_START || build_dc)
|
||
#else
|
||
if (res==FE_START)
|
||
#endif
|
||
{
|
||
//
|
||
// Start playing!!!
|
||
//
|
||
|
||
struct
|
||
{
|
||
CBYTE *mission;
|
||
SLONG dontload;
|
||
SLONG has_balrog;
|
||
|
||
} whattoload[] =
|
||
{
|
||
{"testdrive1a.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"FTutor1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"Assault1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"police1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"police2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"Bankbomb1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"police3.ucm", (1 << PERSON_MIB1) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"Gangorder2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"police4.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"bball2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"wstores1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"e3.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | 0, /* balrog ? */ FALSE},
|
||
{"westcrime1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"carbomb1.ucm", (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"botanicc.ucm", (1 << PERSON_MIB1) | 0, /* balrog ? */ FALSE},
|
||
{"Semtex.ucm", (1 << PERSON_MIB1) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"AWOL1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"mission2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"park2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"MIB.ucm", (1 << PERSON_TRAMP) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"skymiss2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"factory1.ucm", (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"estate2.ucm", (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"Stealtst1.ucm", (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"snow2.ucm", (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"Gordout1.ucm", (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"Baalrog3.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ TRUE },
|
||
{"Finale1.ucm", (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"Gangorder1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"FreeCD1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"jung3.ucm", (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | 0, /* balrog ? */ FALSE},
|
||
{"fight1.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"fight2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"testdrive2.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"testdrive3.ucm", (1 << PERSON_MIB1) | (1 << PERSON_TRAMP) | (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
{"Album1.ucm", (1 << PERSON_SLAG_TART) | (1 << PERSON_SLAG_FATUGLY) | (1 << PERSON_HOSTAGE) | (1 << PERSON_MECHANIC) | 0, /* balrog ? */ FALSE},
|
||
|
||
{"!"}
|
||
};
|
||
|
||
//
|
||
// What level are we loading?
|
||
//
|
||
|
||
SLONG index_into_the_whattoload_array;
|
||
|
||
#ifndef TARGET_DC
|
||
if (build_dc)
|
||
{
|
||
//
|
||
// This bit of code saves out DAD files for all the missions...
|
||
//
|
||
|
||
if (suggest_order[build_dc_mission][0] == '!')
|
||
{
|
||
//
|
||
// All done!
|
||
//
|
||
|
||
exit(0);
|
||
}
|
||
|
||
strcpy(STARTSCR_mission,"levels\\");
|
||
strcat(STARTSCR_mission,suggest_order[build_dc_mission]);
|
||
|
||
index_into_the_whattoload_array = build_dc_mission;
|
||
|
||
build_dc_mission += 1;
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
|
||
previous_mission_launch=mission_launch;
|
||
strcpy(STARTSCR_mission,"levels\\");
|
||
strcat(STARTSCR_mission,FRONTEND_MissionFilename(MISSION_SCRIPT,menu_state.mode-100));
|
||
// strcpy(STARTSCR_mission,"c:\\master~1\\italian\\bankbomb1.ucm");
|
||
|
||
index_into_the_whattoload_array = -1;
|
||
|
||
SLONG i;
|
||
|
||
for (i = 0; whattoload[i].mission[0] != '!'; i++)
|
||
{
|
||
if (strcmp(FRONTEND_MissionFilename(MISSION_SCRIPT,menu_state.mode-100), whattoload[i].mission) == 0)
|
||
{
|
||
ASSERT(index_into_the_whattoload_array == -1);
|
||
|
||
index_into_the_whattoload_array = i;
|
||
}
|
||
}
|
||
|
||
ASSERT(index_into_the_whattoload_array != -1);
|
||
}
|
||
|
||
//
|
||
// What should we or shouldn't we load?
|
||
//
|
||
|
||
ASSERT(WITHIN(index_into_the_whattoload_array, 0, 35));
|
||
|
||
#ifndef TARGET_DC
|
||
extern ULONG DONT_load;
|
||
|
||
this_level_has_the_balrog = whattoload[index_into_the_whattoload_array].has_balrog;
|
||
this_level_has_bane = (index_into_the_whattoload_array == 27); // Just in the finale...
|
||
DONT_load = whattoload[index_into_the_whattoload_array].dontload;
|
||
|
||
//
|
||
// This makes us load all people. Comment it out to load only the
|
||
// people the level needs.
|
||
//
|
||
|
||
DONT_load = 0;
|
||
|
||
// If doing all levels, don't use DONT_load. The two don't mix.
|
||
ASSERT ( !DONT_load || !build_dc );
|
||
|
||
//
|
||
// Does this level have violence?
|
||
//
|
||
#endif
|
||
if(index_into_the_whattoload_array==20) //semtex wetback
|
||
{
|
||
is_semtex=1;
|
||
}
|
||
else
|
||
{
|
||
is_semtex=0;
|
||
}
|
||
|
||
if (index_into_the_whattoload_array == 31 ||
|
||
index_into_the_whattoload_array == 32 ||
|
||
index_into_the_whattoload_array == 1)
|
||
{
|
||
//
|
||
// No violence.
|
||
//
|
||
|
||
VIOLENCE = FALSE;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Default violence.
|
||
//
|
||
|
||
VIOLENCE = TRUE;
|
||
}
|
||
|
||
if (cheating) FRONTEND_diddle_stats();
|
||
|
||
#ifdef TARGET_DC
|
||
g_iLevelNumber = mission_launch;
|
||
#endif
|
||
|
||
FRONTEND_diddle_music();
|
||
menu_state.stackpos = 0;
|
||
menu_thrash = 0;
|
||
return STARTS_START;
|
||
}
|
||
|
||
if (res == FE_CREDITS)
|
||
{
|
||
if (SOFTWARE && 0)
|
||
{
|
||
//
|
||
// This won't work in software... we need other credits :(
|
||
//
|
||
}
|
||
else
|
||
{
|
||
|
||
#ifdef TARGET_DC
|
||
|
||
DreamCastCredits();
|
||
|
||
#else
|
||
#if 0
|
||
extern void OS_hack(void);
|
||
|
||
OS_hack();
|
||
#endif
|
||
#endif
|
||
|
||
MUSIC_mode(MUSIC_MODE_FRONTEND);
|
||
FRONTEND_kibble_init();
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
#ifdef TARGET_DC
|
||
// Unload frontend gubbins to save memory.
|
||
// Can be safely called multiple times.
|
||
void FRONTEND_unload ( void )
|
||
{
|
||
FRONTEND_scr_unload_theme();
|
||
FRONTEND_kibble_destroy();
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|