mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 06:39:17 +00:00
8277c6cb79
sprites are drawn, but I think that's how it should be. 1: No bells or whistles. 2: This setting adds sprite blending, e.g. the smoke at the docks or the display cases at the Glease Gallery. 3: This setting adds light map support, e.g. when walking under the shack at the docks. 4: This setting adds better scaling algorithms. The first three settings should work fine now. In fact, the third setting is what we used to implement. The fourth setting still needs work and testing. I've added code for downscaling case, but frankly I'm not convinced the result is any better than with the simpler scaler. I usually can't even tell the difference. Of course, my translation of the original code could very well be buggy. svn-id: r9867
2817 lines
78 KiB
C++
2817 lines
78 KiB
C++
/* Copyright (C) 1994-2003 Revolution Software Ltd
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* $Header$
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
#include <ctype.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
//#include "src\driver96.h"
|
|
|
|
#include "stdafx.h"
|
|
#include "build_display.h"
|
|
#include "console.h"
|
|
#include "controls.h"
|
|
#include "debug.h"
|
|
#include "defs.h"
|
|
#include "header.h"
|
|
#include "interpreter.h"
|
|
#include "layers.h"
|
|
#include "logic.h"
|
|
#include "maketext.h" // for font resource variables
|
|
#include "mem_view.h"
|
|
#include "memory.h"
|
|
#include "mouse.h"
|
|
#include "protocol.h"
|
|
#include "resman.h"
|
|
#include "router.h"
|
|
#include "save_rest.h"
|
|
#include "sound.h" // for FN_stop_music()
|
|
#include "startup.h"
|
|
#include "sword2.h"
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
#define WINDOW_RES 2016
|
|
#define MAX_STRING_LEN 64 // 20 was too low; better to be safe ;)
|
|
|
|
#define CHARACTER_OVERLAP 2 // overlap characters by 3 pixels
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
void Create_surface_image(_spriteInfo *sprite, uint8 **surface, uint32 res, uint32 x, uint32 y, uint32 pc);
|
|
void Build_surfaces(void);
|
|
void Build_chr_surfaces(void);
|
|
void Kill_chr_surfaces(void);
|
|
void Kill_surfaces(void);
|
|
void Renew_surfaces(void);
|
|
void Engine_string(uint32 x, uint32 y, uint32 res, uint8 **surface_list, uint8 *buf);
|
|
void Kill_mini_surfaces(void);
|
|
void Build_mini_surfaces(void);
|
|
uint32 Generic_mini_control(uint32 text_id);
|
|
uint32 Pixel_text_length(uint8 *buf, uint32 res);
|
|
void Control_error(char* text);
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
#define WINDOW_X 0
|
|
|
|
#define REST_X 84
|
|
#define REST_Y 40
|
|
|
|
#define SLAB_X (REST_X+30)
|
|
#define SLAB_Y (REST_Y+32)
|
|
|
|
#define REST_BUT_X 130
|
|
#define REST_BUT_Y 377
|
|
|
|
#define CAN_BUT_X 350
|
|
#define CAN_BUT_Y 377
|
|
|
|
#define UP_BUT_X 516
|
|
#define UP_BUT_Y 85
|
|
|
|
#define DOWN_BUT_X 516
|
|
#define DOWN_BUT_Y 329
|
|
|
|
#define ZUP_BUT_Y 85-20
|
|
|
|
#define ZDOWN_BUT_Y 329+21
|
|
|
|
#define SLAB_Y_SPACING 35
|
|
|
|
#define QUIT_X 203
|
|
#define QUIT_Y 104
|
|
|
|
#define OPTION_X 45
|
|
#define OPTION_Y 40
|
|
#define OPTION_W 552
|
|
|
|
#define OPT_BUT_W 53
|
|
#define OPT_BUT_H 32
|
|
|
|
#define OPT_OK_X (OPTION_X+(OPTION_W/3)-(OPT_BUT_W/2))
|
|
#define OPT_OK_Y (OPTION_Y+368-(OPT_BUT_W/2))
|
|
|
|
#define OPT_CAN_X (OPTION_X+350)
|
|
#define OPT_CAN_Y (OPT_OK_Y)
|
|
|
|
#define SLIDER_TRK_X (OPTION_X+264)
|
|
#define SLIDER_TRK_W 132
|
|
#define SLIDER_TRK_H 27
|
|
#define SLIDER_W 38
|
|
|
|
#define OBJ_LABEL_X (SLIDER_TRK_X-5)
|
|
#define OBJ_LABEL_Y (OPTION_Y+60)
|
|
|
|
#define SUBTITLE_X (OPTION_X+465)
|
|
#define SUBTITLE_Y (OBJ_LABEL_Y)
|
|
|
|
#define STEREO_X (SLIDER_TRK_X-5)
|
|
#define STEREO_Y (OPTION_Y+253)
|
|
|
|
#define MUSIC_TRK_Y (OPTION_Y+121)
|
|
#define SPEECH_TRK_Y (OPTION_Y+168)
|
|
#define FX_TRK_Y (OPTION_Y+214)
|
|
#define GRFX_TRK_Y (OPTION_Y+301)
|
|
|
|
#define MUTE_W 40
|
|
#define MUTE_H 32
|
|
#define MUTE_X (SUBTITLE_X+OPT_BUT_W/2-MUTE_W/2)
|
|
|
|
#define GRFX_ICON_X (OPTION_X+450)
|
|
#define GRFX_ICON_Y (OPTION_Y+270)
|
|
|
|
//--------------------------------------------
|
|
|
|
uint8 *panel_surface;
|
|
_spriteInfo panel_sprite;
|
|
|
|
_spriteInfo slab_sprite[8];
|
|
uint8 *slab_surface[8];
|
|
|
|
_spriteInfo chr_sprite;
|
|
|
|
#define SIZE_OF_CHAR_SET (256-32) // our fonts start on SPACE character (32)
|
|
uint8 *chr_surface[SIZE_OF_CHAR_SET];
|
|
uint8 *red_chr_surface[SIZE_OF_CHAR_SET];
|
|
|
|
_spriteInfo can_button_sprite[2];
|
|
uint8 *can_button_surface[2];
|
|
uint32 can_button_state=0;
|
|
uint32 touching_can_button=0;
|
|
|
|
_spriteInfo button_sprite[2];
|
|
uint8 *button_surface[2];
|
|
uint32 restore_button_state=0;
|
|
uint32 touching_restore_button=0;
|
|
|
|
_spriteInfo up_button_sprite[2];
|
|
uint8 *up_button_surface[2];
|
|
uint32 up_button_state=0;
|
|
uint32 touching_up_button=0;
|
|
|
|
_spriteInfo down_button_sprite[2];
|
|
uint8 *down_button_surface[2];
|
|
uint32 down_button_state=0;
|
|
uint32 touching_down_button=0;
|
|
|
|
_spriteInfo zup_button_sprite[2];
|
|
uint8 *zup_button_surface[2];
|
|
uint32 zup_button_state=0;
|
|
uint32 touching_zup_button=0;
|
|
|
|
_spriteInfo zdown_button_sprite[2];
|
|
uint8 *zdown_button_surface[2];
|
|
uint32 zdown_button_state=0;
|
|
uint32 touching_zdown_button=0;
|
|
|
|
_spriteInfo grfx_icon_sprite[4];
|
|
uint8 *grfx_icon_surface[4];
|
|
|
|
uint8 *charSet;
|
|
uint8 *red_charSet;
|
|
|
|
_frameHeader *head;
|
|
|
|
uint32 base_slot=0;
|
|
|
|
uint8 subtitles; // text selected
|
|
uint8 speechSelected;
|
|
uint8 stereoReversed = 0;
|
|
|
|
uint8 current_graphics_level;
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
uint32 Restore_control(void) //Tony20Mar97
|
|
{
|
|
//well, this is nice and hard wired - not the way to do it really
|
|
|
|
// returns 0 for no restore
|
|
// 1 for restored ok
|
|
|
|
|
|
int breakOut=0;
|
|
uint32 j;
|
|
char key_press=0;
|
|
uint8 description[SAVE_DESCRIPTION_LEN];
|
|
uint8 buf[8][SAVE_DESCRIPTION_LEN];
|
|
|
|
uint8 chr;
|
|
int char_no;
|
|
_mouseEvent *me;
|
|
|
|
uint8 restore_text[MAX_STRING_LEN];
|
|
uint8 cancel_text[MAX_STRING_LEN];
|
|
uint8 *text;
|
|
|
|
|
|
uint32 slab_text_x;
|
|
uint32 slab_text_y;
|
|
|
|
uint32 slot=1000; //nothing selected
|
|
uint32 clicked_slot;
|
|
uint32 cur_slot_states[9];
|
|
|
|
int scroll_rate=0;
|
|
//static uint32 base_slot=0;
|
|
|
|
int first=0;
|
|
|
|
uint32 rv; // return value for RestoreGame
|
|
uint32 res; //result from primer game cycle
|
|
|
|
|
|
int names_built=0; //0 redo, else dont
|
|
|
|
|
|
|
|
//do some driver stuff
|
|
// for (j=0;j<1000;j++)
|
|
// ResetRenderEngine();
|
|
|
|
|
|
|
|
|
|
//buttons unpressed
|
|
restore_button_state=0;
|
|
can_button_state=0;
|
|
|
|
|
|
|
|
|
|
Build_surfaces();
|
|
Build_chr_surfaces();
|
|
|
|
//fetch the 'restore' text
|
|
text = FetchTextLine( res_man.Res_open(149618690/SIZE), 149618690&0xffff ); // open text file & get the line
|
|
strcpy((char*)&restore_text[0], (char*)text+2);
|
|
//fetch the 'cancel' text
|
|
text = FetchTextLine( res_man.Res_open(149618689/SIZE), 149618689&0xffff ); // open text file & get the line
|
|
strcpy((char*)&cancel_text[0], (char*)text+2);
|
|
//blimey, life's never easy is it?
|
|
|
|
|
|
//control loop
|
|
while (1)
|
|
{
|
|
//--------------------------------------------------
|
|
// Service windows
|
|
if (ServiceWindows() == RDERR_APPCLOSED) // if we pressed Ctrl-Q during the smacker
|
|
{
|
|
Close_game(); //close engine systems down
|
|
CloseAppWindow();
|
|
exit(0); //quit the game
|
|
}
|
|
|
|
while (!gotTheFocus)
|
|
{ names_built=0;
|
|
slot=1000;
|
|
if (ServiceWindows() == RDERR_APPCLOSED)
|
|
break;
|
|
}
|
|
//--------------------------------------------------
|
|
|
|
EraseBackBuffer();
|
|
|
|
|
|
//print panel
|
|
if (DrawSurface(&panel_sprite, panel_surface)==RDERR_SURFACELOST)
|
|
Renew_surfaces();
|
|
|
|
|
|
//print words on panel
|
|
Engine_string(REST_BUT_X+32, REST_BUT_Y, controls_font_id, chr_surface, restore_text);
|
|
Engine_string(CAN_BUT_X+32, REST_BUT_Y, controls_font_id, chr_surface, cancel_text);
|
|
|
|
|
|
|
|
|
|
slab_text_y=76;
|
|
|
|
// print slabs
|
|
for (j=0;j<8;j++)
|
|
{
|
|
|
|
if (slot==base_slot+j) //red
|
|
{ slab_sprite[((base_slot+j)&3)+4].y=SLAB_Y+(j*SLAB_Y_SPACING);
|
|
DrawSurface(&slab_sprite[((base_slot+j)&3)+4], slab_surface[((base_slot+j)&3)+4] );
|
|
}
|
|
else
|
|
{ slab_sprite[((base_slot+j)&3)].y=SLAB_Y+(j*SLAB_Y_SPACING);
|
|
DrawSurface(&slab_sprite[((base_slot+j)&3)], slab_surface[((base_slot+j)&3)] );
|
|
}
|
|
|
|
// print save name on slab if a game is saved in this slot
|
|
if (!names_built)
|
|
{ if (GetSaveDescription(base_slot+j, description) == SR_OK) //if there is a savegame at this slot
|
|
{
|
|
cur_slot_states[j]=1; //slot used
|
|
|
|
if (!description[0])
|
|
Con_fatal_error("NULL file name passed from GetSaveDescription!");
|
|
|
|
// print the name on the slab
|
|
sprintf((char*)buf[j], "%d. %s", base_slot+j, description );
|
|
}
|
|
else
|
|
{
|
|
sprintf((char*)buf[j], "%d.", base_slot+j); //simply print the number
|
|
cur_slot_states[j]=0; //slot not used
|
|
}
|
|
}
|
|
|
|
|
|
char_no=0;
|
|
|
|
slab_text_x=SLAB_X+16;
|
|
|
|
|
|
do
|
|
{
|
|
chr = buf[j][char_no];
|
|
chr-=32; //got true chr$
|
|
|
|
chr_sprite.x=slab_text_x;
|
|
|
|
|
|
chr_sprite.scale=0;
|
|
chr_sprite.type= RDSPR_NOCOMPRESSION+RDSPR_TRANS;
|
|
chr_sprite.blend= 0;
|
|
|
|
if (slot==base_slot+j)
|
|
{
|
|
head = (_frameHeader *)FetchFrameHeader(red_charSet, chr);
|
|
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
|
|
chr_sprite.y=slab_text_y+2;
|
|
DrawSurface(&chr_sprite, red_chr_surface[chr]); //print
|
|
}
|
|
else
|
|
{
|
|
head = (_frameHeader *)FetchFrameHeader(charSet, chr);
|
|
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
|
|
chr_sprite.y=slab_text_y;
|
|
DrawSurface(&chr_sprite, chr_surface[chr]); //print
|
|
}
|
|
|
|
slab_text_x+=head->width-CHARACTER_OVERLAP;
|
|
char_no++;
|
|
}
|
|
while(buf[j][char_no]);
|
|
|
|
|
|
slab_text_y+=SLAB_Y_SPACING;
|
|
}
|
|
|
|
|
|
|
|
names_built=1; //dont GetSaveDescription each cycle
|
|
|
|
//print buttons
|
|
//print restore button
|
|
DrawSurface(&button_sprite[restore_button_state], button_surface[restore_button_state] );
|
|
|
|
//print cancel button
|
|
DrawSurface(&can_button_sprite[can_button_state], can_button_surface[can_button_state] );
|
|
|
|
//print up button
|
|
DrawSurface(&up_button_sprite[up_button_state], up_button_surface[up_button_state] );
|
|
|
|
//print down button
|
|
DrawSurface(&down_button_sprite[down_button_state], down_button_surface[down_button_state] );
|
|
|
|
//print zup button
|
|
DrawSurface(&zup_button_sprite[zup_button_state], zup_button_surface[zup_button_state] );
|
|
|
|
//print zdown button
|
|
DrawSurface(&zdown_button_sprite[zdown_button_state], zdown_button_surface[zdown_button_state] );
|
|
|
|
|
|
ProcessMenu();
|
|
|
|
if (!first)
|
|
{
|
|
first++;
|
|
SetFullPalette(CONTROL_PANEL_PALETTE); // see Build_display.cpp (James17jun97)
|
|
}
|
|
|
|
|
|
//mouse over buttons?
|
|
//restore
|
|
if ((mousex>REST_BUT_X)&&(mousex<REST_BUT_X+24)&&((mousey+40)>REST_BUT_Y)&&((mousey+40)<REST_BUT_Y+24))
|
|
touching_restore_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ restore_button_state=0;
|
|
touching_restore_button=0;
|
|
}
|
|
|
|
//cancel
|
|
if ((mousex>CAN_BUT_X)&&(mousex<CAN_BUT_X+24)&&((mousey+40)>CAN_BUT_Y)&&((mousey+40)<CAN_BUT_Y+24))
|
|
touching_can_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ can_button_state=0;
|
|
touching_can_button=0;
|
|
}
|
|
|
|
//up
|
|
if ((mousex>UP_BUT_X)&&(mousex<UP_BUT_X+17)&&((mousey+40)>UP_BUT_Y)&&((mousey+40)<UP_BUT_Y+17))
|
|
touching_up_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ up_button_state=0;
|
|
touching_up_button=0;
|
|
}
|
|
|
|
//down
|
|
if ((mousex>DOWN_BUT_X)&&(mousex<DOWN_BUT_X+17)&&((mousey+40)>DOWN_BUT_Y)&&((mousey+40)<DOWN_BUT_Y+17))
|
|
touching_down_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ down_button_state=0;
|
|
touching_down_button=0;
|
|
}
|
|
|
|
//up
|
|
if ((mousex>UP_BUT_X)&&(mousex<UP_BUT_X+17)&&((mousey+40)>ZUP_BUT_Y)&&((mousey+40)<ZUP_BUT_Y+17))
|
|
touching_zup_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ zup_button_state=0;
|
|
touching_zup_button=0;
|
|
}
|
|
|
|
//down
|
|
if ((mousex>DOWN_BUT_X)&&(mousex<DOWN_BUT_X+17)&&((mousey+40)>ZDOWN_BUT_Y)&&((mousey+40)<ZDOWN_BUT_Y+17))
|
|
touching_zdown_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ zdown_button_state=0;
|
|
touching_zdown_button=0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//check mouse clicked on a slab
|
|
me = MouseEvent(); //get mouse event
|
|
|
|
if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONDOWN)) //there's a mouse event to be processed
|
|
{
|
|
if ((mousex>SLAB_X)&&(mousex<SLAB_X+384)&&((mousey+40)>SLAB_Y)&&((mousey+40)<SLAB_Y+SLAB_Y_SPACING*8))
|
|
{
|
|
clicked_slot=((mousey+40)-SLAB_Y)/SLAB_Y_SPACING;
|
|
|
|
//Zdebug("clicked slab %d", slot);
|
|
|
|
if (cur_slot_states[clicked_slot]) //a selectable slot
|
|
{
|
|
if (slot!= clicked_slot+base_slot) //can select if not selected now
|
|
slot=clicked_slot+base_slot; //now selected
|
|
|
|
else slot=1000; //else deselect
|
|
}
|
|
}
|
|
|
|
// clicking on the restore button
|
|
if (touching_restore_button)
|
|
restore_button_state=1; //button now down
|
|
|
|
// clicking on the cancel button
|
|
if (touching_can_button)
|
|
can_button_state=1; //button now down
|
|
|
|
// clicking on the up button
|
|
if (touching_up_button)
|
|
{ up_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
|
|
// clicking on the down button
|
|
if (touching_down_button)
|
|
{ down_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
// clicking on the zup button
|
|
if (touching_zup_button)
|
|
{ zup_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
|
|
// clicking on the zdown button
|
|
if (touching_zdown_button)
|
|
{ zdown_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//check for releasing the mouse button over a button
|
|
if ((key_press==13)||((me!=NULL)&&(me->buttons&RD_LEFTBUTTONUP))) //there's a mouse event to be processed
|
|
{
|
|
if ((key_press==13)||((touching_restore_button)&&(restore_button_state)))
|
|
{
|
|
restore_button_state=0;
|
|
|
|
if (slot!=1000) //restore the game!
|
|
{
|
|
breakOut=1;
|
|
|
|
rv = RestoreGame(slot);
|
|
|
|
if (rv == SR_OK)
|
|
{
|
|
// DEAD=0; //in case we were dead - well we're not anymore!
|
|
|
|
// prime system with a game cycle
|
|
Reset_render_lists(); // reset the graphic 'buildit' list before a new logic list (see FN_register_frame)
|
|
Reset_mouse_list(); // reset the mouse hot-spot list (see FN_register_mouse & FN_register_frame)
|
|
|
|
res = LLogic.Process_session();
|
|
|
|
if (res)
|
|
Con_fatal_error("restart 1st cycle failed??");
|
|
|
|
|
|
// Control_error("restored OK :)");
|
|
|
|
Kill_surfaces();
|
|
Kill_chr_surfaces();
|
|
|
|
return(1);
|
|
}
|
|
else
|
|
{
|
|
// Save & Restore error codes
|
|
|
|
// ERROR CODE VALUE MEANING REASON
|
|
// ========== ===== ======= ======
|
|
// SR_OK 0x00000000 // ok No worries
|
|
// SR_ERR_FILEOPEN 0x00000001 // can't open file Could create file for saving, or couldn't find file for loading
|
|
// SR_ERR_INCOMPATIBLE 0x00000002 // (RestoreGame only) incompatible savegame data Savegame file is obsolete. (Won't happen after development stops)
|
|
// SR_ERR_READFAIL 0x00000003 // (RestoreGame only) failed on reading savegame file Something screwed up during the fread()
|
|
// SR_ERR_WRITEFAIL 0x00000004 // (SaveGame only) failed on writing savegame file Something screwed up during the fwrite() - could be hard-drive full..?
|
|
|
|
|
|
// WE NEED A MESSAGE BOX TO INDICATE FAILED SAVE - DON'T HALT THE GAME!
|
|
|
|
if (rv == SR_ERR_FILEOPEN)
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516670/SIZE), 213516670&0xffff)+2));
|
|
// Restore failed - could not open file
|
|
|
|
else if (rv == SR_ERR_INCOMPATIBLE)
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516671/SIZE), 213516671&0xffff)+2));
|
|
// Restore failed - incompatible savegame data
|
|
|
|
else // SR_ERR_READFAIL
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516673/SIZE), 213516673&0xffff)+2));
|
|
// Restore failed
|
|
}
|
|
}
|
|
}
|
|
else if ((touching_can_button)&&(can_button_state)) //quit the screen
|
|
breakOut=1;
|
|
|
|
else if (touching_up_button)
|
|
up_button_state=0;
|
|
|
|
else if (touching_down_button)
|
|
down_button_state=0;
|
|
|
|
else if (touching_zup_button)
|
|
zup_button_state=0;
|
|
|
|
else if (touching_zdown_button)
|
|
zdown_button_state=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//scrolling downward
|
|
if ( ((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(down_button_state)&&(base_slot<92))
|
|
{ base_slot++;
|
|
names_built=0;
|
|
}
|
|
|
|
//scrolling upward
|
|
if (((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(up_button_state)&&(base_slot))
|
|
{ base_slot--;
|
|
names_built=0;
|
|
}
|
|
|
|
//scrolling zdownward
|
|
if (((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(zdown_button_state)&&(base_slot<92))
|
|
{ base_slot+=8;
|
|
if (base_slot>92)
|
|
base_slot=92;
|
|
|
|
names_built=0;
|
|
}
|
|
|
|
//scrolling zupward
|
|
if (((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(zup_button_state)&&(base_slot))
|
|
{ base_slot-=8;
|
|
if (base_slot>92)
|
|
base_slot=0;
|
|
|
|
names_built=0;
|
|
}
|
|
|
|
|
|
//update scroll stuff
|
|
scroll_rate++;
|
|
|
|
|
|
|
|
|
|
//-----
|
|
key_press=0;
|
|
if (KeyWaiting())
|
|
{
|
|
ReadKey(&key_press); //kill the key we just pressed
|
|
if (key_press==27) //ESC
|
|
break;
|
|
}
|
|
|
|
|
|
if (breakOut)
|
|
{
|
|
break; //quit this stuff - ap will eventually close in the mainloop
|
|
}
|
|
|
|
|
|
} //while
|
|
|
|
|
|
Kill_surfaces();
|
|
Kill_chr_surfaces();
|
|
|
|
return(0);
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Create_surface_image(_spriteInfo *sprite, uint8 **surface, uint32 res, uint32 x, uint32 y, uint32 pc) //TonyMarch97
|
|
{
|
|
uint8 *file, *colTablePtr=NULL;
|
|
_animHeader *anim_head;
|
|
_frameHeader *frame_head;
|
|
_cdtEntry *cdt_entry;
|
|
//_spriteInfo spriteInfo;
|
|
uint32 spriteType=RDSPR_TRANS;
|
|
|
|
|
|
file = res_man.Res_open(res); // open anim resource file & point to base
|
|
|
|
|
|
anim_head = FetchAnimHeader( file );
|
|
cdt_entry = FetchCdtEntry( file, pc );
|
|
frame_head = FetchFrameHeader( file, pc );
|
|
|
|
|
|
|
|
|
|
if (anim_head->blend)
|
|
spriteType += RDSPR_BLEND;
|
|
|
|
if ((cdt_entry->frameType) & FRAME_FLIPPED) //if the frame is to be flipped (only really applicable to frames using offsets)
|
|
spriteType += RDSPR_FLIP;
|
|
|
|
switch (anim_head->runTimeComp) // what compression was used?
|
|
{
|
|
case NONE:
|
|
spriteType += RDSPR_NOCOMPRESSION;
|
|
break;
|
|
case RLE256:
|
|
spriteType += RDSPR_RLE256;
|
|
break;
|
|
case RLE16:
|
|
spriteType += RDSPR_RLE16;
|
|
colTablePtr = (uint8*)(anim_head+1) + anim_head->noAnimFrames*sizeof(_cdtEntry);
|
|
// points to just after last cdt_entry, ie. start of colour table
|
|
break;
|
|
}
|
|
|
|
sprite->x = x;
|
|
sprite->y = y;
|
|
sprite->w = frame_head->width;
|
|
sprite->h = frame_head->height;
|
|
sprite->scale = 0;
|
|
// spriteInfo.scaledWidth = build_unit->scaled_width;
|
|
// spriteInfo.scaledHeight = build_unit->scaled_height;
|
|
sprite->type = spriteType;
|
|
sprite->blend = anim_head->blend;
|
|
sprite->data = (uint8*)(frame_head+1); // points to just after frame header, ie. start of sprite data
|
|
// spriteInfo.colourTable = colTablePtr;
|
|
|
|
|
|
// Zdebug("w %d h %d", frame_head->width, frame_head->height);
|
|
|
|
CreateSurface(sprite, surface);
|
|
|
|
|
|
res_man.Res_close(res); //release the anim resource
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Build_surfaces(void) //Tony27March97
|
|
{
|
|
|
|
|
|
//setup the control window
|
|
Create_surface_image(&panel_sprite, &panel_surface, WINDOW_RES, WINDOW_X, REST_Y, 0);
|
|
|
|
|
|
|
|
//setup slabs as surfaces
|
|
Create_surface_image(&slab_sprite[0], &slab_surface[0], 2006, SLAB_X, 0, 0);
|
|
Create_surface_image(&slab_sprite[1], &slab_surface[1], 2007, SLAB_X, 0, 0);
|
|
Create_surface_image(&slab_sprite[2], &slab_surface[2], 2008, SLAB_X, 0, 0);
|
|
Create_surface_image(&slab_sprite[3], &slab_surface[3], 2009, SLAB_X, 0, 0);
|
|
|
|
//now the red selected panels
|
|
Create_surface_image(&slab_sprite[4], &slab_surface[4], 2006, SLAB_X, 0, 1);
|
|
Create_surface_image(&slab_sprite[5], &slab_surface[5], 2007, SLAB_X, 0, 1);
|
|
Create_surface_image(&slab_sprite[6], &slab_surface[6], 2008, SLAB_X, 0, 1);
|
|
Create_surface_image(&slab_sprite[7], &slab_surface[7], 2009, SLAB_X, 0, 1);
|
|
|
|
//restore button
|
|
Create_surface_image(&button_sprite[0], &button_surface[0], 2002, REST_BUT_X, REST_BUT_Y, 0);
|
|
Create_surface_image(&button_sprite[1], &button_surface[1], 2002, REST_BUT_X, REST_BUT_Y, 1);
|
|
|
|
//cancel button
|
|
Create_surface_image(&can_button_sprite[0], &can_button_surface[0], 2002, CAN_BUT_X, CAN_BUT_Y, 0);
|
|
Create_surface_image(&can_button_sprite[1], &can_button_surface[1], 2002, CAN_BUT_X, CAN_BUT_Y, 1);
|
|
|
|
//up button
|
|
Create_surface_image(&up_button_sprite[0], &up_button_surface[0], 2067, UP_BUT_X, UP_BUT_Y, 0);
|
|
Create_surface_image(&up_button_sprite[1], &up_button_surface[1], 2067, UP_BUT_X, UP_BUT_Y, 1);
|
|
|
|
//down button
|
|
Create_surface_image(&down_button_sprite[0], &down_button_surface[0], 1986, DOWN_BUT_X, DOWN_BUT_Y, 0);
|
|
Create_surface_image(&down_button_sprite[1], &down_button_surface[1], 1986, DOWN_BUT_X, DOWN_BUT_Y, 1);
|
|
|
|
//zup button
|
|
Create_surface_image(&zup_button_sprite[0], &zup_button_surface[0], 1982, UP_BUT_X, ZUP_BUT_Y, 0);
|
|
Create_surface_image(&zup_button_sprite[1], &zup_button_surface[1], 1982, UP_BUT_X, ZUP_BUT_Y, 1);
|
|
|
|
//zdown button
|
|
Create_surface_image(&zdown_button_sprite[0], &zdown_button_surface[0], 1988, DOWN_BUT_X, ZDOWN_BUT_Y, 0);
|
|
Create_surface_image(&zdown_button_sprite[1], &zdown_button_surface[1], 1988, DOWN_BUT_X, ZDOWN_BUT_Y, 1);
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Build_chr_surfaces(void) //tony2Apr97
|
|
{
|
|
|
|
int j;
|
|
|
|
|
|
//sort out the font
|
|
charSet = res_man.Res_open(controls_font_id); //open font file
|
|
red_charSet = res_man.Res_open(red_font_id); //open font file
|
|
|
|
|
|
//set up the chr$ set frame surfaces
|
|
chr_sprite.scale=0;
|
|
chr_sprite.type= RDSPR_NOCOMPRESSION+RDSPR_TRANS;
|
|
chr_sprite.blend= 0;
|
|
|
|
for (j=0; j < SIZE_OF_CHAR_SET; j++)
|
|
{ //normal
|
|
head = (_frameHeader *)FetchFrameHeader(charSet,j);
|
|
chr_sprite.data = (uint8 *)(head+1);
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
CreateSurface(&chr_sprite, &chr_surface[j]);
|
|
|
|
// red
|
|
head = (_frameHeader *)FetchFrameHeader(red_charSet,j);
|
|
chr_sprite.data = (uint8 *)(head+1);
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
CreateSurface(&chr_sprite, &red_chr_surface[j]);
|
|
|
|
}
|
|
|
|
res_man.Res_close(controls_font_id); //close font file
|
|
res_man.Res_close(red_font_id); //close font file
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Kill_surfaces(void) //Tony27March97
|
|
{
|
|
|
|
//remove the surfaces
|
|
DeleteSurface(panel_surface);
|
|
DeleteSurface(slab_surface[0]);
|
|
DeleteSurface(slab_surface[1]);
|
|
DeleteSurface(slab_surface[2]);
|
|
DeleteSurface(slab_surface[3]);
|
|
DeleteSurface(slab_surface[4]);
|
|
DeleteSurface(slab_surface[5]);
|
|
DeleteSurface(slab_surface[6]);
|
|
DeleteSurface(slab_surface[7]);
|
|
|
|
DeleteSurface(button_surface[0]);
|
|
DeleteSurface(button_surface[1]);
|
|
|
|
DeleteSurface(can_button_surface[0]);
|
|
DeleteSurface(can_button_surface[1]);
|
|
|
|
DeleteSurface(up_button_surface[0]);
|
|
DeleteSurface(up_button_surface[1]);
|
|
|
|
DeleteSurface(down_button_surface[0]);
|
|
DeleteSurface(down_button_surface[1]);
|
|
|
|
DeleteSurface(zup_button_surface[0]);
|
|
DeleteSurface(zup_button_surface[1]);
|
|
|
|
DeleteSurface(zdown_button_surface[0]);
|
|
DeleteSurface(zdown_button_surface[1]);
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Kill_chr_surfaces(void) //Tony2Apr97
|
|
{
|
|
int j;
|
|
|
|
|
|
|
|
//release chr$ set surfaces
|
|
for (j=0; j < SIZE_OF_CHAR_SET; j++)
|
|
{ //normal
|
|
DeleteSurface(chr_surface[j]);
|
|
// red
|
|
DeleteSurface(red_chr_surface[j]);
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Renew_surfaces(void) //Tony27March97
|
|
{
|
|
Kill_surfaces();
|
|
Kill_chr_surfaces();
|
|
Build_surfaces();
|
|
Build_chr_surfaces();
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Save_control(void) //Tony1Apr97 not a joke
|
|
{
|
|
//largely the same as the restore code
|
|
|
|
|
|
int breakOut=0;
|
|
uint32 j;
|
|
char key_press;
|
|
uint8 description[SAVE_DESCRIPTION_LEN];
|
|
uint8 buf[8][SAVE_DESCRIPTION_LEN];
|
|
uint8 ed_buf[SAVE_DESCRIPTION_LEN];
|
|
int char_no;
|
|
uint8 chr;
|
|
_mouseEvent *me;
|
|
int esc_release=0;
|
|
|
|
uint32 slab_text_x;
|
|
uint32 slab_text_y;
|
|
|
|
uint32 clicked_slot=1000, edit_screen_slot=1000;
|
|
uint32 cur_slot_states[9];
|
|
|
|
int scroll_rate=0;
|
|
// static uint32 base_slot=0;
|
|
|
|
int edit_pos=0, first_chr=0, flash=0;
|
|
|
|
uint8 save_text[MAX_STRING_LEN];
|
|
uint8 cancel_text[MAX_STRING_LEN];
|
|
uint8 *text;
|
|
|
|
int first=0;
|
|
|
|
uint32 rv; // return value for SaveGame
|
|
|
|
uint32 edit_width=0;
|
|
|
|
int names_built=0;
|
|
|
|
|
|
|
|
//buttons unpressed
|
|
restore_button_state=0;
|
|
can_button_state=0;
|
|
|
|
|
|
//do some driver stuff
|
|
// ResetRenderEngine();
|
|
|
|
|
|
|
|
//sort out the font
|
|
charSet = res_man.Res_open(controls_font_id); //open font file
|
|
red_charSet = res_man.Res_open(red_font_id); //open font file
|
|
|
|
chr_sprite.scale=0;
|
|
chr_sprite.type= RDSPR_NOCOMPRESSION+RDSPR_TRANS;
|
|
chr_sprite.blend= 0;
|
|
|
|
|
|
|
|
|
|
Build_surfaces();
|
|
Build_chr_surfaces();
|
|
|
|
//fetch the 'save' text
|
|
text = FetchTextLine( res_man.Res_open(149618691/SIZE), 149618691&0xffff ); // open text file & get the line
|
|
strcpy((char*)&save_text[0], (char*)text+2);
|
|
//fetch the 'cancel' text
|
|
text = FetchTextLine( res_man.Res_open(149618689/SIZE), 149618689&0xffff ); // open text file & get the line
|
|
strcpy((char*)&cancel_text[0], (char*)text+2);
|
|
//blimey, life's never easy is it?
|
|
|
|
|
|
|
|
//control loop
|
|
while (1)
|
|
{
|
|
//--------------------------------------------------
|
|
if (ServiceWindows() == RDERR_APPCLOSED) // if we pressed Ctrl-Q during the smacker
|
|
{
|
|
Close_game(); //close engine systems down
|
|
CloseAppWindow();
|
|
exit(0); //quit the game
|
|
}
|
|
|
|
// Service windows
|
|
while (!gotTheFocus)
|
|
{ names_built=0;
|
|
edit_screen_slot=1000;
|
|
if (ServiceWindows() == RDERR_APPCLOSED)
|
|
break;
|
|
}
|
|
//--------------------------------------------------
|
|
|
|
EraseBackBuffer();
|
|
|
|
|
|
//print panel
|
|
if (DrawSurface(&panel_sprite, panel_surface)==RDERR_SURFACELOST)
|
|
Renew_surfaces();
|
|
|
|
//print words on panel
|
|
Engine_string(REST_BUT_X+32, REST_BUT_Y, controls_font_id, chr_surface, save_text);
|
|
Engine_string(CAN_BUT_X+32, REST_BUT_Y, controls_font_id, chr_surface, cancel_text);
|
|
|
|
|
|
|
|
|
|
|
|
slab_text_y=76;
|
|
|
|
// print slabs
|
|
for (j=0;j<8;j++)
|
|
{
|
|
if (edit_screen_slot!=j)
|
|
{ slab_sprite[((base_slot+j)&3)].y=SLAB_Y+(j*SLAB_Y_SPACING);
|
|
DrawSurface(&slab_sprite[((base_slot+j)&3)], slab_surface[((base_slot+j)&3)] );
|
|
|
|
// print save name on slab if a game is saved in this slot
|
|
if (!names_built)
|
|
{
|
|
if (GetSaveDescription(base_slot+j, description) == SR_OK) //if there is a savegame at this slot
|
|
{ cur_slot_states[j]=1; //slot used
|
|
|
|
if (!description[0])
|
|
Con_fatal_error("NULL file name passed from GetSaveDescription!");
|
|
|
|
|
|
// print the name on the slab
|
|
sprintf((char*)buf[j], "%d. %s", base_slot+j, description );
|
|
}
|
|
else
|
|
{ sprintf((char*)buf[j], "%d.", base_slot+j); //simply print the number
|
|
cur_slot_states[j]=0; //slot not used
|
|
}
|
|
}
|
|
|
|
char_no=0;
|
|
|
|
slab_text_x=SLAB_X+16;
|
|
|
|
|
|
do
|
|
{
|
|
chr = buf[j][char_no];
|
|
chr-=32; //got true chr$
|
|
|
|
chr_sprite.x=slab_text_x;
|
|
|
|
head = (_frameHeader *)FetchFrameHeader(charSet, chr);
|
|
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
|
|
chr_sprite.y=slab_text_y;
|
|
DrawSurface(&chr_sprite, chr_surface[chr]); //print
|
|
|
|
slab_text_x+=head->width-CHARACTER_OVERLAP; // overlap characters by 3 pixels;
|
|
char_no++;
|
|
}
|
|
while(buf[j][char_no]);
|
|
}
|
|
slab_text_y+=SLAB_Y_SPACING;
|
|
}
|
|
|
|
names_built=1;
|
|
|
|
//draw the typing slab and text if we are still editing
|
|
if (edit_screen_slot!=1000) //we are typing a name in
|
|
{
|
|
|
|
flash++;
|
|
if (flash<7)
|
|
ed_buf[edit_pos]='_';
|
|
else
|
|
ed_buf[edit_pos]=' '; //by putting a space in we'll always have a chr$ in the buffer
|
|
|
|
if (flash==14)
|
|
flash=0;
|
|
|
|
|
|
// now draw the current edit line
|
|
// draw a red slab
|
|
slab_sprite[(clicked_slot&3)+4].y=SLAB_Y+(edit_screen_slot*SLAB_Y_SPACING);
|
|
DrawSurface(&slab_sprite[(clicked_slot&3)+4], slab_surface[(clicked_slot&3)+4] );
|
|
|
|
// draw the text line
|
|
char_no=0;
|
|
edit_width=0; //total pixel width of text being typed in
|
|
slab_text_x=SLAB_X+16;
|
|
|
|
// print the chr$
|
|
do
|
|
{
|
|
chr = ed_buf[char_no];
|
|
chr-=32; //got true chr$
|
|
|
|
chr_sprite.x=slab_text_x;
|
|
|
|
head = (_frameHeader *)FetchFrameHeader(red_charSet, chr);
|
|
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
|
|
chr_sprite.y=SLAB_Y+(edit_screen_slot*SLAB_Y_SPACING)+5; //why 5? when its 2 on restore????????
|
|
DrawSurface(&chr_sprite, red_chr_surface[chr]); //print
|
|
|
|
slab_text_x+=head->width-CHARACTER_OVERLAP;
|
|
edit_width+=head->width-CHARACTER_OVERLAP;
|
|
|
|
char_no++;
|
|
}
|
|
while(ed_buf[char_no]);
|
|
}
|
|
|
|
|
|
|
|
|
|
//print buttons
|
|
//print restore button
|
|
DrawSurface(&button_sprite[restore_button_state], button_surface[restore_button_state] );
|
|
|
|
//print cancel button
|
|
DrawSurface(&can_button_sprite[can_button_state], can_button_surface[can_button_state] );
|
|
|
|
//print up button
|
|
DrawSurface(&up_button_sprite[up_button_state], up_button_surface[up_button_state] );
|
|
|
|
//print down button
|
|
DrawSurface(&down_button_sprite[down_button_state], down_button_surface[down_button_state] );
|
|
|
|
//print zup button
|
|
DrawSurface(&zup_button_sprite[zup_button_state], zup_button_surface[zup_button_state] );
|
|
|
|
//print zdown button
|
|
DrawSurface(&zdown_button_sprite[zdown_button_state], zdown_button_surface[zdown_button_state] );
|
|
|
|
|
|
ProcessMenu();
|
|
|
|
|
|
|
|
|
|
//mouse over buttons?
|
|
//restore
|
|
if ((mousex>REST_BUT_X)&&(mousex<REST_BUT_X+24)&&((mousey+40)>REST_BUT_Y)&&((mousey+40)<REST_BUT_Y+24))
|
|
touching_restore_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ restore_button_state=0;
|
|
touching_restore_button=0;
|
|
}
|
|
|
|
//cancel
|
|
if ((mousex>CAN_BUT_X)&&(mousex<CAN_BUT_X+24)&&((mousey+40)>CAN_BUT_Y)&&((mousey+40)<CAN_BUT_Y+24))
|
|
touching_can_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ can_button_state=0;
|
|
touching_can_button=0;
|
|
}
|
|
|
|
//up
|
|
if ((mousex>UP_BUT_X)&&(mousex<UP_BUT_X+17)&&((mousey+40)>UP_BUT_Y)&&((mousey+40)<UP_BUT_Y+17))
|
|
touching_up_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ up_button_state=0;
|
|
touching_up_button=0;
|
|
}
|
|
|
|
//down
|
|
if ((mousex>DOWN_BUT_X)&&(mousex<DOWN_BUT_X+17)&&((mousey+40)>DOWN_BUT_Y)&&((mousey+40)<DOWN_BUT_Y+17))
|
|
touching_down_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ down_button_state=0;
|
|
touching_down_button=0;
|
|
}
|
|
|
|
//up
|
|
if ((mousex>UP_BUT_X)&&(mousex<UP_BUT_X+17)&&((mousey+40)>ZUP_BUT_Y)&&((mousey+40)<ZUP_BUT_Y+17))
|
|
touching_zup_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ zup_button_state=0;
|
|
touching_zup_button=0;
|
|
}
|
|
|
|
//down
|
|
if ((mousex>DOWN_BUT_X)&&(mousex<DOWN_BUT_X+17)&&((mousey+40)>ZDOWN_BUT_Y)&&((mousey+40)<ZDOWN_BUT_Y+17))
|
|
touching_zdown_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ zdown_button_state=0;
|
|
touching_zdown_button=0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//check mouse clicked on a slab
|
|
me = MouseEvent(); //get mouse event
|
|
|
|
if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONDOWN)) //there's a mouse event to be processed
|
|
{
|
|
if ((mousex>SLAB_X)&&(mousex<SLAB_X+384)&&((mousey+40)>SLAB_Y)&&((mousey+40)<SLAB_Y+SLAB_Y_SPACING*8))
|
|
{
|
|
edit_screen_slot=((mousey+40)-SLAB_Y)/SLAB_Y_SPACING;
|
|
clicked_slot=edit_screen_slot+base_slot;
|
|
|
|
Zdebug("+ %d %d", edit_screen_slot, clicked_slot);
|
|
|
|
// now edit the line
|
|
// take a copy of the string
|
|
|
|
for (j=0;j<SAVE_DESCRIPTION_LEN;j++)
|
|
ed_buf[j]=0; //zero the string
|
|
|
|
|
|
sprintf((char*)ed_buf, "%d. ", clicked_slot); //simply print the number - assume no name in panel
|
|
first_chr=strlen((char*)ed_buf);
|
|
edit_pos=first_chr;
|
|
|
|
|
|
if (GetSaveDescription(clicked_slot, description) == SR_OK) //if there is a savegame at this slot
|
|
{
|
|
sprintf((char*)ed_buf, "%d. %s", clicked_slot, description );
|
|
edit_pos=strlen((char*)ed_buf); //recalculate cursor pos to end of string
|
|
}
|
|
|
|
Zdebug("first %d [%s]", first_chr, ed_buf);
|
|
|
|
}
|
|
|
|
// clicking on the restore button
|
|
if (touching_restore_button)
|
|
restore_button_state=1; //button now down
|
|
|
|
// clicking on the cancel button
|
|
if (touching_can_button)
|
|
can_button_state=1; //button now down
|
|
|
|
// clicking on the up button
|
|
if (touching_up_button)
|
|
{ up_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
|
|
// clicking on the down button
|
|
if (touching_down_button)
|
|
{ down_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
// clicking on the zup button
|
|
if (touching_zup_button)
|
|
{ zup_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
|
|
// clicking on the zdown button
|
|
if (touching_zdown_button)
|
|
{ zdown_button_state=1; //button now down
|
|
scroll_rate=0;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//check for releasing the mouse button over a button
|
|
if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONUP)) //there's a mouse event to be processed
|
|
{
|
|
|
|
if ((touching_restore_button)&&(restore_button_state))
|
|
{
|
|
restore_button_state=0;
|
|
|
|
if ((edit_screen_slot!=1000)&&(edit_pos!=first_chr)) //we are editing and have a legal file name typed in
|
|
{ //then save game - can also be saved when you press RETurn
|
|
ed_buf[edit_pos]=0; //remove cursor/[space]
|
|
|
|
rv = SaveGame(clicked_slot, (uint8*)&ed_buf[first_chr]);
|
|
|
|
if (rv == SR_OK)
|
|
{ breakOut=1; //finished
|
|
if ((edit_screen_slot>6)&(base_slot<92))
|
|
base_slot++;
|
|
}
|
|
else
|
|
{
|
|
// Save & Restore error codes
|
|
|
|
// ERROR CODE VALUE MEANING REASON
|
|
// ========== ===== ======= ======
|
|
// SR_OK 0x00000000 // ok No worries
|
|
// SR_ERR_FILEOPEN 0x00000001 // can't open file Could create file for saving, or couldn't find file for loading
|
|
// SR_ERR_INCOMPATIBLE 0x00000002 // (RestoreGame only) incompatible savegame data Savegame file is obsolete. (Won't happen after development stops)
|
|
// SR_ERR_READFAIL 0x00000003 // (RestoreGame only) failed on reading savegame file Something screwed up during the fread()
|
|
// SR_ERR_WRITEFAIL 0x00000004 // (SaveGame only) failed on writing savegame file Something screwed up during the fwrite() - could be hard-drive full..?
|
|
|
|
// WE NEED A MESSAGE BOX TO INDICATE FAILED SAVE - DON'T HALT THE GAME!
|
|
|
|
if (rv == SR_ERR_FILEOPEN)
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516674/SIZE), 213516674&0xffff)+2));
|
|
// Save failed - could not open file
|
|
|
|
else // SR_ERR_WRITEFAIL
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516676/SIZE), 213516676&0xffff)+2));
|
|
// Save failed
|
|
}
|
|
}
|
|
}
|
|
else if ((touching_can_button)&&(can_button_state)) //quit the screen
|
|
breakOut=1;
|
|
|
|
else if (touching_up_button)
|
|
up_button_state=0;
|
|
|
|
else if (touching_down_button)
|
|
down_button_state=0;
|
|
|
|
else if (touching_zup_button)
|
|
zup_button_state=0;
|
|
|
|
else if (touching_zdown_button)
|
|
zdown_button_state=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//scrolling downward
|
|
if ( ((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(down_button_state)&&(base_slot<92))
|
|
{ base_slot++;
|
|
names_built=0;
|
|
|
|
if (edit_screen_slot!=1000)
|
|
{ edit_screen_slot--;
|
|
if (base_slot>clicked_slot)
|
|
edit_screen_slot=1000;
|
|
}
|
|
}
|
|
|
|
//scrolling upward
|
|
if (((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(up_button_state)&&(base_slot))
|
|
{ base_slot--;
|
|
names_built=0;
|
|
|
|
if (edit_screen_slot!=1000)
|
|
{ edit_screen_slot++;
|
|
if ((base_slot+7)<clicked_slot)
|
|
edit_screen_slot=1000;
|
|
}
|
|
}
|
|
|
|
//scrolling zdownward
|
|
if (((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(zdown_button_state)&&(base_slot<92))
|
|
{ base_slot+=8;
|
|
names_built=0;
|
|
|
|
if (base_slot>92)
|
|
base_slot=92;
|
|
|
|
edit_screen_slot=1000; //no more editing
|
|
}
|
|
|
|
//scrolling zupward
|
|
if (((scroll_rate<1)||(scroll_rate>12))&&(!(scroll_rate&3))&&(zup_button_state)&&(base_slot))
|
|
{ base_slot-=8;
|
|
names_built=0;
|
|
|
|
if (base_slot>92)
|
|
base_slot=0;
|
|
edit_screen_slot=1000; //no more editing
|
|
}
|
|
|
|
|
|
|
|
|
|
//update scroll stuff
|
|
scroll_rate++;
|
|
|
|
|
|
|
|
|
|
//-----
|
|
|
|
//deal with user input if the user is inputting
|
|
if ((edit_screen_slot!=1000)&&(KeyWaiting())) //we are typing a name in
|
|
{
|
|
ReadKey(&key_press);
|
|
|
|
if (!key_press) //escape sequences
|
|
{
|
|
}
|
|
else if (key_press==27) //ESC
|
|
{
|
|
edit_screen_slot=1000; //quit this edit
|
|
esc_release=42; //stop the ESC key auto-repeating after this and quiting the save control
|
|
}
|
|
else if (key_press==13) //RETurn
|
|
{
|
|
if (edit_pos!=first_chr)
|
|
{ //save game
|
|
ed_buf[edit_pos]=0; //remove cursor/[space]
|
|
|
|
Zdebug("%d %d %s", first_chr, edit_pos, &ed_buf[first_chr]);
|
|
|
|
rv = SaveGame(clicked_slot, (uint8*)&ed_buf[first_chr]);
|
|
|
|
if (rv == SR_OK)
|
|
{ breakOut=1; //finished
|
|
if ((edit_screen_slot>6)&(base_slot<92))
|
|
base_slot++;
|
|
}
|
|
else
|
|
{
|
|
// Save & Restore error codes
|
|
|
|
// ERROR CODE VALUE MEANING REASON
|
|
// ========== ===== ======= ======
|
|
// SR_OK 0x00000000 // ok No worries
|
|
// SR_ERR_FILEOPEN 0x00000001 // can't open file Could create file for saving, or couldn't find file for loading
|
|
// SR_ERR_INCOMPATIBLE 0x00000002 // (RestoreGame only) incompatible savegame data Savegame file is obsolete. (Won't happen after development stops)
|
|
// SR_ERR_READFAIL 0x00000003 // (RestoreGame only) failed on reading savegame file Something screwed up during the fread()
|
|
// SR_ERR_WRITEFAIL 0x00000004 // (SaveGame only) failed on writing savegame file Something screwed up during the fwrite() - could be hard-drive full..?
|
|
|
|
|
|
// WE NEED A MESSAGE BOX TO INDICATE FAILED SAVE - DON'T HALT THE GAME!
|
|
|
|
if (rv == SR_ERR_FILEOPEN)
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516674/SIZE), 213516674&0xffff)+2));
|
|
// Save failed - could not open file
|
|
|
|
else // SR_ERR_WRITEFAIL
|
|
Control_error((char*)(FetchTextLine( res_man.Res_open(213516676/SIZE), 213516676&0xffff)+2));
|
|
// Save failed
|
|
}
|
|
}
|
|
else edit_screen_slot=1000; //dont save an empty slot and cancel editing
|
|
}
|
|
|
|
else if (key_press==8) //delete
|
|
{
|
|
if (edit_pos!=first_chr)
|
|
{
|
|
ed_buf[edit_pos]=0; //delete cursor chr$
|
|
edit_pos--;
|
|
ed_buf[edit_pos]=0;
|
|
}
|
|
}
|
|
else if ((key_press<32)||(key_press>'z'))
|
|
Zdebug("save ignoring key - %d", key_press);
|
|
else
|
|
{
|
|
// if (edit_pos<(20)) //less one to leave room for the cursor
|
|
|
|
|
|
if ((edit_width<350)&&(edit_pos<SAVE_DESCRIPTION_LEN-2))
|
|
ed_buf[edit_pos++]=key_press;
|
|
else //end of line has been reached, so keep replacing last letter
|
|
ed_buf[edit_pos-1]=key_press; //replace
|
|
}
|
|
}
|
|
else if (KeyWaiting())
|
|
{
|
|
ReadKey(&key_press); //kill the key we just pressed
|
|
if ((key_press==27)&&(!esc_release)) //ESC
|
|
breakOut=1;
|
|
|
|
else if (key_press!=27)
|
|
esc_release=0;
|
|
}
|
|
else if (!KeyWaiting())
|
|
esc_release=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (breakOut)
|
|
{
|
|
break; //quit this stuff - ap will eventually close in the mainloop
|
|
}
|
|
|
|
if (!first)
|
|
{
|
|
first++;
|
|
SetFullPalette(CONTROL_PANEL_PALETTE); // see Build_display.cpp (James17jun97)
|
|
}
|
|
} //while
|
|
|
|
|
|
Kill_surfaces();
|
|
Kill_chr_surfaces();
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Quit_control(void) //Tony2Apr97
|
|
{
|
|
uint32 res;
|
|
|
|
|
|
res=Generic_mini_control(149618692); //quit text
|
|
|
|
|
|
if (!res)
|
|
return; //just return to game
|
|
EraseBackBuffer();
|
|
|
|
Close_game(); //close engine systems down
|
|
CloseAppWindow();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Restart_control(void) //Tony4Apr97
|
|
{
|
|
uint32 res;
|
|
uint32 temp_demo_flag;
|
|
|
|
|
|
res=Generic_mini_control(149618693); //restart text
|
|
|
|
|
|
if (!res)
|
|
return; //just return to game
|
|
|
|
|
|
Kill_music(); // Stop music instantly! (James22aug97)
|
|
|
|
|
|
DEAD=0; //in case we were dead - well we're not anymore!
|
|
|
|
//clean up surface memory
|
|
Kill_mini_surfaces();
|
|
EraseBackBuffer();
|
|
//ProcessMenu(); //draw menu
|
|
|
|
//restart the game
|
|
//clear all memory and reset the globals
|
|
|
|
temp_demo_flag = DEMO;
|
|
|
|
res_man.Remove_all_res(); //remove all resources from memory, including player object & global variables
|
|
SetGlobalInterpreterVariables((int32*)(res_man.Res_open(1)+sizeof(_standardHeader))); //reopen global variables resource & send address to interpreter - it won't be moving
|
|
res_man.Res_close(1);
|
|
|
|
DEMO = temp_demo_flag;
|
|
|
|
FreeAllRouteMem(); // free all the route memory blocks from previous game
|
|
|
|
g_sword2->Start_game(); // call the same function that first started us up
|
|
|
|
|
|
//prime system with a game cycle
|
|
Reset_render_lists(); // reset the graphic 'buildit' list before a new logic list (see FN_register_frame)
|
|
Reset_mouse_list(); // reset the mouse hot-spot list (see FN_register_mouse & FN_register_frame)
|
|
|
|
CloseMenuImmediately();
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// FOR THE DEMO - FORCE THE SCROLLING TO BE RESET! (James29may97)
|
|
// - this is taken from FN_init_background
|
|
this_screen.scroll_flag = 2; // switch on scrolling (2 means first time on screen)
|
|
//---------------------------------------------------------------
|
|
|
|
res = LLogic.Process_session();
|
|
|
|
if (res)
|
|
Con_fatal_error("restart 1st cycle failed??");
|
|
|
|
this_screen.new_palette=99; // (JEL08oct97) so palette not restored immediately after control panel - we want to fade up instead!
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
uint32 Generic_mini_control(uint32 text_id) //Tony2Apr97
|
|
{
|
|
|
|
// returns 1 for OK pressed
|
|
// returns 0 for CANCEL pressed
|
|
|
|
int breakOut=0;
|
|
char c;
|
|
|
|
uint8 quit_text[MAX_STRING_LEN];
|
|
uint8 ok_text[MAX_STRING_LEN];
|
|
uint8 cancel_text[MAX_STRING_LEN];
|
|
uint8 *text;
|
|
|
|
_mouseEvent *me;
|
|
|
|
int first=0;
|
|
|
|
int text_len;
|
|
|
|
#define OK_BUT_X (QUIT_X+40)
|
|
#define OK_BUT_Y (QUIT_Y+110)
|
|
#define CAN_BU_Y (QUIT_Y+172)
|
|
|
|
|
|
//do some driver stuff
|
|
// ResetRenderEngine();
|
|
|
|
|
|
//fetch the 'quit' text
|
|
text = FetchTextLine( res_man.Res_open(text_id/SIZE), text_id&0xffff ); //quit or restart
|
|
strcpy((char*)&quit_text[0], (char*)text+2);
|
|
text_len = Pixel_text_length(&quit_text[0], controls_font_id);
|
|
|
|
|
|
//fetch the 'ok' text
|
|
text = FetchTextLine( res_man.Res_open(149618688/SIZE), 149618688&0xffff ); //ok
|
|
strcpy((char*)&ok_text[0], (char*)text+2);
|
|
|
|
//fetch the 'cancel' text
|
|
text = FetchTextLine( res_man.Res_open(149618689/SIZE), 149618689&0xffff ); //cancel
|
|
strcpy((char*)&cancel_text[0], (char*)text+2);
|
|
//blimey, life's never easy is it?
|
|
|
|
|
|
|
|
|
|
//buttons unpressed
|
|
restore_button_state=0;
|
|
can_button_state=0;
|
|
|
|
|
|
//build surfaces
|
|
Build_mini_surfaces();
|
|
|
|
|
|
|
|
//control loop
|
|
while (1)
|
|
{
|
|
//--------------------------------------------------
|
|
// Service windows
|
|
if (ServiceWindows() == RDERR_APPCLOSED) // if we pressed Ctrl-Q
|
|
{
|
|
Close_game(); //close engine systems down
|
|
CloseAppWindow();
|
|
exit(0); //quit the game
|
|
}
|
|
|
|
while (!gotTheFocus)
|
|
if (ServiceWindows() == RDERR_APPCLOSED)
|
|
break;
|
|
|
|
//--------------------------------------------------
|
|
|
|
|
|
EraseBackBuffer();
|
|
|
|
|
|
//print panel
|
|
if (DrawSurface(&panel_sprite, panel_surface)==RDERR_SURFACELOST)
|
|
{
|
|
Kill_mini_surfaces();
|
|
Build_mini_surfaces();
|
|
}
|
|
|
|
//print words on panel quit_x+81
|
|
Engine_string(310-(text_len/2), QUIT_Y+30, controls_font_id, chr_surface, quit_text); // quit
|
|
Engine_string(QUIT_X+67, QUIT_Y+110, controls_font_id, chr_surface, ok_text); // ok
|
|
Engine_string(QUIT_X+67, QUIT_Y+172, controls_font_id, chr_surface, cancel_text); // cancel
|
|
|
|
//print buttons
|
|
//print ok button
|
|
DrawSurface(&button_sprite[restore_button_state], button_surface[restore_button_state] );
|
|
//print cancel button
|
|
DrawSurface(&can_button_sprite[can_button_state], can_button_surface[can_button_state] );
|
|
|
|
//keep menu up too
|
|
ProcessMenu();
|
|
|
|
//user can ESC quit
|
|
if (KeyWaiting())
|
|
{
|
|
ReadKey(&c); //kill the key we just pressed
|
|
if (c==27) //ESC
|
|
break;
|
|
}
|
|
|
|
|
|
//mouse over ok button?
|
|
if ((mousex>OK_BUT_X)&&(mousex<OK_BUT_X+24)&&((mousey+40)>OK_BUT_Y)&&((mousey+40)<OK_BUT_Y+24))
|
|
touching_restore_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ restore_button_state=0;
|
|
touching_restore_button=0;
|
|
}
|
|
//mouse over cancel button?
|
|
if ((mousex>OK_BUT_X)&&(mousex<OK_BUT_X+24)&&((mousey+40)>CAN_BU_Y)&&((mousey+40)<CAN_BU_Y+24))
|
|
touching_can_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ can_button_state=0;
|
|
touching_can_button=0;
|
|
}
|
|
|
|
|
|
//pressing on a button
|
|
me = MouseEvent(); //get mouse event
|
|
|
|
if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONDOWN)) //there's a mouse event to be processed
|
|
{
|
|
if (touching_restore_button)
|
|
restore_button_state=1;
|
|
|
|
if (touching_can_button)
|
|
can_button_state=1;
|
|
|
|
}
|
|
else if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONUP))
|
|
{
|
|
if ((touching_restore_button)&&(restore_button_state)) //quit the game
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
if ((touching_can_button)&&(can_button_state))
|
|
{ can_button_state=0;
|
|
breakOut=1;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (breakOut)
|
|
break;
|
|
|
|
if (!first)
|
|
{
|
|
first++;
|
|
SetFullPalette(CONTROL_PANEL_PALETTE); // see Build_display.cpp (James17jun97)
|
|
}
|
|
}
|
|
|
|
|
|
Kill_mini_surfaces();
|
|
|
|
return(0);
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Build_mini_surfaces(void) //tony3Apr97
|
|
{
|
|
Create_surface_image(&panel_sprite, &panel_surface, 1996, QUIT_X, QUIT_Y, 0);
|
|
//ok button
|
|
Create_surface_image(&button_sprite[0], &button_surface[0], 2002, OK_BUT_X, OK_BUT_Y, 0);
|
|
Create_surface_image(&button_sprite[1], &button_surface[1], 2002, OK_BUT_X, OK_BUT_Y, 1);
|
|
//cancel button
|
|
Create_surface_image(&can_button_sprite[0], &can_button_surface[0], 2002, OK_BUT_X, CAN_BU_Y, 0);
|
|
Create_surface_image(&can_button_sprite[1], &can_button_surface[1], 2002, OK_BUT_X, CAN_BU_Y, 1);
|
|
|
|
Build_chr_surfaces();
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Kill_mini_surfaces(void) //tony3Apr97
|
|
{
|
|
DeleteSurface(panel_surface);
|
|
//ok button
|
|
DeleteSurface(button_surface[0]);
|
|
DeleteSurface(button_surface[1]);
|
|
//cancel button
|
|
DeleteSurface(can_button_surface[0]);
|
|
DeleteSurface(can_button_surface[1]);
|
|
|
|
Kill_chr_surfaces();
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Engine_string(uint32 x, uint32 y, uint32 res, uint8 **surface_list, uint8 *buf) //tony2Apr97
|
|
{
|
|
//takes fonts as sprites and prints transparently to screen
|
|
//requires the chr$ surfaces have been setup
|
|
|
|
int char_no=0;
|
|
int chr;
|
|
uint8 *chars;
|
|
|
|
|
|
chars = res_man.Res_open(res); //open font file
|
|
|
|
chr_sprite.scale=0;
|
|
chr_sprite.type= RDSPR_NOCOMPRESSION+RDSPR_TRANS;
|
|
chr_sprite.blend= 0;
|
|
|
|
|
|
chr_sprite.x=x;
|
|
chr_sprite.y=y;
|
|
|
|
do
|
|
{
|
|
chr = buf[char_no];
|
|
chr-=32; //got true chr$
|
|
|
|
head = (_frameHeader *)FetchFrameHeader(chars, chr);
|
|
|
|
chr_sprite.w=head->width;
|
|
chr_sprite.h=head->height;
|
|
|
|
DrawSurface(&chr_sprite, surface_list[chr]); //print
|
|
|
|
chr_sprite.x+=head->width-CHARACTER_OVERLAP;
|
|
char_no++;
|
|
}
|
|
while(buf[char_no]);
|
|
|
|
res_man.Res_close(res); //close font file
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
uint32 Pixel_text_length(uint8 *buf, uint32 res) //tony4Apr97
|
|
{
|
|
|
|
int char_no=0;
|
|
int chr;
|
|
uint8 *chars;
|
|
uint32 width=0;
|
|
|
|
|
|
chars = res_man.Res_open(res); //open font file
|
|
|
|
do
|
|
{
|
|
chr = buf[char_no];
|
|
chr-=32; //got true chr$
|
|
|
|
head = (_frameHeader *)FetchFrameHeader(chars, chr);
|
|
|
|
width+=head->width-CHARACTER_OVERLAP;
|
|
|
|
char_no++;
|
|
}
|
|
while(buf[char_no]);
|
|
|
|
res_man.Res_close(res); //close font file
|
|
|
|
return(width);
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Control_error(char* text) //Tony13May97
|
|
{
|
|
//print a message on screen, wait for key, return
|
|
|
|
_mouseEvent *me;
|
|
char c;
|
|
|
|
DisplayMsg( (uint8*)text, 0 ); // 2nd param is duration
|
|
|
|
|
|
while (1)
|
|
{
|
|
//--------------------------------------------------
|
|
// Service windows
|
|
|
|
if (ServiceWindows() == RDERR_APPCLOSED) // if we pressed Ctrl-Q during the smacker
|
|
{
|
|
Close_game(); //close engine systems down
|
|
CloseAppWindow();
|
|
exit(0); //quit the game
|
|
}
|
|
|
|
while (!gotTheFocus)
|
|
if (ServiceWindows() == RDERR_APPCLOSED)
|
|
break;
|
|
//--------------------------------------------------
|
|
|
|
if (KeyWaiting())
|
|
{
|
|
ReadKey(&c); //kill the key we just pressed
|
|
if (c==27) //ESC
|
|
break;
|
|
}
|
|
|
|
me = MouseEvent(); //get mouse event
|
|
|
|
if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONDOWN)) //there's a mouse event to be processed
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
RemoveMsg(); // Removes the message.
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
int32 ReadOptionSettings(void) //pete10Jun97
|
|
{
|
|
// settings file is 9 bytes long, bytes 1 to 3 = music, speech and fx volumes
|
|
// bytes 4 to 6 = music, speech and fx mute states, byte 7 = grfx level
|
|
// byte 8 = subtitle state and byte 9 = object label state.
|
|
|
|
uint8 buff[10];
|
|
char filename[256];
|
|
SaveFile *fp;
|
|
SaveFileManager *mgr = g_system->get_savefile_manager();
|
|
|
|
sprintf(filename, "%s-settings.dat", g_sword2->_game_name);
|
|
|
|
if (!(fp = mgr->open_savefile(filename, g_sword2->getSavePath(), false)))
|
|
return (1);
|
|
|
|
if (fp->read(buff, 10) != 10)
|
|
{
|
|
delete fp;
|
|
delete mgr;
|
|
return (2);
|
|
}
|
|
|
|
delete fp;
|
|
delete mgr;
|
|
|
|
g_sword2->_sound->SetMusicVolume(buff[0]);
|
|
g_sword2->_sound->SetSpeechVolume(buff[1]);
|
|
g_sword2->_sound->SetFxVolume(buff[2]);
|
|
g_sword2->_sound->MuteMusic(buff[3]);
|
|
g_sword2->_sound->MuteSpeech(buff[4]);
|
|
g_sword2->_sound->MuteFx(buff[5]);
|
|
|
|
|
|
UpdateGraphicsLevel(buff[6]); // (James13jun97)
|
|
|
|
speechSelected = !buff[4];
|
|
subtitles = buff[7];
|
|
pointerTextSelected = buff[8];
|
|
|
|
if (buff[9] != stereoReversed)
|
|
g_sword2->_sound->ReverseStereo();
|
|
|
|
stereoReversed = buff[9];
|
|
|
|
return (0);
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
int32 WriteOptionSettings(void) //pete10Jun97
|
|
{
|
|
uint8 buff[10];
|
|
char filename[256];
|
|
SaveFile *fp;
|
|
SaveFileManager *mgr = g_system->get_savefile_manager();
|
|
|
|
sprintf(filename, "%s-settings.dat", g_sword2->_game_name);
|
|
|
|
buff[0] = g_sword2->_sound->GetMusicVolume();
|
|
buff[1] = g_sword2->_sound->GetSpeechVolume();
|
|
buff[2] = g_sword2->_sound->GetFxVolume();
|
|
buff[3] = g_sword2->_sound->IsMusicMute();
|
|
buff[4] = g_sword2->_sound->IsSpeechMute();
|
|
buff[5] = g_sword2->_sound->IsFxMute();
|
|
buff[6] = GetRenderType();
|
|
buff[7] = subtitles;
|
|
buff[8] = pointerTextSelected;
|
|
buff[9] = stereoReversed;
|
|
|
|
if (!(fp = mgr->open_savefile(filename, g_sword2->getSavePath(), true)))
|
|
return (1);
|
|
|
|
if (fp->write(buff, 10) != 10)
|
|
{
|
|
delete fp;
|
|
delete mgr;
|
|
return (2);
|
|
}
|
|
|
|
delete fp;
|
|
delete mgr;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Build_option_surfaces(void) //pete6Jun97
|
|
{
|
|
Create_surface_image(&panel_sprite, &panel_surface, 3405, 0, OPTION_Y, 0);
|
|
// object label button
|
|
Create_surface_image(&up_button_sprite[0], &up_button_surface[0], 3687, OBJ_LABEL_X,OBJ_LABEL_Y, 0);
|
|
Create_surface_image(&up_button_sprite[1], &up_button_surface[1], 3687, OBJ_LABEL_X,OBJ_LABEL_Y, 1);
|
|
//subtitle button
|
|
Create_surface_image(&down_button_sprite[0], &down_button_surface[0], 3687, SUBTITLE_X, SUBTITLE_Y, 0);
|
|
Create_surface_image(&down_button_sprite[1], &down_button_surface[1], 3687, SUBTITLE_X, SUBTITLE_Y, 1);
|
|
//ok button
|
|
Create_surface_image(&button_sprite[0], &button_surface[0], 901, OPT_OK_X, OPT_OK_Y, 0);
|
|
Create_surface_image(&button_sprite[1], &button_surface[1], 901, OPT_OK_X, OPT_OK_Y, 1);
|
|
//cancel button
|
|
Create_surface_image(&can_button_sprite[0], &can_button_surface[0], 901, OPT_CAN_X, OPT_CAN_Y, 0);
|
|
Create_surface_image(&can_button_sprite[1], &can_button_surface[1], 901, OPT_CAN_X, OPT_CAN_Y, 1);
|
|
//sliders
|
|
Create_surface_image(&slab_sprite[0], &slab_surface[0], 3406, SLIDER_TRK_X,MUSIC_TRK_Y,0); // music slider
|
|
Create_surface_image(&slab_sprite[1], &slab_surface[1], 3406, SLIDER_TRK_X,SPEECH_TRK_Y,0); // speech slider
|
|
Create_surface_image(&slab_sprite[2], &slab_surface[2], 3406, SLIDER_TRK_X,FX_TRK_Y,0); // fx slider
|
|
Create_surface_image(&slab_sprite[3], &slab_surface[3], 3406, SLIDER_TRK_X,GRFX_TRK_Y,0); // graphics slider
|
|
//mute buttons
|
|
Create_surface_image(&zup_button_sprite[0], &zup_button_surface[0], 3315, MUTE_X, MUSIC_TRK_Y-4, 0); // music mute
|
|
Create_surface_image(&zup_button_sprite[1], &zup_button_surface[1], 3315, MUTE_X, MUSIC_TRK_Y-4, 1);
|
|
Create_surface_image(&zdown_button_sprite[0], &zdown_button_surface[0],3315, MUTE_X, SPEECH_TRK_Y-3, 0);// speech mute
|
|
Create_surface_image(&zdown_button_sprite[1], &zdown_button_surface[1],3315, MUTE_X, SPEECH_TRK_Y-3, 1);
|
|
Create_surface_image(&slab_sprite[4], &slab_surface[4], 3315, MUTE_X,FX_TRK_Y-4,0); // fx mute
|
|
Create_surface_image(&slab_sprite[5], &slab_surface[5], 3315, MUTE_X,FX_TRK_Y-4,1);
|
|
//graphics level icon
|
|
Create_surface_image(&grfx_icon_sprite[0], &grfx_icon_surface[0], 256, GRFX_ICON_X, GRFX_ICON_Y, 0); // lowest grapihics level icon
|
|
Create_surface_image(&grfx_icon_sprite[1], &grfx_icon_surface[1], 256, GRFX_ICON_X, GRFX_ICON_Y, 1); // medium low grapihics level icon
|
|
Create_surface_image(&grfx_icon_sprite[2], &grfx_icon_surface[2], 256, GRFX_ICON_X, GRFX_ICON_Y, 2); // mewdium high grapihics level icon
|
|
Create_surface_image(&grfx_icon_sprite[3], &grfx_icon_surface[3], 256, GRFX_ICON_X, GRFX_ICON_Y, 3); // highest grapihics level icon
|
|
//reverse stereo button
|
|
Create_surface_image(&slab_sprite[6], &slab_surface[6], 3687, STEREO_X,STEREO_Y,0);
|
|
Create_surface_image(&slab_sprite[7], &slab_surface[7], 3687, STEREO_X,STEREO_Y,1);
|
|
|
|
Build_chr_surfaces();
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Kill_option_surfaces(void) //pete6Jun97
|
|
{
|
|
DeleteSurface(panel_surface);
|
|
//object label button
|
|
DeleteSurface(up_button_surface[0]);
|
|
DeleteSurface(up_button_surface[1]);
|
|
//subtitle button
|
|
DeleteSurface(down_button_surface[0]);
|
|
DeleteSurface(down_button_surface[1]);
|
|
//ok button
|
|
DeleteSurface(button_surface[0]);
|
|
DeleteSurface(button_surface[1]);
|
|
//cancel button
|
|
DeleteSurface(can_button_surface[0]);
|
|
DeleteSurface(can_button_surface[1]);
|
|
//sliders
|
|
DeleteSurface(slab_surface[0]);
|
|
DeleteSurface(slab_surface[1]);
|
|
DeleteSurface(slab_surface[2]);
|
|
DeleteSurface(slab_surface[3]);
|
|
//mute buttons
|
|
DeleteSurface(zup_button_surface[0]);
|
|
DeleteSurface(zup_button_surface[1]);
|
|
DeleteSurface(zdown_button_surface[0]);
|
|
DeleteSurface(zdown_button_surface[1]);
|
|
DeleteSurface(slab_surface[4]);
|
|
DeleteSurface(slab_surface[5]);
|
|
//graphics level icon
|
|
DeleteSurface(grfx_icon_surface[0]);
|
|
DeleteSurface(grfx_icon_surface[1]);
|
|
DeleteSurface(grfx_icon_surface[2]);
|
|
DeleteSurface(grfx_icon_surface[3]);
|
|
//reverse stereo icon
|
|
DeleteSurface(slab_surface[6]);
|
|
DeleteSurface(slab_surface[7]);
|
|
|
|
Kill_chr_surfaces();
|
|
}
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
int Mouse_touching_button(int32 x, int32 y, int32 w, int32 h) //pete9Jun97
|
|
{
|
|
if ((mousex>x)&&(mousex<x+w)&&((mousey+40)>y)&&((mousey+40)<y+h))
|
|
return (1);
|
|
else
|
|
return (0);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------------------
|
|
void Option_control(void) //Pete6Jun97
|
|
{
|
|
#define WORD_BUTTON_GAP 10
|
|
|
|
// some things left by the last tennant
|
|
char c;
|
|
_mouseEvent *me;
|
|
int first = 0;
|
|
|
|
// text strings and lengths
|
|
uint8 title_text[MAX_STRING_LEN];
|
|
uint8 subtitle_text[MAX_STRING_LEN];
|
|
uint8 object_text[MAX_STRING_LEN];
|
|
uint8 ok_text[MAX_STRING_LEN];
|
|
uint8 cancel_text[MAX_STRING_LEN];
|
|
uint8 music_text[MAX_STRING_LEN];
|
|
uint8 speech_text[MAX_STRING_LEN];
|
|
uint8 fx_text[MAX_STRING_LEN];
|
|
uint8 graphics_text[MAX_STRING_LEN];
|
|
uint8 stereo_text[MAX_STRING_LEN];
|
|
uint8 *text;
|
|
int title_len, subtitle_len, ok_len, cancel_len, left_align, test_len;
|
|
|
|
// slider values
|
|
uint8 musicVolume = g_sword2->_sound->GetMusicVolume();
|
|
uint8 speechVolume = g_sword2->_sound->GetSpeechVolume();
|
|
uint8 fxVolume = g_sword2->_sound->GetFxVolume();
|
|
uint8 grfxLevel = GetRenderType();
|
|
|
|
// safe slider values for restoring on cancel
|
|
//uint8 safe_musicVolume = musicVolume;
|
|
//uint8 safe_speechVolume = speechVolume;
|
|
//uint8 safe_fxVolume = fxVolume;
|
|
|
|
// button state variables
|
|
uint8 dreverse_stereo_state = 0, dmusic_mute_state = 0, dspeech_mute_state = 0, dfx_mute_state = 0, dobject_state = 0, dsubtitle_state = 0;
|
|
uint8 touching_reverse_stereo = 0, touching_music_mute = 0, touching_fx_mute = 0, touching_speech_mute = 0, touching_object = 0, touching_subtitle = 0;
|
|
uint8 lb_down = 0;
|
|
|
|
// Slider targets
|
|
uint8 music_target = musicVolume;
|
|
uint8 fx_target = fxVolume;
|
|
uint8 speech_target = speechVolume;
|
|
uint8 grfx_target = grfxLevel;
|
|
|
|
// Slider movement types (click in track or drag button)
|
|
uint8 music_tracking = 0, fx_tracking = 0, speech_tracking = 0, grfx_tracking = 0;
|
|
|
|
//do some driver stuff
|
|
// ResetRenderEngine();
|
|
|
|
// FETCH THE TEXT
|
|
//fetch the 'options' text
|
|
text = FetchTextLine( res_man.Res_open(149618698/SIZE), 149618698&0xffff ); //options (title)
|
|
strcpy((char*)title_text, (char*)text+2);
|
|
title_len = Pixel_text_length(title_text, controls_font_id);
|
|
|
|
//fetch the 'subtitles' text
|
|
text = FetchTextLine( res_man.Res_open(149618699/SIZE), 149618699&0xffff ); //subtitles
|
|
strcpy((char*)subtitle_text, (char*)text+2);
|
|
subtitle_len = Pixel_text_length(subtitle_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
|
|
//fetch the 'object labels' text
|
|
text = FetchTextLine( res_man.Res_open(149618700/SIZE), 149618700&0xffff ); //object
|
|
strcpy((char*)object_text, (char*)text+2);
|
|
left_align = Pixel_text_length(object_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
|
|
//fetch the 'ok' text
|
|
text = FetchTextLine( res_man.Res_open(149618688/SIZE), 149618688&0xffff ); //ok
|
|
strcpy((char*)ok_text, (char*)text+2);
|
|
ok_len = Pixel_text_length(ok_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
|
|
//fetch the 'cancel' text
|
|
text = FetchTextLine( res_man.Res_open(149618689/SIZE), 149618689&0xffff ); //cancel
|
|
strcpy((char*)cancel_text, (char*)text+2);
|
|
cancel_len = Pixel_text_length(cancel_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
|
|
//fetch the 'music volume' text
|
|
text = FetchTextLine( res_man.Res_open(149618702/SIZE), 149618702&0xffff ); //music volume
|
|
strcpy((char*)music_text, (char*)text+2);
|
|
test_len = Pixel_text_length(music_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
if (test_len>left_align)
|
|
left_align = test_len;
|
|
|
|
//fetch the 'speech volume' text
|
|
text = FetchTextLine( res_man.Res_open(149618703/SIZE), 149618703&0xffff ); //speech volume
|
|
strcpy((char*)speech_text, (char*)text+2);
|
|
test_len = Pixel_text_length(speech_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
if (test_len>left_align)
|
|
left_align = test_len;
|
|
|
|
//fetch the 'fx volume' text
|
|
text = FetchTextLine( res_man.Res_open(149618704/SIZE), 149618704&0xffff ); //fx volume
|
|
strcpy((char*)fx_text, (char*)text+2);
|
|
test_len = Pixel_text_length(fx_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
if (test_len>left_align)
|
|
left_align = test_len;
|
|
|
|
//fetch the 'grapihics quality' text
|
|
text = FetchTextLine( res_man.Res_open(149618705/SIZE), 149618705&0xffff ); //graphics quality
|
|
strcpy((char*)graphics_text, (char*)text+2);
|
|
test_len = Pixel_text_length(graphics_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
if (test_len>left_align)
|
|
left_align = test_len;
|
|
|
|
//fetch the 'grapihics quality' text
|
|
text = FetchTextLine( res_man.Res_open(149618709/SIZE), 149618709&0xffff ); //graphics quality
|
|
strcpy((char*)stereo_text, (char*)text+2);
|
|
test_len = Pixel_text_length(stereo_text, controls_font_id) + WORD_BUTTON_GAP;
|
|
if (test_len>left_align)
|
|
left_align = test_len;
|
|
|
|
|
|
//blimey, life's never easy is it?
|
|
//not once you've got out of bed !
|
|
|
|
|
|
//set the button states
|
|
restore_button_state = 0;
|
|
can_button_state = 0;
|
|
touching_object = 0;
|
|
touching_subtitle = 0;
|
|
uint8 object_state = pointerTextSelected;
|
|
uint8 subtitle_state = subtitles;
|
|
uint8 stereo_state = stereoReversed;
|
|
|
|
uint8 music_mute_state = g_sword2->_sound->IsMusicMute();
|
|
uint8 speech_mute_state = g_sword2->_sound->IsSpeechMute();
|
|
uint8 fx_mute_state = g_sword2->_sound->IsFxMute();
|
|
|
|
|
|
//build the button surfaces surfaces
|
|
Build_option_surfaces();
|
|
|
|
//position the sliders
|
|
slab_sprite[0].x = SLIDER_TRK_X + (SLIDER_TRK_W * musicVolume) / 16;
|
|
slab_sprite[1].x = SLIDER_TRK_X + (SLIDER_TRK_W * speechVolume) / 14;
|
|
slab_sprite[2].x = SLIDER_TRK_X + (SLIDER_TRK_W * fxVolume) / 14;
|
|
slab_sprite[3].x = SLIDER_TRK_X + (SLIDER_TRK_W * grfxLevel) / 3;
|
|
|
|
//control loop
|
|
while (1)
|
|
{
|
|
// Update any moving sliders
|
|
// music
|
|
if (slab_sprite[0].x<SLIDER_TRK_X + (SLIDER_TRK_W * music_target) / 16)
|
|
{
|
|
if ((SLIDER_TRK_X + (SLIDER_TRK_W * music_target) / 16)-slab_sprite[0].x<2)
|
|
slab_sprite[0].x++;
|
|
else
|
|
slab_sprite[0].x +=2;
|
|
musicVolume = (int)((float)((slab_sprite[0].x-SLIDER_TRK_X)*16)/(float)SLIDER_TRK_W+0.5);
|
|
}
|
|
else if (slab_sprite[0].x>SLIDER_TRK_X + (SLIDER_TRK_W * music_target) / 16)
|
|
{
|
|
if (slab_sprite[0].x-(SLIDER_TRK_X + (SLIDER_TRK_W * music_target) / 16)<2)
|
|
slab_sprite[0].x--;
|
|
else
|
|
slab_sprite[0].x -=2;
|
|
musicVolume = (int)((float)((slab_sprite[0].x-SLIDER_TRK_X)*16)/(float)SLIDER_TRK_W+0.5);
|
|
|
|
if (!musicVolume)
|
|
music_mute_state = 1;
|
|
else
|
|
music_mute_state = 0;
|
|
}
|
|
|
|
// speech
|
|
if (slab_sprite[1].x<SLIDER_TRK_X + (SLIDER_TRK_W * speech_target) / 14)
|
|
{
|
|
if ((SLIDER_TRK_X + (SLIDER_TRK_W * speech_target) / 14)-slab_sprite[1].x<2)
|
|
slab_sprite[1].x++;
|
|
else
|
|
slab_sprite[1].x +=2;
|
|
speechVolume = (int)((float)((slab_sprite[1].x-SLIDER_TRK_X)*14)/(float)SLIDER_TRK_W+0.5);
|
|
}
|
|
else if (slab_sprite[1].x>SLIDER_TRK_X + (SLIDER_TRK_W * speech_target) / 14)
|
|
{
|
|
if (slab_sprite[1].x-(SLIDER_TRK_X + (SLIDER_TRK_W * speech_target) / 14)<2)
|
|
slab_sprite[1].x--;
|
|
else
|
|
slab_sprite[1].x -=2;
|
|
speechVolume = (int)((float)((slab_sprite[1].x-SLIDER_TRK_X)*14)/(float)SLIDER_TRK_W+0.5);
|
|
|
|
if (!speechVolume)
|
|
speech_mute_state = 1;
|
|
else
|
|
speech_mute_state = 0;
|
|
}
|
|
|
|
// fx
|
|
if (slab_sprite[2].x<SLIDER_TRK_X + (SLIDER_TRK_W * fx_target) / 14)
|
|
{
|
|
if ((SLIDER_TRK_X + (SLIDER_TRK_W * fx_target) / 14)-slab_sprite[2].x<2)
|
|
slab_sprite[2].x++;
|
|
else
|
|
slab_sprite[2].x +=2;
|
|
fxVolume = (int)((float)((slab_sprite[2].x-SLIDER_TRK_X)*14)/(float)SLIDER_TRK_W+0.5);
|
|
}
|
|
else if (slab_sprite[2].x>SLIDER_TRK_X + (SLIDER_TRK_W * fx_target) / 14)
|
|
{
|
|
if (slab_sprite[2].x-(SLIDER_TRK_X + (SLIDER_TRK_W * fx_target) / 14)<2)
|
|
slab_sprite[2].x--;
|
|
else
|
|
slab_sprite[2].x -=2;
|
|
fxVolume = (int)((float)((slab_sprite[2].x-SLIDER_TRK_X)*14)/(float)SLIDER_TRK_W+0.5);
|
|
|
|
if (!fxVolume)
|
|
fx_mute_state = 1;
|
|
else
|
|
fx_mute_state = 0;
|
|
}
|
|
|
|
// grfx
|
|
if (slab_sprite[3].x<SLIDER_TRK_X + (SLIDER_TRK_W * grfx_target) / 3)
|
|
{
|
|
if ((SLIDER_TRK_X + (SLIDER_TRK_W * grfx_target) / 3)-slab_sprite[3].x<2)
|
|
slab_sprite[3].x++;
|
|
else
|
|
slab_sprite[3].x +=2;
|
|
grfxLevel = (int)((float)((slab_sprite[3].x-SLIDER_TRK_X)*3)/(float)SLIDER_TRK_W+0.5);
|
|
}
|
|
else if (slab_sprite[3].x>SLIDER_TRK_X + (SLIDER_TRK_W * grfx_target) / 3)
|
|
{
|
|
if (slab_sprite[3].x-(SLIDER_TRK_X + (SLIDER_TRK_W * grfx_target) / 3)<2)
|
|
slab_sprite[3].x--;
|
|
else
|
|
slab_sprite[3].x -=2;
|
|
grfxLevel = (int)((float)((slab_sprite[3].x-SLIDER_TRK_X)*3)/(float)SLIDER_TRK_W+0.5);
|
|
}
|
|
|
|
|
|
if (music_tracking) // music tracking
|
|
{
|
|
slab_sprite[0].x = mousex - SLIDER_W/2;
|
|
if (slab_sprite[0].x < SLIDER_TRK_X)
|
|
slab_sprite[0].x = SLIDER_TRK_X;
|
|
else if (slab_sprite[0].x > SLIDER_TRK_X+SLIDER_TRK_W)
|
|
slab_sprite[0].x = SLIDER_TRK_X+SLIDER_TRK_W;
|
|
music_target = musicVolume = (int)((float)((slab_sprite[0].x-SLIDER_TRK_X)*16)/(float)SLIDER_TRK_W+0.5);
|
|
|
|
if (!musicVolume)
|
|
music_mute_state = 1;
|
|
else
|
|
music_mute_state = 0;
|
|
|
|
}
|
|
else if (speech_tracking) // speech tracking
|
|
{
|
|
slab_sprite[1].x = mousex - SLIDER_W/2;
|
|
if (slab_sprite[1].x < SLIDER_TRK_X)
|
|
slab_sprite[1].x = SLIDER_TRK_X;
|
|
else if (slab_sprite[1].x > SLIDER_TRK_X+SLIDER_TRK_W)
|
|
slab_sprite[1].x = SLIDER_TRK_X+SLIDER_TRK_W;
|
|
speech_target = speechVolume = (int)((float)((slab_sprite[1].x-SLIDER_TRK_X)*14)/(float)SLIDER_TRK_W+0.5);
|
|
|
|
if (!speechVolume)
|
|
speech_mute_state = 1;
|
|
else
|
|
speech_mute_state = 0;
|
|
|
|
}
|
|
else if (fx_tracking) // fx tracking
|
|
{
|
|
slab_sprite[2].x = mousex - SLIDER_W/2;
|
|
if (slab_sprite[2].x < SLIDER_TRK_X)
|
|
slab_sprite[2].x = SLIDER_TRK_X;
|
|
else if (slab_sprite[2].x > SLIDER_TRK_X+SLIDER_TRK_W)
|
|
slab_sprite[2].x = SLIDER_TRK_X+SLIDER_TRK_W;
|
|
fx_target = fxVolume = (int)((float)((slab_sprite[2].x-SLIDER_TRK_X)*14)/(float)SLIDER_TRK_W+0.5);
|
|
|
|
if (!fxVolume)
|
|
fx_mute_state = 1;
|
|
else
|
|
fx_mute_state = 0;
|
|
|
|
}
|
|
else if (grfx_tracking) // grfx tracking
|
|
{
|
|
slab_sprite[3].x = mousex - SLIDER_W/2;
|
|
if (slab_sprite[3].x < SLIDER_TRK_X)
|
|
slab_sprite[3].x = SLIDER_TRK_X;
|
|
else if (slab_sprite[3].x > SLIDER_TRK_X+SLIDER_TRK_W)
|
|
slab_sprite[3].x = SLIDER_TRK_X+SLIDER_TRK_W;
|
|
grfx_target = grfxLevel = (int)((float)((slab_sprite[3].x-SLIDER_TRK_X)*3)/(float)SLIDER_TRK_W+0.5);
|
|
}
|
|
|
|
if (!music_mute_state)
|
|
g_sword2->_sound->SetMusicVolume(musicVolume);
|
|
else
|
|
g_sword2->_sound->SetMusicVolume(0);
|
|
|
|
if (!fx_mute_state)
|
|
g_sword2->_sound->SetFxVolume(fxVolume);
|
|
else
|
|
g_sword2->_sound->SetFxVolume(0);
|
|
|
|
if (!speech_mute_state)
|
|
g_sword2->_sound->SetSpeechVolume(speechVolume);
|
|
else
|
|
g_sword2->_sound->SetSpeechVolume(0);
|
|
|
|
//--------------------------------------------------
|
|
// Service windows
|
|
|
|
if (ServiceWindows() == RDERR_APPCLOSED) // if we pressed Ctrl-Q during the smacker
|
|
{
|
|
Close_game(); //close engine systems down
|
|
CloseAppWindow();
|
|
exit(0); //quit the game
|
|
}
|
|
|
|
while (!gotTheFocus)
|
|
if (ServiceWindows() == RDERR_APPCLOSED)
|
|
break;
|
|
//--------------------------------------------------
|
|
|
|
EraseBackBuffer();
|
|
|
|
|
|
//print panel
|
|
while (DrawSurface(&panel_sprite, panel_surface)==RDERR_SURFACELOST)
|
|
{
|
|
Kill_option_surfaces();
|
|
Build_option_surfaces();
|
|
};
|
|
|
|
//print words on panel option panel
|
|
Engine_string(OPTION_W/2-(title_len/2)+OPTION_X,OPTION_Y+15, controls_font_id, chr_surface, title_text); //options
|
|
Engine_string(SUBTITLE_X-subtitle_len, SUBTITLE_Y+3, controls_font_id, chr_surface, subtitle_text); //subtitles
|
|
Engine_string(SLIDER_TRK_X-left_align, OBJ_LABEL_Y+3, controls_font_id, chr_surface, object_text); //object labels
|
|
Engine_string(OPT_OK_X-ok_len, OPT_OK_Y, controls_font_id, chr_surface, ok_text); //ok
|
|
Engine_string(OPT_CAN_X-cancel_len, OPT_CAN_Y, controls_font_id, chr_surface, cancel_text); //cancel
|
|
Engine_string(SLIDER_TRK_X-left_align, MUSIC_TRK_Y, controls_font_id, chr_surface, music_text); //music volume
|
|
Engine_string(SLIDER_TRK_X-left_align, SPEECH_TRK_Y, controls_font_id, chr_surface, speech_text); //speech volume
|
|
Engine_string(SLIDER_TRK_X-left_align, FX_TRK_Y, controls_font_id, chr_surface, fx_text); //fx volume
|
|
Engine_string(SLIDER_TRK_X-left_align, GRFX_TRK_Y, controls_font_id, chr_surface, graphics_text); //graphics quality
|
|
Engine_string(SLIDER_TRK_X-left_align, STEREO_Y+3, controls_font_id, chr_surface, stereo_text); //reverse stereo
|
|
|
|
//print buttons
|
|
DrawSurface(&down_button_sprite[subtitle_state], down_button_surface[subtitle_state] ); //print subtitles button
|
|
|
|
DrawSurface(&up_button_sprite[object_state], up_button_surface[object_state] ); //print object labels button
|
|
|
|
DrawSurface(&button_sprite[restore_button_state], button_surface[restore_button_state] ); //print ok button
|
|
|
|
DrawSurface(&can_button_sprite[can_button_state], can_button_surface[can_button_state] ); //print cancel button
|
|
|
|
DrawSurface(&slab_sprite[0], slab_surface[0]); //print sliders
|
|
DrawSurface(&slab_sprite[1], slab_surface[1]);
|
|
DrawSurface(&slab_sprite[2], slab_surface[2]);
|
|
DrawSurface(&slab_sprite[3], slab_surface[3]);
|
|
|
|
DrawSurface(&zup_button_sprite[music_mute_state], zup_button_surface[music_mute_state] ); //print mute buttons
|
|
DrawSurface(&zdown_button_sprite[speech_mute_state], zdown_button_surface[speech_mute_state] );
|
|
DrawSurface(&slab_sprite[fx_mute_state+4], slab_surface[fx_mute_state+4] );
|
|
|
|
DrawSurface(&grfx_icon_sprite[grfxLevel], grfx_icon_surface[grfxLevel] ); //print the graphics level icon
|
|
|
|
DrawSurface(&slab_sprite[6+stereo_state], slab_surface[6+stereo_state]); // print reverse stereo button
|
|
|
|
//keep menu up too
|
|
ProcessMenu();
|
|
|
|
//user can ESC quit
|
|
if (KeyWaiting())
|
|
{
|
|
ReadKey(&c); //kill the key we just pressed
|
|
if (c==27) //ESC
|
|
{
|
|
ReadOptionSettings(); // Reset options to previous settings.
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check what if anything the mouse is touching
|
|
//mouse over ok button?
|
|
if (Mouse_touching_button(OPT_OK_X,OPT_OK_Y,OPT_BUT_W,OPT_BUT_H))
|
|
touching_restore_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ restore_button_state=0;
|
|
touching_restore_button=0;
|
|
}
|
|
|
|
//mouse over cancel button?
|
|
if (Mouse_touching_button(OPT_CAN_X,OPT_CAN_Y,OPT_BUT_W,OPT_BUT_H))
|
|
touching_can_button=1; //mouse over button
|
|
else //not over so release even if pressed previously
|
|
{ can_button_state=0;
|
|
touching_can_button=0;
|
|
}
|
|
|
|
//mouse over object label button?
|
|
if (Mouse_touching_button(OBJ_LABEL_X,OBJ_LABEL_Y,OPT_BUT_W,OPT_BUT_H))
|
|
{
|
|
if (!lb_down)
|
|
touching_object=1; //mouse over button
|
|
}
|
|
else //not over so release even if pressed previously
|
|
{
|
|
if (touching_object && lb_down && !dobject_state)
|
|
object_state=!object_state;
|
|
touching_object=0;
|
|
}
|
|
|
|
//mouse over subtitles button?
|
|
if (Mouse_touching_button(SUBTITLE_X,SUBTITLE_Y,OPT_BUT_W,OPT_BUT_H))
|
|
{
|
|
if (!lb_down)
|
|
touching_subtitle=1; //mouse over button
|
|
}
|
|
else //not over so release even if pressed previously
|
|
{
|
|
if (touching_subtitle && lb_down && !dsubtitle_state)
|
|
subtitle_state=!subtitle_state;
|
|
touching_subtitle=0;
|
|
}
|
|
|
|
//mouse over reverse stereo button?
|
|
if (Mouse_touching_button(STEREO_X,STEREO_Y,OPT_BUT_W,OPT_BUT_H))
|
|
{
|
|
if (!lb_down)
|
|
touching_reverse_stereo=1; //mouse over button
|
|
}
|
|
else //not over so release even if pressed previously
|
|
{
|
|
if (touching_reverse_stereo && lb_down && !dreverse_stereo_state)
|
|
stereo_state=!stereo_state;
|
|
touching_reverse_stereo=0;
|
|
}
|
|
|
|
//mouse over music mute button?
|
|
if (Mouse_touching_button(MUTE_X,MUSIC_TRK_Y-4,MUTE_W,MUTE_H))
|
|
{
|
|
if (!lb_down)
|
|
touching_music_mute=1; //mouse over button
|
|
}
|
|
else //not over so release even if pressed previously
|
|
{
|
|
if (touching_music_mute && lb_down && !dmusic_mute_state)
|
|
music_mute_state=!music_mute_state;
|
|
touching_music_mute=0;
|
|
}
|
|
|
|
//mouse over fx mute button?
|
|
if (Mouse_touching_button(MUTE_X,FX_TRK_Y-4,MUTE_W,MUTE_H))
|
|
{
|
|
if (!lb_down)
|
|
touching_fx_mute=1; //mouse over button
|
|
}
|
|
else //not over so release even if pressed previously
|
|
{
|
|
if (touching_fx_mute && lb_down && !dfx_mute_state)
|
|
fx_mute_state=!fx_mute_state;
|
|
touching_fx_mute=0;
|
|
}
|
|
|
|
//mouse over speech mute button?
|
|
if (Mouse_touching_button(MUTE_X,SPEECH_TRK_Y-4,MUTE_W,MUTE_H))
|
|
{
|
|
if (!lb_down)
|
|
touching_speech_mute=1; //mouse over button
|
|
}
|
|
else //not over so release even if pressed previously
|
|
{
|
|
if (touching_speech_mute && lb_down && !dspeech_mute_state)
|
|
speech_mute_state=!speech_mute_state;
|
|
touching_speech_mute=0;
|
|
}
|
|
|
|
|
|
//pressing on a button
|
|
me = MouseEvent(); //get mouse event
|
|
|
|
if (me!=NULL)
|
|
{
|
|
if (me->buttons&RD_LEFTBUTTONUP)
|
|
{
|
|
lb_down = 0;
|
|
if (touching_restore_button && restore_button_state) // ok to settings
|
|
{
|
|
UpdateGraphicsLevel(grfxLevel); // (James13jun97)
|
|
|
|
g_sword2->_sound->MuteMusic(music_mute_state); // Ensure all the levels are recorded correctly (Pete21Aug97)
|
|
g_sword2->_sound->MuteSpeech(speech_mute_state);
|
|
g_sword2->_sound->MuteFx(fx_mute_state);
|
|
g_sword2->_sound->SetMusicVolume(music_target);
|
|
g_sword2->_sound->SetSpeechVolume(speech_target);
|
|
g_sword2->_sound->SetFxVolume(fx_target);
|
|
|
|
subtitles = subtitle_state; // Save object label and subtitle settings
|
|
pointerTextSelected = object_state;
|
|
speechSelected = !speech_mute_state;
|
|
|
|
if (stereo_state != stereoReversed)
|
|
g_sword2->_sound->ReverseStereo();
|
|
|
|
stereoReversed = stereo_state;
|
|
WriteOptionSettings();
|
|
break;
|
|
}
|
|
|
|
if (touching_can_button && can_button_state) // cancel, so restore old settings
|
|
{
|
|
ReadOptionSettings();
|
|
break;
|
|
}
|
|
|
|
if (touching_object && dobject_state)
|
|
dobject_state = object_state=0; // if the button was in now let it out
|
|
|
|
if (touching_subtitle && dsubtitle_state)
|
|
subtitle_state = dsubtitle_state = 0; // if the button was in now let it out
|
|
|
|
if (touching_reverse_stereo && dreverse_stereo_state)
|
|
dreverse_stereo_state = stereo_state = 0; // if the button was in now let it out
|
|
|
|
if (touching_music_mute && dmusic_mute_state) {
|
|
music_mute_state = dmusic_mute_state = 0; // if the button was in now let it out
|
|
g_sword2->_sound->MuteMusic(0);
|
|
}
|
|
|
|
if (touching_fx_mute && dfx_mute_state) {
|
|
fx_mute_state = dfx_mute_state = 0; // if the button was in now let it out
|
|
g_sword2->_sound->MuteFx(0);
|
|
}
|
|
|
|
if (touching_speech_mute && dspeech_mute_state) {
|
|
speech_mute_state = dspeech_mute_state = 0; // if the button was in now let it out
|
|
g_sword2->_sound->MuteSpeech(0);
|
|
}
|
|
|
|
// Stop tracking any sliders
|
|
music_tracking = fx_tracking = speech_tracking = grfx_tracking = 0;
|
|
}
|
|
|
|
else if (me->buttons&RD_LEFTBUTTONDOWN) //there's a mouse event to be processed
|
|
{
|
|
lb_down = 1;
|
|
if (touching_restore_button)
|
|
restore_button_state=1;
|
|
|
|
if (touching_can_button)
|
|
can_button_state=1;
|
|
|
|
if (touching_object)
|
|
{
|
|
if (object_state) // push in the button if it's out
|
|
dobject_state = 1;
|
|
else
|
|
object_state=!object_state;
|
|
}
|
|
|
|
if (touching_subtitle)
|
|
{
|
|
if (subtitle_state)
|
|
dsubtitle_state = 1;
|
|
else
|
|
subtitle_state=!subtitle_state;
|
|
}
|
|
|
|
if (touching_reverse_stereo)
|
|
{
|
|
if (stereo_state) // push in the button if it's out
|
|
dreverse_stereo_state = 1;
|
|
else
|
|
stereo_state = !stereo_state;
|
|
}
|
|
|
|
|
|
if (touching_music_mute)
|
|
{
|
|
if (music_mute_state)
|
|
dmusic_mute_state = 1;
|
|
else
|
|
{
|
|
music_mute_state = 1;
|
|
g_sword2->_sound->MuteMusic(1);
|
|
}
|
|
}
|
|
|
|
if (touching_fx_mute)
|
|
{
|
|
if (fx_mute_state)
|
|
dfx_mute_state = 1;
|
|
else
|
|
{
|
|
fx_mute_state=1;
|
|
g_sword2->_sound->MuteFx(1);
|
|
}
|
|
}
|
|
|
|
if (touching_speech_mute)
|
|
{
|
|
if (speech_mute_state)
|
|
dspeech_mute_state = 1;
|
|
else
|
|
{
|
|
speech_mute_state=1;
|
|
g_sword2->_sound->MuteSpeech(1);
|
|
}
|
|
}
|
|
|
|
if (Mouse_touching_button(SLIDER_TRK_X,MUSIC_TRK_Y,SLIDER_TRK_W+SLIDER_W,SLIDER_TRK_H))
|
|
{
|
|
if (music_mute_state)
|
|
{
|
|
music_mute_state = 0;
|
|
g_sword2->_sound->MuteMusic(0);
|
|
}
|
|
|
|
if (mousex>(slab_sprite[0].x+SLIDER_W))
|
|
{
|
|
if (music_target<musicVolume)
|
|
music_target = musicVolume;
|
|
music_target++;
|
|
if (music_target>15)
|
|
music_target = 15;
|
|
}
|
|
else if (mousex<slab_sprite[0].x)
|
|
{
|
|
if (music_target>musicVolume)
|
|
music_target = musicVolume;
|
|
music_target--;
|
|
if (music_target>15)
|
|
music_target = 0;
|
|
} else
|
|
music_tracking = 1;
|
|
}
|
|
|
|
if (Mouse_touching_button(SLIDER_TRK_X,SPEECH_TRK_Y,SLIDER_TRK_W+SLIDER_W,SLIDER_TRK_H))
|
|
{
|
|
if (speech_mute_state)
|
|
{
|
|
speech_mute_state = 0;
|
|
g_sword2->_sound->MuteSpeech(0);
|
|
}
|
|
|
|
if (mousex>(slab_sprite[1].x+SLIDER_W))
|
|
{
|
|
if (speech_target<speechVolume)
|
|
speech_target = speechVolume;
|
|
speech_target++;
|
|
if (speech_target>14)
|
|
speech_target = 14;
|
|
}
|
|
else if (mousex<slab_sprite[1].x)
|
|
{
|
|
if (speech_target>speechVolume)
|
|
speech_target = speechVolume;
|
|
speech_target--;
|
|
if (speech_target>14)
|
|
speech_target = 0;
|
|
} else
|
|
speech_tracking = 1;
|
|
}
|
|
|
|
if (Mouse_touching_button(SLIDER_TRK_X,FX_TRK_Y,SLIDER_TRK_W+SLIDER_W,SLIDER_TRK_H))
|
|
{
|
|
if (fx_mute_state)
|
|
{
|
|
fx_mute_state = 0;
|
|
g_sword2->_sound->MuteFx(0);
|
|
}
|
|
|
|
if (mousex>(slab_sprite[2].x+SLIDER_W))
|
|
{
|
|
if (fx_target<fxVolume)
|
|
fx_target = fxVolume;
|
|
fx_target++;
|
|
if (fx_target>14)
|
|
fx_target = 14;
|
|
}
|
|
else if (mousex<slab_sprite[2].x)
|
|
{
|
|
if (fx_target>fxVolume)
|
|
fx_target = fxVolume;
|
|
fx_target--;
|
|
if (fx_target>14)
|
|
fx_target = 0;
|
|
}
|
|
else
|
|
fx_tracking = 1;
|
|
|
|
fx_mute_state = 0;
|
|
}
|
|
|
|
if (Mouse_touching_button(SLIDER_TRK_X,GRFX_TRK_Y,SLIDER_TRK_W+SLIDER_W,SLIDER_TRK_H))
|
|
{
|
|
if (mousex>(slab_sprite[3].x+SLIDER_W))
|
|
{
|
|
if (grfx_target<grfxLevel)
|
|
grfx_target = grfxLevel;
|
|
grfx_target++;
|
|
if (grfx_target>3)
|
|
grfx_target = 3;
|
|
}
|
|
else if (mousex<slab_sprite[3].x)
|
|
{
|
|
if (grfx_target>grfxLevel)
|
|
grfx_target = grfxLevel;
|
|
grfx_target--;
|
|
if (grfx_target>3)
|
|
grfx_target = 0;
|
|
}
|
|
else
|
|
grfx_tracking = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!first)
|
|
{
|
|
first++;
|
|
SetFullPalette(CONTROL_PANEL_PALETTE); // see Build_display.cpp (James17jun97)
|
|
}
|
|
}
|
|
|
|
|
|
Kill_option_surfaces();
|
|
|
|
return; //just return to game
|
|
}
|
|
|
|
void UpdateGraphicsLevel(uint8 newLevel) { // (James13jun97)
|
|
switch (newLevel) {
|
|
case 0: // Lowest setting: no graphics fx
|
|
ClearTransFx();
|
|
ClearShadowFx();
|
|
ClearBltFx();
|
|
break;
|
|
case 1: // Medium-low setting: transparency-blending
|
|
SetTransFx();
|
|
ClearShadowFx();
|
|
ClearBltFx();
|
|
break;
|
|
case 2: // Medium-high setting: transparency-blending + shading
|
|
SetTransFx();
|
|
SetShadowFx();
|
|
ClearBltFx();
|
|
break;
|
|
case 3: // Highest setting: transparency-blending + shading + edge-blending + improved stretching
|
|
SetTransFx();
|
|
SetShadowFx();
|
|
SetBltFx();
|
|
break;
|
|
}
|
|
|
|
// update our global variable - which needs to be checked when dimming
|
|
// the palette in PauseGame() in sword2.cpp (since palette-matching
|
|
// cannot be done with dimmed palette so we turn down one notch while
|
|
// dimmed, if at top level)
|
|
|
|
current_graphics_level = newLevel;
|
|
}
|