12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692 |
- /* Catacomb Armageddon Source Code
- * Copyright (C) 1993-2014 Flat Rock Software
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- //
- // ID Engine
- // ID_US.c - User Manager
- // v1.0d1
- // By Jason Blochowiak
- //
- //
- // This module handles dealing with user input & feedback
- //
- // Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
- // and Refresh Mgrs, Memory Mgr for background save/restore
- //
- // Globals:
- // ingame - Flag set by game indicating if a game is in progress
- // abortgame - Flag set if the current game should be aborted (if a load
- // game fails)
- // loadedgame - Flag set if a game was loaded
- // abortprogram - Normally nil, this points to a terminal error message
- // if the program needs to abort
- // restartgame - Normally set to gd_Continue, this is set to one of the
- // difficulty levels if a new game should be started
- // PrintX, PrintY - Where the User Mgr will print (global coords)
- // WindowX,WindowY,WindowW,WindowH - The dimensions of the current
- // window
- //
- // DEBUG - handle LPT3 for Sound Source
- #include "ID_HEADS.H"
- #define CTL_M_ADLIBUPPIC CTL_S_ADLIBUPPIC
- #define CTL_M_ADLIBDNPIC CTL_S_ADLIBDNPIC
- #pragma hdrstop
- #pragma warn -pia
- #define MaxX 320
- #define MaxY 200
- #define MaxHelpLines 500
- #define MaxHighName 57
- #define MaxScores 10
- typedef struct
- {
- char name[MaxHighName + 1];
- long score;
- word completed;
- } HighScore;
- #define MaxGameName 32
- #define MaxSaveGames 7
- typedef struct
- {
- char signature[4];
- boolean present;
- char name[MaxGameName + 1];
- } SaveGame;
- // Hack import for TED launch support
- extern boolean tedlevel;
- extern word tedlevelnum;
- extern void TEDDeath(void);
- static char *ParmStrings[] = {"TEDLEVEL","NOWAIT",""};
- // Global variables
- boolean ingame,abortgame,loadedgame;
- char *abortprogram;
- GameDiff restartgame = gd_Continue;
- word PrintX,PrintY;
- word WindowX,WindowY,WindowW,WindowH;
- // Internal variables
- static boolean US_Started;
- static boolean GameIsDirty,
- HighScoresDirty,
- QuitToDos,
- ResumeGame,
- NoWait;
- static memptr LineOffsets;
- static boolean Button0,Button1,
- CursorBad;
- static int CursorX,CursorY;
- static void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
- (*USL_DrawString)(char far *) = VWB_DrawPropString;
- static boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int);
- static void (*USL_ResetGame)(void);
- static SaveGame Games[MaxSaveGames];
- static HighScore Scores[MaxScores] =
- {
- {"Sir Lancelot",500},
- {"",0},
- {"",0},
- {"",0},
- {"",0},
- {"",0},
- {"",0},
- {"",0},
- {"",0},
- {"",0}
- };
- // Internal routines
- // Public routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
- // from DOS.
- //
- ///////////////////////////////////////////////////////////////////////////
- #pragma warn -par
- #pragma warn -rch
- int
- USL_HardError(word errval,int ax,int bp,int si)
- {
- #define IGNORE 0
- #define RETRY 1
- #define ABORT 2
- extern void ShutdownId(void);
- static char buf[32];
- static WindowRec wr;
- static boolean oldleavedriveon;
- int di;
- char c,*s,*t;
- di = _DI;
- oldleavedriveon = LeaveDriveOn;
- LeaveDriveOn = false;
- if (ax < 0)
- s = "Device Error";
- else
- {
- if ((di & 0x00ff) == 0)
- s = "Drive ~ is Write Protected";
- else
- s = "Error on Drive ~";
- for (t = buf;*s;s++,t++) // Can't use sprintf()
- if ((*t = *s) == '~')
- *t = (ax & 0x00ff) + 'A';
- *t = '\0';
- s = buf;
- }
- c = peekb(0x40,0x49); // Get the current screen mode
- if ((c < 4) || (c == 7))
- goto oh_kill_me;
- // DEBUG - handle screen cleanup
- US_SaveWindow(&wr);
- US_CenterWindow(30,3);
- US_CPrint(s);
- US_CPrint("(R)etry or (A)bort?");
- VW_UpdateScreen();
- IN_ClearKeysDown();
- asm sti // Let the keyboard interrupts come through
- while (true)
- {
- switch (IN_WaitForASCII())
- {
- case key_Escape:
- case 'a':
- case 'A':
- goto oh_kill_me;
- break;
- case key_Return:
- case key_Space:
- case 'r':
- case 'R':
- US_ClearWindow();
- VW_UpdateScreen();
- US_RestoreWindow(&wr);
- LeaveDriveOn = oldleavedriveon;
- return(RETRY);
- break;
- }
- }
- oh_kill_me:
- abortprogram = s;
- ShutdownId();
- fprintf(stderr,"Terminal Error: %s\n",s);
- if (tedlevel)
- fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
- return(ABORT);
- #undef IGNORE
- #undef RETRY
- #undef ABORT
- }
- #pragma warn +par
- #pragma warn +rch
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_GiveSaveName() - Returns a pointer to a static buffer that contains
- // the filename to use for the specified save game
- //
- ///////////////////////////////////////////////////////////////////////////
- static char *
- USL_GiveSaveName(word game)
- {
- static char filename[32];
- char *s,*t;
- for (s = "SAVEGM",t = filename;*s;)
- *t++ = *s++;
- *t++ = game + '0';
- for (s = "."EXTENSION;*s;)
- *t++ = *s++;
- *t = '\0';
- return(filename);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_SetLoadSaveHooks() - Sets the routines that the User Mgr calls after
- // reading or writing the save game headers
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_SetLoadSaveHooks(boolean (*load)(int),boolean (*save)(int),void (*reset)(void))
- {
- USL_LoadGame = load;
- USL_SaveGame = save;
- USL_ResetGame = reset;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_ReadConfig() - Reads the configuration file, if present, and sets
- // things up accordingly. If it's not present, uses defaults. This file
- // includes the high scores.
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_ReadConfig(void)
- {
- boolean gotit;
- int file;
- SDMode sd;
- SMMode sm;
- ControlType ctl;
- if ((file = open("CONFIG."EXTENSION,O_BINARY | O_RDONLY)) != -1)
- {
- read(file,Scores,sizeof(HighScore) * MaxScores);
- read(file,&sd,sizeof(sd));
- read(file,&sm,sizeof(sm));
- read(file,&ctl,sizeof(ctl));
- read(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));
- close(file);
- HighScoresDirty = false;
- gotit = true;
- }
- else
- {
- sd = sdm_Off;
- sm = smm_Off;
- ctl = ctrl_Keyboard;
- gotit = false;
- HighScoresDirty = true;
- }
- SD_Default(gotit,sd,sm);
- IN_Default(gotit,ctl);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_WriteConfig() - Writes out the current configuration, including the
- // high scores.
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_WriteConfig(void)
- {
- int file;
- file = open("CONFIG."EXTENSION,O_CREAT | O_BINARY | O_WRONLY,
- S_IREAD | S_IWRITE | S_IFREG);
- if (file != -1)
- {
- write(file,Scores,sizeof(HighScore) * MaxScores);
- write(file,&SoundMode,sizeof(SoundMode));
- write(file,&MusicMode,sizeof(MusicMode));
- write(file,&(Controls[0]),sizeof(Controls[0]));
- write(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));
- close(file);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CheckSavedGames() - Checks to see which saved games are present
- // & valid
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_CheckSavedGames(void)
- {
- boolean ok;
- char *filename;
- word i;
- int file;
- SaveGame *game;
- USL_SaveGame = 0;
- USL_LoadGame = 0;
- for (i = 0,game = Games;i < MaxSaveGames;i++,game++)
- {
- filename = USL_GiveSaveName(i);
- ok = false;
- if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
- {
- if
- (
- (read(file,game,sizeof(*game)) == sizeof(*game))
- && (!strcmp(game->signature,EXTENSION))
- )
- ok = true;
- close(file);
- }
- if (ok)
- game->present = true;
- else
- {
- strcpy(game->signature,EXTENSION);
- game->present = false;
- strcpy(game->name,"Empty");
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_Startup() - Starts the User Mgr
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_Startup(void)
- {
- if (US_Started)
- return;
- harderr(USL_HardError); // Install the fatal error handler
- US_InitRndT(true); // Initialize the random number generator
- USL_ReadConfig(); // Read config file
- US_Started = true;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_Setup() - Does the disk access part of the User Mgr's startup
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_Setup(void)
- {
- USL_CheckSavedGames(); // Check which saved games are present
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_Shutdown() - Shuts down the User Mgr
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_Shutdown(void)
- {
- if (!US_Started)
- return;
- if (!abortprogram)
- USL_WriteConfig();
- US_Started = false;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_CheckParm() - checks to see if a string matches one of a set of
- // strings. The check is case insensitive. The routine returns the
- // index of the string that matched, or -1 if no matches were found
- //
- ///////////////////////////////////////////////////////////////////////////
- int
- US_CheckParm(char *parm,char **strings)
- {
- char cp,cs,
- *p,*s;
- int i;
- while (!isalpha(*parm)) // Skip non-alphas
- parm++;
- for (i = 0;*strings && **strings;i++)
- {
- for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
- {
- cs = *s++;
- if (!cs)
- return(i);
- cp = *p++;
- if (isupper(cs))
- cs = tolower(cs);
- if (isupper(cp))
- cp = tolower(cp);
- }
- }
- return(-1);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_ScreenDraw() - Draws a chunk of the text screen (called only by
- // US_TextScreen())
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_ScreenDraw(word x,word y,char *s,byte attr)
- {
- byte far *screen;
- screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));
- while (*s)
- {
- *screen++ = *s++;
- *screen++ = attr;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_ClearTextScreen() - Makes sure the screen is in text mode, clears it,
- // and moves the cursor to the leftmost column of the bottom line
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_ClearTextScreen(void)
- {
- // Set to 80x25 color text mode
- _AL = 3; // Mode 3
- _AH = 0x00;
- geninterrupt(0x10);
- // Use BIOS to move the cursor to the bottom of the screen
- _AH = 0x0f;
- geninterrupt(0x10); // Get current video mode into _BH
- _DL = 0; // Lefthand side of the screen
- _DH = 24; // Bottom row
- _AH = 0x02;
- geninterrupt(0x10);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_TextScreen() - Puts up the startup text screen
- // Note: These are the only User Manager functions that can be safely called
- // before the User Mgr has been started up
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_TextScreen(void)
- {
- word i,n,
- sx,sy;
- extern char far introscn;
- USL_ClearTextScreen();
- _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);
- // Check for TED launching here
- for (i = 1;i < _argc;i++)
- {
- n = US_CheckParm(_argv[i],ParmStrings);
- if (n == 0)
- {
- tedlevelnum = atoi(_argv[i + 1]);
- if (tedlevelnum >= 0)
- {
- tedlevel = true;
- return;
- }
- else
- break;
- }
- else if (n == 1)
- {
- NoWait = true;
- return;
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_Show() - Changes the appearance of one of the fields on the text
- // screen. Possibly adds a checkmark in front of it and highlights it
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_Show(word x,word y,word w,boolean show,boolean hilight)
- {
- byte far *screen;
- screen = MK_FP(0xb800,((x - 1) * 2) + (y * 80 * 2));
- *screen++ = show? 251 : ' '; // Checkmark char or space
- *screen = 0x48;
- if (show && hilight)
- {
- for (w++;w--;screen += 2)
- *screen = 0x4f;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_ShowMem() - Right justifies a longword in one of the memory fields on
- // the text screen
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_ShowMem(word x,word y,long mem)
- {
- char buf[16];
- word i;
- for (i = strlen(ltoa(mem,buf,10));i < 5;i++)
- USL_ScreenDraw(x++,y," ",0x48);
- USL_ScreenDraw(x,y,buf,0x48);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_UpdateTextScreen() - Called after the ID libraries are started up.
- // Displays what hardware is present.
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_UpdateTextScreen(void)
- {
- boolean b;
- byte far *screen;
- word i;
- longword totalmem;
- // Show video card info
- b = (grmode == CGAGR);
- USL_Show(21,7,4,(videocard >= CGAcard) && (videocard <= VGAcard),b);
- b = (grmode == EGAGR);
- USL_Show(21,8,4,(videocard >= EGAcard) && (videocard <= VGAcard),b);
- b = (grmode == VGAGR);
- USL_Show(21,9,4,videocard == VGAcard,b);
- if (compatability)
- USL_ScreenDraw(5,10,"SVGA Compatibility Mode Enabled.",0x4f);
- // Show input device info
- USL_Show(60,7,8,true,true);
- USL_Show(60,8,11,JoysPresent[0],true);
- USL_Show(60,9,11,JoysPresent[1],true);
- USL_Show(60,10,5,MousePresent,true);
- // Show sound hardware info
- USL_Show(21,14,11,true,SoundMode == sdm_PC);
- b = (SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib);
- USL_Show(21,15,5,AdLibPresent && !SoundBlasterPresent,
- b && !SoundBlasterPresent);
- USL_Show(21,16,13,SoundBlasterPresent,
- SoundBlasterPresent && (b || (SoundMode == sdm_SoundBlaster)));
- USL_Show(21,17,13,SoundSourcePresent,SoundMode == sdm_SoundSource);
- // Show memory available/used
- USL_ShowMem(63,15,mminfo.mainmem / 1024);
- USL_Show(53,15,23,true,true);
- USL_ShowMem(63,16,mminfo.EMSmem / 1024);
- USL_Show(53,16,23,mminfo.EMSmem? true : false,true);
- USL_ShowMem(63,17,mminfo.XMSmem / 1024);
- USL_Show(53,17,23,mminfo.XMSmem? true : false,true);
- totalmem = mminfo.mainmem + mminfo.EMSmem + mminfo.XMSmem;
- USL_ShowMem(63,18,totalmem / 1024);
- screen = MK_FP(0xb800,1 + (((63 - 1) * 2) + (18 * 80 * 2)));
- for (i = 0;i < 13;i++,screen += 2)
- *screen = 0x4f;
- // Change Initializing... to Loading...
- USL_ScreenDraw(27,22," Loading... ",0x9c);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_FinishTextScreen() - After the main program has finished its initial
- // loading, this routine waits for a keypress and then clears the screen
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_FinishTextScreen(void)
- {
- // Change Loading... to Press a Key
- USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
- if (!(tedlevel || NoWait))
- {
- IN_ClearKeysDown();
- IN_Ack();
- }
- IN_ClearKeysDown();
- USL_ClearTextScreen();
- }
- // Window/Printing routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_SetPrintRoutines() - Sets the routines used to measure and print
- // from within the User Mgr. Primarily provided to allow switching
- // between masked and non-masked fonts
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
- {
- USL_MeasureString = measure;
- USL_DrawString = print;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_Print() - Prints a string in the current window. Newlines are
- // supported.
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_Print(char *s)
- {
- char c,*se;
- word w,h;
- while (*s)
- {
- se = s;
- while ((c = *se) && (c != '\n'))
- se++;
- *se = '\0';
- USL_MeasureString(s,&w,&h);
- px = PrintX;
- py = PrintY;
- USL_DrawString(s);
- s = se;
- if (c)
- {
- *se = c;
- s++;
- PrintX = WindowX;
- PrintY += h;
- }
- else
- PrintX += w;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_PrintUnsigned() - Prints an unsigned long
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_PrintUnsigned(longword n)
- {
- char buffer[32];
- US_Print(ultoa(n,buffer,10));
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_PrintSigned() - Prints a signed long
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_PrintSigned(long n)
- {
- char buffer[32];
- US_Print(ltoa(n,buffer,10));
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_PrintInCenter() - Prints a string in the center of the given rect
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_PrintInCenter(char *s,Rect r)
- {
- word w,h,
- rw,rh;
- USL_MeasureString(s,&w,&h);
- rw = r.lr.x - r.ul.x;
- rh = r.lr.y - r.ul.y;
- px = r.ul.x + ((rw - w) / 2);
- py = r.ul.y + ((rh - h) / 2);
- USL_DrawString(s);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_PrintCentered() - Prints a string centered in the current window.
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_PrintCentered(char *s)
- {
- Rect r;
- r.ul.x = WindowX;
- r.ul.y = WindowY;
- r.lr.x = r.ul.x + WindowW;
- r.lr.y = r.ul.y + WindowH;
- USL_PrintInCenter(s,r);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_CPrintLine() - Prints a string centered on the current line and
- // advances to the next line. Newlines are not supported.
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_CPrintLine(char *s)
- {
- word w,h;
- USL_MeasureString(s,&w,&h);
- if (w > WindowW)
- Quit("US_CPrintLine() - String exceeds width");
- px = WindowX + ((WindowW - w) / 2);
- py = PrintY;
- USL_DrawString(s);
- PrintY += h;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_CPrint() - Prints a string in the current window. Newlines are
- // supported.
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_CPrint(char *s)
- {
- char c,*se;
- word w,h;
- while (*s)
- {
- se = s;
- while ((c = *se) && (c != '\n'))
- se++;
- *se = '\0';
- US_CPrintLine(s);
- s = se;
- if (c)
- {
- *se = c;
- s++;
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_ClearWindow() - Clears the current window to white and homes the
- // cursor
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_ClearWindow(void)
- {
- VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
- PrintX = WindowX;
- PrintY = WindowY;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_DrawWindow() - Draws a frame and sets the current window parms
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_DrawWindow(word x,word y,word w,word h)
- {
- word i,
- sx,sy,sw,sh;
- WindowX = x * 8;
- WindowY = y * 8;
- WindowW = w * 8;
- WindowH = h * 8;
- PrintX = WindowX;
- PrintY = WindowY;
- sx = (x - 1) * 8;
- sy = (y - 1) * 8;
- sw = (w + 1) * 8;
- sh = (h + 1) * 8;
- US_ClearWindow();
- VWB_DrawTile8M(sx,sy,0),VWB_DrawTile8M(sx,sy + sh,6);
- for (i = sx + 8;i <= sx + sw - 8;i += 8)
- VWB_DrawTile8M(i,sy,1),VWB_DrawTile8M(i,sy + sh,7);
- VWB_DrawTile8M(i,sy,2),VWB_DrawTile8M(i,sy + sh,8);
- for (i = sy + 8;i <= sy + sh - 8;i += 8)
- VWB_DrawTile8M(sx,i,3),VWB_DrawTile8M(sx + sw,i,5);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_CenterWindow() - Generates a window of a given width & height in the
- // middle of the screen
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_CenterWindow(word w,word h)
- {
- US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_CenterSaveWindow() - Generates a window of a given width & height in
- // the middle of the screen, saving the background
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_CenterSaveWindow(word w,word h,memptr *save)
- {
- word x,y,
- screen;
- x = ((MaxX / 8) - w) / 2;
- y = ((MaxY / 8) - h) / 2;
- MM_GetPtr(save,(w * h) * CHARWIDTH);
- screen = bufferofs + panadjust + ylookup[y] + (x * CHARWIDTH);
- VW_ScreenToMem(screen,*save,w * CHARWIDTH,h);
- US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_RestoreSaveWindow() - Restores the background of the size of the
- // current window from the memory specified by save
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_RestoreSaveWindow(memptr *save)
- {
- word screen;
- screen = bufferofs + panadjust + ylookup[WindowY] + (WindowX * CHARWIDTH);
- VW_MemToScreen(*save,screen,WindowW * CHARWIDTH,WindowH);
- MM_FreePtr(save);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_SaveWindow() - Saves the current window parms into a record for
- // later restoration
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_SaveWindow(WindowRec *win)
- {
- win->x = WindowX;
- win->y = WindowY;
- win->w = WindowW;
- win->h = WindowH;
- win->px = PrintX;
- win->py = PrintY;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_RestoreWindow() - Sets the current window parms to those held in the
- // record
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_RestoreWindow(WindowRec *win)
- {
- WindowX = win->x;
- WindowY = win->y;
- WindowW = win->w;
- WindowH = win->h;
- PrintX = win->px;
- PrintY = win->py;
- }
- // Cursor routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_StartCursor() - Sets up the cursor for User Mgr use
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_StartCursor(void)
- {
- CursorInfo info;
- VW_SetCursor(CURSORARROWSPR);
- CursorX = MaxX / 2;
- CursorY = MaxY / 2;
- VW_MoveCursor(CursorX,CursorY);
- VW_ShowCursor();
- IN_ReadCursor(&info); // Dispose of any accumulated movement
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_ShutCursor() - Cleans up after US_StartCursor()
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_ShutCursor(void)
- {
- VW_HideCursor();
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_UpdateCursor() - Gets the new cursor position & button states from
- // the Input Mgr and tells the View Mgr where the cursor is
- //
- ///////////////////////////////////////////////////////////////////////////
- boolean
- US_UpdateCursor(void)
- {
- CursorInfo info;
- IN_ReadCursor(&info);
- if (info.x || info.y || CursorBad)
- {
- CursorX += info.x;
- if (CursorX >= MaxX)
- CursorX = MaxX - 1;
- else if (CursorX < 0)
- CursorX = 0;
- CursorY += info.y;
- if (CursorY >= MaxY)
- CursorY = MaxY - 1;
- else if (CursorY < 0)
- CursorY = 0;
- VW_MoveCursor(CursorX,CursorY);
- CursorBad = false;
- }
- Button0 = info.button0;
- Button1 = info.button1;
- return(Button0 || Button1);
- }
- // Input routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_XORICursor(int x,int y,char *s,word cursor)
- {
- char buf[MaxString];
- word w,h;
- strcpy(buf,s);
- buf[cursor] = '\0';
- USL_MeasureString(buf,&w,&h);
- px = x + w - 1;
- py = y;
- USL_DrawString("\x80");
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_LineInput() - Gets a line of user input at (x,y), the string defaults
- // to whatever is pointed at by def. Input is restricted to maxchars
- // chars or maxwidth pixels wide. If the user hits escape (and escok is
- // true), nothing is copied into buf, and false is returned. If the
- // user hits return, the current string is copied into buf, and true is
- // returned
- //
- ///////////////////////////////////////////////////////////////////////////
- boolean
- US_LineInput(int x,int y,char *buf,char *def,boolean escok,
- int maxchars,int maxwidth)
- {
- boolean redraw,
- cursorvis,cursormoved,
- done,result;
- ScanCode sc;
- char c,
- s[MaxString],olds[MaxString];
- word i,
- cursor,
- w,h,
- len;
- longword lasttime;
- VW_HideCursor();
- if (def)
- strcpy(s,def);
- else
- *s = '\0';
- *olds = '\0';
- cursor = strlen(s);
- cursormoved = redraw = true;
- cursorvis = done = false;
- lasttime = TimeCount;
- LastASCII = key_None;
- LastScan = sc_None;
- while (!done)
- {
- if (cursorvis)
- USL_XORICursor(x,y,s,cursor);
- asm pushf
- asm cli
- sc = LastScan;
- LastScan = sc_None;
- c = LastASCII;
- LastASCII = key_None;
- asm popf
- switch (sc)
- {
- case sc_LeftArrow:
- if (cursor)
- cursor--;
- c = key_None;
- cursormoved = true;
- break;
- case sc_RightArrow:
- if (s[cursor])
- cursor++;
- c = key_None;
- cursormoved = true;
- break;
- case sc_Home:
- cursor = 0;
- c = key_None;
- cursormoved = true;
- break;
- case sc_End:
- cursor = strlen(s);
- c = key_None;
- cursormoved = true;
- break;
- case sc_Return:
- strcpy(buf,s);
- done = true;
- result = true;
- c = key_None;
- break;
- case sc_Escape:
- if (escok)
- {
- done = true;
- result = false;
- }
- c = key_None;
- break;
- case sc_BackSpace:
- if (cursor)
- {
- strcpy(s + cursor - 1,s + cursor);
- cursor--;
- redraw = true;
- }
- c = key_None;
- cursormoved = true;
- break;
- case sc_Delete:
- if (s[cursor])
- {
- strcpy(s + cursor,s + cursor + 1);
- redraw = true;
- }
- c = key_None;
- cursormoved = true;
- break;
- case 0x4c: // Keypad 5
- case sc_UpArrow:
- case sc_DownArrow:
- case sc_PgUp:
- case sc_PgDn:
- case sc_Insert:
- c = key_None;
- break;
- }
- if (c)
- {
- len = strlen(s);
- USL_MeasureString(s,&w,&h);
- if
- (
- isprint(c)
- && (len < MaxString - 1)
- && ((!maxchars) || (len < maxchars))
- && ((!maxwidth) || (w < maxwidth))
- )
- {
- for (i = len + 1;i > cursor;i--)
- s[i] = s[i - 1];
- s[cursor++] = c;
- redraw = true;
- }
- }
- if (redraw)
- {
- px = x;
- py = y;
- USL_DrawString(olds);
- strcpy(olds,s);
- px = x;
- py = y;
- USL_DrawString(s);
- redraw = false;
- }
- if (cursormoved)
- {
- cursorvis = false;
- lasttime = TimeCount - TickBase;
- cursormoved = false;
- }
- if (TimeCount - lasttime > TickBase / 2)
- {
- lasttime = TimeCount;
- cursorvis ^= true;
- }
- if (cursorvis)
- USL_XORICursor(x,y,s,cursor);
- VW_UpdateScreen();
- }
- if (cursorvis)
- USL_XORICursor(x,y,s,cursor);
- if (!result)
- {
- px = x;
- py = y;
- USL_DrawString(olds);
- }
- VW_ShowCursor();
- VW_UpdateScreen();
- IN_ClearKeysDown();
- return(result);
- }
- // Control panel routines
- static boolean FlushHelp;
- static WindowRec HelpWindow,BottomWindow;
- typedef enum
- {
- uic_Draw,uic_Hit
- } UserCall;
- typedef enum
- {
- uii_Bad,uii_Button,uii_RadioButton,uii_CheckBox,uii_KeyCap
- } UIType;
- #define ui_Normal 0
- #define ui_Selected 1
- #define ui_Disabled 2
- // Prototype the custom routines
- static boolean USL_CtlButtonCustom(UserCall,word,word),
- USL_CtlPButtonCustom(UserCall,word,word),
- USL_CtlPSButtonCustom(UserCall,word,word),
- USL_CtlPRButtonCustom(UserCall,word,word),
- USL_CtlHButtonCustom(UserCall,word,word),
- USL_CtlDButtonCustom(UserCall,word,word),
- USL_CtlDEButtonCustom(UserCall,word,word),
- USL_CtlDLButtonCustom(UserCall,word,word),
- USL_CtlDSButtonCustom(UserCall,word,word),
- USL_CtlSButtonCustom(UserCall,word,word),
- USL_CtlCButtonCustom(UserCall,word,word),
- USL_CtlCKbdButtonCustom(UserCall,word,word),
- USL_CtlCJoyButtonCustom(UserCall,word,word);
- // The structure of a user interaction item
- typedef struct {
- Rect r; // The enclosing rectangle
- UIType type; // The type of item
- int picup,picdown; // What to draw when up/down
- char *help; // Floating help string
- ScanCode key; // Key equiv
- word sel; // Interaction flags (ui_XXX)
- boolean (*custom)(UserCall,word,word); // Custom routine
- char *text; // Text for some items
- } UserItem;
- typedef struct {
- ScanCode key;
- word i,n, // Hit CtlPanels2[i][n]
- toi,ton; // Move to CtlPanels2[toi][ton]
- } HotKey; // MARK
- static ScanCode *KeyMaps[] =
- {
- &KbdDefs[0].button0,&KbdDefs[0].button1,
- &KbdDefs[0].upleft,&KbdDefs[0].up,&KbdDefs[0].upright,
- &KbdDefs[0].left, &KbdDefs[0].right,
- &KbdDefs[0].downleft,&KbdDefs[0].down,&KbdDefs[0].downright,
- };
- // Some macros to make rectangle definition quite a bit less unpleasant
- #define CtlPanelX 8
- #define CtlPanelY 4
- #define CtlPanel2X (8*8)
- #define CtlPanel2Y (2*8)
- #define CtlPanel3X (8*8)
- #define CtlPanel3Y (7*8)
- #define CtlPanelR(n) { CtlPanelX,CtlPanelY+(32 * (n)),\
- CtlPanelX+40,CtlPanelY+(32 * (n)) + 32}
- #define CtlPanel2R(x,y) { CtlPanel2X+(x)*8,CtlPanel2Y+(y)*8,\
- CtlPanel2X+32+(x)*8,CtlPanel2Y+24+(y)*8}
- #define CtlPanel3R(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
- CtlPanel3X+32+(x)*8,CtlPanel3Y+24+(y)*8}
- static UserItem CtlPanels[] =
- {
- {CtlPanelR(0),uii_RadioButton,CTL_STARTUPPIC,CTL_STARTDNPIC,"Start or Resume a Game",sc_None,ui_Normal,USL_CtlButtonCustom},
- {CtlPanelR(1),uii_RadioButton,CTL_HELPUPPIC,CTL_HELPDNPIC,"Get Help With Commander Keen",sc_None,ui_Normal,USL_CtlButtonCustom},
- {CtlPanelR(2),uii_RadioButton,CTL_DISKUPPIC,CTL_DISKDNPIC,"Load / Save / Quit",sc_None,ui_Normal,USL_CtlButtonCustom},
- {CtlPanelR(3),uii_RadioButton,CTL_CONTROLSUPPIC,CTL_CONTROLSDNPIC,"Choose Controls",sc_C,ui_Normal,USL_CtlButtonCustom},
- {CtlPanelR(4),uii_RadioButton,CTL_SOUNDUPPIC,CTL_SOUNDDNPIC,"Select Sound Device",sc_F2,ui_Normal,USL_CtlButtonCustom},
- {CtlPanelR(5),uii_RadioButton,CTL_MUSICUPPIC,CTL_MUSICDNPIC,"Turn Music On / Off",sc_F7,ui_Normal,USL_CtlButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlPPanels[] =
- {
- {CtlPanel2R(10,0),uii_RadioButton,CTL_P_NEWGAMEUPPIC,CTL_P_NEWGAMEDNPIC,"Choose Difficulty for the New Game",sc_F5,ui_Normal,USL_CtlPButtonCustom},
- {CtlPanel2R(15,0),uii_RadioButton,CTL_P_RESUMEUPPIC,CTL_P_RESUMEDNPIC,"Go Back to Current Game",sc_None,ui_Normal,USL_CtlPButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlPSPanels[] =
- {
- {CtlPanel3R(13,5),uii_Button,CTL_P_MEDUPPIC,CTL_P_MEDDNPIC,"Start New Game in Normal Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},
- {CtlPanel3R(8,5),uii_Button,CTL_P_EASYUPPIC,CTL_P_EASYDNPIC,"Start New Game in Easy Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},
- {CtlPanel3R(18,5),uii_Button,CTL_P_HARDUPPIC,CTL_P_HARDDNPIC,"Start New Game in Hard Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlPRPanels[] =
- {
- {CtlPanel3R(13,5),uii_Button,CTL_P_GORESUMEUPPIC,CTL_P_GORESUMEDNPIC,"Resume Current Game",sc_None,ui_Normal,USL_CtlPRButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlHPanels[] =
- {
- {CtlPanel2R(8,0),uii_Button,CTL_H_LOSTUPPIC,CTL_H_LOSTDNPIC,"Help Me, I'm Lost!",sc_F1,ui_Normal,USL_CtlHButtonCustom},
- {CtlPanel2R(13,0),uii_Button,CTL_H_CTRLUPPIC,CTL_H_CTRLDNPIC,"Get Help with Controls",sc_None,ui_Normal,USL_CtlHButtonCustom},
- {CtlPanel2R(18,0),uii_Button,CTL_H_STORYUPPIC,CTL_H_STORYDNPIC,"Read Story & Game Tips",sc_None,ui_Normal,USL_CtlHButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlDPanels[] =
- {
- {CtlPanel2R(9,0),uii_RadioButton,CTL_D_LSGAMEUPPIC,CTL_D_LSGAMEDNPIC,"Load or Save a Game",sc_F6,ui_Normal,USL_CtlDButtonCustom},
- {CtlPanel2R(15,0),uii_RadioButton,CTL_D_DOSUPPIC,CTL_D_DOSDNPIC,"Exit to DOS",sc_Q,ui_Normal,USL_CtlDButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlDLSPanels[] =
- {
- #define CtlPanel3LSR(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
- CtlPanel3X+32+(x)*8,CtlPanel3Y+16+(y)*8}
- {CtlPanel3LSR(1,0),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,0),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {CtlPanel3LSR(1,2),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,2),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {CtlPanel3LSR(1,4),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,4),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {CtlPanel3LSR(1,6),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,6),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {CtlPanel3LSR(1,8),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,8),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {CtlPanel3LSR(1,10),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,10),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {CtlPanel3LSR(1,12),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
- {CtlPanel3LSR(6,12),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlDEPanels[] =
- {
- #define CtlPanel3ER(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
- CtlPanel3X+40+(x)*8,CtlPanel3Y+24+(y)*8}
- {CtlPanel3ER(12,5),uii_Button,CTL_D_EXITUPPIC,CTL_D_EXITDNPIC,"Really Exit to DOS",sc_None,ui_Normal,USL_CtlDEButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlCPanels[] =
- {
- {CtlPanel2R(8,0),uii_RadioButton,CTL_C_KBDUPPIC,CTL_C_KBDDNPIC,"Use / Configure Keyboard",sc_F3,ui_Normal,USL_CtlCButtonCustom},
- {CtlPanel2R(13,0),uii_RadioButton,CTL_C_JOY1UPPIC,CTL_C_JOY1DNPIC,"Use / Configure Joystick 1",sc_None,ui_Normal,USL_CtlCButtonCustom},
- {CtlPanel2R(18,0),uii_RadioButton,CTL_C_JOY2UPPIC,CTL_C_JOY2DNPIC,"Use / Configure Joystick 2",sc_None,ui_Normal,USL_CtlCButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- #define CtlPanelKC3R(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
- CtlPanel3X+56+(x)*8,CtlPanel3Y+32+(y)*8}
- CtlCKbdPanels[] =
- {
- {CtlPanelKC3R(1,2),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key for Jumping",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(1,6),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key for Throwing",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(8,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up & Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(15,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(22,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up & Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(8,4),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(22,4),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(8,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down & Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(15,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {CtlPanelKC3R(22,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down & Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlCJoyPanels[] =
- {
- {CtlPanel3R(13,5),uii_Button,CTL_C_CALIBRATEUPPIC,CTL_C_CALIBRATEDNPIC,"Configure Joystick",sc_None,ui_Normal,USL_CtlCJoyButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlSPanels[] =
- {
- {CtlPanel2R(3,0),uii_RadioButton,CTL_S_NOSNDUPPIC,CTL_S_NOSNDDNPIC,"Turn Sound Off",sc_None,ui_Normal,USL_CtlSButtonCustom},
- {CtlPanel2R(8,0),uii_RadioButton,CTL_S_PCSNDUPPIC,CTL_S_PCSNDDNPIC,"Use PC Speaker",sc_None,ui_Normal,USL_CtlSButtonCustom},
- {CtlPanel2R(13,0),uii_RadioButton,CTL_S_ADLIBUPPIC,CTL_S_ADLIBDNPIC,"Use AdLib Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},
- {CtlPanel2R(18,0),uii_RadioButton,CTL_S_SNDBLUPPIC,CTL_S_SNDBLDNPIC,"Use SoundBlaster Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},
- {CtlPanel2R(23,0),uii_RadioButton,CTL_S_SNDSRCUPPIC,CTL_S_SNDSRCDNPIC,"Use Sound Source Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlSSSPanels[] =
- {
- {CtlPanel3R(7,2),uii_CheckBox,CTL_CHECKUPPIC,CTL_CHECKDNPIC,"Turn Tandy Mode On / Off",sc_None,ui_Normal,0,"Tandy Mode"},
- {CtlPanel3R(7,6),uii_CheckBox,CTL_CHECKUPPIC,CTL_CHECKDNPIC,"Switch between LPT1 & LPT2",sc_None,ui_Normal,0,"Use LPT2"},
- {-1,-1,-1,-1,uii_Bad}
- },
- CtlMPanels[] =
- {
- {CtlPanel2R(9,0),uii_RadioButton,CTL_M_NOMUSUPPIC,CTL_M_NOMUSDNPIC,"Background Music Off"},
- {CtlPanel2R(15,0),uii_RadioButton,CTL_M_ADLIBUPPIC,CTL_M_ADLIBDNPIC,"Use AdLib/SoundBlaster Music"},
- {-1,-1,-1,-1,uii_Bad}
- },
- *CtlPanels2[] =
- {
- CtlPPanels, // Start
- CtlHPanels, // Help
- CtlDPanels, // Disk
- CtlCPanels, // Controls
- CtlSPanels, // Sound
- CtlMPanels // Music
- },
- *TheItems[4] = {CtlPanels};
- static int CtlPanelButton;
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_TurnOff() - Goes through a list of UserItems and sets them all to
- // the normal state
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_TurnOff(UserItem *ip)
- {
- while (ip->type != uii_Bad)
- {
- ip->sel = ui_Normal;
- ip++;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_FindDown() - Finds which UserItem, if any, is selected in the given
- // list
- //
- ///////////////////////////////////////////////////////////////////////////
- static int
- USL_FindDown(UserItem *ip)
- {
- int i;
- for (i = 0;ip->type != uii_Bad;i++,ip++)
- if (ip->sel & ui_Selected)
- return(i);
- return(-1);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_ShowHelp() - Shows the specified string in the help window
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_ShowHelp(char *s)
- {
- WindowRec wr;
- if (!s)
- return;
- US_SaveWindow(&wr);
- US_RestoreWindow(&HelpWindow);
- US_ClearWindow();
- US_PrintCentered(s);
- US_RestoreWindow(&wr);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_HandleError() - Handles telling the user that there's been an error
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_HandleError(int num)
- {
- char buf[64];
- strcpy(buf,"Error: ");
- if (num < 0)
- strcat(buf,"Unknown");
- else if (num == ENOMEM)
- strcat(buf,"Disk is Full");
- else if (num == EINVFMT)
- strcat(buf,"File is Incomplete");
- else
- strcat(buf,sys_errlist[num]);
- VW_HideCursor();
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp(buf);
- fontcolor = F_BLACK;
- VW_UpdateScreen();
- IN_ClearKeysDown();
- IN_Ack();
- VW_ShowCursor();
- VW_UpdateScreen();
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_DrawItem() - Draws a UserItem. If there's a custom routine, this will
- // call it with a uic_Draw command. If the custom routine returns true,
- // then the routine handled all of the drawing. If it returns false,
- // then this routine does the default drawing.
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_DrawItem(word hiti,word hitn)
- {
- boolean handled,centered;
- char *text;
- word w,h;
- int picup,picdown;
- Rect r;
- UserItem *ip;
- ip = &TheItems[hiti][hitn];
- if (ip->custom)
- handled = ip->custom(uic_Draw,hiti,hitn);
- else
- handled = false;
- if (!handled)
- {
- picup = ip->picup;
- picdown = ip->picdown;
- switch (ip->type)
- {
- case uii_CheckBox:
- px = ip->r.lr.x + 8;
- py = ip->r.ul.y + 8;
- text = ip->text;
- centered = false;
- break;
- case uii_KeyCap:
- if (!(ip->sel & ui_Selected))
- {
- text = ip->text;
- if (text)
- {
- r = ip->r;
- centered = true;
- }
- }
- else
- text = nil;
- break;
- default:
- text = nil;
- break;
- }
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,
- (ip->sel & ui_Selected)? picdown : picup);
- if (text)
- {
- if (centered)
- USL_PrintInCenter(text,r);
- else
- {
- USL_MeasureString(text,&w,&h);
- VWB_Bar(px,py,w + 7,h,WHITE);
- USL_DrawString(text);
- }
- }
- if (ip->sel & ui_Disabled)
- {
- if ((picup == CTL_D_LOADUPPIC) || (picup == CTL_D_SAVEUPPIC))
- VWB_DrawMPic(ip->r.ul.x,ip->r.ul.y,CTL_LSMASKPICM);
- else
- VWB_DrawMPic(ip->r.ul.x,ip->r.ul.y,CTL_LITTLEMASKPICM);
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_DoHit() - Handles a hit on a UserItem. If there's a custom routine,
- // it will be called. If it returns true, then don't do anything
- // more. If it returns false, then use the standard behaviour
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_DoHit(word hiti,word hitn)
- {
- boolean handled;
- word i;
- UserItem *ip;
- ip = &TheItems[hiti][hitn];
- if (ip->custom)
- handled = ip->custom(uic_Hit,hiti,hitn);
- else
- handled = false;
- if (!handled)
- {
- if (TheItems[hiti][hitn].sel & ui_Disabled)
- {
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("This Item is Disabled");
- fontcolor = F_BLACK;
- return;
- }
- FlushHelp = true;
- switch (ip->type)
- {
- case uii_Button:
- // Must have a custom routine to handle hits - this just redraws
- ip->sel ^= ui_Selected;
- USL_DrawItem(hiti,hitn);
- case uii_CheckBox:
- ip->sel ^= ui_Selected;
- USL_DrawItem(hiti,hitn);
- break;
- case uii_RadioButton:
- for (i = 0,ip = TheItems[hiti];ip->type != uii_Bad;i++,ip++)
- {
- if
- (
- (i != hitn)
- && (ip->type == uii_RadioButton)
- && (ip->sel & ui_Selected)
- )
- {
- ip->sel &= ~ui_Selected;
- USL_DrawItem(hiti,i);
- }
- }
- TheItems[hiti][hitn].sel |= ui_Selected;
- USL_DrawItem(hiti,hitn);
- break;
- case uii_KeyCap:
- break;
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_IsInRect() - Checks to see if the coordinates given are within any
- // of the Rects in the UserItem list. If so, returns true & sets the
- // index & number for lookup. If not, returns false.
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_IsInRect(word x,word y,word *index,word *number)
- {
- UserItem *item,**items;
- items = TheItems;
- *index = 0;
- while (*items)
- {
- item = *items;
- *number = 0;
- while (item->type != uii_Bad)
- {
- if
- (
- (x >= item->r.ul.x)
- && (x < item->r.lr.x)
- && (y >= item->r.ul.y)
- && (y < item->r.lr.y)
- )
- return(true);
- (*number)++;
- item++;
- }
- (*index)++;
- items++;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_TrackItem() - Tracks the given item. If the cursor is inside of the
- // item, it's redrawn as down. If the cursor is outside, the item is
- // drawn in its original state. Returns true if the button was released
- // while the cursor was inside the item, or false if it wasn't.
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_TrackItem(word hiti,word hitn)
- {
- boolean inside,last;
- word ini,inn,
- on,
- sel,othersel;
- UserItem *ip,*op;
- ip = &TheItems[hiti][hitn];
- sel = ip->sel;
- if (ip->type == uii_RadioButton)
- {
- inside = false;
- for (op = TheItems[hiti],on = 0;op->type != uii_Bad;op++,on++)
- {
- if (op->sel & ui_Selected)
- {
- inside = true;
- break;
- }
- }
- if (!inside)
- op = ip;
- othersel = op->sel;
- }
- else
- op = nil;
- if (ip->sel & ui_Disabled)
- {
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("This item is disabled");
- fontcolor = F_BLACK;
- while (US_UpdateCursor())
- VW_UpdateScreen();
- FlushHelp = true;
- return(false);
- }
- last = false;
- do
- {
- USL_IsInRect(CursorX,CursorY,&ini,&inn);
- inside = (ini == hiti) && (inn == hitn);
- if (inside != last)
- {
- if (inside)
- {
- if (op)
- {
- op->sel &= ~ui_Selected;
- ip->sel |= ui_Selected;
- }
- else
- ip->sel = sel ^ ui_Selected;
- }
- else
- {
- if (op && (op != ip))
- {
- op->sel |= ui_Selected;
- ip->sel &= ~ui_Selected;
- }
- else
- ip->sel = sel;
- }
- USL_DrawItem(hiti,hitn);
- if (op && (op != ip))
- USL_DrawItem(hiti,on);
- last = inside;
- }
- VW_UpdateScreen();
- } while (US_UpdateCursor());
- if (op)
- op->sel = othersel;
- ip->sel = sel;
- if (!inside)
- {
- if (op && (op != ip))
- USL_DrawItem(hiti,on);
- USL_DrawItem(hiti,hitn);
- VW_UpdateScreen();
- }
- return(inside);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_GlideCursor() - Smoothly moves the cursor to the given location
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_GlideCursor(long newx,long newy)
- {
- word steps;
- long x,y,
- dx,dy;
- if (grmode == CGAGR)
- steps = 1;
- else
- steps = 8;
- x = (long)CursorX << 16;
- dx = ((newx << 16) - x) / steps;
- y = (long)CursorY << 16;
- dy = ((newy << 16) - y) / steps;
- while ((CursorX != newx) || (CursorY != newy))
- {
- x += dx;
- y += dy;
- CursorX = x >> 16;
- CursorY = y >> 16;
- VW_MoveCursor(CursorX,CursorY);
- VW_UpdateScreen();
- }
- CursorBad = true;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_FindRect() - Code so ugly you'll puke! Given a Rect and direction,
- // this routine will try to find a UserItem to move the cursor to
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_FindRect(Rect r,Motion xd,Motion yd)
- {
- word i,i1,i2,i3;
- Motion m1,m2;
- Point diffs[9],diff,*dp;
- Rect *rp,*good,*goods[9];
- UserItem *ip,**items;
- for (m1 = motion_Up,dp = diffs;m1 <= motion_Down;m1++)
- {
- for (m2 = motion_Left;m2 <= motion_Right;m2++,dp++)
- {
- dp->x = m2 * 1024;
- dp->y = m1 * 1024;
- }
- }
- for (i = 0;i < 9;i++)
- goods[i] = nil;
- // Find out which octants all of the rects (except r) are in
- for (items = TheItems;*items;items++)
- {
- for (ip = *items;ip->type != uii_Bad;ip++)
- {
- rp = &ip->r;
- diff.x = rp->ul.x - r.ul.x;
- diff.y = rp->ul.y - r.ul.y;
- if (!(diff.x || diff.y))
- continue;
- if // 1,4,7
- (
- ((rp->ul.x >= r.ul.x) && (rp->ul.x < r.lr.x))
- || ((rp->lr.x > r.ul.x) && (rp->lr.x <= r.lr.x))
- )
- {
- if (rp->lr.y <= r.ul.y)
- {
- if (!(goods[1] && (diff.y < diffs[1].y)))
- {
- goods[1] = rp;
- diffs[1] = diff;
- }
- }
- else if (rp->ul.y >= r.lr.y)
- {
- if (!(goods[7] && (diff.y > diffs[7].y)))
- {
- goods[7] = rp;
- diffs[7] = diff;
- }
- }
- }
- if // 3,4,5
- (
- ((rp->ul.y >= r.ul.y) && (rp->ul.y < r.lr.y))
- || ((rp->lr.y > r.ul.y) && (rp->lr.y <= r.lr.y))
- )
- {
- if (rp->lr.x <= r.ul.x)
- {
- if (!(goods[3] && (diff.x < diffs[3].x)))
- {
- goods[3] = rp;
- diffs[3] = diff;
- }
- }
- else if (rp->ul.x >= r.lr.x)
- {
- if (!(goods[5] && (diff.x > diffs[5].x)))
- {
- goods[5] = rp;
- diffs[5] = diff;
- }
- }
- }
- if (rp->ul.x < r.ul.x) // 0,6
- {
- if (rp->lr.y <= r.ul.y)
- {
- if
- (
- (!goods[0])
- || (diff.y > diffs[0].y)
- || (diff.x > diffs[6].x)
- )
- {
- goods[0] = rp;
- diffs[0] = diff;
- }
- }
- else if (rp->ul.y >= r.lr.y)
- {
- if
- (
- (!goods[6])
- || (diff.y < diffs[6].y)
- || (diff.x > diffs[6].x)
- )
- {
- goods[6] = rp;
- diffs[6] = diff;
- }
- }
- }
- if (rp->lr.x > r.lr.x) // 2,8
- {
- if (rp->lr.y <= r.ul.y)
- {
- if
- (
- (!goods[2])
- || (diff.y > diffs[2].y)
- || (diff.x < diffs[2].x)
- )
- {
- goods[2] = rp;
- diffs[2] = diff;
- }
- }
- else if (rp->ul.y >= r.lr.y)
- {
- if
- (
- (!goods[8])
- || (diff.y < diffs[8].y)
- || (diff.x < diffs[8].x)
- )
- {
- goods[8] = rp;
- diffs[8] = diff;
- }
- }
- }
- }
- }
- switch (yd)
- {
- case motion_Up:
- i1 = 1,i2 = 0,i3 = 2;
- break;
- case motion_None:
- switch (xd)
- {
- case motion_Left:
- i1 = 3,i2 = 0,i3 = 6;
- break;
- case motion_Right:
- i1 = 5,i2 = 8,i3 = 2;
- break;
- }
- break;
- case motion_Down:
- i1 = 7,i2 = 8,i3 = 6;
- break;
- }
- (
- (good = goods[i1])
- || (good = goods[i2])
- || (good = goods[i3])
- || (good = &r)
- );
- #if 0
- CursorX = good->lr.x - 8;
- CursorY = good->lr.y - 8;
- CursorBad = true;
- US_UpdateCursor();
- #endif
- USL_GlideCursor(good->lr.x - 8,good->lr.y - 8);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlButtonCustom() - The custom routine for all of the Control Panel
- // (leftmost) buttons. Clears all of the other item lists, clears the
- // large area, and draws the line dividing the top and bottom areas.
- // Then it sets up and draws the appropriate top row of icons.
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlButtonCustom(UserCall call,word i,word n)
- {
- word j;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- if (n == CtlPanelButton)
- return(true);
- US_ClearWindow();
- for (j = 8;j < 38;j++)
- {
- VWB_DrawTile8M(j * 8,6 * 8,10);
- VWB_DrawTile8M(j * 8,21 * 8,10);
- }
- VWB_DrawTile8M(7 * 8,6 * 8,9);
- VWB_DrawTile8M(38 * 8,6 * 8,11);
- VWB_DrawTile8M(7 * 8,21 * 8,9);
- VWB_DrawTile8M(38 * 8,21 * 8,11);
- for (j = 1;j < 4;j++)
- TheItems[j] = nil;
- // Set to new button
- CtlPanelButton = n;
- // Draw new items
- TheItems[1] = ip = CtlPanels2[CtlPanelButton];
- j = 0;
- while (ip && (ip->type != uii_Bad))
- {
- USL_DrawItem(i + 1,j);
- if (ip->sel & ui_Selected)
- USL_DoHit(i + 1,j);
- j++;
- ip++;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlCKbdButtonCustom() - The custom routine for the keyboard keycaps.
- // This routine gets a scancode and puts it in the appropriate
- // KbdDefs[0] member.
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlCKbdButtonCustom(UserCall call,word i,word n)
- {
- boolean state;
- word j;
- ScanCode scan;
- longword time;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- ip = &TheItems[i][n];
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp(ip->help);
- fontcolor = F_BLACK;
- VW_HideCursor();
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,ip->picdown);
- VW_UpdateScreen();
- LastScan = sc_None;
- time = TimeCount;
- state = true;
- do
- {
- if (TimeCount - time > 35) // Half-second delays
- {
- state ^= true;
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,state? ip->picdown : ip->picup);
- VW_UpdateScreen();
- time = TimeCount;
- }
- if (US_UpdateCursor())
- {
- while (US_UpdateCursor())
- ;
- scan = sc_Escape;
- break;
- }
- asm pushf
- asm cli
- if (LastScan == sc_LShift)
- LastScan = sc_None;
- asm popf
- } while (!(scan = LastScan));
- IN_ClearKey(scan);
- if (scan != sc_Escape)
- {
- for (j = 0,state = false;j < 10;j++)
- {
- if (j == n)
- continue;
- if (*(KeyMaps[j]) == scan)
- {
- state = true;
- break;
- }
- }
- if (state)
- {
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("That Key is Already Used!");
- fontcolor = F_BLACK;
- }
- else
- {
- ip->text = IN_GetScanName(scan);
- *(KeyMaps[n]) = scan;
- FlushHelp = true;
- }
- }
- USL_DrawItem(i,n);
- VW_ShowCursor();
- VW_UpdateScreen();
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlCJoyButtonCustom() - The custom button routine for joystick
- // calibration
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlCJoyButtonCustom(UserCall call,word i,word n)
- {
- word joy,
- minx,maxx,
- miny,maxy;
- i++,n++; // Shut the compiler up
- if (call != uic_Hit)
- return(false);
- IN_ClearKeysDown();
- joy = USL_FindDown(CtlCPanels) - 1;
- VW_HideCursor();
- FlushHelp = true;
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("Move Joystick to the Upper-Left");
- VW_UpdateScreen();
- while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joy))
- ;
- if (LastScan != sc_Escape)
- {
- IN_GetJoyAbs(joy,&minx,&miny);
- while (IN_GetJoyButtonsDB(joy))
- ;
- USL_ShowHelp("Move Joystick to the Lower-Right");
- VW_UpdateScreen();
- while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joy))
- ;
- if (LastScan != sc_Escape)
- {
- IN_GetJoyAbs(0,&maxx,&maxy);
- IN_SetupJoy(joy,minx,maxx,miny,maxy);
- }
- }
- if (LastScan != sc_Escape)
- while (IN_GetJoyButtonsDB(joy))
- ;
- if (LastScan)
- IN_ClearKeysDown();
- fontcolor = F_BLACK;
- VW_ShowCursor();
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_ClearBottom() - Clears the bottom part of the window
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_ClearBottom(void)
- {
- WindowRec wr;
- US_SaveWindow(&wr);
- US_RestoreWindow(&BottomWindow);
- US_ClearWindow();
- US_RestoreWindow(&wr);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_FormatHelp() - Formats helptext. Runs through and calculates the
- // number of lines, and the offset for the start of each line. Stops
- // after len bytes or when it hits a tilde ('~'). Munges the text.
- //
- ///////////////////////////////////////////////////////////////////////////
- static word
- USL_FormatHelp(char far *text,long len)
- {
- word line,
- w,h,
- far *off;
- char c,
- far *s,far *l,far *le;
- WindowX += 4;
- WindowW -= 4;
- MM_GetPtr(&LineOffsets,MaxHelpLines * sizeof(word));
- off = (word far *)LineOffsets;
- for (line = 0,le = l = s = text;(s - text < len) && (*s != '~');s++)
- {
- if ((c = *s) == '\n')
- {
- *s = '\0';
- *off++ = l - text; // Save offset of start of line
- line++; // Bump line number
- le = l = s + 1; // Set start of line ptr
- }
- if (c == '\r')
- c = *s = ' ';
- if // Strip orphaned spaces
- (
- (c == ' ')
- && (s == l)
- && (*(s - 1) == '\0')
- && (*(s + 1) != ' ')
- && (s > text)
- )
- le = l = s + 1;
- else if (c == ' ')
- {
- *s = '\0';
- USL_MeasureString(l,&w,&h);
- if (w >= WindowW) // If string width exceeds window,
- {
- *s = c; // Replace null char with proper char
- *le = '\0'; // Go back to last line end
- *off++ = l - text; // Save offset of start of line
- line++; // Bump line number
- l = s = le + 1; // Start next time through after last line end
- }
- else
- {
- *s = c; // Width still ok - put char back
- le = s; // And save ptr to last ok end of word
- }
- }
- }
- WindowX -= 4;
- WindowW += 4;
- return(line);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_DrawHelp() - Draws helptext in the current window
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_DrawHelp(char far *text,word start,word end,word line,word h,word far *lp)
- {
- px = WindowX + 4;
- py = WindowY + (line * h);
- for (lp += start;start < end;start++,px = WindowX + 4,py += h)
- USL_DrawString(text + *lp++);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_DoHelp() - Formats and displays the specified help
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_DoHelp(memptr text,long len)
- {
- boolean done,
- moved;
- int scroll;
- word i,
- pixdiv,
- w,h,
- lines,cur,page,
- top,num,loc,
- far *lp,
- base,srcbase,destbase;
- ScanCode waitkey;
- longword lasttime;
- WindowRec wr;
- CursorInfo info;
- USL_ShowHelp("Arrow Keys Move / Escape Exits");
- fontcolor = F_BLACK;
- US_SaveWindow(&wr);
- US_RestoreWindow(&BottomWindow);
- US_ClearWindow();
- VW_HideCursor();
- VW_UpdateScreen();
- lines = USL_FormatHelp((char far *)text,len);
- USL_MeasureString("",&w,&h);
- page = WindowH / h;
- cur = 0;
- lp = LineOffsets;
- IN_ClearKeysDown();
- moved = true;
- lasttime = 0;
- scroll = 0;
- done = false;
- waitkey = sc_None;
- while (!done)
- {
- if (moved)
- {
- while (TimeCount - lasttime < 5)
- ;
- lasttime = TimeCount;
- if (scroll == -1)
- {
- top = cur;
- num = 1;
- loc = 0;
- }
- else if (scroll == +1)
- {
- num = 1;
- loc = page - 1;
- top = cur + loc;
- }
- else
- {
- top = cur;
- num = (page < lines)? page : lines;
- loc = 0;
- }
- if (scroll)
- {
- if (grmode == CGAGR)
- {
- pixdiv = 4;
- base = bufferofs + panadjust + (WindowX / pixdiv);
- }
- else if (grmode == EGAGR)
- {
- VWB_Bar(WindowX,WindowY + (loc * h),WindowW,num * h,WHITE);
- USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);
- pixdiv = 8;
- base = displayofs + panadjust + (WindowX / pixdiv);
- }
- else if (grmode == VGAGR)
- pixdiv = 1;
- if (scroll == 1)
- {
- srcbase = base + ylookup[WindowY + h];
- destbase = base + ylookup[WindowY];
- if (grmode == EGAGR)
- {
- EGAWRITEMODE(1);
- VW_WaitVBL(1);
- }
- VW_ScreenToScreen(srcbase,destbase,WindowW / pixdiv,
- WindowH - h);
- }
- else
- {
- i = WindowY + (h * (page - 1));
- srcbase = base + ylookup[i - h];
- destbase = base + ylookup[i];
- base = ylookup[h];
- for (i = page - 1;i;i--,srcbase -= base,destbase -= base)
- VW_ScreenToScreen(srcbase,destbase,WindowW / pixdiv,h);
- }
- if (grmode == CGAGR)
- {
- VWB_Bar(WindowX,WindowY + (loc * h),WindowW,num * h,WHITE);
- USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);
- VW_UpdateScreen();
- }
- else if (grmode == EGAGR)
- {
- base = panadjust + (WindowX / pixdiv) +
- ylookup[WindowY + (loc * h)];
- VW_ScreenToScreen(base + bufferofs,base + displayofs,
- WindowW / pixdiv,h);
- }
- }
- else
- {
- US_ClearWindow();
- USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);
- VW_UpdateScreen();
- }
- moved = false;
- scroll = 0;
- }
- if (waitkey)
- while (IN_KeyDown(waitkey))
- ;
- waitkey = sc_None;
- IN_ReadCursor(&info);
- if (info.y < 0)
- {
- if (cur > 0)
- {
- scroll = -1;
- cur--;
- moved = true;
- }
- }
- else if (info.y > 0)
- {
- if (cur + page < lines)
- {
- scroll = +1;
- cur++;
- moved = true;
- }
- }
- else if (info.button0 || info.button1)
- done = true;
- else if (IN_KeyDown(LastScan))
- {
- switch (LastScan)
- {
- case sc_Escape:
- done = true;
- break;
- case sc_UpArrow:
- if (cur > 0)
- {
- scroll = -1;
- cur--;
- moved = true;
- }
- break;
- case sc_DownArrow:
- if (cur + page < lines)
- {
- scroll = +1;
- cur++;
- moved = true;
- }
- break;
- case sc_PgUp:
- if (cur > page)
- cur -= page;
- else
- cur = 0;
- moved = true;
- waitkey = sc_PgUp;
- break;
- case sc_PgDn:
- if (cur + page < lines)
- {
- cur += page;
- if (cur + page >= lines)
- cur = lines - page;
- moved = true;
- }
- waitkey = sc_PgDn;
- break;
- }
- }
- }
- IN_ClearKeysDown();
- do
- {
- IN_ReadCursor(&info);
- } while (info.button0 || info.button1);
- VW_ShowCursor();
- US_ClearWindow();
- VW_UpdateScreen();
- US_RestoreWindow(&wr);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlHButtonCustom() - The custom routine for all of the help buttons
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlHButtonCustom(UserCall call,word i,word n)
- {
- word j;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- ip = &TheItems[i][n];
- if (ip->sel & ui_Disabled)
- return(false);
- ip->sel |= ui_Selected;
- USL_DrawItem(i,n);
- USL_ClearBottom();
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("Loading & Formatting Text...");
- VW_UpdateScreen();
- #ifdef HELPTEXTLINKED // Ugly hack because of lack of disk space...
- {
- extern char far gametext,far context,far story;
- char far *buf;
- memptr dupe;
- switch (n)
- {
- case 0:
- buf = &gametext;
- break;
- case 1:
- buf = &context;
- break;
- case 2:
- buf = &story;
- break;
- }
- MM_GetPtr(&dupe,5000);
- _fmemcpy((char far *)dupe,buf,5000);
- USL_DoHelp(dupe,5000);
- MM_FreePtr(&dupe);
- if (LineOffsets)
- MM_FreePtr(&LineOffsets);
- }
- #else
- {
- char *name;
- int file;
- long len;
- memptr buf;
- switch (n)
- {
- case 0:
- name = "GAMETEXT."EXTENSION;
- break;
- case 1:
- name = "CONTEXT."EXTENSION;
- break;
- case 2:
- name = "STORY."EXTENSION;
- break;
- default:
- Quit("Bad help button number");
- }
- if ((file = open(name,O_RDONLY | O_TEXT)) == -1)
- USL_HandleError(errno);
- else
- {
- len = filelength(file);
- MM_GetPtr(&buf,len);
- if (CA_FarRead(file,(byte far *)buf,len))
- USL_DoHelp(buf,len);
- else
- USL_HandleError(errno);
- close(file);
- MM_FreePtr(&buf);
- }
- if (LineOffsets)
- MM_FreePtr(&LineOffsets);
- }
- #endif
- fontcolor = F_BLACK;
- ip->sel &= ~ui_Selected;
- USL_DrawItem(i,n);
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlDButtonCustom() - The custom routine for all of the disk buttons.
- // Sets up the bottom area of the window with the appropriate buttons
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlDButtonCustom(UserCall call,word i,word n)
- {
- word j;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- ip = &TheItems[i][n];
- if (ip->sel & ui_Disabled)
- return(false);
- USL_ClearBottom();
- j = 0;
- TheItems[i + 1] = ip = n? CtlDEPanels : CtlDLSPanels;
- while (ip && (ip->type != uii_Bad))
- {
- USL_DrawItem(i + 1,j++);
- ip++;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_DLSRect() - Draw the rectangle for the save game names
- //
- ///////////////////////////////////////////////////////////////////////////
- static Rect
- USL_DLSRect(UserItem *ip)
- {
- Rect r;
- r.ul.x = ip->r.lr.x + 40 + 2;
- r.ul.y = ip->r.ul.y + 2;
- r.lr.x = WindowX + WindowW - 8 - 2;
- r.lr.y = ip->r.lr.y - 2;
- VWB_Bar(r.ul.x,r.ul.y,r.lr.x - r.ul.x,r.lr.y - r.ul.y,WHITE);
- VWB_Hlin(r.ul.x,r.lr.x,r.ul.y,BLACK);
- VWB_Hlin(r.ul.x,r.lr.x,r.lr.y,BLACK);
- VWB_Vlin(r.ul.y,r.lr.y,r.ul.x,BLACK);
- VWB_Vlin(r.ul.y,r.lr.y,r.lr.x,BLACK);
- px = r.ul.x + 2;
- py = r.ul.y + 2;
- return(r);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlDLButtonCustom() - The load game custom routine
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlDLButtonCustom(UserCall call,word i,word n)
- {
- char *filename,
- msg[MaxGameName + 12];
- word err;
- int file;
- UserItem *ip;
- SaveGame *game;
- WindowRec wr;
- // DEBUG - deal with warning user about loading a game causing abort
- game = &Games[n / 2];
- ip = &TheItems[i][n];
- switch (call)
- {
- case uic_Draw:
- if (!loadedgame)
- {
- USL_DLSRect(ip);
- fontcolor = game->present? F_BLACK : F_FIRSTCOLOR;
- USL_DrawString(game->present? game->name : "Empty");
- fontcolor = F_BLACK;
- }
- break;
- case uic_Hit:
- if (ip->sel & ui_Disabled)
- return(false);
- LeaveDriveOn++;
- filename = USL_GiveSaveName(n / 2);
- US_SaveWindow(&wr);
- US_CenterWindow(30,3);
- strcpy(msg,"Loading `");
- strcat(msg,game->name);
- strcat(msg,"\'");
- US_PrintCentered(msg);
- VW_HideCursor();
- VW_UpdateScreen();
- err = 0;
- if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
- {
- if (read(file,game,sizeof(*game)) == sizeof(*game))
- {
- if (USL_LoadGame)
- if (!USL_LoadGame(file))
- USL_HandleError(err = errno);
- }
- else
- USL_HandleError(err = errno);
- close(file);
- }
- else
- USL_HandleError(err = errno);
- if (err)
- abortgame = true;
- else
- loadedgame = true;
- game->present = true;
- if (loadedgame)
- Paused = true;
- VW_ShowCursor();
- US_RestoreWindow(&wr);
- LeaveDriveOn--;
- break;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlDSButtonCustom() - The save game custom routine
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlDSButtonCustom(UserCall call,word i,word n)
- {
- boolean ok;
- char *filename;
- word err;
- int file;
- Rect r;
- UserItem *ip;
- SaveGame *game;
- WindowRec wr;
- if (call != uic_Hit)
- return(false);
- game = &Games[n / 2];
- ip = &TheItems[i][n];
- if (ip->sel & ui_Disabled)
- return(false);
- FlushHelp = true;
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("Enter Game Name / Escape Aborts");
- fontcolor = F_BLACK;
- r = USL_DLSRect(ip - 1);
- ok = US_LineInput(px,py,game->name,game->present? game->name : nil,true,
- MaxGameName,r.lr.x - r.ul.x - 8);
- if (!strlen(game->name))
- strcpy(game->name,"Untitled");
- if (ok)
- {
- US_SaveWindow(&wr);
- US_CenterWindow(10,3);
- US_PrintCentered("Saving");
- VW_HideCursor();
- VW_UpdateScreen();
- LeaveDriveOn++;
- filename = USL_GiveSaveName(n / 2);
- err = 0;
- file = open(filename,O_CREAT | O_BINARY | O_WRONLY,
- S_IREAD | S_IWRITE | S_IFREG);
- if (file != -1)
- {
- if (write(file,game,sizeof(*game)) == sizeof(*game))
- {
- if (USL_SaveGame)
- ok = USL_SaveGame(file);
- if (!ok)
- USL_HandleError(err = errno);
- }
- else
- USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));
- close(file);
- }
- else
- USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));
- if (err)
- {
- remove(filename);
- ok = false;
- }
- LeaveDriveOn--;
- VW_ShowCursor();
- US_RestoreWindow(&wr);
- USL_DoHit(i - 1,0);
- VW_UpdateScreen();
- }
- if (!game->present)
- game->present = ok;
- if (ok)
- {
- GameIsDirty = false;
- (ip - 1)->sel &= ~ui_Disabled;
- }
- USL_DrawItem(i,n - 1);
- // USL_CtlDLButtonCustom(uic_Draw,i,n - 1);
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlSButtonCustom() - The custom routine for all of the sound buttons
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlSButtonCustom(UserCall call,word i,word n)
- {
- word j;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- ip = &TheItems[i][n];
- if (ip->sel & ui_Disabled)
- return(false);
- USL_ClearBottom();
- if (n == sdm_SoundSource)
- {
- j = 0;
- TheItems[i + 1] = ip = CtlSSSPanels;
- while (ip && (ip->type != uii_Bad))
- {
- USL_DrawItem(i + 1,j++);
- ip++;
- }
- }
- else
- TheItems[i + 1] = nil;
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlPButtonCustom() - The custom routine for all of the start game btns
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlPButtonCustom(UserCall call,word i,word n)
- {
- word j;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- ip = &TheItems[i][n];
- if (ip->sel & ui_Disabled)
- return(false);
- USL_ClearBottom();
- j = 0;
- TheItems[i + 1] = ip = n? CtlPRPanels : CtlPSPanels;
- while (ip && (ip->type != uii_Bad))
- {
- USL_DrawItem(i + 1,j++);
- ip++;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_GiveAbortWarning() - Draws a string that warns the user that an
- // action they're about to take will abort the game in progress
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_GiveAbortWarning(void)
- {
- WindowRec wr;
- if (!GameIsDirty)
- return;
- US_SaveWindow(&wr);
- US_RestoreWindow(&BottomWindow);
- US_HomeWindow();
- PrintY += 5;
- VWB_Bar(WindowX,WindowY,WindowW,30,WHITE);
- fontcolor = F_SECONDCOLOR;
- US_CPrint("Warning! If you do this, you'll");
- US_CPrint("abort the current game.");
- fontcolor = F_BLACK;
- US_RestoreWindow(&wr);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlPSButtonCustom() - The custom routine for the start game button
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlPSButtonCustom(UserCall call,word i,word n)
- {
- boolean result;
- UserItem *ip;
- i++; // Shut the compiler up
- switch (call)
- {
- case uic_Hit:
- switch (n)
- {
- case 0:
- restartgame = gd_Normal;
- break;
- case 1:
- restartgame = gd_Easy;
- break;
- case 2:
- restartgame = gd_Hard;
- break;
- }
- if (restartgame && ingame && USL_ResetGame)
- USL_ResetGame();
- result = false;
- break;
- case uic_Draw:
- USL_GiveAbortWarning();
- result = false;
- break;
- default:
- result = false;
- break;
- }
- return(result);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlPRButtonCustom() - The custom routine for the resume game button
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlPRButtonCustom(UserCall call,word i,word n)
- {
- if (call != uic_Hit)
- return(false);
- i++,n++; // Shut the compiler up
- ResumeGame = true;
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlDEButtonCustom() - The custom routine for the exit to DOS button
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlDEButtonCustom(UserCall call,word i,word n)
- {
- boolean result;
- UserItem *ip;
- i++,n++; // Shut the compiler up
- switch (call)
- {
- case uic_Hit:
- QuitToDos = true;
- break;
- case uic_Draw:
- USL_GiveAbortWarning();
- default:
- result = false;
- break;
- }
- return(result);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CtlCButtonCustom() - The custom routine for all of the control
- // buttons
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CtlCButtonCustom(UserCall call,word i,word n)
- {
- word j;
- Point p;
- UserItem *ip;
- if (call != uic_Hit)
- return(false);
- ip = &TheItems[i][n];
- if (ip->sel & ui_Disabled)
- return(false);
- USL_ClearBottom();
- if (n == 0) // Keyboard
- {
- TheItems[i + 1] = ip = CtlCKbdPanels;
- p = CtlCKbdPanels[2].r.lr;
- VWB_DrawPic(p.x,p.y,CTL_DIRSPIC);
- }
- else
- TheItems[i + 1] = ip = CtlCJoyPanels;
- j = 0;
- while (ip && (ip->type != uii_Bad))
- {
- USL_DrawItem(i + 1,j++);
- ip++;
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_HitHotKey() - After a hotkey was hit, move the cursor to the first
- // selected item in the group after the group containing the item
- // holding the hotkey
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_HitHotKey(int i,int n)
- {
- UserItem *ip;
- if (ip = TheItems[++i])
- {
- if ((n = USL_FindDown(TheItems[i])) == -1)
- n = 0;
- ip += n;
- CursorX = ip->r.lr.x - 8;
- CursorY = ip->r.lr.y - 8;
- CursorBad = true;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_CheckScan() - Checks to see if the scancode in LastScan corresponds
- // to anything in the list of useritems. If so, selects the item.
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- USL_CheckScan(word *ci,word *cn)
- {
- word i,n;
- UserItem *ip;
- if (!LastScan)
- return(false);
- #if 1 // DEBUG - probably kill this code
- // Use 1..? for the items across the top row
- if (TheItems[1] && !IN_KeyDown(sc_RShift))
- {
- for (i = 0,ip = TheItems[1];(ip->type != uii_Bad) && (i < 9);i++,ip++)
- ;
- for (n = 0;n < i;n++)
- {
- if (LastScan == 2 + n) // Numbers from 1..9
- {
- if (!(TheItems[1][n].sel & ui_Disabled))
- {
- LastScan = sc_None;
- USL_DoHit(1,n);
- return(true);
- }
- }
- }
- }
- // Use Alt-1..6 for the items in the leftmost column
- if (IN_KeyDown(sc_RShift))
- {
- n = LastScan - 2;
- if (n < 6) // Numbers from 1..6
- {
- USL_DoHit(0,n);
- LastScan = sc_None;
- return(true);
- }
- }
- #endif
- // Check normal hotkeys for the leftmost column
- for (i = 0;CtlPanels[i].type != uii_Bad;i++)
- {
- if (CtlPanels[i].key == LastScan)
- {
- LastScan = sc_None;
- USL_DoHit(0,i);
- *ci = 0;
- *cn = i;
- USL_HitHotKey(0,i);
- return(true);
- }
- }
- // Check normal hotkeys for the top row
- for (i = 0;i < 6;i++)
- {
- for (n = 0,ip = CtlPanels2[i];ip && ip->type != uii_Bad;n++,ip++)
- {
- if ((ip->key == LastScan) && !(ip->sel & ui_Disabled))
- {
- LastScan = sc_None;
- USL_DoHit(0,i);
- USL_DoHit(1,n);
- *ci = 1;
- *cn = n;
- USL_HitHotKey(1,n);
- return(true);
- }
- }
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_SetUpCtlPanel() - Sets the states of the UserItems to reflect the
- // values of all the appropriate variables
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_SetUpCtlPanel(void)
- {
- word i,j;
- GameIsDirty = ingame;
- // Set up restart game
- USL_TurnOff(CtlPPanels);
- CtlPPanels[0].sel = ingame? ui_Normal : ui_Selected;
- CtlPPanels[1].sel = ingame? ui_Selected : ui_Disabled;
- // Set up disk stuff - default to load/save game
- USL_TurnOff(CtlDPanels);
- CtlDPanels[0].sel = ui_Selected;
- // Set up load/save buttons
- USL_TurnOff(CtlDLSPanels);
- for (i = 0;i < MaxSaveGames;i++)
- {
- if (!Games[i].present)
- CtlDLSPanels[i * 2].sel = ui_Disabled;
- if (!ingame)
- CtlDLSPanels[(i * 2) + 1].sel = ui_Disabled;
- }
- // Set up Controls
- USL_TurnOff(CtlCPanels);
- CtlCPanels[1].sel = JoysPresent[0]? ui_Normal : ui_Disabled;
- CtlCPanels[2].sel = JoysPresent[1]? ui_Normal : ui_Disabled;
- if (Controls[0] == ctrl_Keyboard)
- i = 0;
- else
- i = (Controls[0] == ctrl_Joystick1)? 1 : 2;
- CtlCPanels[i].sel |= ui_Selected;
- if (JoysPresent[1] && !JoysPresent[0])
- CtlCPanels[2].key = sc_F4;
- else
- CtlCPanels[1].key = sc_F4;
- // Set up Keyboard
- for (i = 0;i < 10;i++)
- CtlCKbdPanels[i].text = IN_GetScanName(*(KeyMaps[i]));
- // Set up Sounds
- USL_TurnOff(CtlSPanels);
- CtlSPanels[sdm_AdLib].sel = AdLibPresent? ui_Normal : ui_Disabled;
- #if 0 // DEBUG - hack because no space for digitized sounds on Keen Dreams
- CtlSPanels[sdm_SoundBlaster].sel =
- SoundBlasterPresent? ui_Normal : ui_Disabled;
- CtlSPanels[sdm_SoundSource].sel =
- SoundSourcePresent? ui_Normal : ui_Disabled;
- #else
- CtlSPanels[sdm_SoundBlaster].sel = ui_Disabled;
- CtlSPanels[sdm_SoundSource].sel = ui_Disabled;
- #endif
- CtlSPanels[SoundMode].sel |= ui_Selected;
- // Set up SoundSource
- USL_TurnOff(CtlSSSPanels);
- CtlSSSPanels[0].sel = ssIsTandy? ui_Selected : ui_Normal;
- CtlSSSPanels[1].sel = (ssPort == 2)? ui_Selected : ui_Normal;
- // Set up Music
- USL_TurnOff(CtlMPanels);
- CtlMPanels[smm_AdLib].sel = AdLibPresent? ui_Normal : ui_Disabled;
- CtlMPanels[MusicMode].sel |= ui_Selected;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // USL_TearDownCtlPanel() - Given the state of the control panel, sets the
- // modes and values as appropriate
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- USL_TearDownCtlPanel(void)
- {
- int i;
- i = USL_FindDown(CtlCPanels);
- if (i != -1)
- {
- i = i? (i == 1? ctrl_Joystick1 : ctrl_Joystick2) : ctrl_Keyboard;
- IN_SetControlType(0,i);
- }
- CtlCPanels[1].key = CtlCPanels[2].key = sc_None;
- i = USL_FindDown(CtlSPanels);
- if (i != -1)
- SD_SetSoundMode(i);
- ssIsTandy = CtlSSSPanels[0].sel & ui_Selected;
- ssPort = (CtlSSSPanels[1].sel & ui_Selected)? 2 : 1;
- i = USL_FindDown(CtlMPanels);
- if (i != -1)
- {
- SD_SetMusicMode(i);
- if (!QuitToDos)
- {
- US_CenterWindow(20,8);
- US_CPrint("Loading");
- #if 0
- fontcolor = F_SECONDCOLOR;
- US_CPrint("Sounds");
- fontcolor = F_BLACK;
- #endif
- VW_UpdateScreen();
- CA_LoadAllSounds();
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_ControlPanel() - This is the main routine for the control panel
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_ControlPanel(void)
- {
- char gamename[MaxGameName + 10 + 1];
- ScanCode c;
- boolean done,
- buttondown,inrect;
- word hiti,hitn,
- i,n,
- lasti,lastn,
- lastx,lasty;
- longword lasttime;
- Point p;
- Rect userect;
- UserItem *ip;
- c = LastScan;
- if (c == sc_Escape) // Map escape from game to Exit to DOS
- c = sc_Q;
- CA_UpLevel();
- for (i = CONTROLS_LUMP_START;i <= CONTROLS_LUMP_END;i++)
- CA_MarkGrChunk(i);
- CA_MarkGrChunk(CTL_LITTLEMASKPICM);
- CA_MarkGrChunk(CTL_LSMASKPICM);
- CA_CacheMarks("Options Screen");
- USL_SetUpCtlPanel();
- US_SetPrintRoutines(VW_MeasurePropString,VWB_DrawPropString);
- fontcolor = F_BLACK;
- VW_InitDoubleBuffer();
- VWB_Bar(0,0,MaxX,MaxY,FIRSTCOLOR);
- US_DrawWindow(8,22,30,2);
- US_SaveWindow(&HelpWindow);
- US_DrawWindow(8,7,30,14);
- US_SaveWindow(&BottomWindow);
- US_DrawWindow(8,1,30,20);
- for (ip = CtlPanels;ip->type != uii_Bad;ip++)
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,ip->picup);
- US_StartCursor();
- CursorX = (8 * 8) + ((MaxX - (8 * 8)) / 2);
- CursorBad = true;
- CtlPanelButton = -1;
- LastScan = c;
- USL_CheckScan(&i,&n);
- if (CtlPanelButton == -1)
- USL_DoHit(0,0);
- ResumeGame = false;
- done = false;
- FlushHelp = true;
- lastx = lasty = -1;
- while
- (
- (restartgame == gd_Continue)
- && !(done || loadedgame || ResumeGame)
- )
- {
- VW_UpdateScreen();
- buttondown = US_UpdateCursor();
- inrect = USL_IsInRect(CursorX,CursorY,&i,&n);
- if (FlushHelp)
- {
- lasti = -2;
- lasttime = TimeCount;
- FlushHelp = false;
- }
- if (inrect)
- {
- if ((lasti != i) || (lastn != n))
- {
- // If over a Load button
- if
- (
- (CtlPanelButton == 2)
- && (i == 2)
- && (TheItems[1][0].sel & ui_Selected)
- && (Games[n / 2].present)
- && !(n & 1)
- )
- {
- strcpy(gamename,"Load `");
- strcat(gamename,Games[n / 2].name);
- strcat(gamename,"'");
- USL_ShowHelp(gamename);
- }
- else
- USL_ShowHelp(TheItems[i][n].help);
- lasti = i;
- lastn = n;
- }
- }
- else if (lasti != (word)-1)
- {
- USL_ShowHelp("Select a Button");
- lasti = -1;
- }
- hiti = i;
- hitn = n;
- if (inrect)
- userect = TheItems[i][n].r;
- else
- {
- userect.ul.x = CursorX;
- userect.ul.y = CursorY;
- userect.lr = userect.ul;
- }
- if (IN_KeyDown(sc_UpArrow))
- {
- USL_FindRect(userect,motion_None,motion_Up);
- buttondown = false;
- IN_ClearKey(sc_UpArrow);
- }
- else if (IN_KeyDown(sc_DownArrow))
- {
- USL_FindRect(userect,motion_None,motion_Down);
- buttondown = false;
- IN_ClearKey(sc_DownArrow);
- }
- else if (IN_KeyDown(sc_LeftArrow))
- {
- USL_FindRect(userect,motion_Left,motion_None);
- buttondown = false;
- IN_ClearKey(sc_LeftArrow);
- }
- else if (IN_KeyDown(sc_RightArrow))
- {
- USL_FindRect(userect,motion_Right,motion_None);
- buttondown = false;
- IN_ClearKey(sc_RightArrow);
- }
- else if
- (
- IN_KeyDown(c = sc_Return)
- || IN_KeyDown(c = KbdDefs[0].button0)
- || IN_KeyDown(c = KbdDefs[0].button1)
- )
- {
- IN_ClearKey(c);
- if (inrect)
- {
- ip = &TheItems[hiti][hitn];
- if ((ip->type == uii_Button) && !(ip->sel & ui_Disabled))
- {
- lasttime = TimeCount;
- ip->sel |= ui_Selected;
- USL_DrawItem(hiti,hitn);
- VW_UpdateScreen();
- while (TimeCount - lasttime < TickBase / 4)
- ;
- lasttime = TimeCount;
- ip->sel &= ~ui_Selected;
- USL_DrawItem(hiti,hitn);
- VW_UpdateScreen();
- while (TimeCount - lasttime < TickBase / 4)
- ;
- }
- USL_DoHit(hiti,hitn);
- }
- }
- else if (USL_CheckScan(&i,&n))
- ;
- else if (buttondown && inrect && USL_TrackItem(hiti,hitn))
- USL_DoHit(hiti,hitn);
- if (LastScan == sc_Escape)
- {
- IN_ClearKey(sc_Escape);
- done = true;
- }
- if (QuitToDos)
- done = true;
- if ((lastx != CursorX) || (lasty != CursorY))
- {
- lastx = CursorX;
- lasty = CursorY;
- lasttime = TimeCount;
- }
- if (TimeCount - lasttime > TickBase * 10)
- {
- if (((TimeCount - lasttime) / TickBase) & 2)
- fontcolor = F_SECONDCOLOR;
- USL_ShowHelp("Press F1 for Help");
- fontcolor = F_BLACK;
- }
- }
- US_ShutCursor();
- USL_TearDownCtlPanel();
- if (restartgame && USL_ResetGame)
- USL_ResetGame();
- if (QuitToDos)
- {
- if (tedlevel)
- TEDDeath();
- else
- {
- US_CenterWindow(20,3);
- fontcolor = F_SECONDCOLOR;
- US_PrintCentered("Now Exiting to DOS...");
- fontcolor = F_BLACK;
- VW_UpdateScreen();
- Quit(nil);
- }
- }
- CA_DownLevel();
- }
- // High score routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_DisplayHighScores() - Assumes that double buffering has been started.
- // If passed a -1 will just display the high scores, but if passed
- // a non-negative number will display that entry in red and let the
- // user type in a name
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_DisplayHighScores(int which)
- {
- char buffer[16],*str;
- word i,
- w,h,
- x,y;
- HighScore *s;
- US_CenterWindow(30,MaxScores + (MaxScores / 2));
- x = WindowX + (WindowW / 2);
- US_Print(" Name");
- PrintX = x + 20;
- US_Print("Score");
- PrintX = x + 60;
- US_Print("Done\n\n");
- PrintY -= 3;
- for (i = WindowX;i < WindowX + WindowW;i += 8)
- VWB_DrawTile8M(i,WindowY + 8,10);
- VWB_DrawTile8M(WindowX - 8,WindowY + 8,9);
- VWB_DrawTile8M(WindowX + WindowW,WindowY + 8,11);
- for (i = 0,s = Scores;i < MaxScores;i++,s++)
- {
- fontcolor = (i == which)? F_SECONDCOLOR : F_BLACK;
- if (i != which)
- {
- US_Print(" ");
- if (strlen(s->name))
- US_Print(s->name);
- else
- US_Print("-");
- }
- else
- y = PrintY;
- PrintX = x + (7 * 8);
- ultoa(s->score,buffer,10);
- for (str = buffer;*str;str++)
- *str = *str + (129 - '0'); // Used fixed-width numbers (129...)
- USL_MeasureString(buffer,&w,&h);
- PrintX -= w;
- US_Print(buffer);
- PrintX = x + 60;
- if (s->completed)
- US_PrintUnsigned(s->completed);
- else
- US_Print("-");
- US_Print("\n");
- }
- if (which != -1)
- {
- fontcolor = F_SECONDCOLOR;
- PrintY = y;
- PrintX = WindowX;
- US_Print(" ");
- strcpy(Scores[which].name,"");
- US_LineInput(PrintX,PrintY,Scores[which].name,nil,true,MaxHighName,
- (WindowW / 2) - 8);
- }
- fontcolor = F_BLACK;
- VW_UpdateScreen();
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // US_CheckHighScore() - Checks gamestate to see if the just-ended game
- // should be entered in the high score list. If so, lets the user
- // enter their name
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- US_CheckHighScore(long score,word other)
- {
- word i,j,
- n;
- HighScore myscore;
- strcpy(myscore.name,"");
- myscore.score = score;
- myscore.completed = other;
- for (i = 0,n = -1;i < MaxScores;i++)
- {
- if
- (
- (myscore.score > Scores[i].score)
- || (
- (myscore.score == Scores[i].score)
- && (myscore.completed > Scores[i].completed)
- )
- )
- {
- for (j = MaxScores;--j > i;)
- Scores[j] = Scores[j - 1];
- Scores[i] = myscore;
- n = i;
- HighScoresDirty = true;
- break;
- }
- }
- VW_InitDoubleBuffer();
- VWB_Bar(0,0,MaxX,MaxY,FIRSTCOLOR);
- US_DisplayHighScores(n);
- IN_UserInput(5 * TickBase,false);
- }
|