aboutsummaryrefslogtreecommitdiff
path: root/sword2/controls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sword2/controls.cpp')
-rw-r--r--sword2/controls.cpp2917
1 files changed, 2917 insertions, 0 deletions
diff --git a/sword2/controls.cpp b/sword2/controls.cpp
new file mode 100644
index 0000000000..d30a2ebf99
--- /dev/null
+++ b/sword2/controls.cpp
@@ -0,0 +1,2917 @@
+/* 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 "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, uint32 *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, uint32 *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)
+
+//--------------------------------------------
+
+uint32 panel_surface;
+_spriteInfo panel_sprite;
+
+_spriteInfo slab_sprite[8];
+uint32 slab_surface[8];
+
+_spriteInfo chr_sprite;
+
+#define SIZE_OF_CHAR_SET (256-32) // our fonts start on SPACE character (32)
+uint32 chr_surface[SIZE_OF_CHAR_SET];
+uint32 red_chr_surface[SIZE_OF_CHAR_SET];
+
+_spriteInfo can_button_sprite[2];
+uint32 can_button_surface[2];
+uint32 can_button_state=0;
+uint32 touching_can_button=0;
+
+_spriteInfo button_sprite[2];
+uint32 button_surface[2];
+uint32 restore_button_state=0;
+uint32 touching_restore_button=0;
+
+_spriteInfo up_button_sprite[2];
+uint32 up_button_surface[2];
+uint32 up_button_state=0;
+uint32 touching_up_button=0;
+
+_spriteInfo down_button_sprite[2];
+uint32 down_button_surface[2];
+uint32 down_button_state=0;
+uint32 touching_down_button=0;
+
+_spriteInfo zup_button_sprite[2];
+uint32 zup_button_surface[2];
+uint32 zup_button_state=0;
+uint32 touching_zup_button=0;
+
+_spriteInfo zdown_button_sprite[2];
+uint32 zdown_button_surface[2];
+uint32 zdown_button_state=0;
+uint32 touching_zdown_button=0;
+
+_spriteInfo grfx_icon_sprite[4];
+uint32 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
+
+
+ uint8 *colTablePtr=NULL;
+
+ int breakOut=0;
+ uint32 j;
+ uint8 black[4]={0,0,0,0};
+ 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
+ RestoreDisplay();
+ 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)
+ }
+
+ FlipScreens();
+
+
+
+
+
+
+
+
+//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, uint32 *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
+
+
+ uint8 *colTablePtr=NULL;
+
+ int breakOut=0;
+ uint32 j;
+ uint8 black[4]={0,0,0,0};
+ 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 slot=1000; //nothing selected
+ uint32 clicked_slot, edit_screen_slot=1000;
+ uint32 cur_slot_states[9];
+
+ int scroll_rate=0;
+// static uint32 base_slot=0;
+
+ int edit_pos, first_chr, 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;
+
+ 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
+ RestoreDisplay();
+ 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)
+ }
+
+ FlipScreens();
+
+ } //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
+
+//avoid corruption when windows kicks back in
+ EraseBackBuffer();
+ FlipScreens();
+ EraseBackBuffer();
+ FlipScreens();
+
+ Close_game(); //close engine systems down
+ RestoreDisplay();
+ 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
+ FlipScreens();
+
+
+//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
+
+ 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
+
+ uint8 black[4]={0,0,0,0};
+ 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
+ RestoreDisplay();
+ 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;
+
+ FlipScreens();
+ 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, uint32 *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
+ RestoreDisplay();
+ 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];
+ FILE *fp;
+
+ if ((fp = fopen("Settings.dat","rb"))== NULL)
+ return (1);
+
+ if (fread(buff,1,10,fp) != 10)
+ {
+ fclose(fp);
+ return (2);
+ }
+
+ fclose(fp);
+
+ SetMusicVolume(buff[0]);
+ SetSpeechVolume(buff[1]);
+ SetFxVolume(buff[2]);
+ MuteMusic(buff[3]);
+ MuteSpeech(buff[4]);
+ MuteFx(buff[5]);
+
+
+ UpdateGraphicsLevel(GetRenderType(), buff[6]); // (James13jun97)
+
+ speechSelected = !buff[4];
+ subtitles = buff[7];
+ pointerTextSelected = buff[8];
+
+ if (buff[9] != stereoReversed)
+ ReverseStereo();
+
+ stereoReversed = buff[9];
+
+ return (0);
+}
+//-----------------------------------------------------------------------------------------------------------------------
+int32 WriteOptionSettings(void) //pete10Jun97
+{
+ uint8 buff[10];
+ FILE *fp;
+
+ buff[0] = GetMusicVolume();
+ buff[1] = GetSpeechVolume();
+ buff[2] = GetFxVolume();
+ buff[3] = IsMusicMute();
+ buff[4] = IsSpeechMute();
+ buff[5] = IsFxMute();
+ buff[6] = GetRenderType();
+ buff[7] = subtitles;
+ buff[8] = pointerTextSelected;
+ buff[9] = stereoReversed;
+
+ if ((fp = fopen("Settings.dat","wb"))== NULL)
+ return (1);
+
+ if (fwrite(buff,1,10,fp) != 10)
+ {
+ fclose(fp);
+ return (2);
+ }
+
+ fclose(fp);
+
+ 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
+ uint8 black[4] = {0,0,0,0};
+ 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 = GetMusicVolume();
+ uint8 speechVolume = GetSpeechVolume();
+ uint8 fxVolume = GetFxVolume();
+ uint8 grfxLevel = GetRenderType();
+
+// safe slider values for restoring on cancel
+ uint8 safe_musicVolume = musicVolume;
+ uint8 safe_speechVolume = speechVolume;
+ uint8 safe_fxVolume = fxVolume;
+ uint8 safe_grfxLevel = grfxLevel;
+
+// 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, touching_music_mute, touching_fx_mute, touching_speech_mute, touching_object, touching_subtitle;
+ 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 = IsMusicMute();
+ uint8 speech_mute_state = IsSpeechMute();
+ uint8 fx_mute_state = 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)
+ SetMusicVolume(musicVolume);
+ else
+ SetMusicVolume(0);
+
+ if (!fx_mute_state)
+ SetFxVolume(fxVolume);
+ else
+ SetFxVolume(0);
+
+ if (!speech_mute_state)
+ SetSpeechVolume(speechVolume);
+ else
+ SetSpeechVolume(0);
+
+ //--------------------------------------------------
+ // Service windows
+
+ if (ServiceWindows() == RDERR_APPCLOSED) // if we pressed Ctrl-Q during the smacker
+ {
+ Close_game(); //close engine systems down
+ RestoreDisplay();
+ 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(safe_grfxLevel, grfxLevel); // (James13jun97)
+
+ MuteMusic(music_mute_state); // Ensure all the levels are recorded correctly (Pete21Aug97)
+ MuteSpeech(speech_mute_state);
+ MuteFx(fx_mute_state);
+ SetMusicVolume(music_target);
+ SetSpeechVolume(speech_target);
+ SetFxVolume(fx_target);
+
+ subtitles = subtitle_state; // Save object label and subtitle settings
+ pointerTextSelected = object_state;
+ speechSelected = !speech_mute_state;
+
+ if (stereo_state != stereoReversed)
+ 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
+ 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
+ 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
+ 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;
+ MuteMusic(1);
+ }
+ }
+
+ if (touching_fx_mute)
+ {
+ if (fx_mute_state)
+ dfx_mute_state = 1;
+ else
+ {
+ fx_mute_state=1;
+ MuteFx(1);
+ }
+ }
+
+ if (touching_speech_mute)
+ {
+ if (speech_mute_state)
+ dspeech_mute_state = 1;
+ else
+ {
+ speech_mute_state=1;
+ 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;
+ 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;
+ 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;
+ 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)
+ }
+ FlipScreens();
+ }
+
+
+ Kill_option_surfaces();
+
+ return; //just return to game
+}
+
+//-----------------------------------------------------------------------------------------------------------------------
+void UpdateGraphicsLevel(uint8 oldLevel, uint8 newLevel) // (James13jun97)
+{
+
+ switch (oldLevel) // Set the graphics level
+ {
+ //-------------------------------
+ case 0: // lowest setting: h/w only; no graphics fx
+ switch(newLevel)
+ {
+ case 0:
+ break;
+
+ case 1:
+ RenderSoft();
+ ClearBltFx();
+ ClearShadowFx();
+ CloseBackgroundLayer();
+ break;
+
+ case 2:
+ RenderSoft();
+ ClearBltFx();
+ CloseBackgroundLayer();
+ break;
+
+ case 3: // same as case 2 until case 2 has edge-blending inactivated
+ RenderSoft();
+ CloseBackgroundLayer();
+ break;
+ }
+ break;
+ //-------------------------------
+ case 1: // medium-low setting: s/w transparency-blending
+ switch(newLevel)
+ {
+ case 1:
+ break;
+
+ case 0:
+ RenderHard();
+ SetUpBackgroundLayers(); // InitialiseBackgroundLayer for each layer! (see layers.cpp)
+ break;
+
+ case 2:
+ SetShadowFx();
+ break;
+
+ case 3: // same as case 2 until case 2 has edge-blending inactivated
+ SetBltFx();
+ break;
+ }
+ break;
+ //-------------------------------
+ case 2: // medium-high setting: s/w transparency-blending + shading
+ switch(newLevel)
+ {
+ case 2:
+ break;
+
+ case 3: // same as case 2 until case 2 has edge-blending inactivated
+ SetBltFx();
+ break;
+
+ case 1:
+ ClearShadowFx();
+ break;
+
+ case 0:
+ RenderHard();
+ SetUpBackgroundLayers(); // InitialiseBackgroundLayer for each layer! (see layers.cpp)
+ break;
+ }
+ break;
+ //-------------------------------
+ case 3: // highest setting: s/w transparency-blending + shading + edge-blending (& improved stretching)
+ switch(newLevel)
+ {
+ case 2:
+ ClearBltFx();
+ break;
+
+ case 3: // same as case 2 until case 2 has edge-blending inactivated
+ break;
+
+ case 1:
+ ClearBltFx();
+ ClearShadowFx();
+ break;
+
+ case 0:
+ RenderHard();
+ SetUpBackgroundLayers(); // InitialiseBackgroundLayer for each layer! (see layers.cpp)
+ break;
+ }
+ 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;
+}
+//-----------------------------------------------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------------------------------------------
+