12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // 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
- //
- // GameEdit.cpp
- // Project: Nostril (aka Postal)
- //
- // This module impliments the game editor.
- //
- // History:
- // 12/18/96 MJR Started.
- //
- // 01/14/97 BRH Added CDoofus and CTkachuk keys to the editor
- //
- // 01/17/97 BRH Added CRocketMan key to the editor
- //
- // 01/21/97 JMI Converted from rspGetKey() and rspGetMouseEvent() to
- // RInputEvent API (rspGetNextInputEvent() ).
- //
- // 01/21/97 JMI Added Realm Bar GUI and Object Picker GUI.
- // Now open and save realm invoke file system dialogs
- // to browse.
- //
- // 01/22/97 JMI Now requests that you save before doing anything that
- // might be detremental(sp!) to the current level (e.g., New,
- // Close, etc.).
- //
- // 01/22/97 JMI PlayRealm() now saves and loads the current level in
- // TEMP_FILE_NAME.
- //
- // 01/22/97 JMI The object picker list box now only adds items that are
- // user creatable in the editor (as indicated by
- // CThing::ms_aClassInfo[ID].bEditorCreatable.
- //
- // 01/22/97 MJR Added use of realm's time object. Also, it now uses a
- // separate realm object in the play loop so as to avoid any
- // possible interference between it and the editor's realm.
- //
- // 01/23/97 JMI Fixed 'assing' comment because we definitely wouldn't
- // want the word 'assing' appearing in our code anywhere.
- // Who's the assinine jack ass for a dumb ass that wrote
- // 'assing' in the first place anyway?! What an asswipe.
- // Now you are only asked if you want to save before an op
- // that destroys the current realm if that realm contains
- // anything.
- // Now hots for individual GUIs are called independently in
- // the editor.
- //
- // 01/23/97 JMI Now when you click an item in the list box, the item is
- // created, the EditNew() is called, and then the item can
- // be moved to the drop spot.
- //
- // 01/23/97 JMI Now shows the system cursor when not placing an object.
- //
- // 01/24/97 JMI Can now adjust display size with Numpad + and -. Always
- // restores display size when exiting editor to the original
- // size (when entered editor).
- // External effects: g_pimScreenBuf.
- //
- // 01/24/97 JMI Now PlayRealm() also supports the adjustment of the display
- // area. Also, cursor no longer does height cursor's drag
- // logic unless in drop dude mode.
- //
- // 01/25/97 JMI Added scrollbars to edit mode.
- //
- // 01/26/97 JMI Forgot to update scrollbars in PlayRealm().
- //
- // 01/26/97 JMI Added selection. This required creating a root RHot for
- // the Hood and a child RHot for each of the other CThings.
- //
- // 01/27/97 JMI Now you can double click an existing item to move it,
- // hit enter while it is selected to modify it, or hit
- // delete while it is selected to delete it.
- //
- // 01/27/97 JMI Now if you delete the item with the selection and then try
- // to move it, it doesn't crash. A technological breakthrough
- // enabled this by collapsing ms_p*Move into ms_p*Sel and
- // adding an ms_sMoving flag.
- //
- // 01/28/97 JMI Now you can toggle layers on and off using the layers list-
- // box.
- //
- // 01/29/97 JMI Quickly changed UI...will update cleaner later...just need
- // to get this to Bill so he can do cool Buoy stuff.
- //
- // 01/29/97 BRH Added ability to link Bouys. It draws the link between
- // two bouy's that you are attempting to link. Also added
- // a CNavigationNet pointer to the editor to keep track
- // of the currently selected NavNet to which new Bouys
- // are added. Will need to add a GUI item to let the user
- // select the 'current' NavNet when you have more than one.
- // Also still need to add the function to display the lines
- // between all bouys once the network is linked together.
- //
- // 01/30/97 JMI Now when you open/load or new a realm, the size affected
- // stuff is updated via a call to SizeUpdate().
- //
- // 01/30/97 BRH Added key 'B' as a toggle for showing the bouy lines.
- // Added a set of bouy lines to the editor which can be
- // added to when a new line is drawn or completely set
- // up with all bouy lines by calling UpdateNetLines.
- // Now I need the CThing unique ID numbers so that when
- // bouys are reloaded, they will know what CNavigationNet
- // to relink themselves to.
- //
- // 01/30/97 JMI Now the editor assigns a realm unique ID to every item it
- // creates.
- //
- // 01/31/97 JMI If CreateNewThing() failed to create a new CBuoy b/c there
- // was no current NavNet, it returned success. Now it returns
- // failure.
- //
- // 02/02/97 JMI If a CThing derived class has an EditHotSpot() defined, the
- // editor will be able to smoothly drag the thing. If it does
- // not have this function, the cursor will jump when a drag
- // is started.
- // Also, made cursor aware of the height on the attribute map.
- // Also, made the distinction between an editor hotbox event
- // and another event.
- //
- // 02/03/97 JMI Moved all input in editor loop into DoInput() and all output
- // in editor loop to DoOutput(). This makes it a little easier
- // to figure out what's going on, but DoInput() is still rather
- // large (mainly due to the two switch statements).
- //
- // 02/03/97 JMI Can track a particular CThing during PlayRealm(). To track
- // a CThing, hold down shift and then click the thing. There
- // should be a beep signifying the item was set as the tracked
- // thing. Hit 'T' in PlayRealm() mode to toggle tracking mode
- // vs. scrollbar mode.
- //
- // 02/03/97 JMI Now loads GUIs and cursor images via
- // FullPath(GAME_PATH_VD, "...") and uses temp path
- // FullPath(GAME_PATH_HD, "...") for realms in PlayRealm().
- // In PlayRealm(), the grip is now reset when switching from
- // scrollbar to track target mode.
- //
- // 02/04/97 JMI Changed LoadDib() call to Load() (which now supports
- // loading of DIBs).
- //
- // 02/04/97 JMI SizeUpdate() was directly accessing members of CHood. Now
- // calls CHood.GetWidth(),GetHeight() instead.
- //
- // 02/04/97 JMI You can now change the game's priority level via the keys
- // '1', '2', & '3' where '1' is the highest priority and
- // '3' is lowest.
- //
- // 02/05/97 BRH NewRealm now automatically creates a NavNet for the realm
- // right after it creates a Hood. Many objects depend on the
- // NavNet object being in place before they are added so
- // the editor now creates one by default.
- //
- // 02/05/97 JMI The toggle of layers is now stimulated by the actual list-
- // box item, rather than the "Toggle Button" which I will
- // remove from the LAYERS.GUI after checking this in.
- //
- // 02/06/97 BRH Checked for CBouy and CNavigationNet when deleting things
- // in the editor. You may not delete the last remaining
- // NavNet. If you delete a Bouy, it will unlink the bouy from
- // its network first and update the lines if necessary. If
- // you delete a NavNet, it will delete all of its bouys.
- //
- // 02/07/97 JMI Added use of new CGameEditThing.
- //
- // 02/12/97 JMI Added pause feature in PlayRealm(). Also, added keys for
- // speeding up, slowing down, and normalizing game time, but
- // have not implemented that yet b/c it requires a change to
- // CTime.
- //
- // 02/12/97 JMI Temp fix until GetMaxHeight() returns *4 value (or the *4
- // an app thing?). Also, fixed bug where I was getting the
- // height via the cursor's screen pos (not the cursor's world
- // pos).
- //
- // 02/13/97 JMI Now the editor sets the Camera's Hood. This fixed the prob
- // the grip was having finding the realm limits and allows us
- // to utilize the newest scene which gets its alpha stuff from
- // the hood passed to it by the camera. The camera's connect-
- // ed to the realm bone, ... .
- //
- // 02/13/97 JMI In the previous update, the camera's hood was being set
- // after the load realm, but too late. Now it's set earlier.
- // Since before, it was never set, it was never a problem b/c
- // the camera's hood was NULL.
- //
- // 02/13/97 JMI On the second entrance to GameEdit(), ms_pcameraCur was
- // already pointing at an old deleted camera.
- // Also, I guess the camera and realm were not being delete'd
- // in GameEdit().
- //
- // 02/14/97 JMI SizeUpdate() now makes sure the camera's hood is up to
- // date.
- // 02/17/97 JMI Now checks rspGetQuitStatus().
- //
- // 02/19/97 JMI PlayRealm() now checks for camera tracking object
- // iteratively.
- //
- // 02/20/97 JMI Now uses input interface for user input.
- //
- // 02/21/97 JMI Now makes sure scrollbars don't have focus in PlayRealm().
- // Also, makes all CDudes X-Rayable.
- //
- // 02/22/97 JMI Now SetDisplayArea() only changes the display device
- // settings if g_GameSettings.m_sUseCurrentDeviceDimensions
- // is FALSE.
- //
- // 02/22/97 JMI Now sets working dir to levels dir when entering editor.
- //
- // 02/24/97 JMI CloseRealm() now purges g_resmgrGame.
- //
- // 02/25/97 JMI CloseRealm() now also purges prealm->m_resmgr.
- // Also, CloseRealm() now clears ms_pcameraCur's hood ptr
- // and calls SizeUpdate().
- //
- // 02/25/97 JMI Resized viewable area and repositioned GUIs into non-
- // viewable areas.
- // Also, added SetCameraArea() function which will resize the
- // device mode and the display area such that the camera area
- // will be the specified size.
- //
- // 02/28/97 JMI Added satellite cameras. No current way to resize them
- // though. That kinda sux. But they're there.
- //
- // 03/03/97 JMI Now cameras work in PlayRealm() mode.
- // Also, now, on entry to GameEdit(), stores device settings
- // and uses them in restoring the display area on exit.
- // Previously, only the display area was restored with the
- // device mode as returned by rspSuggestVideoMode().
- //
- // 03/05/97 JMI Dude now commits suicide when user exits PlayRealm().
- // CreateNewThing() now uses CThing::ConstructWithID() to
- // create new things.
- //
- // 03/06/97 JMI PlayRealm() now sends a suicide message to the local dude
- // instead of setting his state.
- //
- // 03/06/97 BRH Added NetLog() function for debugging NavNet links. Prints
- // out a text file of connected bouys.
- //
- // 03/09/97 JMI Added GUIs bar for showing/hiding GUIs, NavNets listbox,
- // and Map GUI.
- // Also, CloseRealm() now clears ms_pgething.
- //
- // 03/10/97 JMI Now using correct rspBlitT scale version so map actually
- // gets blit (but transparent for color 0 (which it should
- // not contain)).
- //
- // 03/10/97 JMI Now you can click on the map to move the main camera to the
- // clicked area.
- //
- // 03/10/97 BRH Added a route table printout to NetLog function to verify
- // that the routing tables are correct.
- //
- // 03/13/97 BRH Made a change to the route table printout.
- //
- // 03/13/97 JMI Now calls CDude::DrawStatus() for the local dude.
- //
- // 03/17/97 JMI Now scrolls the view if a dragged item is on or beyond an
- // edge.
- // Also, now cancels current drag in CloseRealm() and before
- // calling PlayRealm().
- //
- // 03/19/97 JMI Added flag indicating the view should not be scrolled while
- // dragging/moving a CThing. This is utilized when a CThing
- // is first created from the CThing pick list so it doesn't
- // cause immediate scrolling. It is re-enabled as soon as the
- // thing is dragged into the view, destroyed, or placed.
- // Also, now the view will start scrolling within
- // DRAG_SCROLL_BUFFER pixels of any view edge.
- //
- // 03/19/97 JMI Switched to the new input event hotbox callback for thing
- // hotboxes.
- //
- // 03/19/97 BRH Made sure network line draw is turned off when the current
- // realm is closed so that lines don't show up on the next
- // realm and it doesn't crash when you quit the editor with
- // lines turned on.
- //
- // 03/24/97 JMI PlayRealm() now passes a ptr to the realm to GetLocalInput.
- //
- // 03/25/97 JMI Changed CURSOR_BASE_IMAGE_FILE, CURSOR_TIP_IMAGE_FILE, and
- // PICK_OBJECT_FILE to 8.3 compliant names.
- //
- // 03/27/97 JMI ThingHotCall now makes sure the event it processes has not
- // yet been used. Also, you may no longer drag the hood.
- //
- // 03/28/97 JMI Now the scrollbar tray and button clicks will advance more
- // than just a few pixels.
- // Now, if there is no current camera focus, it is set to the
- // first CDude created.
- //
- // 03/28/97 JMI Fixed exit button. Also my last change made change had
- // caused the Hood hotbox to parent itself which caused hosed
- // behavior. Fixed.
- //
- // 03/28/97 JMI Now resets directory back to original when done.
- //
- // 04/03/97 JMI Main dude's status is now displayed below the view (instead
- // of on it).
- //
- // 04/04/97 JMI ms_sbVert and ms_sbHorz are now smooth scrollers.
- //
- // 04/10/97 BRH Updated this to work with the new multi layer attribute
- // maps using the helper functions.
- //
- // 04/11/97 JMI Changed GetLocalInput() to take the RInputEvent.
- //
- // 04/16/97 BRH Added an #ifdef REALM_NONSTL for testing the new
- // non-stl lists for the CThings in the realm. References
- // to either method are available by changing the
- // REALM_NONSTRL macro in realm.h
- //
- // 04/17/97 BRH Fixed a bug in the new list code where it wasn't
- // advancing the list pointer at the end of the loop, cauing
- // an infinite loop.
- //
- // 04/17/97 BRH Changed call to Startup and Shutdown in realm, changed
- // calls in this file from 1 parameter to 0 parameters.
- //
- // 04/21/97 JMI Menu is now activated by escape key.
- //
- // 04/21/97 BRH Bouys are now linked by right clicking on the bouy, or
- // on the Mac, hold down open-apple & click to connect
- // bouy lines. Double click on a bouy now brings up
- // its EditModify dialog box.
- //
- // 04/22/97 JMI No longer uses chdir() to get the open dialog into the
- // correct directory. Now we simply default ms_szFileName
- // to the path of the dir we want to save under.
- //
- // 04/22/97 JMI Removed #include <direct.h>.
- //
- // 04/29/97 JMI Added key motivated new item placement.
- //
- // 05/01/97 JMI Added ability to create regions to be associated with
- // pylons. These regions are saved with the .RLM with the
- // same name except the .RLM is changed to .RGN.
- // To edit a pylon's region, double right click it, use left
- // and right mouse buttons to paint, Num pad + and - to
- // control brush size, and Escape to end trigger region paint
- // mode.
- // Also, added focus next and prev.
- // Also, made enlarge/reduce screen during PlayRealm() update
- // the CDude's status area.
- //
- // 05/02/97 JMI Now, while editing a pylon's trigger region, it is drawn
- // with a game sprite so we can have alpha so you can see
- // what you're drawing on.
- //
- // 05/02/97 JMI Changed number of pylons trigger regions to 256 b/c I didn't
- // want to bother adding 1 in all the special locations.
- //
- // 05/04/97 BRH Removed #ifdef sections referring to STL lists.
- //
- // 05/09/97 JMI Assigned pylon instance IDs into ms_argns[].u16InstanceId
- // so the multigrid for pylon triggers can contain a mapping
- // from pylon ID to instance ID.
- //
- // 05/12/97 JRD Added the creation of the Trigger Attribute map into the
- // save realm process.
- //
- // 05/15/97 JMI Added a common SaveRealm(char*) that does all the stuff
- // necessary to save the realm and triggers so that the
- // PlayRealm() gets everything done that would happen normally.
- //
- // 05/23/97 BRH Added support for NavNets in the editor's list box.
- // Added code for button callbacks to switch the current
- // Nav Net, and to remove them from the list when they are
- // deleted.
- //
- // 05/25/97 JMI Holding down CONTROL, ALT, and/or SHIFT provides different
- // variations on the amount pylon regions are moved by arrow
- // keys.
- //
- // 05/26/97 JMI If you hold down CONTROL while hitting DEL, the editor will
- // delete all objects of the type of the currently selected
- // objects.
- //
- // 05/29/97 JMI Removed references to m_pRealm->m_pAttribMap which no longer
- // exists.
- //
- // 06/07/97 JMI Now, in PlayRealm(), if no dude exists, we attempt to use
- // CWarp::WarpInAnywhere() to create one. This will fail, if
- // there are no warps in the specified realm.
- // Changed message for CTRL-DEL group deletes as per
- // humiliation.
- // Added realm status info to PlayRealm().
- //
- // 06/09/97 JMI Now generates a unique temp filename for PlayRealm() that
- // is generated at least in part by the current OS.
- //
- // 06/11/97 MJR If mouse is enabled (via InputSettings) then the mouse
- // cursor is now hidden and then restored while playing
- // the realm.
- //
- // 06/12/97 JMI Commented out use of rspSetDoSystemMode() in PlayRealm().
- //
- // 06/16/97 JMI Now passes destination buffer in StartMenu() call.
- //
- // 06/16/97 JMI Added copy/paste.
- //
- // 06/16/97 JMI PlayRealm() now calls the realm's hood's SetPalette().
- // It also clears the key status array.
- //
- // 06/17/97 JMI Converted all occurrences of rand() to GetRand() and
- // srand() to SeedRand().
- //
- // 06/26/97 JMI Now enables RMix's autopump feature during the PlayRealm()
- // and disables it before exiting.
- //
- // 06/26/97 JMI DrawCursor() now uses the realm's Map3Dto2D().
- //
- // 06/26/97 JMI Now editor's cursor is fully 3D and there are two functions
- // for mapping between screen & realm coords
- // (MapScreen2Realm() and Maprealm2Screen() ).
- //
- // 06/30/97 JMI Converted to use new m_pLayers member of CScene (was using
- // m_layers).
- //
- // MJR Replaced SAFE_GUI_REF with new GuiItem.h-defined macro.
- //
- // JMI Now all bouy lines are mapped through Maprealm2Screen()
- // before being drawn.
- //
- // 07/03/97 JMI Converted calls to rspOpen/SaveBox() to new parm
- // conventions.
- //
- // 07/05/97 JMI Now you can clear the current camera focus thing by
- // SHIFT-Left-clicking on the hood.
- //
- // 07/05/97 MJR Changed to RSP_BLACK_INDEX instead of 0.
- //
- // 07/07/97 JMI Added extremely CHEEZY thing that checks for an active
- // input settings menu and, if so, calls EditInputSettings().
- //
- // 07/07/97 JMI Now SetCameraArea() sets the display area based on user
- // settings from g_GameSettings. Also, SetDisplayArea()
- // always updates these settings when the user changes the
- // display area.
- //
- // 07/07/97 BRH Added processing for the properties button on the Realm
- // bar which calls the realm's EditModify function to put
- // up its properties dialog box for the realm.
- //
- // MJR Added regular plus and minus in addition to numpad versions
- // for changing display size.
- //
- // 07/10/97 JMI Now you cannot select an item in the 'PickObj' list when
- // you are dragging an item.
- //
- // 07/14/97 JMI Now there is a place to put exceptions to what can be
- // copied (via Copy/Paste). Currently, you cannot copy
- // Bouys, Pylons, NavNets, and Hoods.
- //
- // 07/15/97 JMI Now you can display the attributes with a green mist over
- // the hood by checking boxes in 'View Attributes'. You can
- // also use NUMPAD_MULTIPLY and NUMPAD_DIVIDE to vary the
- // opacity of this mist.
- //
- // 07/16/97 JMI Can now take snap shots from editor. Also, F3 does auto
- // X ray.
- //
- // 07/18/97 JMI Now updates the sound location with the camera target.
- //
- // 07/18/97 JMI Got rid of bogus immitation PlaySample functions.
- // Now there is one PlaySample() function. Also, you now
- // MUST specify a category and you don't have to specify a
- // SoundInstance ptr to specify a volume.
- //
- // 07/19/97 JMI Now calls InitLocalInput() in PlayRealm() just prior to
- // starting.
- //
- // 07/20/97 JMI Now uses back/foreground callbacks to suspend/resume the
- // realm (PlayRealm() only), adjust CPU hoggage, and make
- // sure the cursor is visible when in the background.
- //
- // 07/20/97 JMI DelThing() was dereferencing the ptr to the object to be
- // deleted after it was cleared by the special cases that
- // don't allow deletion. Fixed.
- //
- // 07/20/97 MJR Added conditional compile to disable save & play.
- // Added use of RFile callback during load to call Update().
- //
- // 07/20/97 JMI Fixed syntax error produced when we added the above
- // conditional compile option.
- //
- // 07/21/97 JMI PlayRealm() now sets the input mode to live via
- // SetInputMode().
- //
- // 07/22/97 JMI Now shows the info for the currently selected thing.
- //
- // 07/22/97 JMI Now PlayRealm() displays the "display info" (FPS, etc.).
- //
- // 07/23/97 JMI Changed EDIT_KEY_TRACKING_TOGGLE to CONTROL T (was T).
- //
- // 07/25/97 BRH Fixed problem of last bouy link causing the editor
- // to crash when the highlight was left active. Also fixed
- // bug that crashed the editor if you hit space bar before
- // loading a hood.
- //
- // 07/25/97 MJR Made separate function to get temp file names and added
- // mac-specific version of that code.
- // Also added message box if there's an error playing the
- // realm.
- //
- // 07/27/97 JMI Now maps pylon trigger regions' initial positions from 3D
- // to 2D viewing plane.
- // Also, added '=' as another option for enlarging the display
- // since most games don't actually require you to hit SHIFT to
- // get the actual '+'.
- // Also, converted movement keys for pylon trigger regions to
- // use the key status array (instead of
- // rspGetNextInputEvent() ).
- // Also, CTRL, ALT, and SHIFT speed ups for movement now speed
- // up draw block sizing.
- //
- // 07/30/97 BRH Changed the toggle bouy key to turn off the bouys in
- // addition to the bouy lines.
- //
- // 07/31/97 JMI Now allows you to turn off clipping to the realm edges
- // via the '?' key so you can scroll off the world looking
- // for lost souls or whatever.
- // Also, added realm statistics activated by 'I' key in both
- // edit and play modes.
- //
- // 07/31/97 BRH Made the hots on the bouys inactive when they are hidden.
- //
- // 07/31/97 JMI Now shows the cursor, if hidden, in ShowRealmStatistics()
- // and restores its show level when done. Also, clears inputs
- // before returning.
- // Also, PlayRealm() Suspend()s the realm before calling
- // ShowRealmStatistics() and Resume()s it afterward.
- //
- // 07/31/97 JMI Changed EDIT_KEY_REALM_STATISTICS to F11 (was 'I') so it
- // wouldn't interfere with typing cheats.
- //
- // 08/01/97 JMI Changed %.2f sprintf format specifiers to %g. It's not as
- // pretty but it's more compact. The problem if the %f is it
- // will put hundreds of 0's after the decimal point if it
- // needs to display a very small number.
- //
- // 08/02/97 JMI Now makes sure the CBouys' show/hidden status is in synch
- // with the ms_bDrawNetwork flag (the flag defaults to false
- // and the bouys default to shown).
- // Also, now does not actiavte bouys' hots when loading a
- // level while ms_bDrawNetwork is false.
- // Also, if a new bouy is created while ms_bDrawNetwork is
- // false, its hot is initially inactive.
- //
- // 08/05/97 BRH Defaulted the bouy network to ON.
- //
- // 08/06/97 JMI Changed instances of InitLocalInput() to ClearLocalInput().
- //
- // 08/07/97 JMI Now PlayRealm() and GameEdit() set the appropriate realm
- // flags so things can know what we're doing.
- //
- // 08/08/97 MJR Moved background/foreground callbacks to game.cpp.
- //
- // 08/08/97 BRH Fixed display of NavNet names in the listbox after loading,
- // also clears them on CloseRealm.
- //
- // 08/09/97 JMI Now shows wait cursor during CRealm::Load() calls.
- //
- // 08/09/97 JMI Added some pretty UNdeluxe, ugly, not-too-useful load/save
- // progress feedback.
- //
- // 08/10/97 JMI Now allows ALT-ENTER to function as EditModify() as well as
- // the original ENTER.
- //
- // 08/10/97 JMI Removed unreferenced local var u32ColorIndex.
- //
- // 08/12/97 JMI No longer sets the realm's progress callback.
- // Also, now passes input events to GetLocalInput() which
- // GetLocalInput() now uses for finding cheat key combos.
- //
- // 08/13/97 JMI No longer attempts to show the attribute map when there
- // is no hood.
- //
- // 08/14/97 JMI Now you can select a thing from the realm stats list to
- // be selected by the editor in 'edit mode' (not edit play
- // mode which could be done later using IDs) which would be
- // cool.
- //
- // 08/16/97 BRH Added the feature that deletes all but the pylons, bouys,
- // soundthings and sound relays on a level so that it is
- // easy to strip a level down to a template. Also fixed a
- // problem with left over bouy lines if you had a level
- // showing bouys and then started a new level, the lines
- // would still be showing on that new level. Now it deletes
- // the bouy lines when a new level is started.
- //
- // 08/17/97 JMI Now unlocks the composite buffer before a video mode change
- // and relocks it again after a video mode change. This
- // occurred in two spots.
- //
- // JMI Now hides the mouse cursor while the menu is up.
- //
- // JMI Now ignores all input when in a menu.
- //
- // JMI Also, disables postal organ option from within the editor.
- //
- // 08/21/97 JMI PlayRealm() now sets the difficulty to the global settings
- // difficulty.
- //
- // 08/21/97 JMI Changed call to Update() to UpdateSystem() and occurrences
- // of rspUpdateDisplay() to UpdateDisplay().
- //
- // 08/22/97 JMI Changed occurrences of UpdateDisplay() back to
- // rspUpdateDisplay(). Now that we are using the lock
- // functions correctly, we don't need them.
- // Also, removed rspLockBuffer() and rspUnlockBuffer() that
- // were used to encapsulate the entire app in a lock.
- // Incorporated correct usage of rspLock/UnlockBuffer().
- //
- // 08/23/97 JMI Now does not save the .rgns when in PlayRealm().
- //
- // 08/25/97 JMI Made the dude show up with the user selected texture.
- //
- // 08/27/97 JMI Changed file counter messages to be very short (no file
- // name) and be in the upper left corner.
- //
- // 08/27/97 JMI Now sets the editor GUIs font back to the editor's pref
- // after ending a menu b/c the menu uses the global RGuiItem
- // RPrint too.
- //
- // 08/27/97 JMI Set video mode was being called while the composite buffer
- // was locked which, perhaps, should not be allowed. Fixed.
- //
- // 08/30/97 JMI Now, if a warp is selected when Play is chosen, PlayRealm()
- // will use that warp. Also, tried to make a generic
- // mechanism for PlayRealm() to utilize the current selection
- // in choosing among multiple things.
- //
- // 09/04/97 JMI If the quit status was non zero, it wasn't calling
- // CloseRealm() before exiting.
- //
- // 09/12/97 MJR Now the entire file doesn't compile when the editor is
- // disabled.
- //
- // 10/15/97 JMI Now LoadRealm() converts the system path returned from
- // rspOpenBox() to a RSPiX path before passing it to
- // CRealm::Load() which then converts it back to system. Even
- // though it was working without this change on the PC, it did
- // not work on the Mac.
- //
- // 10/15/97 JMI Applied above change to PlayRealm() as well.
- //
- // 12/02/97 JMI Now uses gsi.sAlwaysSetHWMode on Win32 platforms to avoid
- // flicker when changing display area without changing video
- // hardware settings.
- //
- // 10/03/99 JMI Fixed pasto in RealmOpProgress() where buffer was unlocked
- // twice rather than being locked and unlocked.
- //
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Features to be added:
- //
- // Add ability for cursor to track the attribute map height. Maybe just a key
- // you hit and it adjust the cursor height to whatever the attribute map says
- // at the current cursor position.
- //
- // Add ability to move screen using cursor keys in play mode. Use key to
- // toggle between that and the ability to track the currently tagged target.
- // When you aren't using keys to move screen, they can be used by the main
- // dude. Need to create a mechanism by which main dude gets keyboard and mouse
- // input indirectly.
- //
- // Add a way to tag any object in the game so the camera will follow it.
- // This might actually require a fundamental CThing change, because there
- // would need to be a standardized method of getting an object's position.
- // CDude's would need to have such a feature, but I don't know if it's worth
- // generalizing this to all CThings.
- //
- // Modify EditNew() and EditModify(), or add an EditRect(), so that we can
- // get a rect that will be used as the basis for the object's hotbox. Maybe
- // EditRect() would be better because it could double as a way for us to track
- // an object! In fact, it HAS to be a separate function because when we load
- // a realm, we need to go through all the objects that were loaded and adding
- // new hotboxes to them, since the hotbox info doesn't get saved. A separate
- // function makes this easy.
- //
- // Once we have a separate EditRect() function, we'd be very tempted not to
- // use RHot anymore, because all we need is a simple list of rects that we
- // scan through for collisions. The main advantage would be that I could
- // impliment a simple method of re-ordering the priorities, which helps when
- // you've got multiple objects in the same area. RHot could be made to do
- // this, but it seems like it would be clumsy.
- //
- // Add psuedo-xray mode to scene so we can see objects when they go behind
- // buildings.
- //
- ////////////////////////////////////////////////////////////////////////////////
- #include "RSPiX.h"
- #include <ctype.h>
- #include <set>
- // This is used to get rid of all trace of the editor code when it's disabled
- #if !defined(EDITOR_DISABLED)
- #include "game.h"
- #include "update.h"
- #include "realm.h"
- #include "camera.h"
- #include "localize.h"
- #include "hood.h"
- #include "bouy.h"
- #include "navnet.h"
- #include "grip.h"
- #include "menus.h"
- #include "SampleMaster.h"
- #include "gameedit.h"
- #include "input.h"
- #include "pylon.h"
- #include "TriggerRgn.h"
- #include "TriggerRegions.h"
- #include "trigger.h"
- #include "dude.h"
- #include "warp.h"
- #include "InputSettingsDlg.h"
- #include "play.h"
- #include "score.h"
- #include "CompileOptions.h"
- ////////////////////////////////////////////////////////////////////////////////
- // Macros/types/etc.
- ////////////////////////////////////////////////////////////////////////////////
- #define EDIT_KEY_LOADREALM 'L'
- #define EDIT_KEY_OPENREALM 'O'
- #define EDIT_KEY_SAVEREALM 'S'
- #define EDIT_KEY_NEWREALM 'N'
- #define EDIT_KEY_TOGGLEBOUY 'B'
- #define EDIT_KEY_PICKOBJECT1 '1'
- #define EDIT_KEY_PICKOBJECT2 '2'
- #define EDIT_KEY_PICKOBJECT3 '3'
- #define EDIT_KEY_PICKOBJECT4 '4'
- #define EDIT_KEY_PICKOBJECT5 '5'
- #define EDIT_KEY_PICKOBJECT6 '6'
- #define EDIT_KEY_EXIT 27
- #define EDIT_KEY_MENU 27
- #define EDIT_KEY_CANCEL 27
- #define EDIT_KEY_PLAY 'P'
- #define EDIT_KEY_SCROLL_L RSP_GK_LEFT
- #define EDIT_KEY_SCROLL_R RSP_GK_RIGHT
- #define EDIT_KEY_SCROLL_U RSP_GK_UP
- #define EDIT_KEY_SCROLL_D RSP_GK_DOWN
- #define EDIT_KEY_ENDPLAY 27
- #define EDIT_KEY_PAUSE RSP_GK_PAUSE
- #define EDIT_KEY_SPEED_UP RSP_GK_NUMPAD_ASTERISK
- #define EDIT_KEY_SPEED_DOWN RSP_GK_NUMPAD_DIVIDE
- #define EDIT_KEY_SPEED_NORMAL RSP_GK_NUMPAD_DECIMAL
- #define EDIT_KEY_MODIFY1 '\r'
- #define EDIT_KEY_MODIFY2 ('\r' | RSP_GKF_ALT)
- #define EDIT_KEY_DELETE RSP_GK_DELETE
- #define EDIT_KEY_DELETE_GROUP (RSP_GK_DELETE | RSP_GKF_CONTROL)
- #define EDIT_KEY_DELETE_MOST (RSP_GKF_CONTROL | 'D')
- #define EDIT_KEY_ENLARGE_DISPLAY1 RSP_GK_NUMPAD_PLUS
- #define EDIT_KEY_ENLARGE_DISPLAY2 '+'
- #define EDIT_KEY_ENLARGE_DISPLAY3 '='
- #define EDIT_KEY_REDUCE_DISPLAY1 RSP_GK_NUMPAD_MINUS
- #define EDIT_KEY_REDUCE_DISPLAY2 '-'
- #define EDIT_KEY_INCREASE_OPACITY RSP_GK_NUMPAD_ASTERISK
- #define EDIT_KEY_DECREASE_OPACITY RSP_GK_NUMPAD_DIVIDE
- #define EDIT_KEY_CAMERA_TRACKING (RSP_GKF_CONTROL | 'T')
- #define EDIT_KEY_SENDTOBACK RSP_SK_CONTROL
- #define EDIT_KEY_SETCAMERATRACK RSP_SK_SHIFT
- #define EDIT_KEY_NEWITEM ' '
- #define EDIT_KEY_NEXTITEM '\t'
- #define EDIT_KEY_PREVITEM (RSP_GKF_SHIFT | '\t')
- #define EDIT_KEY_COPY (RSP_GKF_CONTROL | 'C')
- #define EDIT_KEY_CUT (RSP_GKF_CONTROL | 'X')
- #define EDIT_KEY_PASTE (RSP_GKF_CONTROL | 'V')
- #define EDIT_KEY_DOS_COPY (RSP_GKF_CONTROL | RSP_GK_INSERT)
- #define EDIT_KEY_DOS_CUT (RSP_GKF_SHIFT | RSP_GK_DELETE)
- #define EDIT_KEY_DOS_PASTE (RSP_GKF_SHIFT | RSP_GK_INSERT)
- #define EDIT_KEY_TOGGLE_DISP_INFO RSP_GK_F4
- #define EDIT_KEY_SHOW_MISSION RSP_GK_F5
- #define EDIT_KEY_OVERSHOOT_EDGES1 (RSP_GKF_SHIFT | '?')
- #define EDIT_KEY_OVERSHOOT_EDGES2 ('?')
- #define EDIT_KEY_REALM_STATISTICS (RSP_GK_F11)
- // Note that this uses RSP_SK_* macros for use the rspGetKeyStatusArray() key interface.
- #define KEY_XRAY_ALL RSP_SK_F3
- #define KEY_SNAP_PICTURE RSP_SK_ENTER
- #define KEY_ABORT_REALM_OPERATION RSP_SK_ESCAPE
- #define EDIT_SCROLL_AMOUNT 16
- #define CURSOR_BASE_IMAGE_FILE "res/editor/CursBase.bmp"
- #define CURSOR_BASE_HOTX 7
- #define CURSOR_BASE_HOTY 7
- #define CURSOR_TIP_IMAGE_FILE "res/editor/CursTip.bmp"
- #define CURSOR_TIP_HOTX 7
- #define CURSOR_TIP_HOTY 7
- #define DRAG_MIN_X 1
- #define DRAG_MIN_Y 1
- #define DRAG_MIN_TIME 500
- #define CURSOR_NOTHING 0
- #define CURSOR_LEFT_BUTTON_UP 1
- #define CURSOR_LEFT_DOUBLE_CLICK 2
- #define CURSOR_LEFT_DRAG_BEGIN 3
- #define CURSOR_LEFT_DRAG_END 4
- #define CURSOR_RIGHT_BUTTON_UP 5
- #define CURSOR_RIGHT_DOUBLE_CLICK 6
- #define CURSOR_RIGHT_DRAG_BEGIN 7
- #define CURSOR_RIGHT_DRAG_END 8
- #define REALM_BAR_FILE "res/editor/RealmBar.gui"
- #define PICK_OBJECT_FILE "res/editor/PickObj.gui"
- #define LAYERS_GUI_FILE "res/editor/Layers.gui"
- #define CAMERAS_GUI_FILE "res/editor/Cameras.gui"
- #define SHOWATTRIBS_GUI_FILE "res/editor/Attribs.gui"
- #define INFO_GUI_FILE "res/editor/Info.gui"
- #define VIEW_GUI_FILE "res/editor/camera.gui"
- #define REALM_STATISTICS_GUI_FILE "res/editor/stats.gui"
- #define GUIS_FONT_HEIGHT 15
- #define REALM_BAR_X 0
- #define REALM_BAR_Y (g_pimScreenBuf->m_sHeight - DISPLAY_BOTTOM_BORDER)
- #define PICKOBJ_LIST_X (g_pimScreenBuf->m_sWidth - DISPLAY_RIGHT_BORDER)
- #define PICKOBJ_LIST_Y 0
- #define LAYERS_LIST_X (g_pimScreenBuf->m_sWidth - DISPLAY_RIGHT_BORDER)
- #define LAYERS_LIST_Y (ms_pguiPickObj->m_sY + ms_pguiPickObj->m_im.m_sHeight)
- #define CAMERAS_LIST_X (LAYERS_LIST_X)
- #define CAMERAS_LIST_Y (ms_pguiLayers->m_sY + ms_pguiLayers->m_im.m_sHeight)
- #define GUIS_BAR_X 0
- #define GUIS_BAR_Y (ms_pguiRealmBar->m_sY + ms_pguiRealmBar->m_im.m_sHeight)
- #define MAP_X MAX(ms_pguiRealmBar->m_sX + ms_pguiRealmBar->m_im.m_sWidth, \
- ms_pguiGUIs->m_sX + ms_pguiGUIs->m_im.m_sWidth)
- #define MAP_Y (g_pimScreenBuf->m_sHeight - DISPLAY_BOTTOM_BORDER)
- #define NAVNETS_X (g_pimScreenBuf->m_sWidth - DISPLAY_RIGHT_BORDER)
- #define NAVNETS_Y (ms_pguiCameras->m_sY + ms_pguiCameras->m_im.m_sHeight)
- #define SHOWATTRIBS_X 0
- #define SHOWATTRIBS_Y (ms_pguiGUIs->m_sY + ms_pguiGUIs->m_im.m_sHeight)
- #define INFO_X (ms_pguiShowAttribs->m_sX + ms_pguiShowAttribs->m_im.m_sWidth)
- #define INFO_Y SHOWATTRIBS_Y
- #define SCROLL_BAR_THICKNESS 15
- // IDs:
- #define GUI_ID_NEW_REALM 1
- #define GUI_ID_OPEN_REALM 2
- #define GUI_ID_SAVE_REALM 3
- #define GUI_ID_CLOSE_REALM 4
- #define GUI_ID_PLAY_REALM 5
- #define GUI_ID_SAVE_REALM_AS 6
- #define GUI_ID_TOGGLE_LAYER 7
- #define GUI_ID_EXIT 8
- #define GUI_ID_PROPERTIES 23
- #define GUI_ID_NEW_CAMERA 9
- #define GUI_ID_CLOSE_CAMERA 10
- #define GUI_ID_CAMERA_LIST 11
- #define GUI_ID_NAVNET_LIST 11
- #define GUI_ID_REALM_VISIBLE 12
- #define GUI_ID_LAYERS_VISIBLE 13
- #define GUI_ID_THINGS_VISIBLE 14
- #define GUI_ID_CAMERAS_VISIBLE 15
- #define GUI_ID_NAVNETS_VISIBLE 16
- #define GUI_ID_MAP_VISIBLE 17
- #define GUI_ID_MAP_REFRESH 18
- #define GUI_ID_NEW_THING 19
- #define GUI_ID_COPY 20
- #define GUI_ID_CUT 21
- #define GUI_ID_PASTE 22
- #define GUI_ID_PICK_LIST 3
- #define GUI_ID_LAYER_LIST 3
- #define GUI_ID_MAP_ZONE 1
- #define GUI_ID_ATTRIB_LAYERS 100
- #define GUI_ID_ATTRIB_HEIGHT 101
- #define GUI_ID_ATTRIB_NOWALK 102
- #define GUI_ID_ATTRIB_LIGHT 103
- #define GUI_ID_INFO_X_POS 100
- #define GUI_ID_INFO_Y_POS 101
- #define GUI_ID_INFO_Z_POS 102
- #define GUI_ID_REALM_STATISTICS 1000
- // The ID of the item to be selected by default.
- #define DEFAULT_THING_ID CThing::CDudeID
- // Each item added to the Pick Object listbox will have an GUI ID of this plus
- // their class ID (e.g., CDude's list item would be LIST_ITEM_GUI_ID_BASE + CDudeId).
- // Don't define any editor GUI items with GUI IDs above this.
- #define LIST_ITEM_GUI_ID_BASE 0x70000000
- // Determines the number of elements in the passed array at compile time.
- #define NUM_ELEMENTS(a) (sizeof(a) / sizeof(a[0]) )
- // Amount to inc or dec display area when adjusted.
- // Indicate here as inc (i.e., positive).
- #define DISPLAY_SIZE_DELTA_X 20
- #define DISPLAY_SIZE_DELTA_Y 20
- // Amount of bottom border.
- #define DISPLAY_BOTTOM_BORDER 200
- #define DISPLAY_RIGHT_BORDER 100
- // Initial camera viewable area.
- #define INITIAL_CAMERA_X 640
- #define INITIAL_CAMERA_Y 400
- // Front most priority for a hotbox.
- #define FRONTMOST_HOT_PRIORITY -32767
- // The colors used for the selection rectangle surrounding the currently
- // selected CThing.
- #define SELECTION_COLOR1 RSP_BLACK_INDEX
- #define SELECTION_COLOR2 RSP_WHITE_INDEX
- #define SELECTION_THICKNESS 1
- #define GUIS_GUI_FILE "res/editor/GUIs.gui"
- #define MAP_GUI_FILE "res/editor/Map.gui"
- #define NAVNETS_GUI_FILE "res/editor/NavNets.gui"
- #define DISP_INFO_FONT_H 15
- #define DUDE_STATUS_RECT_X 10
- #define DUDE_STATUS_RECT_Y (REALM_STATUS_RECT_Y + REALM_STATUS_RECT_H + 3)
- #define DUDE_STATUS_RECT_W (ms_pcameraCur->m_sViewW - DUDE_STATUS_RECT_X)
- #define DUDE_STATUS_RECT_H (g_GameSettings.m_sDisplayInfo ? (INFO_STATUS_RECT_Y - DUDE_STATUS_RECT_Y) : (g_pimScreenBuf->m_sHeight - DUDE_STATUS_RECT_Y) )// (g_pimScreenBuf->m_sHeight - DUDE_STATUS_RECT_Y)
- #define REALM_STATUS_RECT_X 10
- #define REALM_STATUS_RECT_Y (ms_pcameraCur->m_sFilmViewY + ms_pcameraCur->m_sViewH + 3)
- #define REALM_STATUS_RECT_W (ms_pcameraCur->m_sViewW - REALM_STATUS_RECT_X)
- #define REALM_STATUS_RECT_H (40)
- #define INFO_STATUS_RECT_X 10
- #define INFO_STATUS_RECT_Y (g_pimScreenBuf->m_sHeight - INFO_STATUS_RECT_H)
- #define INFO_STATUS_RECT_W (g_pimScreenBuf->m_sWidth - INFO_STATUS_RECT_X)
- #define INFO_STATUS_RECT_H (DISP_INFO_FONT_H + 1)
- // This value is mutliplied by the amount the cursor is off the edge of the view
- // and the result is used to scroll the view.
- #define EDGE_MOVEMENT_MULTIPLIER 1
- // This value indicates the number of pixels around the edge of the view that
- // imply scrolling while dragging or moving an object.
- #define DRAG_SCROLL_BUFFER 10
- // Amount the scroll bar buttons will scroll.
- #define SCROLL_BTN_INCDEC 10
- // Directory to get *.RLM files from.
- #define INITIAL_REALM_DIR "res/Levels/."
- // Defines the alpha level used when blitting the trigger region currently being
- // editted.
- #define DEF_TRIGGER_RGN_ALPHA_LEVEL 80
- // The alpha level used when showing the attributes.
- #define DEF_ATTRIBUTES_ALPHA_LEVEL 80
- #define TRIGGER_RGN_DRAW_INDEX 250
- #define SHOW_ATTRIBS_DRAW_INDEX 250
- // Initial size for paste buffer.
- #define PASTE_BUFFER_INITIAL_SIZE 1024
- // Amount paste buffer grows as it gets larger.
- #define PASTE_BUFFER_GROW_SIZE 1024
- #define MAX_ALPHA_LEVEL 255
- #define MIN_ALPHA_LEVEL 15
- #define INCDEC_ALPHA_LEVEL 10
- #define MY_RFILE_CALLBACK_INTERVAL 100
- #define PROGRESS_CALLBACK_INTERVAL 100
- #define PROGRESS_X (ms_pcameraCur->m_sFilmViewX + 10)
- #define PROGRESS_Y (ms_pcameraCur->m_sFilmViewY + 30)
- #define PROGRESS_W (ms_pcameraCur->m_sViewW - PROGRESS_X - 10)
- #define PROGRESS_H 10
- #define PROGRESS_COLOR_INDEX 252
- #define PROGRESS_OUTLINE_COLOR_INDEX 249
- // The font for the editor GUIs.
- #define EDITOR_GUI_FONT g_fontBig
- ////////////////////////////////////////////////////////////////////////////////
- // Typedefs/structures
- ////////////////////////////////////////////////////////////////////////////////
- typedef struct TAG_Line
- {
- short sX0;
- short sY0;
- short sX1;
- short sY1;
- bool operator < (const TAG_Line& rhs) const
- {
- if (this->sX0 > rhs.sX0)
- return false;
-
- if (this->sX0 < rhs.sX0)
- return true;
-
- // sX0 is equal at this point
- if (this->sY0 > rhs.sY0)
- return false;
- if (this->sY0 < rhs.sY0)
- return true;
- // sX0 & sY0 are equal at this point
- if (this->sX1 > rhs.sX1)
- return false;
- if (this->sX1 < rhs.sX1)
- return true;
- // sX0 & sY0 & sX1 are equal at this point
- if (this->sY1 > rhs.sY1)
- return false;
- if (this->sY1 < rhs.sY1)
- return true;
- // Else the whole thing is equal
- return false;
- }
- bool operator == (const TAG_Line& rhs) const
- {
- return (this->sX0 == rhs.sX0 &&
- this->sY0 == rhs.sY0 &&
- this->sX1 == rhs.sX1 &&
- this->sY1 == rhs.sY1);
- }
- } LINKLINE;
- #if _MSC_VER >= 1020 || __MWERKS__ >= 0x1100
- #if __MWERKS >= 0x1100
- ITERATOR_TRAITS(const LINKLINE);
- #endif
- typedef set <LINKLINE, less<LINKLINE>, allocator<LINKLINE> > lineset;
- #else
- typedef set <LINKLINE, less<LINKLINE> > lineset;
- #endif
- // Container for a GUI and Camera pair.
- typedef struct
- {
- RGuiItem* pgui;
- RScrollBar* psbVert;
- RScrollBar* psbHorz;
- CCamera cam;
- short sViewW;
- short sViewH;
- } View;
- ////////////////////////////////////////////////////////////////////////////////
- // Variables/data
- ////////////////////////////////////////////////////////////////////////////////
- RImage* m_pimCursorBase;
- RImage* m_pimCursorTip;
- CBouy* m_pBouyLink0;
- CBouy* m_pBouyLink1;
- lineset m_NetLines;
- static bool ms_bDrawNetwork = true;
- // ID of item most recently pressed or 0, if none.
- static long ms_lPressedId = 0;
- // Realm filename. Assuming only one Realm loaded at once.
- static char ms_szFileName[RSP_MAX_PATH] = "";
- static short ms_sMoving = FALSE; // TRUE, if moving/placing a thing (ms_pthingSel).
- static CThing* ms_pthingSel = NULL; // CThing* to thing currently selected.
- static RHot* ms_photSel = NULL; // RHot* to hotbox associated with selected thing.
- // Initial width and height of display so we can
- // restore video mode when done editting.
- static short ms_sInitialDisplayWidth = 0;
- static short ms_sInitialDisplayHeight = 0;
- static short ms_sInitialDeviceDepth = 0;
- static short ms_sInitialDeviceWidth = 0;
- static short ms_sInitialDeviceHeight = 0;
- // The current camera.
- // Scrollbars' callback update camera pointed to by this.
- static CCamera* ms_pcameraCur = NULL;
- // Global GUIs (used in both editing and edit play modes).
- static RScrollBar ms_sbVert;
- static RScrollBar ms_sbHorz;
- // This points to the CHood's hotbox which is the root of all other CThing
- // hotboxes.
- static RHot* ms_photHood = NULL;
- // This is the hotbox priority of the farthest item from the user.
- // Start out as close to front as possible.
- static short ms_sBackPriority = FRONTMOST_HOT_PRIORITY;
- // Made this global (was static in GetCursor()) for temp.
- static short ms_sDragState = 0;
- // Root level GUIs to load from *.gui files.
- static RGuiItem* ms_pguiRealmBar = NULL;
- static RGuiItem* ms_pguiPickObj = NULL;
- static RGuiItem* ms_pguiLayers = NULL;
- static RGuiItem* ms_pguiCameras = NULL;
- static RGuiItem* ms_pguiGUIs = NULL;
- static RGuiItem* ms_pguiMap = NULL;
- static RGuiItem* ms_pguiNavNets = NULL;
- static RGuiItem* ms_pguiShowAttribs = NULL;
- static RGuiItem* ms_pguiInfo = NULL;
- // Child GUIs that need to be frequently accessed.
- static RListBox* ms_plbLayers = NULL;
- static RGuiItem* ms_pguiMapZone = NULL;
- static RGuiItem* ms_pguiInfoXPos = NULL;
- static RGuiItem* ms_pguiInfoYPos = NULL;
- static RGuiItem* ms_pguiInfoZPos = NULL;
- // The current ratio being used for the map.
- static double ms_dMapRatio = 0.0;
- // The current CGameEditThing.
- static CGameEditThing* ms_pgething = NULL;
- // List of cameras and their GUI.
- static RList<View> ms_listViews;
- // If true, scrolling via drag/move of CThing is allowed.
- static bool ms_bDragScroll = true;
- // Trigger regions for pylons.
- static TriggerRgn ms_argns[256];
- // Current pylon being editted.
- static CPylon* ms_pylonEdit = NULL; // NULL for none.
- // Current block size for drawing.
- static short ms_sDrawBlockSize = 5;
- // Sprite used to draw pylon trigger region in the editor.
- static CSprite2 ms_spriteTriggerRgn;
- // Copy/Paste buffer.
- static RFile ms_filePaste;
- // File count used for items in the paste buffer (always decremented so we
- // can guarantee that statics are saved).
- static short ms_sFileCount = -1;
- // Type of item to paste.
- static CThing::ClassIDType ms_idPaste;
- // Sprite used to draw attributes.
- static CSprite2 ms_spriteAttributes;
- // Attribute masks to draw.
- static U16 ms_u16TerrainMask;
- static U16 ms_u16LayerMask;
- // Used by RFile callback function
- static long ms_lRFileCallbackTime;
- static long ms_lFileBytesSoFar;
- static char ms_szFileOpDescriptionFrmt[512];
- static RPrint ms_printFile;
- static short ms_sFileOpTextX;
- static short ms_sFileOpTextY;
- static short ms_sFileOpTextW;
- static short ms_sFileOpTextH;
- // Amount to scroll off edge of realm.
- static long ms_lEdgeOvershoot = 1000;
- ////////////////////////////////////////////////////////////////////////////////
- // Function prototypes
- ////////////////////////////////////////////////////////////////////////////////
- // Do ALL editor input.
- static bool DoInput( // Returns true when done.
- CRealm* prealm, // Ptr to current realm.
- CCamera* pcamera, // Ptr to current camera.
- short* psCursorX, // Out: Cursor X position.
- short* psCursorY, // Out: Cursor Y position.
- short* psCursorZ); // Out: Cursor Z position.
- // Do ALL editor output.
- static void DoOutput( // Returns nothing.
- CRealm* prealm, // Ptr to current realm.
- CCamera* pcamera, // Ptr to current camera.
- short sCursorX, // Cursor X position.
- short sCursorY, // Cursor Y position.
- short sCursorZ); // Cursor Z position.
- static void GetCursor( // Returns nothing.
- RInputEvent* pie, // In: Input event.
- // Out: pie->sUsed = TRUE, if used.
- short* psX, // Out: X coord of event.
- short* psY, // Out: Y coord of event.
- short* psZ, // Out: Z coord of event.
- short* psEvent); // Out: Event type.
- static short InitCursor(
- void);
- static void KillCursor(
- void);
- static void DrawCursor(
- short sCursorX, // In: Cursor hotspot x coord
- short sCursorY, // In: Cursor hotspot y coord
- short sCursorZ, // In: Cursor hotspot z coord
- RImage* pimDst, // In: Image to draw to
- CRealm* prealm, // In: Realm.
- CCamera* pcamera); // In: Camera on prealm.
- static short NewRealm(
- CRealm* prealm);
- static short CloseRealm(
- CRealm* prealm);
- static short LoadRealm(
- CRealm* prealm);
- static short SaveRealm( // Returns 0 on success.
- CRealm* prealm, // In: Realm to save.
- char* pszRealmName, // In: Filename to save as.
- bool bSaveTriggerRegions); // In: Save the trigger regions too.
- static short SaveRealm(
- CRealm* prealm);
- static short SaveRealmAs(
- CRealm* prealm);
- static void PlayRealm( // Returns nothing.
- CRealm* prealm, // In: Realm to play.
- CThing* pthingSel); // In: Currently selected CThing which can
- // be used to give PlayRealm() a hint on which
- // of several things the user wants to use.
- // For example, a selected warp is the used
- // as the warp in point.
- // Create a new CThing derived object of type id in prealm at the specified
- // position.
- static short CreateNewThing( // Returns 0 on success.
- CRealm* prealm, // In: Realm to add new CThing to.
- CThing::ClassIDType id, // ID of new CThing type to create.
- short sPosX, // Position for new CThing.
- short sPosY, // Position for new CThing.
- short sPosZ, // Position for new CThing.
- CThing** ppthing, // Out: Pointer to new thing.
- RHot** pphot, // Out: Pointer to new hotbox for thing.
- RFile* pfile = NULL); // In: Optional file to load from (instead of EditNew()).
- // Move a thing to the specified location and update its RHot with an
- // EditRect() call.
- static void MoveThing( // Returns nothing.
- CThing* pthing, // Thing to move.
- RHot* phot, // Thing's hotbox.
- short sPosX, // New position.
- short sPosY, // New position.
- short sPosZ); // New position.
- // Enlarges the display area.
- static void OnEnlargeDisplay(
- CCamera* pcamera, // Camera to update.
- CRealm* prealm); // Realm to update.
- // Reduces the display area.
- static void OnReduceDisplay(
- CCamera* pcamera, // Camera to update.
- CRealm* prealm); // Realm to update.
- // Set display mode such that display area is as
- // specified.
- static short SetDisplayArea( // Returns 0 on success.
- short sDisplayD, // New depth of display.
- short sDisplayW, // New width of display area.
- short sDisplayH); // New height of display area.
- // Set display mode and display area such that camera view
- // is specified size.
- static short SetCameraArea(void); // Returns 0 on success.
- // Adjust the display area by the specified deltas.
- static short AdjustDisplaySize( // Returns 0 on success.
- short sAdjustX, // Amount to increase width of display area.
- // Can be negative to decrease.
- short sAdjustY, // Amount to increase height of display area.
- // Can be negative to decrease.
- CCamera* pcamera, // Camera to update.
- CRealm* prealm); // Realm to update.
- // Update screen size sensitive objects.
- static short SizeUpdate( // Returns 0 on success.
- CCamera* pcamera, // Camera to update.
- CRealm* prealm); // Realm to update.
- // Resets all RHots including and descended from ms_photHood
- // to FRONTMOST_HOT_PRIORITY.
- static void ResetHotPriorities(void); // Returns nothing.
- // Callback from GUIs. This will set ms_lPressedId to pgui->m_lId.
- static void GuiPressedCall( // Returns nothing.
- RGuiItem* pgui); // GUI item pressed.
- // Callback from pressed list items.
- static void ListItemPressedCall( // Returns nothing.
- RGuiItem* pgui); // GUI item pressed.
- // Callback from scrollbars indicating change in thumb position.
- static void ScrollPosUpdate( // Returns nothing.
- RScrollBar* psb); // ScrollBar that was updated.
- // Callback from RHot when an event occurs within it.
- static void ThingHotCall( // Returns nothing.
- RHot* phot, // Ptr to RHot that generated event.
- RInputEvent* pie); // In: Most recent user input event.
- // Out: Depends on callbacks. Generally,
- // pie->sUsed = TRUE, if used.
- // Draws the rubber band type line while creating bouy links.
- static void DrawBouyLink( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera); // In: View of prealm.
- // AddLine - add the newly drawn line to the set of lines.
- static void AddNewLine(short sX0, short sY0, short sX1, short sY1);
- // Writes out a log of connected bouys. This is for debugging only
- static void NetLog(CNavigationNet* pNavNet);
- // UpdateNetLines - build the full list of link lines from the
- // navigation net. This function can be used after the bouys have
- // been loaded for a realm before the first time the DrawNetwork is
- // called. There may also be a key to refresh the lines. This will
- // also be called when switching the 'current' network
- static void UpdateNetLines(CNavigationNet* pNavNet);
- // Draw network - draw the lines
- static void DrawNetwork( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera); // In: View of prealm.
- // Get the Editor Thing from the specified realm.
- static CGameEditThing* GetEditorThing( // Returns ptr to editor thing for
- // specified realm or NULL.
- CRealm* prealm); // Realm to get editor thing from.
- // Creates a view and adds it to the list of views.
- static short AddView( // Returns 0 on success.
- CRealm* prealm); // In: Realm in which to setup camera.
- // Kills a view and removes it from the list of views.
- static void RemoveView( // Returns nothing.
- View* pview); // In: View to remove or NULL to remove currently
- // selected view.
- // Removes all current views.
- static void RemoveViews(void);
- // Creates a new View and adds it to the list of Views.
- static short CreateView( // Returns 0 on success.
- View** ppview, // Out: New view, if not NULL.
- CRealm* prealm); // In: Realm in which to setup camera.
- // Destroys a View and removes it from the list of Views.
- static void KillView( // Returns nothing.
- View* pview); // View to kill.
- // Draw specified view.
- static void DrawView( // Returns nothing.
- View* pview, // View to draw.
- CRealm* prealm); // Realm to draw.
- // Draw all views.
- static void DrawViews( // Returns nothing.
- CRealm* prealm); // Realm to draw.
- // Clear the specified GUI's area.
- static void ClearGUI( // Returns nothing.
- RGuiItem* pgui); // In: GUI's whose area we should clean.
- // Clear all views.
- static void ClearViews(void); // Returns nothing.
- // Do focus hotbox logic and such for GUIs.
- static void DoView( // Returns nothing.
- View* pview, // View to do.
- RInputEvent* pie); // Input event to process.
- // Do all views.
- static void DoViews( // Returns nothing.
- RInputEvent* pie); // Input event to process.
- // Draw the map.
- static void RefreshMap( // Returns nothing.
- CRealm* prealm); // Realm to map.
- // Cancel any thing drag.
- static void CancelDrag(CRealm* prealm);// Returns nothing.
- // Place any thing being dragged.
- static void DragDrop( // Returns nothing.
- short sDropX, // In: Drop x position.
- short sDropY, // In: Drop y position.
- short sDropZ); // In: Drop z position.
- // Move focus to next item in realm's thing list.
- static void NextItem( // Returns nothing.
- CRealm* prealm); // In: The realm we want the next thing in.
- // Move focus to previous item in realm's thing list.
- static void PrevItem( // Returns nothing.
- CRealm* prealm); // In: The realm we want the next thing in.
- // Load the trigger regions for the specified realm.
- static short LoadTriggerRegions( // Returns 0 on success.
- char* pszRealmName); // In: Name of the REALM (*.RLM) file.
- // The .ext is stripped and .rgn is appended.
- // Save the trigger regions for the specified realm.
- static short SaveTriggerRegions( // Returns 0 on success.
- char* pszRealmName, // In: Name of the REALM (*.RLM) file.
- CRealm* prealm); // The .ext is stripped and .rgn is appended.
- // Create the trigger attribute layer for the realm
- static short CreateTriggerRegions( // Returns 0 on success.
- CRealm* prealm ); // In: Access of Realm Info
- // Change or clear the current pylon being edited.
- static void EditPylonTriggerRegion( // Returns nothing.
- CThing* pthingPylon); // In: Pylon whose trigger area we want to
- // Set the selection to the specified CThing.
- static CThing* SetSel( // Returns CThing that previously was selected.
- CThing* pthingSel, // In: CThing to be selected.
- RHot* photSel); // In: Hotbox of CThing to be selected.
- // Delete the specified item.
- static void DelThing( // Returns nothing.
- CThing* pthingDel, // In: CThing to be deleted.
- RHot* photDel, // In: Hotbox of CThing to be deleted.
- CRealm* prealm); // In: Current realm
- // Delete all the items in the currently selected class.
- static void DelClass( // Returns nothing.
- CThing* pthingDel, // In: CThing to be deleted.
- CRealm* prealm); // In: Current realm
- // Delete all but the basic items from the realm in order to make template levels
- static void DelMost( // Return nothing
- CRealm* prealm); // In: Current realm
- // Copy a thing to the paste buffer.
- static short CopyItem( // Returns 0 on success.
- CThing* pthingCopy); // In: CThing to copy.
- // Copy a thing to the paste buffer.
- static short PasteItem( // Returns 0 on success.
- CRealm* prealm, // In: The realm to paste into.
- short sX, // In: Location for new thing.
- short sY, // In: Location for new thing.
- short sZ); // In: Location for new thing.
- // Map a screen coordinate to a realm coordinate.
- // Note that this function's *psRealmY output is always
- // the height specified by the realm's attribute map
- // at the resulting *psRealmX, *psRealmZ.
- static void MapScreen2Realm( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera, // In: View of prealm.
- short sScreenX, // In: Screen x coord.
- short sScreenY, // In: Screen y coord.
- short* psRealmX, // Out: Realm x coord.
- short* psRealmY, // Out: Realm y coord (always via realm's height map).
- short* psRealmZ); // Out: Realm z coord.
- // Map a realm coordinate to a screen coordinate.
- static void Maprealm2Screen( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera, // In: View of prealm.
- short sRealmX, // In: Realm x coord.
- short sRealmY, // In: Realm y coord.
- short sRealmZ, // In: Realm z coord.
- short* psScreenX, // Out: Screen x coord.
- short* psScreenY); // Out: Screen y coord.
- // Blit attribute areas lit by the specified mask into the specified image.
- static void AttribBlit( // Returns nothing.
- RMultiGrid* pmg, // In: Multigrid of attributes.
- U16 u16Mask, // In: Mask of important attributes.
- RImage* pimDst, // In: Destination image.
- short sSrcX, // In: Where in Multigrid to start.
- short sSrcY, // In: Where in Multigrid to start.
- short sW, // In: How much of multigrid to use.
- short sH); // In: How much of multigrid to use.
- // Callback for attrib mask multibtns.
- static void AttribMaskBtnPressed( // Returns nothing.
- RGuiItem* pgui_pmb); // In: Ptr to the pressed GUI (which is a multibtn).
- // Resizes the attribute sprite, if allocated.
- static short SizeShowAttribsSprite(void); // Returns 0 on success.
- // Convert a .RLM filename to a .RGN one.
- static void RlmNameToRgnName( // Returns nothing.
- char* pszRealmName, // In: .RLM name.
- char* pszRgnName); // Out: .RGN name.
- // Our RFile callback
- static void MyRFileCallback(long lBytes);
- // Update selection info in the info GUI.
- static void UpdateSelectionInfo( // Returns nothing.
- bool bTitle = false); // In: true to update the title info as well.
- static short TmpFileName( // Returns 0 if successfull, non-zero otherwise
- char* pszFileName, // Out: Temp file name returned here
- short sMaxSize); // In: Maximum size of file name
- // Show statistics for the specified realm.
- static short ShowRealmStatistics( // Returns 0 on success.
- CRealm* prealm, // In: Realm to get stats on.
- CThing** ppthing); // Out: Selected thing, if not NULL.
- // Init load/save counter. You should call KillFileCounter() after
- // done with the file access.
- static void InitFileCounter( // Returns nothing.
- char* pszDescriptionFrmt); // In: sprintf format for description of
- // operation.
- // Kill load/save counter. Can be called multiple times w/o corresponding
- // Init().
- static void KillFileCounter(void); // Returns nothing.
- // Callback from realm during time intensive operations.
- static bool RealmOpProgress( // Returns true to continue; false to
- // abort operation.
- short sLastItemProcessed, // In: Number of items processed so far.
- short sTotalItemsToProcess); // In: Total items to process.
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Set some basic stuff for specified item.
- //
- ////////////////////////////////////////////////////////////////////////////////
- inline void SetPressedCall( // Returns nothing.
- RGuiItem* pguiRoot, // Root item.
- long lId) // ID of GUI item to set.
- {
- ASSERT(pguiRoot != NULL);
- RGuiItem* pgui = pguiRoot->GetItemFromId(lId);
- if (pgui != NULL)
- {
- // Set callback.
- pgui->m_bcUser = GuiPressedCall;
- }
- else
- {
- TRACE("SetPressedCall(): ID %ld missing.\n", lId);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Set the user values of the specified GUI.
- //
- ////////////////////////////////////////////////////////////////////////////////
- inline void SetMBValsAndCallback( // Returns nothing.
- RGuiItem* pguiRoot, // In: Root item.
- long lId, // In: ID of child to set user vals on.
- U32 u32UserInstance, // In: Value for m_ulUserInstance.
- U32 u32UserData, // In: Value for m_ulUserData.
- short sState) // In: Initial MultiBtn state.
- {
- RMultiBtn* pmb = (RMultiBtn*)pguiRoot->GetItemFromId(lId);
- if (pmb)
- {
- pmb->m_ulUserInstance = u32UserInstance;
- pmb->m_ulUserData = u32UserData;
- pmb->m_bcUser = AttribMaskBtnPressed;
- pmb->m_sState = sState;
- // Reflect new state.
- pmb->Compose();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Run the game editor
- //
- ////////////////////////////////////////////////////////////////////////////////
- extern void GameEdit(
- void)
- {
- // Clear any members that need to be intialized on each entrance.
- ms_pcameraCur = NULL;
- ms_pthingSel = NULL;
- ms_photSel = NULL;
- ms_plbLayers = NULL;
- ms_pgething = NULL;
- ms_photHood = NULL;
- // Disable 'Organ' on 'Audio Options' menu.
- menuAudioOptions.ami[1].sEnabled = FALSE;
- // Set alpha level to default.
- ms_spriteTriggerRgn.m_sAlphaLevel = DEF_TRIGGER_RGN_ALPHA_LEVEL;
- ms_spriteAttributes.m_sAlphaLevel = DEF_ATTRIBUTES_ALPHA_LEVEL;
- // Set attrib masks to not display any attributes.
- ms_u16TerrainMask = 0;
- ms_u16LayerMask = 0;
- // Set filename such that initially open and save dialogs start in
- // *.RLM dir.
- strcpy(ms_szFileName, FullPathVD(INITIAL_REALM_DIR));
- // Clear mouse and keyboard events
- rspClearAllInputEvents();
- // Remember initial display settings.
- rspGetVideoMode(
- &ms_sInitialDeviceDepth,
- &ms_sInitialDeviceWidth,
- &ms_sInitialDeviceHeight,
- NULL,
- &ms_sInitialDisplayWidth,
- &ms_sInitialDisplayHeight);
- // Clear screen
- rspLockBuffer();
- rspRect(RSP_BLACK_INDEX, g_pimScreenBuf, 0, 0, g_pimScreenBuf->m_sWidth, g_pimScreenBuf->m_sHeight);
-
- rspUnlockBuffer();
- rspUpdateDisplay();
- // Display message if necessary
- #ifdef DISABLE_EDITOR_SAVE_AND_PLAY
- rspMsgBox(
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "Postal Editor",
- "This is the same game editor we used to create the entire game. "
- "The only things that aren't working in it are the \"Save\" and "
- "\"Play\" functions. We had to disable these for various reasons, "
- "not the least of which is that it would have taken up more space. "
- "But please, check it out and let us know what you think!");
- #endif
-
- // Clear rubber band links for bouys
- m_pBouyLink0 = m_pBouyLink1 = NULL;
- // Init cursor stuff
- if (InitCursor() == 0)
- {
- //////////////////////////////////////////////////////////////////////
- // Create realm.
- //////////////////////////////////////////////////////////////////////
- // Create a realm. At some point we will probably extend the editor to
- // be able to handle multiple realms at once. For now it just has one.
- CRealm* prealm = new CRealm;
- ASSERT(prealm != 0);
- // This realm will only be used for editting, so it make it known.
- prealm->m_flags.bEditing = true;
- // Setup progress callback right away.
- // prealm->m_fnProgress = RealmOpProgress;
- // Reset realm time here and never do anything to it while in the editor.
- // This way, game objects will be able to access the time, but will never
- // see any change, which seems like a good thing.
- prealm->m_time.Reset();
- //////////////////////////////////////////////////////////////////////
- // Setup camera.
- //////////////////////////////////////////////////////////////////////
- CCamera* pcamera = new CCamera;
- ASSERT(pcamera != NULL);
- pcamera->SetScene(&(prealm->m_scene));
- // Update display size sensitive objects.
- SizeUpdate(pcamera, prealm);
- pcamera->SetFilm(g_pimScreenBuf, 0, 0);
- ms_pcameraCur = pcamera;
- /////////////////////////////////////////////////////////////////////////
- // Set up GUIs.
- /////////////////////////////////////////////////////////////////////////
- // Make sure there's a font in the default RPrint for GUIs.
- // Also, sets the size the GUIs will use when printing text.
- RGuiItem::ms_print.SetFont(GUIS_FONT_HEIGHT, &EDITOR_GUI_FONT);
- // Load GUIs.
- ms_pguiRealmBar = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, REALM_BAR_FILE) );
- ms_pguiPickObj = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, PICK_OBJECT_FILE) );
- ms_pguiLayers = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, LAYERS_GUI_FILE) );
- ms_pguiCameras = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, CAMERAS_GUI_FILE) );
- ms_pguiGUIs = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, GUIS_GUI_FILE) );
- ms_pguiMap = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, MAP_GUI_FILE) );
- ms_pguiNavNets = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, NAVNETS_GUI_FILE) );
- ms_pguiShowAttribs = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, SHOWATTRIBS_GUI_FILE) );
- ms_pguiInfo = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, INFO_GUI_FILE) );
- // Make sure we got all our GUIs . . .
- if ( ms_pguiRealmBar != NULL
- && ms_pguiPickObj != NULL
- && ms_pguiLayers != NULL
- && ms_pguiCameras != NULL
- && ms_pguiGUIs != NULL
- && ms_pguiMap != NULL
- && ms_pguiNavNets != NULL
- && ms_pguiShowAttribs
- && ms_pguiInfo)
- {
- // Set items that are to notify us.
- SetPressedCall(ms_pguiRealmBar, GUI_ID_NEW_REALM);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_OPEN_REALM);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_SAVE_REALM);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_CLOSE_REALM);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_PLAY_REALM);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_SAVE_REALM_AS);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_EXIT);
- SetPressedCall(ms_pguiRealmBar, GUI_ID_PROPERTIES);
- // Show the Realm Bar.
- ms_pguiRealmBar->SetVisible(ms_pguiRealmBar->m_sVisible);
- // Get object picker list box.
- RListBox* plbPicker = (RListBox*)ms_pguiPickObj->GetItemFromId(GUI_ID_PICK_LIST);
- ASSERT(plbPicker != NULL);
- ASSERT(plbPicker->m_type == RGuiItem::ListBox);
-
- // Add available objects to listbox.
- CThing::ClassIDType idCur;
- RGuiItem* pguiItem;
- for (idCur = 1; idCur < CThing::TotalIDs; idCur++)
- {
- // If item is editor creatable . . .
- if (CThing::ms_aClassInfo[idCur].bEditorCreatable == true)
- {
- // Add string for each item to listbox.
- pguiItem = plbPicker->AddString((char*)CThing::ms_aClassInfo[idCur].pszClassName);
- if (pguiItem != NULL)
- {
- pguiItem->m_lId = LIST_ITEM_GUI_ID_BASE + idCur;
- pguiItem->m_ulUserData = (ULONG)idCur;
- // Set the callback on pressed.
- pguiItem->m_bcUser = ListItemPressedCall;
- }
- }
- }
- // Format list items.
- plbPicker->AdjustContents();
- // Select the DEFAULT_THING_ID.
- RGuiItem* pguiDefThing = ms_pguiPickObj->GetItemFromId(DEFAULT_THING_ID + LIST_ITEM_GUI_ID_BASE);
- if (pguiDefThing != NULL)
- {
- plbPicker->SetSel(pguiDefThing);
- // Ensure that the default item is visible. Not scrolled off somewhere.
- plbPicker->EnsureVisible(pguiDefThing);
- }
- // Activate pick object box.
- ms_pguiPickObj->SetVisible(ms_pguiPickObj->m_sVisible);
- // Get layer tweaker list box.
- ms_plbLayers = (RListBox*)ms_pguiLayers->GetItemFromId(GUI_ID_LAYER_LIST);
- ASSERT(ms_plbLayers != NULL);
- ASSERT(ms_plbLayers->m_type == RGuiItem::ListBox);
- // Add available layers to listbox.
- short sLayer;
- for (sLayer = CRealm::LayerBg; sLayer < CRealm::TotalLayers; sLayer++)
- {
- // Add string for each item to listbox.
- pguiItem = ms_plbLayers->AddString(CRealm::ms_apszLayerNames[sLayer]);
- if (pguiItem != NULL)
- {
- // Remember which layer it's associated with.
- pguiItem->m_ulUserData = (ULONG)sLayer;
- // We'll need to know when these are pressed.
- pguiItem->m_bcUser = ListItemPressedCall;
- pguiItem->m_lId = GUI_ID_TOGGLE_LAYER;
- // These are push buttons.
- ASSERT(pguiItem->m_type == RGuiItem::PushBtn);
- ((RPushBtn*)pguiItem)->m_state
- = (prealm->m_scene.m_pLayers[sLayer].m_bHidden == false) ? RPushBtn::On : RPushBtn::Off;
- // Realize state.
- pguiItem->Compose();
- }
- }
- // Format list items.
- ms_plbLayers->AdjustContents();
- ms_pguiLayers->SetVisible(ms_pguiLayers->m_sVisible);
- // Set callbacks.
- SetPressedCall(ms_pguiCameras, GUI_ID_NEW_CAMERA);
- SetPressedCall(ms_pguiCameras, GUI_ID_CLOSE_CAMERA);
- ms_pguiCameras->SetVisible(ms_pguiCameras->m_sVisible);
- // --------- GUIs bar --------
- // Set items that are to notify us.
- SetPressedCall(ms_pguiGUIs, GUI_ID_REALM_VISIBLE);
- SetPressedCall(ms_pguiGUIs, GUI_ID_LAYERS_VISIBLE);
- SetPressedCall(ms_pguiGUIs, GUI_ID_THINGS_VISIBLE);
- SetPressedCall(ms_pguiGUIs, GUI_ID_CAMERAS_VISIBLE);
- SetPressedCall(ms_pguiGUIs, GUI_ID_NAVNETS_VISIBLE);
- SetPressedCall(ms_pguiGUIs, GUI_ID_MAP_VISIBLE);
- // Set items' states.
- ms_pguiGUIs->SetVisible(TRUE);
- // ---------- NavNets list --------
- ms_pguiNavNets->SetVisible(ms_pguiNavNets->m_sVisible);
- // ---------- Show Attribs --------
- SetMBValsAndCallback(ms_pguiShowAttribs, GUI_ID_ATTRIB_LAYERS, (U32)(&ms_u16LayerMask), REALM_ATTR_LAYER_MASK, 1);
- SetMBValsAndCallback(ms_pguiShowAttribs, GUI_ID_ATTRIB_HEIGHT, (U32)(&ms_u16TerrainMask), REALM_ATTR_HEIGHT_MASK, 1);
- SetMBValsAndCallback(ms_pguiShowAttribs, GUI_ID_ATTRIB_NOWALK, (U32)(&ms_u16TerrainMask), REALM_ATTR_NOT_WALKABLE, 1);
- SetMBValsAndCallback(ms_pguiShowAttribs, GUI_ID_ATTRIB_LIGHT, (U32)(&ms_u16TerrainMask), REALM_ATTR_LIGHT_BIT, 1);
- ms_pguiShowAttribs->SetVisible(TRUE);
- // ---------- Info ----------------
- ms_pguiInfoXPos = ms_pguiInfo->GetItemFromId(GUI_ID_INFO_X_POS);
- ms_pguiInfoYPos = ms_pguiInfo->GetItemFromId(GUI_ID_INFO_Y_POS);
- ms_pguiInfoZPos = ms_pguiInfo->GetItemFromId(GUI_ID_INFO_Z_POS);
- ms_pguiInfo->SetVisible(TRUE);
- // ---------- Map -----------------
- SetPressedCall(ms_pguiMap, GUI_ID_MAP_REFRESH);
- ms_pguiMapZone = ms_pguiMap->GetItemFromId(GUI_ID_MAP_ZONE);
- ms_pguiMap->SetVisible(ms_pguiMap->m_sVisible);
- // Copy colors and such to scrollbars.
- ms_pguiPickObj->CopyParms(&ms_sbVert);
- ms_pguiPickObj->CopyParms(&ms_sbHorz);
- ms_sbHorz.m_oOrientation = RScrollBar::Horizontal;
- ms_sbVert.SetVisible(TRUE);
- ms_sbHorz.SetVisible(TRUE);
- ms_sbVert.m_upcUser = ScrollPosUpdate;
- ms_sbHorz.m_upcUser = ScrollPosUpdate;
- // Smooth scrolling.
- ms_sbVert.m_scrollage = RScrollBar::Smooth;
- ms_sbHorz.m_scrollage = RScrollBar::Smooth;
- // Set display size based on the user's settings.
- SetCameraArea();
- // Update size sensitive objects (including scrollbars).
- SizeUpdate(pcamera, prealm);
- //////////////////////////////////////////////////////////////////////
- // Prepare user input.
- //////////////////////////////////////////////////////////////////////
- // Clear mouse and keyboard events
- rspClearAllInputEvents();
- // Make sure the system cursor is visible.
- // Store show level so we can restore it.
- short sCursorShowLevel = rspGetMouseCursorShowLevel();
- rspSetMouseCursorShowLevel(1);
- // User must load an existing realm or start a new one to go any further
- bool bGoEdit = false;
- bool bExit = false;
- // Set currently select thing to default value
- CThing::ClassIDType idCurrent = DEFAULT_THING_ID;
- // Clear mouse and keyboard events
- rspClearAllInputEvents();
- //////////////////////////////////////////////////////////////////////
- // Editor's main loop.
- //////////////////////////////////////////////////////////////////////
- bExit = false;
- short sCursorX, sCursorY, sCursorZ;
- while (!bExit)
- {
- ///////////////////////////////////////////////////////////////////
- // System update.
- ///////////////////////////////////////////////////////////////////
- UpdateSystem();
- ///////////////////////////////////////////////////////////////////
- // Input.
- ///////////////////////////////////////////////////////////////////
- bExit = DoInput(prealm, pcamera, &sCursorX, &sCursorY, &sCursorZ);
- ///////////////////////////////////////////////////////////////////
- // Output.
- ///////////////////////////////////////////////////////////////////
- DoOutput(prealm, pcamera, sCursorX, sCursorY, sCursorZ);
- }
- // Done with the views.
- RemoveViews();
- // Restore cursor show level.
- rspSetMouseCursorShowLevel(sCursorShowLevel);
- // Done with GUIs.
- delete ms_pguiRealmBar;
- ms_pguiRealmBar = NULL;
- delete ms_pguiPickObj;
- ms_pguiPickObj = NULL;
- delete ms_pguiLayers;
- ms_pguiLayers = NULL;
- delete ms_pguiCameras;
- ms_pguiCameras = NULL;
- delete ms_pguiGUIs;
- ms_pguiGUIs = NULL;
- delete ms_pguiMap;
- ms_pguiMap = NULL;
- delete ms_pguiNavNets;
- ms_pguiNavNets = NULL;
- delete ms_pguiShowAttribs;
- ms_pguiShowAttribs = NULL;
- delete ms_pguiInfo;
- ms_pguiInfo = NULL;
- }
- else
- {
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- g_pszCriticalErrorTitle,
- g_pszAssetsMissingError);
- }
- // Done with the realm.
- delete prealm;
- prealm = NULL;
- // Done with the camera.
- delete pcamera;
- pcamera = NULL;
- ms_pcameraCur = NULL;
- // Kill cursor stuff
- KillCursor();
- }
- // If there is an image, delete it.
- delete ms_spriteAttributes.m_pImage;
- ms_spriteAttributes.m_pImage = NULL;
- // If paste buffer open . . .
- if (ms_filePaste.IsOpen() != FALSE)
- {
- ms_filePaste.Close();
- }
- // Restore display mode.
- rspSetVideoMode(
- ms_sInitialDeviceDepth,
- ms_sInitialDeviceWidth,
- ms_sInitialDeviceHeight,
- ms_sInitialDisplayWidth,
- ms_sInitialDisplayHeight);
- // Give Jeff a chance to update his cool wrapper.
- // I'm not sure if this is necessary, but let's be safe.
- rspNameBuffers(&g_pimScreenBuf);
- // Clear mouse and keyboard events
- rspClearAllInputEvents();
- // Clear screen
- rspLockBuffer();
- rspRect(RSP_BLACK_INDEX, g_pimScreenBuf, 0, 0, g_pimScreenBuf->m_sWidth, g_pimScreenBuf->m_sHeight);
- rspUnlockBuffer();
- rspUpdateDisplay();
- // Re-enable 'Organ' on 'Audio Options' menu.
- menuAudioOptions.ami[1].sEnabled = TRUE;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Do ALL editor input.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static bool DoInput( // Returns true when done.
- CRealm* prealm, // Ptr to current realm.
- CCamera* pcamera, // Ptr to current camera.
- short* psCursorX, // Out: Cursor X position.
- short* psCursorY, // Out: Cursor Y position.
- short* psCursorZ) // Out: Cursor Z position.
- {
- bool bExit = false;
- short sCursorX;
- short sCursorY;
- short sCursorZ;
- short sCursorEvent;
- RInputEvent ie;
- // Get next input event.
- ie.type = RInputEvent::None;
- rspGetNextInputEvent(&ie);
-
- Menu* pmenu = GetCurrentMenu();
- // If there is a menu . . .
- if (pmenu != NULL)
- {
- // This is CHEEZY AS HELL but the normal menu callback calls
- // game.cpp which sets its action flag telling it to call this
- // function. Not sure how to do it here. Will we need to call
- // game.cpp, play.cpp, and gameedit.cpp whenever this menu is
- // activated?
- if (pmenu == &menuJoystick || pmenu == &menuMouse || pmenu == &menuKeyboard)
- {
- // Do the input settings.
- EditInputSettings();
- }
- // Menu on top (even of cursor).
- DoMenuInput(&ie, 0);
- // If there is no longer a menu . . .
- if (GetCurrentMenu() == NULL)
- {
- // Show the mouse.
- rspShowMouseCursor();
- // Fade in and restore colors.
- PalTranOff();
- }
- }
- else
- {
- // If editting a pylon trigger region . . .
- if (ms_pylonEdit != NULL)
- {
- static short sButtons = 0;
- // Get cursor position and event
- GetCursor(&ie, &sCursorX, &sCursorY, &sCursorZ, &sCursorEvent);
-
- UCHAR ucId = ms_pylonEdit->m_ucID;
- static U8* pau8KeyStatus = rspGetKeyStatusArray();
- // Move unit for arrow key movement of region.
- // Note: Combinations of SHIFT, CONTROL, and ALT
- // provide super fast movement.
- short sMoveUnit = 1;
- if (pau8KeyStatus[RSP_SK_SHIFT] & 1)
- sMoveUnit *= 2;
- if (pau8KeyStatus[RSP_SK_CONTROL] & 1)
- sMoveUnit *= 3;
- if (pau8KeyStatus[RSP_SK_ALT] & 1)
- sMoveUnit *= 4;
- if (pau8KeyStatus[RSP_SK_LEFT] & 1)
- {
- ms_argns[ucId].sX -= sMoveUnit;
- ms_spriteTriggerRgn.m_sX2 -= sMoveUnit;
- // Update sprite in scene.
- prealm->m_scene.UpdateSprite(&ms_spriteTriggerRgn);
- }
- else if (pau8KeyStatus[RSP_SK_RIGHT] & 1)
- {
- ms_argns[ucId].sX += sMoveUnit;
- ms_spriteTriggerRgn.m_sX2 += sMoveUnit;
- // Update sprite in scene.
- prealm->m_scene.UpdateSprite(&ms_spriteTriggerRgn);
- }
- else if (pau8KeyStatus[RSP_SK_UP] & 1)
- {
- ms_argns[ucId].sY -= sMoveUnit;
- ms_spriteTriggerRgn.m_sY2 -= sMoveUnit;
- // Update sprite in scene.
- prealm->m_scene.UpdateSprite(&ms_spriteTriggerRgn);
- }
- else if (pau8KeyStatus[RSP_SK_DOWN] & 1)
- {
- ms_argns[ucId].sY += sMoveUnit;
- ms_spriteTriggerRgn.m_sY2 += sMoveUnit;
- // Update sprite in scene.
- prealm->m_scene.UpdateSprite(&ms_spriteTriggerRgn);
- }
- // If unused event . . .
- if (ie.sUsed == FALSE)
- {
- if (ie.type == RInputEvent::Mouse)
- {
- sButtons = ie.sButtons;
- }
- else
- {
- if (ie.type == RInputEvent::Key)
- {
- switch (ie.lKey & 0x0000FFFF)
- {
- case 27:
- EditPylonTriggerRegion(NULL);
- break;
- case EDIT_KEY_ENLARGE_DISPLAY1:
- case EDIT_KEY_ENLARGE_DISPLAY2:
- case EDIT_KEY_ENLARGE_DISPLAY3:
- if (ms_sDrawBlockSize + sMoveUnit > ms_sDrawBlockSize)
- {
- ms_sDrawBlockSize += sMoveUnit;
- }
- break;
- case EDIT_KEY_REDUCE_DISPLAY1:
- case EDIT_KEY_REDUCE_DISPLAY2:
- ms_sDrawBlockSize -= sMoveUnit;
- if (ms_sDrawBlockSize < 2)
- {
- ms_sDrawBlockSize = 2;
- }
- break;
- case EDIT_KEY_DECREASE_OPACITY:
- ms_spriteTriggerRgn.m_sAlphaLevel -= INCDEC_ALPHA_LEVEL;
- if (ms_spriteTriggerRgn.m_sAlphaLevel < MIN_ALPHA_LEVEL)
- {
- ms_spriteTriggerRgn.m_sAlphaLevel = MIN_ALPHA_LEVEL;
- }
- break;
- case EDIT_KEY_INCREASE_OPACITY:
- ms_spriteTriggerRgn.m_sAlphaLevel += INCDEC_ALPHA_LEVEL;
- if (ms_spriteTriggerRgn.m_sAlphaLevel > MAX_ALPHA_LEVEL)
- {
- ms_spriteTriggerRgn.m_sAlphaLevel = MAX_ALPHA_LEVEL;
- }
- break;
- }
- }
- }
- }
- switch (sButtons)
- {
- case 1:
- rspRect(
- TRIGGER_RGN_DRAW_INDEX, // *** FUDGE ***.
- ms_argns[ucId].pimRgn,
- pcamera->m_sScene2FilmX + sCursorX - ms_argns[ucId].sX - ms_sDrawBlockSize / 2,
- pcamera->m_sScene2FilmY + sCursorZ - ms_argns[ucId].sY - ms_sDrawBlockSize / 2,
- ms_sDrawBlockSize,
- ms_sDrawBlockSize);
- break;
- case 2:
- rspRect(
- 0,
- ms_argns[ucId].pimRgn,
- pcamera->m_sScene2FilmX + sCursorX - ms_argns[ucId].sX - ms_sDrawBlockSize / 2,
- pcamera->m_sScene2FilmY + sCursorZ - ms_argns[ucId].sY - ms_sDrawBlockSize / 2,
- ms_sDrawBlockSize,
- ms_sDrawBlockSize);
- break;
- }
- }
- else
- {
- // If unused key event . . .
- if (ie.type == RInputEvent::Key && ie.sUsed == FALSE)
- {
- // Force alpha keys to upper keys
- if (isalpha(ie.lKey & 0xffff))
- ie.lKey = (ie.lKey & 0xffff0000) | toupper(ie.lKey & 0xffff);
- // In case we're gonna scroll, set amount based on CTRL key status
- short sScrollX = EDIT_SCROLL_AMOUNT;
- short sScrollY = EDIT_SCROLL_AMOUNT;
- if (ie.lKey & RSP_GKF_CONTROL)
- {
- sScrollX = pcamera->m_sViewW;
- sScrollY = pcamera->m_sViewH;
- }
- // Check for special editor keys
- switch (ie.lKey)
- {
- case EDIT_KEY_LOADREALM:
- case EDIT_KEY_OPENREALM:
- ms_lPressedId = GUI_ID_OPEN_REALM;
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_SAVEREALM:
- ms_lPressedId = GUI_ID_SAVE_REALM_AS;
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_NEWREALM:
- ms_lPressedId = GUI_ID_NEW_REALM;
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_TOGGLEBOUY:
- // Toggle the draw bouy flag
- ms_bDrawNetwork = !ms_bDrawNetwork;
- if (ms_bDrawNetwork)
- {
- CThing* pThing;
- CListNode<CThing>* pNext = prealm->m_aclassHeads[CThing::CBouyID].m_pnNext;
- while (pNext->m_powner != NULL)
- {
- pThing = pNext->m_powner;
- if (pThing)
- if (pThing->m_phot)
- pThing->m_phot->SetActive(TRUE);
- pNext = pNext->m_pnNext;
- }
-
- UpdateNetLines(prealm->GetCurrentNavNet());
- CBouy::Show();
- }
- else
- {
- CThing* pThing;
- CListNode<CThing>* pNext = prealm->m_aclassHeads[CThing::CBouyID].m_pnNext;
- while (pNext->m_powner != NULL)
- {
- pThing = pNext->m_powner;
- if (pThing)
- if (pThing->m_phot)
- pThing->m_phot->SetActive(FALSE);
- pNext = pNext->m_pnNext;
- }
- CBouy::Hide();
- }
- // Used the key
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_PLAY:
- ms_lPressedId = GUI_ID_PLAY_REALM;
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_MENU: // EDIT_KEY_CANCEL
- // If moving . . .
- if (ms_sMoving != FALSE)
- {
- CancelDrag(prealm);
- }
- else
- {
- #if 1
- // If menu is not running . . .
- if (GetCurrentMenu() == NULL)
- {
- // Fade out and preserve colors.
- PalTranOn();
- if (StartMenu(&menuEditor, &g_resmgrShell, g_pimScreenBuf) == 0)
- {
- // Hide the mouse.
- rspHideMouseCursor();
- }
- }
- #else
- ms_lPressedId = GUI_ID_EXIT;
- #endif
- }
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_SCROLL_L:
- // Scroll left
- ms_sbHorz.SetPos(pcamera->m_sSceneViewX - sScrollX);
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_SCROLL_R:
- // Scroll right
- ms_sbHorz.SetPos(pcamera->m_sSceneViewX + sScrollX);
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_SCROLL_U:
- // Scroll up
- ms_sbVert.SetPos(pcamera->m_sSceneViewY - sScrollY);
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_SCROLL_D:
- // Scroll down
- ms_sbVert.SetPos(pcamera->m_sSceneViewY + sScrollY);
- // Used the key.
- ie.sUsed = TRUE;
- break;
- case EDIT_KEY_ENLARGE_DISPLAY1:
- case EDIT_KEY_ENLARGE_DISPLAY2:
- case EDIT_KEY_ENLARGE_DISPLAY3:
- OnEnlargeDisplay(pcamera, prealm);
- break;
- case EDIT_KEY_REDUCE_DISPLAY1:
- case EDIT_KEY_REDUCE_DISPLAY2:
- OnReduceDisplay(pcamera, prealm);
- break;
- case EDIT_KEY_MODIFY1:
- case EDIT_KEY_MODIFY2:
- // Verify there is a selection . . .
- if (ms_pthingSel != NULL)
- {
- ASSERT(ms_photSel != NULL);
- // Modify.
- ms_pthingSel->EditModify();
- // Size may have changed.
- RRect rc;
- ms_pthingSel->EditRect(&rc);
- // Update hot.
- ms_photSel->m_sX = rc.sX;
- ms_photSel->m_sY = rc.sY;
- ms_photSel->m_sW = rc.sW;
- ms_photSel->m_sH = rc.sH;
- }
- break;
- case EDIT_KEY_NEWITEM:
- ms_lPressedId = GUI_ID_NEW_THING;
- break;
- case EDIT_KEY_NEXTITEM:
- NextItem(prealm);
- break;
- case EDIT_KEY_PREVITEM:
- PrevItem(prealm);
- break;
- case EDIT_KEY_DELETE_GROUP:
- DelClass(ms_pthingSel, prealm);
- break;
- case EDIT_KEY_DELETE_MOST:
- DelMost(prealm);
- break;
-
- case EDIT_KEY_DELETE:
- // Delete item.
- DelThing(ms_pthingSel, ms_photSel, prealm);
- break;
- case EDIT_KEY_DOS_COPY:
- case EDIT_KEY_COPY:
- ms_lPressedId = GUI_ID_COPY;
- break;
- case EDIT_KEY_DOS_CUT:
- case EDIT_KEY_CUT:
- ms_lPressedId = GUI_ID_CUT;
- break;
- case EDIT_KEY_DOS_PASTE:
- case EDIT_KEY_PASTE:
- ms_lPressedId = GUI_ID_PASTE;
- break;
- case EDIT_KEY_DECREASE_OPACITY:
- if (ms_spriteAttributes.m_pImage)
- {
- ms_spriteAttributes.m_sAlphaLevel -= INCDEC_ALPHA_LEVEL;
- if (ms_spriteAttributes.m_sAlphaLevel < MIN_ALPHA_LEVEL)
- {
- ms_spriteAttributes.m_sAlphaLevel = MIN_ALPHA_LEVEL;
- }
- }
- break;
- case EDIT_KEY_INCREASE_OPACITY:
- if (ms_spriteAttributes.m_pImage)
- {
- ms_spriteAttributes.m_sAlphaLevel += INCDEC_ALPHA_LEVEL;
- if (ms_spriteAttributes.m_sAlphaLevel > MAX_ALPHA_LEVEL)
- {
- ms_spriteAttributes.m_sAlphaLevel = MAX_ALPHA_LEVEL;
- }
- }
- break;
- case EDIT_KEY_OVERSHOOT_EDGES1:
- case EDIT_KEY_OVERSHOOT_EDGES2:
- if (pcamera->m_bClip == true)
- {
- pcamera->m_bClip = false;
- // Update visual components.
- SizeUpdate(pcamera, prealm);
- }
- else
- {
- pcamera->m_bClip = true;
- // Update visual components.
- SizeUpdate(pcamera, prealm);
- }
- break;
- case EDIT_KEY_REALM_STATISTICS:
- {
-
- CThing* pthing;
- ShowRealmStatistics(prealm, &pthing);
- if (pthing)
- {
- SetSel(pthing, NULL);
- }
- break;
- }
- default:
- break;
- }
- }
- // Pass events to hotboxes before sucked up by edit cursor.
- ms_pguiGUIs->m_hot.Do(&ie);
- ms_pguiRealmBar->m_hot.Do(&ie);
- //If there is a hood . . .
- if (prealm->m_asClassNumThings[CThing::CHoodID] > 0)
- {
- // Do extra views.
- DoViews(&ie);
- // Do other GUIs.
- ms_pguiPickObj->m_hot.Do(&ie);
- ms_pguiLayers->m_hot.Do(&ie);
- ms_pguiNavNets->m_hot.Do(&ie);
- ms_pguiMap->m_hot.Do(&ie);
- ms_pguiShowAttribs->m_hot.Do(&ie);
- ms_pguiInfo->m_hot.Do(&ie);
- }
- ms_sbVert.m_hot.Do(&ie);
- ms_sbHorz.m_hot.Do(&ie);
- // If there's a hood hotbox and no item being dragged . . .
- if (ms_photHood != NULL && ms_sMoving == FALSE)
- {
- // Pass the event to the Thing hotboxes in Realm coords.
- RInputEvent ieRealm = ie;
- ieRealm.sPosX += pcamera->m_sScene2FilmX;
- ieRealm.sPosY += pcamera->m_sScene2FilmY;
- ms_photHood->Do(&ieRealm);
- // If used by editor hotbox . . .
- if (ie.sUsed != ieRealm.sUsed)
- {
- // Note that it was used by editor hotbox.
- ie.lUser = 1;
- }
- }
- else
- {
- // If not yet used . . .
- if (ie.sUsed == FALSE)
- {
- // Make it an editor event.
- ie.lUser = 1;
- }
- }
- // Get cursor position and event
- GetCursor(&ie, &sCursorX, &sCursorY, &sCursorZ, &sCursorEvent);
-
- // If there is a realm . . .
- if (prealm != NULL)
- {
- // Map the cursor position to a realm coordinate.
- MapScreen2Realm(prealm, pcamera, sCursorX, sCursorZ, &sCursorX, &sCursorY, &sCursorZ);
- }
- switch(sCursorEvent)
- {
- case CURSOR_LEFT_BUTTON_UP:
- break;
- case CURSOR_RIGHT_BUTTON_UP:
- break;
- case CURSOR_LEFT_DOUBLE_CLICK:
- break;
- case CURSOR_RIGHT_DOUBLE_CLICK:
- break;
- case CURSOR_LEFT_DRAG_BEGIN:
- // If there is a selection . . .
- if (ms_pthingSel != NULL)
- {
- // Let's not drag the hood . . .
- if (ms_pthingSel->GetClassID() != CThing::CHoodID)
- {
- // Move mode.
- ms_sMoving = TRUE;
- // Make sure this is valid.
- ASSERT(ms_photSel != NULL);
- // Get hotspot for item in 2D.
- short sOffsetX;
- short sOffsetY;
- ms_pthingSel->EditHotSpot(&sOffsetX, &sOffsetY);
- // Reposition cursor to hotspot.
- rspSetMouse(
- (ms_photSel->m_sX - pcamera->m_sScene2FilmX) + sOffsetX,
- (ms_photSel->m_sY - pcamera->m_sScene2FilmY) + sOffsetY);
- // If cursor shown . . .
- if (rspGetMouseCursorShowLevel() > 0)
- {
- // Hide it.
- rspHideMouseCursor();
- }
- }
- }
- break;
- case CURSOR_LEFT_DRAG_END:
-
- DragDrop(
- sCursorX, // x
- sCursorY, // y
- sCursorZ); // z
-
- break;
- case CURSOR_NOTHING:
- // If there is an item being moved . . .
- if (ms_sMoving != FALSE)
- {
- ASSERT(ms_pthingSel != NULL);
- ASSERT(ms_photSel != NULL);
- MoveThing(
- ms_pthingSel,
- ms_photSel,
- sCursorX, // x
- sCursorY, // y
- sCursorZ); // z
- bool bInsideNonScroll = true;
- CNavigationNet* pNavNet = prealm->GetCurrentNavNet();
- if (pNavNet)
- UpdateNetLines(pNavNet);
- short sScreenX;
- short sScreenY;
- Maprealm2Screen(
- prealm,
- pcamera,
- sCursorX,
- 0,
- sCursorZ,
- &sScreenX,
- &sScreenY);
- // If on or beyond any edge of the view . . .
- if (sScreenX < DRAG_SCROLL_BUFFER)
- {
- if (ms_bDragScroll == true)
- {
- ms_sbHorz.SetPos(ms_sbHorz.GetPos() + (sScreenX - DRAG_SCROLL_BUFFER) * EDGE_MOVEMENT_MULTIPLIER);
- }
-
- // Note that the cursor is not in the non-scroll area.
- bInsideNonScroll = false;
- }
- else if (sScreenX > pcamera->m_sViewW - DRAG_SCROLL_BUFFER)
- {
- if (ms_bDragScroll == true)
- {
- ms_sbHorz.SetPos(ms_sbHorz.GetPos() + (sScreenX - (pcamera->m_sViewW - DRAG_SCROLL_BUFFER)) * EDGE_MOVEMENT_MULTIPLIER);
- }
-
- // Note that the cursor is not in the non-scroll area.
- bInsideNonScroll = false;
- }
- if (sScreenY < DRAG_SCROLL_BUFFER)
- {
- if (ms_bDragScroll == true)
- {
- ms_sbVert.SetPos(ms_sbVert.GetPos() + (sScreenY - DRAG_SCROLL_BUFFER) * EDGE_MOVEMENT_MULTIPLIER);
- }
-
- // Note that the cursor is not in the non-scroll area.
- bInsideNonScroll = false;
- }
- else if (sScreenY > pcamera->m_sViewH - DRAG_SCROLL_BUFFER)
- {
- if (ms_bDragScroll == true)
- {
- ms_sbVert.SetPos(ms_sbVert.GetPos() + (sScreenY - (pcamera->m_sViewH - DRAG_SCROLL_BUFFER)) * EDGE_MOVEMENT_MULTIPLIER);
- }
-
- // Note that the cursor is not in the non-scroll area.
- bInsideNonScroll = false;
- }
- // If inside the non-scroll area . . .
- if (bInsideNonScroll == true)
- {
- // Enable scrolling.
- ms_bDragScroll = true;
- }
- }
- break;
- default:
- break;
- }
- // Do GUI input focus stuff.
- RGuiItem::DoFocus(&ie);
- // Switch on ID of item clicked.
- switch (ms_lPressedId)
- {
- case 0: // Nothin'.
- break;
- case GUI_ID_NEW_REALM:
- // Create new realm
- NewRealm(prealm);
- // Setup camera.
- pcamera->SetHood(prealm->m_phood);
- m_pBouyLink0 = NULL;
- m_pBouyLink1 = NULL;
- break;
- case GUI_ID_OPEN_REALM:
- // Load realm
- LoadRealm(prealm);
- m_pBouyLink0 = NULL;
- m_pBouyLink1 = NULL;
- break;
- case GUI_ID_SAVE_REALM:
- // Save realm
- SaveRealm(prealm);
- break;
- case GUI_ID_SAVE_REALM_AS:
- // Save realm
- SaveRealmAs(prealm);
- break;
- case GUI_ID_PLAY_REALM:
- if (prealm->m_phood != NULL)
- {
- CancelDrag(prealm);
- // Simulate playing the realm
- PlayRealm(prealm, ms_pthingSel);
- // Restore global camera.
- ms_pcameraCur = pcamera;
- // Display size may have changed.
- SizeUpdate(pcamera, prealm);
- }
- else
- {
- // ***LOCALIZE***.
- rspMsgBox(
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "Play a Realm",
- "There is no hood. Cannot play.");
- }
- break;
- case GUI_ID_CLOSE_REALM:
- // Clear the ream.
- CloseRealm(prealm);
- m_pBouyLink0 = NULL;
- m_pBouyLink1 = NULL;
- break;
- case GUI_ID_EXIT:
- // If we can close the realm . . .
- if (CloseRealm(prealm) == 0)
- {
- // Exit the editor
- bExit = true;
- m_pBouyLink0 = NULL;
- m_pBouyLink1 = NULL;
- }
- break;
- case GUI_ID_PROPERTIES:
- // Call the realm's edit modify dialog function
- prealm->EditModify();
- break;
- case GUI_ID_TOGGLE_LAYER:
- {
- // Get currently selected list item.
- RGuiItem* pguiSel = ms_plbLayers->GetSel();
- if (pguiSel != NULL)
- {
- // Get layer to toggle.
- CRealm::Layer layer = (CRealm::Layer)pguiSel->m_ulUserData;
- // Should be push btn.
- ASSERT(pguiSel->m_type == RGuiItem::PushBtn);
- // Toggle.
- prealm->m_scene.m_pLayers[layer].m_bHidden
- = (((RPushBtn*)pguiSel)->m_state == RPushBtn::On) ? false : true;
- }
- break;
- }
- case GUI_ID_NEW_CAMERA:
- {
- AddView(prealm);
- break;
- }
- case GUI_ID_CLOSE_CAMERA:
- {
- RemoveView(NULL);
- break;
- }
- case GUI_ID_REALM_VISIBLE:
- ms_pguiRealmBar->SetVisible(!ms_pguiRealmBar->m_sVisible);
- break;
- case GUI_ID_LAYERS_VISIBLE:
- ms_pguiLayers->SetVisible(!ms_pguiLayers->m_sVisible);
- break;
- case GUI_ID_THINGS_VISIBLE:
- ms_pguiPickObj->SetVisible(!ms_pguiPickObj->m_sVisible);
- break;
- case GUI_ID_CAMERAS_VISIBLE:
- ms_pguiCameras->SetVisible(!ms_pguiCameras->m_sVisible);
- break;
- case GUI_ID_NAVNETS_VISIBLE:
- ms_pguiNavNets->SetVisible(!ms_pguiNavNets->m_sVisible);
- break;
- case GUI_ID_MAP_VISIBLE:
- ms_pguiMap->SetVisible(!ms_pguiMap->m_sVisible);
- break;
-
- case GUI_ID_MAP_REFRESH:
- RefreshMap(prealm);
- break;
- case GUI_ID_COPY:
- // Copy the selection to the paste buffer.
- CopyItem(ms_pthingSel);
- break;
- case GUI_ID_CUT:
- // Copy the selection to the paste buffer.
- CopyItem(ms_pthingSel);
- // Delete the selection.
- DelThing(ms_pthingSel, ms_photSel, prealm);
- break;
- case GUI_ID_PASTE:
- // Paste from the paste buffer.
- PasteItem(
- prealm, // In: The realm to paste into.
- sCursorX, // x
- sCursorY, // y
- sCursorZ); // z
- break;
- case GUI_ID_NEW_THING:
- {
- // Drop anything currently being dragged.
- DragDrop(
- sCursorX, // x
- sCursorY, // y
- sCursorZ); // z
- // Get object picker list box.
- RListBox* plbPicker = (RListBox*)ms_pguiPickObj->GetItemFromId(GUI_ID_PICK_LIST);
- if (plbPicker != NULL)
- {
- RGuiItem* pguiSel = plbPicker->GetSel();
- // If there is a selection . . .
- if (pguiSel != NULL)
- {
- // Get ID of list item representing thing to create.
- ms_lPressedId = pguiSel->m_lId;
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
- }
- ////// INTENTIONAL FALL THROUGH TO DEFAULT CASE //////
- default:
- // If the range of CThings . . .
- if ( ms_lPressedId >= LIST_ITEM_GUI_ID_BASE
- && ms_lPressedId < LIST_ITEM_GUI_ID_BASE + CThing::TotalIDs
- && ms_sMoving == FALSE)
- {
- CThing* pthingNew;
- RHot* photNew;
- if (CreateNewThing( // CThing* to new thing.
- prealm, // Realm to create in.
- ms_lPressedId - LIST_ITEM_GUI_ID_BASE, // ID to create.
- sCursorX, // x
- sCursorY, // y
- sCursorZ, // z
- &pthingNew, // New thing.
- &photNew) == 0) // New hotbox for thing.
- {
- // Select the new item.
- SetSel(pthingNew, photNew);
- // Start moving/placing object.
- ms_sMoving = TRUE;
- // Disable drag view scrolling.
- ms_bDragScroll = false;
- // Enter drag. Cheesy...Just need to get this to Bill and
- // Then I'll clean up.
- ms_sDragState = 4;
- if (rspGetMouseCursorShowLevel() > 0)
- {
- rspHideMouseCursor();
- }
- }
- }
- break;
- }
- // If the mapped is pressed . . .
- if (ms_pguiMapZone != NULL)
- {
- if (ms_pguiMapZone->m_sPressed != FALSE)
- {
- // Determine position.
- short sPosX, sPosY;
- rspGetMouse(&sPosX, &sPosY, NULL);
- ms_pguiMapZone->TopPosToClient(&sPosX, &sPosY);
- // Map position into map coords scroll to it.
- ms_sbVert.SetPos(sPosY / ms_dMapRatio - pcamera->m_sViewH / 2);
- ms_sbHorz.SetPos(sPosX / ms_dMapRatio - pcamera->m_sViewW / 2);
- }
- }
- }
-
- // Clear ID.
- ms_lPressedId = 0;
- }
- // If quitting . . .
- if (rspGetQuitStatus() != FALSE)
- {
- bExit = true;
- // Make sure to close the realm...kind've a hack doing it here.
- CloseRealm(prealm);
- }
- // Return cursor position values.
- *psCursorX = sCursorX;
- *psCursorY = sCursorY;
- *psCursorZ = sCursorZ;
- return bExit;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Do ALL editor output.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void DoOutput( // Returns nothing.
- CRealm* prealm, // Ptr to current realm.
- CCamera* pcamera, // Ptr to current camera.
- short sCursorX, // Cursor X position.
- short sCursorY, // Cursor Y position.
- short sCursorZ) // Cursor Z position.
- {
- // If not in menu . . .
- if (GetCurrentMenu() == NULL)
- {
- // Lock the composite buffer for much access.
- rspLockBuffer();
- // Update and render realm (in edit mode)
- prealm->EditUpdate();
- prealm->EditRender();
- // Need hood for this . . .
- if (prealm->m_asClassNumThings[CThing::CHoodID] > 0)
- {
- // If showing any attributes . . .
- if (ms_spriteAttributes.m_pImage)
- {
- // Clear the image.
- rspRect(
- 0,
- ms_spriteAttributes.m_pImage,
- 0, 0,
- ms_spriteAttributes.m_pImage->m_sWidth,
- ms_spriteAttributes.m_pImage->m_sHeight);
- prealm->m_scene.UpdateSprite(&ms_spriteAttributes);
- }
- else
- {
- // Get outta there.
- prealm->m_scene.RemoveSprite(&ms_spriteAttributes);
- }
- // If showing any terrain attributes . . .
- if (ms_u16TerrainMask)
- {
- AttribBlit( // Returns nothing.
- prealm->m_pTerrainMap, // In: Multigrid of attributes.
- ms_u16TerrainMask, // In: Mask of important attributes.
- ms_spriteAttributes.m_pImage, // In: Destination image.
- pcamera->m_sScene2FilmX, // In: Where in Multigrid to start.
- pcamera->m_sScene2FilmY, // In: Where in Multigrid to start.
- pcamera->m_sViewW, // In: How much of multigrid to use.
- pcamera->m_sViewH); // In: How much of multigrid to use.
- }
- // If showing any layer attributes . . .
- if (ms_u16LayerMask)
- {
- AttribBlit( // Returns nothing.
- prealm->m_pLayerMap, // In: Multigrid of attributes.
- ms_u16LayerMask, // In: Mask of important attributes.
- ms_spriteAttributes.m_pImage, // In: Destination image.
- pcamera->m_sScene2FilmX, // In: Where in Multigrid to start.
- pcamera->m_sScene2FilmY, // In: Where in Multigrid to start.
- pcamera->m_sViewW, // In: How much of multigrid to use.
- pcamera->m_sViewH); // In: How much of multigrid to use.
- }
- }
- // If avoiding clipping . . .
- if (pcamera->m_bClip == false)
- {
- // Keep it clean.
- pcamera->SnapWithLensCoverOn();
- }
- // Snap a picture.
- pcamera->Snap();
- // Draw the bouy connection line
- DrawBouyLink(prealm, pcamera);
- DrawNetwork(prealm, pcamera);
- // If there's a selected item . . .
- if (ms_pthingSel != NULL)
- {
- static RRect rc;
- static short sColorSwap = 0;
- sColorSwap = (sColorSwap + 1) % 2;
- ms_pthingSel->EditRect(&rc);
- rspRect(
- SELECTION_THICKNESS,
- (sColorSwap == 0) ? SELECTION_COLOR1 : SELECTION_COLOR2,
- g_pimScreenBuf,
- rc.sX - pcamera->m_sScene2FilmX - 1,
- rc.sY - pcamera->m_sScene2FilmY - 1,
- rc.sW + 2,
- rc.sH + 2);
- rspRect(
- SELECTION_THICKNESS,
- (sColorSwap == 1) ? SELECTION_COLOR1 : SELECTION_COLOR2,
- g_pimScreenBuf,
- rc.sX - pcamera->m_sScene2FilmX - SELECTION_THICKNESS - 1,
- rc.sY - pcamera->m_sScene2FilmY - SELECTION_THICKNESS - 1,
- rc.sW + SELECTION_THICKNESS * 2 + 2,
- rc.sH + SELECTION_THICKNESS * 2 + 2);
- }
- // If there's no current hood . . .
- if (prealm->m_phood == NULL)
- {
- // Erase entire screen.
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- 0, 0,
- g_pimScreenBuf->m_sWidth,
- g_pimScreenBuf->m_sHeight);
- }
- else
- {
- // Erase non-view area of screen.
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- g_pimScreenBuf->m_sWidth - DISPLAY_RIGHT_BORDER,
- 0,
- DISPLAY_RIGHT_BORDER,
- g_pimScreenBuf->m_sHeight);
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- 0,
- g_pimScreenBuf->m_sHeight - DISPLAY_BOTTOM_BORDER,
- g_pimScreenBuf->m_sWidth,
- DISPLAY_BOTTOM_BORDER);
- }
- // Update GUIs to composite buffer.
- ms_sbVert.Draw(g_pimScreenBuf);
- ms_sbHorz.Draw(g_pimScreenBuf);
- //If there is a hood . . .
- if (prealm->m_asClassNumThings[CThing::CHoodID] > 0)
- {
- ms_pguiLayers->Draw(g_pimScreenBuf);
- ms_pguiPickObj->Draw(g_pimScreenBuf);
- ms_pguiInfo->Draw(g_pimScreenBuf);
- ms_pguiShowAttribs->Draw(g_pimScreenBuf);
- ms_pguiMap->Draw(g_pimScreenBuf);
- ms_pguiNavNets->Draw(g_pimScreenBuf);
- // Draw extra views.
- DrawViews(prealm);
- }
- ms_pguiRealmBar->Draw(g_pimScreenBuf);
- ms_pguiGUIs->Draw(g_pimScreenBuf);
- // If editting a pylon . . .
- if (ms_pylonEdit != NULL)
- {
- UCHAR ucId = ms_pylonEdit->m_ucID;
- ASSERT(ms_argns[ucId].pimRgn != NULL);
- // Draw trigger region.
- #if 0 // Now done with a sprite.
- rspBlitT(
- 0, // Src transparent color or index.
- ms_argns[ucId].pimRgn, // Src.
- g_pimScreenBuf, // Dst.
- 0, // Src.
- 0, // Src.
- ms_argns[ucId].sX - pcamera->m_sScene2FilmX, // Dst.
- ms_argns[ucId].sY - pcamera->m_sScene2FilmY, // Dst.
- ms_argns[ucId].pimRgn->m_sWidth, // Both.
- ms_argns[ucId].pimRgn->m_sHeight, // Both.
- NULL, // Dst.
- NULL // Src.
- );
- #endif
- // Draw border bounding max bounding rect for region.
- rspRect(
- 1,
- 246 + (GetRand() % 10), // *** HOKEY(sp?) ***
- g_pimScreenBuf,
- ms_argns[ucId].sX - pcamera->m_sScene2FilmX - 1,
- ms_argns[ucId].sY - pcamera->m_sScene2FilmY - 1,
- ms_argns[ucId].pimRgn->m_sWidth + 2,
- ms_argns[ucId].pimRgn->m_sHeight + 2
- );
- // Draw cursor.
- rspRect(
- 1,
- 246 + (GetRand() % 10), // *** HOKEY(sp?) ***
- g_pimScreenBuf,
- sCursorX - ms_sDrawBlockSize / 2,
- sCursorZ - ms_sDrawBlockSize / 2,
- ms_sDrawBlockSize,
- ms_sDrawBlockSize
- );
- }
- // If placing/moving . . .
- if (ms_sMoving != FALSE)
- {
- // Draw cursor at current mouse position
- DrawCursor(sCursorX, sCursorY, sCursorZ, g_pimScreenBuf, prealm, pcamera);
- }
- // Whew. Unlock buffer now that we're done.
- rspUnlockBuffer();
- }
- else
- {
- // Menu.
- DoMenuOutput(g_pimScreenBuf);
- }
- // Update screen
- rspUpdateDisplay();
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Get cursor position and event
- // Ignores events that have already been used.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void GetCursor( // Returns nothing.
- RInputEvent* pie, // In: Input event.
- // Out: pie->sUsed = TRUE, if used.
- short* psX, // Out: X coord of event.
- short* psY, // Out: Y coord of event.
- short* psZ, // Out: Z coord of event.
- short* psEvent) // Out: Event type.
- {
- // Init mouse drag stuff
- static short sDragX;
- static short sDragY;
- static long lDragTime;
- // Init mouse pressed stuff.
- static short sPressed = FALSE;
- // Init cursor stuff
- static short sCursorY = 0;
- static short sOrigCursorY;
- // Default to no event
- *psEvent = CURSOR_NOTHING;
- ASSERT(pie != NULL);
- short sMouseX = pie->sPosX;
- short sMouseY = pie->sPosY;
- short sButtonEvent = pie->sEvent;
- // If mouse event . . .
- if (pie->type == RInputEvent::Mouse)
- {
- // Evaluate button stuff
- switch (sButtonEvent)
- {
- case RSP_MB0_PRESSED:
- // If occurred in one of our hots . . .
- if (pie->lUser == 1)
- {
- // Note pressed.
- sPressed = TRUE;
- if (ms_sDragState == 0)
- {
- ms_sDragState = 1;
- sDragX = sMouseX;
- sDragY = sMouseY;
- // Might as well use the actual time the event occurred, no?
- lDragTime = pie->lTime;
- // We used the event.
- pie->sUsed = TRUE;
- }
- }
- break;
- case RSP_MB0_RELEASED:
- // If we didn't get the down, we should not process this event.
- if (sPressed != FALSE)
- {
- // If button is released after drag mode was already started, then
- // it acts to end drag mode. Otherwise, we kill any chance of drag
- // mode and use the button for whatever else it might be needed for.
- if (ms_sDragState >= 2)
- {
- if (ms_sDragState == 3)
- {
- // Set mouse position back to where it was where when the drag
- // started. The idea is to hide the drag so the cursor doesn't "jump".
- sMouseX = sDragX;
- sMouseY = sDragY;
- rspSetMouse(sMouseX, sMouseY);
- // We used the event.
- pie->sUsed = TRUE;
- }
- else
- {
- // Return drag event
- *psEvent = CURSOR_LEFT_DRAG_END;
- // We used the event.
- pie->sUsed = TRUE;
- }
- }
- else
- {
- // If not yet used . . .
- if (pie->sUsed == FALSE)
- {
- // Return button event
- *psEvent = CURSOR_LEFT_BUTTON_UP;
- // We used the event.
- pie->sUsed = TRUE;
- }
- }
- // Clera pressed state.
- sPressed = FALSE;
- // Clear drag state
- ms_sDragState = 0;
- }
- break;
- case RSP_MB0_DOUBLECLICK:
- // A double-click SHOULD end drag mode, except that it's possible
- // we assumed it was a drag, and started doing a drag, but now the
- // system sees a second click and decides it was a double-click
- // instead. So I decided that if we're already in "full" drag
- // mode, we ignore the double-click. Otherwise, it ends drag mode.
- if (ms_sDragState < 2)
- {
- ms_sDragState = 0;
- *psEvent = CURSOR_LEFT_DOUBLE_CLICK;
- }
- // We used the event.
- pie->sUsed = TRUE;
- break;
- case RSP_MB1_DOUBLECLICK:
- // If occurred in one of our hots . . .
- if (pie->lUser == 1)
- {
- *psEvent = CURSOR_RIGHT_DOUBLE_CLICK;
- // We used the event.
- pie->sUsed = TRUE;
- }
- break;
- default:
- break;
- }
- }
- else
- {
- // If there was no mouse event, just get the current mouse position
- rspGetMouse(&sMouseX, &sMouseY, NULL);
- }
-
- // If we're in "maybe" drag mode, check if we should go to "full" drag mode
- if (ms_sDragState == 1)
- {
- // Full drag mode is entered if a minimum amount of time has elapsed or
- // if a minimum movement of the mouse has occurred. This is assuming
- // that the mouse button is still down from when it first went down.
- if (((rspGetMilliseconds() - lDragTime) >= DRAG_MIN_TIME) ||
- (ABS(sMouseX - sDragX) >= DRAG_MIN_X) ||
- (ABS(sMouseY - sDragY) >= DRAG_MIN_Y))
- ms_sDragState = 2;
- }
- // If we reach full drag mode, then we still need to determine whether to
- // pass this drag event back to the caller or use it ourselves as a way to
- // change the cursor's Y-coord (height). I'm not sure how to do it, but
- // it will probably mean checking for collisions with objects at this
- // level. If we are over an object, we would return the drag event. If
- // not, we would use the drag ourselves.
- if (ms_sDragState == 2)
- {
- // For now, it's hardwired to never assume the drag is used to modify the cursor
- if (0)
- {
- // Save info we need when adjusting cursor's y coord
- sOrigCursorY = sCursorY;
- ms_sDragState = 3; // Stretchy cursor mode.
- }
- else
- {
- // Return drag event
- *psEvent = CURSOR_LEFT_DRAG_BEGIN;
- ms_sDragState = 4; // Drag mode.
- }
- }
- // This is the special drag state that means we're adjusting the cursor's y coord
- if (ms_sDragState == 3)
- {
- sCursorY = sOrigCursorY + (sDragY - sMouseY);
- *psX = sDragX; // Keep cursor position where it was at start of drag!
- *psY = sCursorY;
- *psZ = sDragY; // Keep cursor position where it was at start of drag!
- }
- else
- {
- // Move cursor to latest mouse position
- *psX = sMouseX;
- *psY = sCursorY;
- *psZ = sMouseY;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Init cursor
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short InitCursor(
- void)
- {
- short sResult = 0;
- m_pimCursorBase = new RImage;
- ASSERT(m_pimCursorBase != NULL);
- if (m_pimCursorBase->Load(FullPath(GAME_PATH_VD, CURSOR_BASE_IMAGE_FILE) ) != 0)
- {
- sResult = -1;
- TRACE("LoadCursor(): Couldn't load cursor file: %s\n",
- FullPath(GAME_PATH_VD, CURSOR_BASE_IMAGE_FILE));
- goto Exit;
- }
- if (m_pimCursorBase->Convert(RImage::FSPR8) != RImage::FSPR8)
- {
- sResult = -1;
- TRACE("LoadCursor(): Couldn't convert cursor base to FSPR8!\n");
- goto Exit;
- }
- m_pimCursorTip = new RImage;
- ASSERT(m_pimCursorTip != NULL);
- if (m_pimCursorTip->Load(FullPath(GAME_PATH_VD, CURSOR_TIP_IMAGE_FILE) ) != 0)
- {
- sResult = -1;
- TRACE("LoadCursor(): Couldn't load cursor file: %s\n",
- FullPath(GAME_PATH_VD, CURSOR_TIP_IMAGE_FILE) );
- goto Exit;
- }
- if (m_pimCursorTip->Convert(RImage::FSPR8) != RImage::FSPR8)
- {
- sResult = -1;
- TRACE("LoadCursor(): Couldn't convert cursor tip to FSPR8!\n");
- goto Exit;
- }
- Exit:
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Kill cursor
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void KillCursor(
- void)
- {
- // Delete cursors (delete doesn't mind if pointer is already 0)
- delete m_pimCursorBase;
- m_pimCursorBase = 0;
- delete m_pimCursorTip;
- m_pimCursorTip = 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Draw edit cursor at specified location on specified image
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void DrawCursor(
- short sCursorX, // In: Cursor hotspot x coord
- short sCursorY, // In: Cursor hotspot y coord
- short sCursorZ, // In: Cursor hotspot z coord
- RImage* pimDst, // In: Image to draw to
- CRealm* prealm, // In: Realm.
- CCamera* pcamera) // In: Camera on prealm.
- {
- // Convert to 2D.
- short sBaseX2;
- short sBaseY2;
- Maprealm2Screen(prealm, pcamera, sCursorX, 0, sCursorZ, &sBaseX2, &sBaseY2);
- short sTipX2;
- short sTipY2;
- Maprealm2Screen(prealm, pcamera, sCursorX, sCursorY, sCursorZ, &sTipX2, &sTipY2);
- // Draw the base (I think this is the hotspot).
- rspBlit(
- m_pimCursorBase,
- pimDst,
- sBaseX2 - CURSOR_BASE_HOTX,
- sBaseY2 - CURSOR_BASE_HOTY);
- // Draw the top offset from the base by y coord (needs to be negated here!)
- rspBlit(
- m_pimCursorTip,
- pimDst,
- sTipX2 - CURSOR_TIP_HOTX,
- sTipY2 - CURSOR_TIP_HOTY);
- // If height is not 0 . . .
- if (sCursorY != 0)
- {
- // Draw a line connecting the base and the tip.
- #if 0
- short sMin = MIN(sCursorZ, (short)(sCursorZ - sCursorY));
- short sMax = MAX(sCursorZ, (short)(sCursorZ - sCursorY));
- for (short y = sMin; y <= sMax; y++)
- rspPlot((UCHAR)255, pimDst, sCursorX, y);
- #else
- rspLine(
- (UCHAR)255,
- pimDst,
- sBaseX2,
- sBaseY2,
- sTipX2,
- sTipY2);
- #endif
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Create new realm
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short NewRealm(
- CRealm* prealm)
- {
- short sResult = 0;
- // Close realm in case it contains anything
- sResult = CloseRealm(prealm);
- if (sResult == 0)
- {
- // Set the bouy lines to default to on
- ms_bDrawNetwork = true;
- // Clear the network lines from the previous level (if any)
- UpdateNetLines(NULL);
- // Set disk path for this realm.
- prealm->m_resmgr.SetBasePath(g_GameSettings.m_szNoSakDir);
- CThing* pthing;
- short sResult = CreateNewThing(prealm, CThing::CHoodID, 0, 0, 0, &pthing, &ms_photHood);
- // Create hood object because we can't really do anything without it
- if (sResult == 0)
- {
- RHot* photdummy;
- sResult = CreateNewThing(prealm, CThing::CGameEditThingID, 0, 0, 0, &pthing, &photdummy);
- // Create editor object . . .
- if (sResult == 0)
- {
- // Store ptr to GameEdit thing.
- ms_pgething = (CGameEditThing*)pthing;
- ms_pgething->m_plbNavNetList = (RListBox*) ms_pguiNavNets->GetItemFromId(GUI_ID_NAVNET_LIST);
- sResult = CreateNewThing(prealm, CThing::CNavigationNetID, 150, 0, 50, &pthing, &ms_photSel);
- if (sResult == 0)
- {
- // Success.
- // Update size affected stuff.
- SizeUpdate(ms_pcameraCur, prealm);
- // Set the palette.
- prealm->m_phood->SetPalette();
-
- // Freshen the map.
- RefreshMap(prealm);
- sResult = CreateNewThing(prealm, CThing::CTriggerID, 0, 0, 0, &pthing, &photdummy);
- if (sResult == 0)
- {
- prealm -> m_pTriggerMap = ((CTrigger*)pthing)->m_pmgi;
- }
- }
- else
- {
- TRACE("GameEdit:NewRealm - Failed to create default NavNet.\n");
- TRACE(" other objects depending on one may not work correctly.\n");
- }
- }
- }
- }
-
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Close realm.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short CloseRealm(
- CRealm* prealm)
- {
- short sResult = 0;
- // Cancel drag, if one is in progress.
- CancelDrag(prealm);
- // Cancle network line draw if it is on
- if (ms_bDrawNetwork)
- ms_bDrawNetwork = false;
- // Clear the Navigation Net list box in the editor
- if (ms_pgething && ms_pgething->m_plbNavNetList)
- ms_pgething->m_plbNavNetList->RemoveAll();
- // If the realm has anything worth saving . . .
- if (prealm->m_sNumThings > 0)
- {
- // Check for save . . .
- switch (rspMsgBox(
- RSP_MB_ICN_QUERY | RSP_MB_BUT_YESNOCANCEL,
- g_pszAppName,
- g_pszSaveFileQuery) )
- {
- case RSP_MB_RET_YES:
- sResult = SaveRealm(prealm);
- break;
- case RSP_MB_RET_NO:
- break;
- case RSP_MB_RET_CANCEL:
- // User abort.
- sResult = 1;
- break;
- }
- }
- // If successful so far . . .
- if (sResult == 0)
- {
- if (ms_pcameraCur != NULL)
- {
- // Clear hood ptr.
- ms_pcameraCur->SetHood(NULL);
- }
-
- // Clear realm in case it contains anything
- prealm->Clear();
- // This's gone now.
- ms_pgething = NULL;
- // If there are any . . .
- if (ms_photHood != NULL)
- {
- // Destroy all child hotboxes.
- RHot* phot = ms_photHood->m_listChildren.GetHead();
- while (phot != NULL)
- {
- delete phot;
- phot = ms_photHood->m_listChildren.GetNext();
- }
- // Destroy root/hood hotbox.
- delete ms_photHood;
- ms_photHood = NULL;
- }
- // Clean up trigger regions.
- short i;
- for (i = 0; i < NUM_ELEMENTS(ms_argns); i++)
- {
- ms_argns[i].Destroy();
- }
- // Better clear these.
- ms_sMoving = FALSE;
- SetSel(NULL, NULL);
- // Set filename such that initially open and save dialogs start in
- // *.RLM dir.
- strcpy(ms_szFileName, FullPathVD(INITIAL_REALM_DIR));
- // Update size dependent stuff.
- SizeUpdate(ms_pcameraCur, prealm);
- // Purge resource managers.
- g_resmgrGame.Purge();
- prealm->m_resmgr.Purge();
- }
-
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Load realm.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short LoadRealm(
- CRealm* prealm)
- {
- short sResult = 0;
- // Close current realm.
- sResult = CloseRealm(prealm);
- if (sResult == 0)
- {
- // Attempt to get filename . . .
- // ***LOCALIZE***
- sResult = rspOpenBox(
- "Load Realm",
- ms_szFileName,
- ms_szFileName,
- sizeof(ms_szFileName),
- ".rlm");
- if (sResult == 0)
- {
- // Attach file counter callback to RFile and setup necessary components.
- InitFileCounter("Loading -- %ld bytes so far.");
-
- // Convert to RSPiX format b/c CRealm::Load() now likes it that way.
- char szRealmName[sizeof(ms_szFileName)];
- strcpy(szRealmName, rspPathFromSystem(ms_szFileName) );
- // Load realm in edit mode
- sResult = prealm->Load(szRealmName, true);
- // Clean and detach file counter.
- KillFileCounter();
- // If load was successful . . .
- if (sResult == 0)
- {
- // Get the editor thing.
- ms_pgething = GetEditorThing(prealm);
- // Start the realm.
- prealm->Startup();
- if (prealm->m_phood)
- {
- // Set hood's palette.
- prealm->m_phood->SetPalette();
- }
- // Store ptr to GameEdit thing.
- CListNode<CThing>* pEditorList = prealm->m_aclassHeads[CThing::CGameEditThingID].m_pnNext;
- CGameEditThing* peditor = (CGameEditThing*) pEditorList->m_powner;
- if (peditor)
- {
- peditor->m_plbNavNetList = (RListBox*) ms_pguiNavNets->GetItemFromId(GUI_ID_NAVNET_LIST);
- }
- ///////////////////////////////////////////////////////////////////
- // Create Hot for every CThing.
- ///////////////////////////////////////////////////////////////////
- // Get the hood . . .
- if (prealm->m_asClassNumThings[CThing::CHoodID] > 0)
- {
- RRect rc;
- // Get first and only Hood iterator.
- CHood* phood = (CHood*) prealm->m_aclassHeads[CThing::CHoodID].m_pnNext->m_powner;
- // Get rectangle.
- phood->EditRect(&rc);
- // Create and setup RHot for hood.
- phood->m_phot = ms_photHood = new RHot(
- rc.sX, // Position.
- rc.sY, // Position.
- rc.sW, // Dimensions.
- rc.sH, // Dimensions.
- ThingHotCall, // Callback.
- TRUE, // TRUE, if active.
- (U32)phood, // User value (CThing*).
- FRONTMOST_HOT_PRIORITY); // New items towards front.
- // If successful . . .
- if (ms_photHood != NULL)
- {
- // Setup hotboxes for all objects.
- CListNode<CThing>* pList;
- CThing* pthing;
- short sActivateHot;
- pList = prealm->m_everythingHead.m_pnNext;
- while (pList->m_powner != NULL && sResult == 0)
- {
- pthing = pList->m_powner;
- // Already got one for Hood. If not the Hood . . .
- if (pthing->GetClassID() != CThing::CHoodID)
- {
- sActivateHot = TRUE;
- // Some types may need to hook in here.
- switch (pthing->GetClassID() )
- {
- case CThing::CBouyID:
- // If bouy lines are hidden . . .
- if (ms_bDrawNetwork == false)
- {
- // Don't activate new bouy hots.
- sActivateHot = FALSE;
- }
- break;
- case CThing::CNavigationNetID:
- ((CNavigationNet*) pthing)->EditPostLoad();
- break;
- }
- // Get rectangle.
- pthing->EditRect(&rc);
- // Create and setup RHot.
- pthing->m_phot = new RHot(
- rc.sX, // Position.
- rc.sY, // Position.
- rc.sW, // Dimensions.
- rc.sH, // Dimensions.
- ThingHotCall, // Callback.
- sActivateHot, // TRUE, if initially active.
- (U32)pthing, // User value (CThing*).
- FRONTMOST_HOT_PRIORITY); // New items towards front.
- // If successful . . .
- if (pthing->m_phot != NULL)
- {
- // Make child of Hood's hotbox.
- pthing->m_phot->SetParent(ms_photHood);
- }
- else
- {
- TRACE("LoadRealm(): Unable to allocate hotbox for thing.\n");
- sResult = 1;
- }
- }
- // Go to next item
- pList = pList->m_pnNext;
- }
- }
- else
- {
- TRACE("LoadRealm(): Unable to allocate hotbox for Hood.\n");
- sResult = 1;
- }
- }
- else
- {
- TRACE("LoadRealm(): Realm has no hood.\n");
- sResult = 1;
- }
-
- // If any errors occurred . . .
- if (sResult != 0)
- {
- // Clean up any partial stuff.
- CloseRealm(prealm);
- // Report.
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- g_pszCriticalErrorTitle,
- g_pszGeneralError);
- }
- else
- {
- // Make sure our loaded settings are unaffected.
- short sViewPosX = 0;
- short sViewPosY = 0;
- if (ms_pgething != NULL)
- {
- sViewPosX = ms_pgething->m_sViewPosX;
- sViewPosY = ms_pgething->m_sViewPosY;
- }
- // Set camera's hood.
- ms_pcameraCur->SetHood(prealm->m_phood);
- // Update size affected stuff.
- SizeUpdate(ms_pcameraCur, prealm);
- // If there is an editor thing . . .
- if (ms_pgething != NULL)
- {
- // Update view position.
- ms_sbVert.SetPos(sViewPosY);
- ms_sbHorz.SetPos(sViewPosX);
- }
-
- // Freshen the map.
- RefreshMap(prealm);
- // Load the regions for the pylons.
- if (LoadTriggerRegions(ms_szFileName) < 0)
- {
- rspMsgBox( // ****LOCALIZE****
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "LoadRealm()",
- "Pylon editor regions failed to load.");
- }
- // Make sure the bouys' show/hidden state reflects this flag's status.
- if (ms_bDrawNetwork == true)
- {
- CBouy::Show();
- }
- else
- {
- CBouy::Hide();
- }
- }
- }
- else
- {
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- g_pszCriticalErrorTitle,
- g_pszGeneralError);
- }
- }
- }
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Save realm as . . .
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short SaveRealmAs(
- CRealm* prealm)
- {
- short sResult = 0;
-
- #ifdef DISABLE_EDITOR_SAVE_AND_PLAY
- rspMsgBox(
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "Postal Editor",
- "Sorry, but the save feature is disabled.");
- sResult = -1;
- #else
- // Attempt to get filename . . .
- // ***LOCALIZE***
- if (rspSaveBox(
- "Save Realm",
- ms_szFileName,
- ms_szFileName,
- sizeof(ms_szFileName),
- ".rlm") == 0)
- {
- ASSERT(ms_szFileName[0] != '\0');
- // Save realm.
- // Note that SaveRealm() can call SaveRealmAs(), but should not in this
- // case (since we have a filename now).
- sResult = SaveRealm(prealm);
- }
- else
- {
- // Cancelled.
- sResult = 1;
- }
- #endif
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Save realm
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short SaveRealm(
- CRealm* prealm)
- {
- short sResult = 0;
-
- // If filename . . .
- if (strcmp(ms_szFileName, FullPathVD(INITIAL_REALM_DIR)) != 0)
- {
- // Save realm with trigger regions.
- sResult = SaveRealm(prealm, ms_szFileName, true);
- }
- else
- {
- // Get filename before save.
- // Note that SaveRealmAs() calls this SaveRealm().
- sResult = SaveRealmAs(prealm);
- }
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Save realm with specified name.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short SaveRealm( // Returns 0 on success.
- CRealm* prealm, // In: Realm to save.
- char* pszRealmName, // In: Filename to save as.
- bool bSaveTriggerRegions) // In: Save the trigger regions too.
- {
- short sResult = 0;
- #ifdef DISABLE_EDITOR_SAVE_AND_PLAY
- rspMsgBox(
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "Postal Editor",
- "Sorry, but the save feature is disabled.");
- sResult = -1;
- #else
- // Convert the Trigger Regions into an attribute map:
- CreateTriggerRegions(prealm);
- // Attach file counter callback to RFile and setup necessary components.
- InitFileCounter("Saving -- %ld bytes so far.");
- // Save realm
- sResult = prealm->Save(pszRealmName);
- // Clean and detach file counter.
- KillFileCounter();
- // If successful . . .
- if (sResult == 0)
- {
- // If we are to save the trigger regions . . .
- if (bSaveTriggerRegions == true)
- {
- // Save the regions for the pylons.
- if (SaveTriggerRegions(pszRealmName, prealm) < 0)
- {
- rspMsgBox( // ****LOCALIZE****
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "SaveRealm()",
- "Pylon editor regions failed to save.");
- sResult = -1;
- }
- }
- }
- else
- {
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- g_pszCriticalErrorTitle,
- g_pszGeneralError);
- }
- #endif
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Editor's simulated play loop
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void PlayRealm(
- CRealm* pEditRealm, // In: Realm to play.
- CThing* pthingSel) // In: Currently selected CThing which can
- // be used to give PlayRealm() a hint on which
- // of several things the user wants to use.
- // For example, a selected warp is the used
- // as the warp in point.
- {
- #ifdef DISABLE_EDITOR_SAVE_AND_PLAY
- rspMsgBox(
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "Postal Editor",
- "Sorry, but the play feature is disabled.");
- #else
- // This is not returned by the function, but used internally
- short sResult = 0;
- // Enable RMix's autopump.
- RMix::SetAutoPump(TRUE);
- rspClearAllInputEvents();
- // If mouse is being used, hide mouse cursor
- if (g_InputSettings.m_sUseMouse)
- rspHideMouseCursor();
- // Create a temporary filename
- char szFileName[RSP_MAX_PATH];
- if (TmpFileName(szFileName, sizeof(szFileName)) == 0)
- {
- // Attach file counter callback to RFile and setup necessary components.
- InitFileCounter("Saving -- %ld bytes so far.");
- // Save realm being edited without the trigger regions.
- sResult = SaveRealm(pEditRealm, szFileName, false);
- // Clean and detach file counter.
- KillFileCounter();
- // If successful . . .
- if (sResult == 0)
- {
- // Create a new realm so we don't accidentally rely on any side-effects
- // that may result from using the editor's realm.
- CRealm* prealm = new CRealm;
- ASSERT(prealm != NULL);
- // Setup progress callback right away.
- // prealm->m_fnProgress = RealmOpProgress;
- // Clear realm (just in case)
- prealm->Clear();
- // Note that we are playing from the editor. Might be useful.
- prealm->m_flags.bEditPlay = true;
- prealm->m_flags.sDifficulty = g_GameSettings.m_sDifficulty;
- // Reset time here so that objects can use it when they are loaded
- prealm->m_time.Reset();
- // No memorex here.
- SetInputMode(INPUT_MODE_LIVE);
- // Attach file counter callback to RFile and setup necessary components.
- InitFileCounter("Loading -- %ld bytes so far.");
-
- // Convert to RSPiX format b/c CRealm::Load() now likes it that way.
- char szRealmName[sizeof(szFileName)];
- strcpy(szRealmName, rspPathFromSystem(szFileName) );
- // Load realm (false indicates NOT edit mode)
- sResult = prealm->Load(szRealmName, false);
- // Clean and detach file counter.
- KillFileCounter();
- // If successful . . .
- if (sResult == 0)
- {
- // Set up the score module - initialize the font etc.
- ScoreInit();
- // Set the multiplayer scores to zero
- ScoreReset();
- // Reset the display timer
- ScoreResetDisplay();
- // Set score mode.
- ScoreSetMode(CScoreboard::SinglePlayer);
- // Startup the realm
- if (prealm->Startup() == 0)
- {
- U16 idSpecificWarp = CIdBank::IdNil;
- //////////// Special behaviors based on the current selection ////////////
- // Note that pthingSel does not exist in prealm (it is in pEditRealm).
- // There is, however, a clone of it with the same ID in prealm. These
- // special behaviors should, therefore, get the thing's ID here and use
- // it to get the ID of the specificied thing in the playing realm.
- // If there is a selection . . .
- if (pthingSel)
- {
- switch (pthingSel->GetClassID() )
- {
- case CThing::CWarpID:
- // Get user's preferred warp.
- idSpecificWarp = pthingSel->GetInstanceID();
- break;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- rspLockBuffer();
- // Erase screen.
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- 0,
- 0,
- g_pimScreenBuf->m_sWidth,
- g_pimScreenBuf->m_sHeight);
- rspUnlockBuffer();
- // Could do rspUpdateDisplay() here to guarantee no palette flash
- // but that should not happen anyways b/c the current palette
- // (from the realm's hood loaded in the editor) should be this
- // realm's hood's palette.
- // Set hood palette.
- prealm->m_phood->SetPalette();
- // Clear local input.
- ClearLocalInput();
- // We'll need access to the key status array.
- U8* pau8KeyStatus = rspGetKeyStatusArray();
-
- // Setup camera
- CCamera* pcamera = new CCamera;
- ASSERT(pcamera != NULL);
- pcamera->SetScene(&(prealm->m_scene));
- // Update display size sensitive objects.
- SizeUpdate(pcamera, prealm);
- pcamera->SetFilm(g_pimScreenBuf, 0, 0);
- pcamera->SetHood(prealm->m_phood);
- ms_pcameraCur = pcamera;
- ScrollPosUpdate(&ms_sbVert);
- ScrollPosUpdate(&ms_sbHorz);
- // Set grip to control camera
- CGrip grip;
- grip.SetParms(100, 1, 1, 8, 8, 1, 1, true);
- grip.SetCamera(pcamera);
- grip.ResetTarget(0, 0, 30);
- // Default to tracking the track ID.
- bool bTracking = true;
- // Get thing to track . . .
- CThing* pthingTrack = NULL;
- U16 u16IdTrack = CIdBank::IdNil;
- if (ms_pgething != NULL)
- {
- u16IdTrack = ms_pgething->m_u16CameraTrackId;
- }
- // Make sure no Scrollbars have focus.
- RGuiItem::SetFocus(NULL);
- CListNode<CThing>* pNext = prealm->m_aclassHeads[CThing::CDudeID].m_pnNext;
- U16 u16IdDude = CIdBank::IdNil;
- while (pNext->m_powner != NULL)
- {
- CDude* pdude = (CDude*) pNext->m_powner;
- // if this is the local dude...
- if (pdude->m_sDudeNum == 0)
- {
- // Store 'im
- u16IdDude = pdude->GetInstanceID();
- // Make him X-Rayable.
- pdude->m_sprite.m_sInFlags |= CSprite::InXrayee;
- }
- pNext = pNext->m_pnNext;
- }
- // If no dude yet . . .
- if (u16IdDude == CIdBank::IdNil)
- {
- // Create one using warps (if any):
- CDude* pdude = NULL;
- CWarp* pwarp = NULL;
- // If there's a specific warp desired . . .
- if (prealm->m_idbank.GetThingByID( (CThing**)&pwarp, idSpecificWarp) == 0)
- {
- // Use the specific warp to create the dude . . .
- if (pwarp->WarpIn( // Returns 0 on success.
- &pdude, // In: CDude to 'warp in', *ppdude = NULL to create one.
- // Out: Newly created CDude, if no CDude passed in.
- CWarp::None) == 0) // In: Options for 'warp in'.
- {
- // Success.
- }
- else
- {
- TRACE("PlayRealm(): Failed to use user specified warp.\n");
- }
- }
- // If no dude yet . . .
- if (pdude == NULL)
- {
- // Warp one in anywhere . . .
- if (CWarp::WarpInAnywhere( // Returns 0 on success.
- prealm, // In: Realm in which to choose CWarp.
- &pdude, // In: CDude to 'warp in', *ppdude = NULL to create one.
- // Out: Newly created CDude, if no CDude passed in.
- CWarp::None) == 0) // In: Options for 'warp in'.
- {
- // Success.
- }
- }
- // If a dude was created . . .
- if (pdude)
- {
- // Store 'im
- u16IdDude = pdude->GetInstanceID();
- // Make him X-Rayable.
- pdude->m_sprite.m_sInFlags |= CSprite::InXrayee;
- // If nothing to track yet . . .
- if (u16IdTrack == CIdBank::IdNil)
- {
- // Use the local dude.
- u16IdTrack = u16IdDude;
- }
- }
- }
- CDude* pdudeLocal = NULL;
- if (prealm->m_idbank.GetThingByID((CThing**)&pdudeLocal, u16IdDude) == 0)
- {
- pdudeLocal->m_sTextureIndex = MAX((short)0, MIN((short)(CDude::MaxTextures - 1), g_GameSettings.m_sPlayerColorIndex));
- // Don't use later.
- pdudeLocal = NULL;
- }
- RInputEvent ie;
- // Setup rectangular area for dude's status.
- RRect rcDudeStatus(
- DUDE_STATUS_RECT_X,
- DUDE_STATUS_RECT_Y,
- DUDE_STATUS_RECT_W,
- DUDE_STATUS_RECT_H);
- // Setup rectangular area for realm's status.
- RRect rcRealmStatus(
- REALM_STATUS_RECT_X,
- REALM_STATUS_RECT_Y,
- REALM_STATUS_RECT_W,
- REALM_STATUS_RECT_H);
- // Setup rectangular area for display info.
- RRect rcInfoStatus(
- INFO_STATUS_RECT_X,
- INFO_STATUS_RECT_Y,
- INFO_STATUS_RECT_W,
- INFO_STATUS_RECT_H);
- long lLastDispTime = 0;
- long lFramesTime = 0;
- long lUpdateDisplayTime = 0;
- long lNumFrames = 0;
- RPrint printDisp;
- printDisp.SetFont(DISP_INFO_FONT_H, &g_fontBig);
- printDisp.SetColor(250, 0, 0);
- printDisp.SetDestination(g_pimScreenBuf);
- char szFileDescriptor[512];
- Play_GetApplicationDescriptor(szFileDescriptor, sizeof(szFileDescriptor) );
- // Reset time again so that the first time update doesn't show (much) elapsed time
- prealm->m_time.Reset();
- bool bDone = false;
- bool bExitRequest = false;
- bool bSuspended = false;
- // Do the loop
- while (bDone == false)
- {
- // Update the realm's game time
- prealm->m_time.Update();
- // System update
- UpdateSystem();
- ie.type = RInputEvent::None;
- rspGetNextInputEvent(&ie);
- if (ie.type == RInputEvent::Key)
- {
- // Force alpha keys to upper keys
- if (isalpha(ie.lKey & 0xffff))
- ie.lKey = (ie.lKey & 0xffff0000) | toupper(ie.lKey & 0xffff);
- switch (ie.lKey)
- {
- case EDIT_KEY_PAUSE:
- if (bSuspended == false)
- {
- prealm->Suspend();
- }
- else
- {
- prealm->Resume();
- }
- bSuspended = !bSuspended;
- break;
- #if 0
- case EDIT_KEY_SPEED_UP:
- break;
- case EDIT_KEY_SPEED_DOWN:
- break;
- case EDIT_KEY_SPEED_NORMAL:
- break;
- #endif
- case EDIT_KEY_ENDPLAY:
- // If first request . . .
- if (bExitRequest == false)
- {
- bExitRequest = true;
- }
- else
- {
- bDone = true;
- }
- break;
- case EDIT_KEY_ENLARGE_DISPLAY1:
- case EDIT_KEY_ENLARGE_DISPLAY2:
- case EDIT_KEY_ENLARGE_DISPLAY3:
- OnEnlargeDisplay(pcamera, prealm);
- // Update status areas. That is, repaginate now.
- rcDudeStatus.sX = DUDE_STATUS_RECT_X;
- rcDudeStatus.sY = DUDE_STATUS_RECT_Y;
- rcDudeStatus.sW = DUDE_STATUS_RECT_W;
- rcDudeStatus.sH = DUDE_STATUS_RECT_H;
- rcRealmStatus.sX = REALM_STATUS_RECT_X;
- rcRealmStatus.sY = REALM_STATUS_RECT_Y;
- rcRealmStatus.sW = REALM_STATUS_RECT_W;
- rcRealmStatus.sH = REALM_STATUS_RECT_H;
- rcInfoStatus.sX = INFO_STATUS_RECT_X;
- rcInfoStatus.sY = INFO_STATUS_RECT_Y;
- rcInfoStatus.sW = INFO_STATUS_RECT_W;
- rcInfoStatus.sH = INFO_STATUS_RECT_H;
- break;
- case EDIT_KEY_REDUCE_DISPLAY1:
- case EDIT_KEY_REDUCE_DISPLAY2:
- OnReduceDisplay(pcamera, prealm);
- // Update status areas. That is, repaginate now.
- rcDudeStatus.sX = DUDE_STATUS_RECT_X;
- rcDudeStatus.sY = DUDE_STATUS_RECT_Y;
- rcDudeStatus.sW = DUDE_STATUS_RECT_W;
- rcDudeStatus.sH = DUDE_STATUS_RECT_H;
- rcRealmStatus.sX = REALM_STATUS_RECT_X;
- rcRealmStatus.sY = REALM_STATUS_RECT_Y;
- rcRealmStatus.sW = REALM_STATUS_RECT_W;
- rcRealmStatus.sH = REALM_STATUS_RECT_H;
- rcInfoStatus.sX = INFO_STATUS_RECT_X;
- rcInfoStatus.sY = INFO_STATUS_RECT_Y;
- rcInfoStatus.sW = INFO_STATUS_RECT_W;
- rcInfoStatus.sH = INFO_STATUS_RECT_H;
- break;
- case EDIT_KEY_CAMERA_TRACKING:
- bTracking = !bTracking;
- // If we are now using grip . . .
- if (bTracking == true)
- {
- // Erase scrollbars.
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- ms_sbVert.m_sX,
- ms_sbVert.m_sY,
- ms_sbVert.m_im.m_sWidth,
- ms_sbVert.m_im.m_sHeight);
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- ms_sbHorz.m_sX,
- ms_sbHorz.m_sY,
- ms_sbHorz.m_im.m_sWidth,
- ms_sbHorz.m_im.m_sHeight);
- // Reset the grip, if necessary.
- if (pthingTrack != NULL && bTracking == true)
- {
- RRect rc;
- pthingTrack->EditRect(&rc);
- short sHotX, sHotY;
- pthingTrack->EditHotSpot(&sHotX, &sHotY);
- grip.ResetTarget(rc.sX + sHotX, rc.sY + sHotY, rc.sH / 2);
- // Make sure no Scrollbars have focus.
- RGuiItem::SetFocus(NULL);
- }
- }
- else // We are now using scrollbars.
- {
- // Update scroll pos via camera pos.
- ms_sbVert.SetPos(ms_pcameraCur->m_sSceneViewY);
- ms_sbHorz.SetPos(ms_pcameraCur->m_sSceneViewX);
- }
- break;
- // Change priority level.
- case '1':
- case '2':
- case '3':
- // rspSetDoSystemMode(ie.lKey - '1');
- break;
- case EDIT_KEY_TOGGLE_DISP_INFO:
- // Toggle display info flag.
- if (g_GameSettings.m_sDisplayInfo == FALSE)
- {
- g_GameSettings.m_sDisplayInfo = TRUE;
- }
- else
- {
- g_GameSettings.m_sDisplayInfo = FALSE;
- }
- // Repaginate now.
- rcDudeStatus.sH = DUDE_STATUS_RECT_H;
- break;
- case EDIT_KEY_SHOW_MISSION:
- // Show the mission goal line again for about 5 seconds.
- ScoreDisplayStatus(prealm);
- break;
- case EDIT_KEY_REALM_STATISTICS:
-
- prealm->Suspend();
- ShowRealmStatistics(prealm, NULL);
- prealm->Resume();
- break;
- }
- }
- // If xray all pressed . . .
- if (pau8KeyStatus[KEY_XRAY_ALL] & 1)
- {
- prealm->m_scene.SetXRayAll(TRUE);
- }
- else
- {
- prealm->m_scene.SetXRayAll(FALSE);
- }
- // Lock the composite buffer for access.
- rspLockBuffer();
- // Process input for extra camera GUIs.
- DoViews(&ie);
- // Only do scrollbars if not tracking . . .
- if (bTracking == false)
- {
- // Update hots.
- ms_sbVert.m_hot.Do(&ie);
- ms_sbHorz.m_hot.Do(&ie);
- }
- // Do GUI input focus stuff.
- RGuiItem::DoFocus(&ie);
- // Get local player input and
- // Set controls for the one-and-only CDude
- // Allow cheats.
- SetInput(0, GetLocalInput(prealm, &ie));
- // If exit requested . . .
- if (bExitRequest == true)
- {
- CDude* pdudeLocal;
- // If there's a local dude . . .
- if (prealm->m_idbank.GetThingByID((CThing**)&pdudeLocal, u16IdDude) == 0)
- {
- // If dead . . .
- if (pdudeLocal->m_state == CCharacter::State_Dead)
- {
- // Okay, done.
- bDone = true;
- }
- else
- {
- // Commit suicide.
- GameMessage msg;
- msg.msg_Generic.eType = typeSuicide;
- msg.msg_Generic.sPriority = 0;
- pdudeLocal->SendThingMessage(&msg, pdudeLocal);
- }
- }
- else
- {
- bDone = true;
- }
- }
- // Update and render realm
- prealm->Update();
- prealm->Render();
- if (u16IdTrack != CIdBank::IdNil)
- {
- if (prealm->m_idbank.GetThingByID(&pthingTrack, u16IdTrack) != 0)
- {
- u16IdTrack = CIdBank::IdNil;
- }
- }
- // Update grip/camera
- if (pthingTrack != NULL)
- {
- RRect rc;
- pthingTrack->EditRect(&rc);
- short sHotX, sHotY;
- pthingTrack->EditHotSpot(&sHotX, &sHotY);
- sHotX += rc.sX;
- sHotY += rc.sY;
- short sRealmX, sRealmY, sRealmZ;
- // Convert to realm.
- MapScreen2Realm(
- prealm, // In: Realm.
- pcamera, // In: View of prealm.
- sHotX - pcamera->m_sScene2FilmX, // In: Screen x coord.
- sHotY - pcamera->m_sScene2FilmY, // In: Screen y coord.
- &sRealmX, // Out: Realm x coord.
- &sRealmY, // Out: Realm y coord (always via realm's height map).
- &sRealmZ); // Out: Realm z coord.
- // Set the location of our ear.
- SetSoundLocation(sRealmX, sRealmY, sRealmZ);
- if (bTracking == true)
- {
- grip.TrackTarget(sHotX, sHotY, rc.sH / 2);
- }
- }
- // If quitting . . .
- if (rspGetQuitStatus() != FALSE)
- {
- bDone = true;
- }
- // Snap picture of scene
- pcamera->Snap();
- // If there is a local dude . . .
- CDude* pdudeLocal = NULL;
- // If there's a local dude, get him.
- prealm->m_idbank.GetThingByID((CThing**)&pdudeLocal, u16IdDude);
- // Only do scrollbars if not tracking . . .
- if (bTracking == false)
- {
- // Update GUIs to composite buffer.
- ms_sbVert.Draw(g_pimScreenBuf);
- ms_sbHorz.Draw(g_pimScreenBuf);
- }
- // Draw extra cameras.
- DrawViews(prealm);
- // Done with the composite buffer (except to update it to
- // the screen).
- rspUnlockBuffer();
- // Until the editor is merged into the new play, just do it this way. The only "loss" is that
- // we don't get the various status stuff being displayed while in the editor.
- #if 0
- Play_UpdateDisplays( // Returns nothing.
- prealm, // In: Realm.
- pcamera, // In: Camera.
- pdudeLocal, // In: Local dude.
- &rcDudeStatus, // In: Rect for dude status display.
- &rcRealmStatus, // In: Rect for realm status display.
- &rcInfoStatus, // In: Rect for info status display.
- &printDisp, // In: Print to output display info.
- szFileDescriptor, // In: Date/Time stamp of exe.
- &lLastDispTime, // In/Out: Last time display info was output.
- &lFramesTime, // In/Out: Total time of all frames since last display info output.
- &lUpdateDisplayTime, // In/Out: Total time of all rspUpdateDisplay()s since last display info output.
- &lNumFrames, // In/Out: Number of frames since last display info output.
- 0, // In: Current input sequence number.
- 0, // In: Current frame number.
- NULL, // In: pointer to net client to get player names for Score
- TRUE); // In: Update entire display.
- #else
- rspUpdateDisplay();
- #endif
- // Lock buffer for clearage.
- rspLockBuffer();
- // Clear extra cameras.
- ClearViews();
- rspUnlockBuffer();
- // If snap key is pressed . . .
- if (pau8KeyStatus[KEY_SNAP_PICTURE])
- {
- // Take the snap shot.
- Play_SnapPicture();
- // Clear key status.
- pau8KeyStatus[KEY_SNAP_PICTURE] = 0;
- }
- }
- // Shutdown realm
- prealm->Shutdown();
- // Done with the camera.
- delete pcamera;
- pcamera = NULL;
- ms_pcameraCur = NULL;
- }
- else
- {
- TRACE("EditPlay(): Error starting-up temporary realm!\n");
- sResult = -1;
- }
- }
- else
- {
- TRACE("EditPlay(): Error loading temporary realm!\n");
- }
- // Delete the realm
- delete prealm;
- // Delete temporary file
- remove(szFileName);
- }
- else
- {
- TRACE("EditPlay(): Error saving temporary realm!\n");
- }
- }
- else
- {
- TRACE("PlayRealm(): Error getting temporary file name!\n");
- sResult = -1;
- }
- // If mouse is being used, restore mouse cursor
- if (g_InputSettings.m_sUseMouse)
- rspShowMouseCursor();
- rspClearAllInputEvents();
- // Disable autopump.
- RMix::SetAutoPump(FALSE);
- // If something went wrong, let the user know
- if (sResult)
- {
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- "Postal Editor",
- "An error has occurred that prevents this realm from being played.");
- }
- #endif // DISABLE_EDITOR_SAVE_AND_PLAY
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Create a new CThing derived object of type id in prealm at the specified
- // position.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short CreateNewThing( // Returns 0 on success.
- CRealm* prealm, // In: Realm to add new CThing to.
- CThing::ClassIDType id, // ID of new CThing type to create.
- short sPosX, // Position for new CThing.
- short sPosY, // Position for new CThing.
- short sPosZ, // Position for new CThing.
- CThing** ppthing, // Out: Pointer to new thing.
- RHot** pphot, // Out: Pointer to new hotbox for thing.
- RFile* pfile/* = NULL*/) // In: Optional file to load from (instead of EditNew()).
- {
- short sError = 0;
- // Don't allow more than one CHood . . .
- if ((id == CThing::CHoodID) && (prealm->m_asClassNumThings[CThing::CHoodID] > 0))
- {
- // ***LOCALIZE***
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- "Editor: ",
- "Can't have multiple CHood's!");
- //STRACE("Editor: Can't have multiple CHood's!\n");
- sError = 1;
- }
- else
- {
- if (prealm->m_asClassNumThings[CThing::CHoodID] > 0 || id == CThing::CHoodID)
- {
- if (!(id == CThing::CBouyID && prealm->GetCurrentNavNet() == NULL))
- {
- // Create new object of currently selected type
- if (CThing::ConstructWithID(id, prealm, ppthing) == 0)
- {
- // Successfully allocated object.
- // If loading from file specified . . .
- if (pfile != NULL)
- {
- // Remember its ID.
- U16 idInstance = (*ppthing)->GetInstanceID();
- // Release its ID.
- (*ppthing)->SetInstanceID(CIdBank::IdNil);
- // Load object . . .
- if ((*ppthing)->Load(pfile, true, ms_sFileCount--, CRealm::FileVersion) == 0)
- {
- // Loaded.
- // Reset ID.
- (*ppthing)->SetInstanceID(idInstance);
- // Reserve ID.
- prealm->m_idbank.Take(*ppthing, idInstance);
- // Startup.
- (*ppthing)->Startup();
- // Move.
- (*ppthing)->EditMove(sPosX, sPosY, sPosZ);
- }
- else
- {
- TRACE("CreateNewThing(): Load() failed for object.\n");
- sError = 4;
- }
- }
- else
- {
- // Edit new object (required to get object up and running)
- if ((*ppthing)->EditNew(sPosX, sPosY, sPosZ) == 0)
- {
- // Newed.
- }
- else
- {
- TRACE("CreateNewThing(): EditNew() failed for object.\n");
- sError = 4;
- }
- }
- // If successful so far . . .
- if (sError == 0)
- {
- short sActivateHot = TRUE;
- // Some types may need to hook in here.
- switch ( (*ppthing)->GetClassID() )
- {
- case CThing::CBouyID:
- // If bouy lines are hidden . . .
- if (ms_bDrawNetwork == false)
- {
- // Don't activate new bouy hots.
- sActivateHot = FALSE;
- }
- break;
- }
- // Get pos and dimensions for hot.
- RRect rc;
- (*ppthing)->EditRect(&rc);
- // Allocate a RHot for the item . . .
- (*ppthing)->m_phot = *pphot = new RHot(
- rc.sX, // Position.
- rc.sY, // Position.
- rc.sW, // Dimensions.
- rc.sH, // Dimensions.
- ThingHotCall, // Callback.
- sActivateHot, // TRUE, if initially active.
- (U32)*ppthing, // User value (CThing*).
- FRONTMOST_HOT_PRIORITY); // New items towards front.
- if (*pphot != NULL)
- {
- // If this is not THE HOOD . . .
- if (id != CThing::CHoodID)
- {
- (*pphot)->SetParent(ms_photHood);
- }
- // Special things.
- switch (id)
- {
- case CThing::CDudeID:
- // If there is an editor thing . . .
- if (ms_pgething != NULL)
- {
- // If no camera focus yet . . .
- if (ms_pgething->m_u16CameraTrackId == CIdBank::IdNil)
- {
- // Track this dude.
- ms_pgething->m_u16CameraTrackId = (*ppthing)->GetInstanceID();
- }
- }
-
- CDude* pdude = (CDude*)(*ppthing);
- // If this is the local dude . . .
- if (pdude->m_sDudeNum == 0)
- {
- // Set him to the user selected color.
- pdude->m_sTextureIndex = MAX((short)0, MIN((short)(CDude::MaxTextures - 1), g_GameSettings.m_sPlayerColorIndex));
- }
- break;
- }
- // If an error occurred after allocation . . .
- if (sError != 0)
- {
- // On error, destroy object
- delete *pphot;
- *pphot = NULL;
- }
- }
- else
- {
- TRACE("CreateNewThing(): Failed to allocate new RHot.\n");
- sError = 3;
- }
- }
- // If an error occurred after allocation . . .
- if (sError != 0)
- {
- // On error, destroy object
- delete *ppthing;
- *ppthing = NULL;
- }
- }
- }
- else
- {
- TRACE("CreateNewThing(): Cannot create a buoy when there's no current NavNet.\n");
- // ***LOCALIZE***
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- "No current NavNet",
- "Cannot create new Buoy when there is no current NavNet.");
- sError = 6;
- }
- }
- else
- {
- sError = 7;
- }
- }
- return sError;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Move a thing to the specified location and update its RHot with an
- // EditRect() call.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void MoveThing( // Returns nothing.
- CThing* pthing, // Thing to move.
- RHot* phot, // Thing's hotbox.
- short sPosX, // New position.
- short sPosY, // New position.
- short sPosZ) // New position.
- {
- ASSERT(pthing != NULL);
- ASSERT(phot != NULL);
- // Move to 3D position.
- pthing->EditMove(
- sPosX,
- sPosY,
- sPosZ);
- // Get 2D position.
- RRect rc;
- pthing->EditRect(
- &rc);
- // Copy to hot.
- phot->m_sX = rc.sX;
- phot->m_sY = rc.sY;
- phot->m_sW = rc.sW;
- phot->m_sH = rc.sH;
- // Update info GUI.
- UpdateSelectionInfo(false);
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Enlarges the display area.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void OnEnlargeDisplay(
- CCamera* pcamera, // Camera to update.
- CRealm* prealm) // Realm to update.
- {
- AdjustDisplaySize(DISPLAY_SIZE_DELTA_X, DISPLAY_SIZE_DELTA_Y, pcamera, prealm);
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Reduces the display area.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void OnReduceDisplay(
- CCamera* pcamera, // Camera to update.
- CRealm* prealm) // Realm to update.
- {
- AdjustDisplaySize(-DISPLAY_SIZE_DELTA_X, -DISPLAY_SIZE_DELTA_Y, pcamera, prealm);
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Set display mode such that display area is as
- // specified.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short SetDisplayArea( // Returns 0 on success.
- short sDeviceD, // New depth of display.
- short sDisplayW, // New width of display area.
- short sDisplayH) // New height of display area.
- {
- short sError = 0;
- short sDeviceW, sDeviceH;
- short sDeviceScaling = FALSE;
- // Get device size/mode for this display size.
- sError = rspSuggestVideoMode(
- sDeviceD,
- sDisplayW,
- sDisplayH,
- 1,
- sDeviceScaling,
- &sDeviceW,
- &sDeviceH,
- &sDeviceScaling);
- // If we are not supposed to change the device dimensions . . .
- if (g_GameSettings.m_sUseCurrentDeviceDimensions != FALSE)
- {
- // Get current device settings.
- rspGetVideoMode(
- &sDeviceD,
- &sDeviceW,
- &sDeviceH);
- // Limit display area.
- sDisplayW = MIN(sDeviceW, sDisplayW);
- sDisplayH = MIN(sDeviceH, sDisplayH);
- }
- // If successful so far . . .
- if (sError == 0)
- {
- // Set the adjusted mode . . .
- sError = rspSetVideoMode(
- sDeviceD,
- sDeviceW,
- sDeviceH,
- sDisplayW,
- sDisplayH,
- 1,
- sDeviceScaling);
- // Give Jeff a chance to update his cool wrapper.
- // I'm not sure if this is necessary, but let's be safe.
- rspNameBuffers(&g_pimScreenBuf);
- if (sError == 0)
- {
- }
- else
- {
- TRACE("SetDisplayArea(): rspSetVideoMode() failed.\n");
- }
- }
- else
- {
- TRACE("SetDisplayArea(): rspSuggestVideoMode() failed.\n");
- }
- // Store latest values (in success or failure).
- g_GameSettings.m_sEditorViewWidth = g_pimScreenBuf->m_sWidth;
- g_GameSettings.m_sEditorViewHeight = g_pimScreenBuf->m_sHeight;
- return sError;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Set display mode and display area such that camera view
- // is specified size.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short SetCameraArea(void) // Returns 0 on success.
- {
- short sDepth = 8; // Safety.
- rspGetVideoMode(&sDepth);
-
- // Determine display area for this camera size.
- short sDisplayW = g_GameSettings.m_sEditorViewWidth;//sCameraW + DISPLAY_RIGHT_BORDER;
- short sDisplayH = g_GameSettings.m_sEditorViewHeight;//sCameraH + DISPLAY_BOTTOM_BORDER;
- // Set the display area/mode.
- return SetDisplayArea(sDepth, sDisplayW, sDisplayH);
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Adjust the display area by the specified deltas.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short AdjustDisplaySize( // Returns 0 on success.
- short sAdjustX, // Amount to increase width of display area.
- // Can be negative to decrease.
- short sAdjustY, // Amount to increase height of display area.
- // Can be negative to decrease.
- CCamera* pcamera, // Camera to update.
- CRealm* prealm) // Realm to update.
- {
- short sError = 0;
- short sDisplayW = 640; // Safety.
- short sDisplayH = 480; // Safety.
- short sDeviceD = 8; // Safety.
- // Get current settings.
- rspGetVideoMode(
- &sDeviceD,
- NULL,
- NULL,
- NULL,
- &sDisplayW,
- &sDisplayH);
- // New area.
- if (SetDisplayArea(
- sDeviceD,
- sDisplayW + sAdjustX,
- sDisplayH + sAdjustY) == 0)
- {
- SizeUpdate(pcamera, prealm);
- }
- else
- {
- sError = 1;
- }
- return sError;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Update screen size sensitive objects.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short SizeUpdate( // Returns 0 on success.
- CCamera* pcamera, // Camera to update.
- CRealm* prealm) // Realm to update.
- {
- short sRes = 0; // Assume success.
- short sDisplayW = 640; // Safety.
- short sDisplayH = 480; // Safety.
- short sDisplayD = 8; // Safety.
- // Get current settings.
- rspGetVideoMode(
- &sDisplayD,
- NULL,
- NULL,
- NULL,
- &sDisplayW,
- &sDisplayH);
- short sViewW = sDisplayW - DISPLAY_RIGHT_BORDER - SCROLL_BAR_THICKNESS;
- short sViewH = sDisplayH - DISPLAY_BOTTOM_BORDER - SCROLL_BAR_THICKNESS;
- // Get the hood . . .
- CHood* phood = NULL;
- if (prealm->m_asClassNumThings[CThing::CHoodID] > 0)
- phood = (CHood*) prealm->m_aclassHeads[CThing::CHoodID].GetNext();
- else
- {
- TRACE("SizeUpdate(): No hood.\n");
- sRes = -1;
- }
- // Give Jeff a chance to update his cool wrapper.
- // I'm not sure if this is necessary, but let's be safe.
- rspNameBuffers(&g_pimScreenBuf);
- // If there's a camera to update . . .
- if (pcamera != NULL)
- {
- pcamera->SetHood(phood);
- // Adjust camera by same amount.
- pcamera->SetView(
- pcamera->m_sSceneViewX,
- pcamera->m_sSceneViewY,
- sViewW,
- sViewH);
- pcamera->SetFilm(g_pimScreenBuf, 0, 0);
- }
- // Put GUIs somewhere out of the way.
- if (ms_pguiRealmBar != NULL)
- {
- ms_pguiRealmBar->Move(REALM_BAR_X, REALM_BAR_Y);
- }
- if (ms_pguiPickObj != NULL)
- {
- ms_pguiPickObj->Move(PICKOBJ_LIST_X, PICKOBJ_LIST_Y);
- }
- if (ms_pguiLayers != NULL)
- {
- ms_pguiLayers->Move(LAYERS_LIST_X, LAYERS_LIST_Y);
- }
- if (ms_pguiCameras != NULL)
- {
- ms_pguiCameras->Move(CAMERAS_LIST_X, CAMERAS_LIST_Y);
- }
- if (ms_pguiGUIs != NULL)
- {
- ms_pguiGUIs->Move(GUIS_BAR_X, GUIS_BAR_Y);
- }
- if (ms_pguiNavNets != NULL)
- {
- ms_pguiNavNets->Move(NAVNETS_X, NAVNETS_Y);
- }
- if (ms_pguiMap != NULL)
- {
- ms_pguiMap->Move(MAP_X, MAP_Y);
- }
- if (ms_pguiShowAttribs)
- {
- ms_pguiShowAttribs->Move(SHOWATTRIBS_X, SHOWATTRIBS_Y);
- }
- if (ms_pguiInfo)
- {
- ms_pguiInfo->Move(INFO_X, INFO_Y);
- }
- long lEdgeOvershoot;
- // If not clipping to realm . . .
- if (pcamera->m_bClip == false)
- {
- lEdgeOvershoot = ms_lEdgeOvershoot;
- }
- else
- {
- lEdgeOvershoot = 0;
- }
- // (Re)Create scrollbars at appropriate sizes . . .
- if (ms_sbVert.Create(
- sViewW,
- 0,
- SCROLL_BAR_THICKNESS,
- sViewH + SCROLL_BAR_THICKNESS,
- sDisplayD) == 0)
- {
- // Set scroll range.
- if (phood != NULL)
- {
- ms_sbVert.SetRange(-lEdgeOvershoot, phood->GetHeight() - sViewH + lEdgeOvershoot);
- }
- else
- {
- ms_sbVert.SetRange(0, 0);
- }
- ms_sbVert.m_lTrayIncDec = sViewH - SCROLL_BTN_INCDEC;
- ms_sbVert.m_lButtonIncDec = SCROLL_BTN_INCDEC;
- ms_sbVert.m_lPosPerSecond = sViewH * 2;
- }
- else
- {
- TRACE("SizeUpdate(): ms_sbVert.Create() failed.\n");
- sRes = -3;
- }
- if (ms_sbHorz.Create(
- 0,
- sViewH,
- sViewW,
- SCROLL_BAR_THICKNESS,
- sDisplayD) == 0)
- {
- // Set scroll range.
- if (phood != NULL)
- {
- ms_sbHorz.SetRange(-lEdgeOvershoot, phood->GetWidth() - sViewW + lEdgeOvershoot);
- }
- else
- {
- ms_sbHorz.SetRange(0, 0);
- }
- ms_sbHorz.m_lTrayIncDec = sViewW - SCROLL_BTN_INCDEC;
- ms_sbHorz.m_lButtonIncDec = SCROLL_BTN_INCDEC;
- ms_sbHorz.m_lPosPerSecond = sViewW * 2;
- }
- else
- {
- TRACE("SizeUpdate(): ms_sbHorz.Create() failed.\n");
- sRes = -3;
- }
- // Re-Create attribute displayer sprite.
- SizeShowAttribsSprite();
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Get the Editor Thing from the specified realm.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static CGameEditThing* GetEditorThing( // Returns ptr to editor thing for
- // specified realm or NULL.
- CRealm* prealm) // Realm to get editor thing from.
- {
- CGameEditThing* pgething = NULL;
- if (prealm->m_asClassNumThings[CThing::CGameEditThingID] > 0)
- {
- pgething = (CGameEditThing*) prealm->m_aclassHeads[CThing::CGameEditThingID].GetNext();
- }
- else
- {
- TRACE("GetEditorThing(): No editor thing.\n");
- }
- return pgething;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Callback from GUIs. This will set ms_lPressedId to pgui->m_lId.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void GuiPressedCall( // Returns nothing.
- RGuiItem* pgui) // GUI item pressed.
- {
- // Set ID of item pressed.
- ms_lPressedId = pgui->m_lId;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Callback from pressed list items.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void ListItemPressedCall( // Returns nothing.
- RGuiItem* pgui) // GUI item pressed.
- {
- // If not dragging . . .
- if (ms_sMoving == FALSE)
- {
- // Default logic.
- GuiPressedCall(pgui);
- // Select item.
- RListBox* plb = (RListBox*)pgui->m_ulUserInstance;
- if (plb != NULL)
- {
- // Set new item as selection.
- plb->SetSel(pgui);
- }
- else
- {
- TRACE("ListItemPressedCall(): ListItem has no parent? That would be wrong.\n");
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Callback from Nav Net listbox
- //
- ////////////////////////////////////////////////////////////////////////////////
- void NavNetListPressedCall( // Returns nothing
- RGuiItem* pgui) // GUI item pressed
- {
- // Default logic
- // GuiPressedCall(pgui);
- // Select item
- RGuiItem* pitem = (RGuiItem*) pgui->GetParent();
- RListBox* plb = (RListBox*) pitem->GetParent();
- if (plb != NULL)
- {
- // Set selection
- plb->SetSel(pgui);
- // Set as default Nav Net
- ((CNavigationNet*) pgui->m_ulUserInstance)->SetAsDefault();
- // Make the net lines redraw
- UpdateNetLines((CNavigationNet*) pgui->m_ulUserInstance);
- }
- else
- {
- TRACE("NavNetListPressedCall(): List Item has no parent?\n");
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Callback from scrollbars indicating change in thumb position.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void ScrollPosUpdate( // Returns nothing.
- RScrollBar* psb) // ScrollBar that was updated.
- {
- // Switch on orientation. Say....
- switch (psb->m_oOrientation)
- {
- case RScrollBar::Vertical:
- // If there's a camera . . .
- if (ms_pcameraCur != NULL)
- {
- ms_pcameraCur->m_sSceneViewY = psb->GetPos();
- ms_pcameraCur->Update();
- }
- // If there is an editor object . . .
- if (ms_pgething != NULL)
- {
- ms_pgething->m_sViewPosY = psb->GetPos();
- }
- break;
- case RScrollBar::Horizontal:
- // If there's a camera . . .
- if (ms_pcameraCur != NULL)
- {
- ms_pcameraCur->m_sSceneViewX = psb->GetPos();
- ms_pcameraCur->Update();
- }
- // If there is an editor object . . .
- if (ms_pgething != NULL)
- {
- ms_pgething->m_sViewPosX = psb->GetPos();
- }
- break;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Callback from RHot when an event occurs within it.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void ThingHotCall( // Returns nothing.
- RHot* phot, // Ptr to RHot that generated event.
- RInputEvent* pie) // In: Most recent user input event.
- // Out: Depends on callbacks. Generally,
- // pie->sUsed = TRUE, if used.
- {
- CThing* pthing = (CThing*)phot->m_ulUser;
- ASSERT(pthing != NULL);
- // If not used . . .
- if (pie->sUsed == FALSE)
- {
- // Switch on event.
- switch (pie->sEvent)
- {
- case RSP_MB0_PRESSED:
- {
- SetSel(pthing, phot);
- // Note that we used the event.
- pie->sUsed = TRUE;
- pie->lUser = 1;
- break;
- }
- case RSP_MB0_RELEASED:
- {
- SetSel(pthing, phot);
- // If EDIT_KEY_SENDTOBACK held down . . .
- UCHAR aucKeys[128];
- rspScanKeys(aucKeys);
- if (aucKeys[EDIT_KEY_SENDTOBACK] != 0)
- {
- // Send this hot to back.
- phot->SetPriority(++ms_sBackPriority);
- // If we hit the back . . .
- if (ms_sBackPriority == RHOT_NO_PRIORITY)
- {
- ResetHotPriorities();
- }
- // Unselect.
- SetSel(NULL, NULL);
- }
- // If EDIT_KEY_SETCAMERATRACK held down . . .
- else if (aucKeys[EDIT_KEY_SETCAMERATRACK] != 0)
- {
- // If there is an editor thing . . .
- if (ms_pgething != NULL)
- {
- // If this thing is not the hood . . .
- if (pthing->GetClassID() != CThing::CHoodID)
- {
- // Get ID of item to track.
- ms_pgething->m_u16CameraTrackId = pthing->GetInstanceID();
- }
- else
- {
- // Clear camera track ID.
- ms_pgething->m_u16CameraTrackId = CIdBank::IdNil;
- }
- // User feedback.
- PlaySample(g_smidGeneralBeep, SampleMaster::UserFeedBack);
- }
- else
- {
- TRACE("ThingHotCall(): No Editor CThing.\n");
- }
- }
- // Note that we used the event.
- pie->sUsed = TRUE;
- pie->lUser = 1;
- break;
- }
- // This works on the Mac too because we faked a right mouse button
- // earlier in DoInput.
- // System_Key+Mouse_Button on the mac == PC right mouse button
- case RSP_MB1_PRESSED:
- {
- SetSel(pthing, phot);
- // Size may have changed.
- RRect rc;
- ms_pthingSel->EditRect(&rc);
- // Update hot.
- ms_photSel->m_sX = rc.sX;
- ms_photSel->m_sY = rc.sY;
- ms_photSel->m_sW = rc.sW;
- ms_photSel->m_sH = rc.sH;
- // See if a bouy was double clicked on
- if (ms_pthingSel->GetClassID() == CThing::CBouyID)
- {
- // If no bouys have been clicked on yet, set the
- // starting bouy link and start drawing the line
- if ((m_pBouyLink0 == NULL && m_pBouyLink1 == NULL) ||
- (m_pBouyLink0 != NULL && m_pBouyLink1 != NULL))
- {
- m_pBouyLink0 = (CBouy*) ms_pthingSel;
- m_pBouyLink1 = NULL;
-
- }
- // This is the ending bouy
- else if (m_pBouyLink0 != NULL && m_pBouyLink1 == NULL)
- {
- m_pBouyLink1 = (CBouy*) ms_pthingSel;
- m_pBouyLink0->AddLink(m_pBouyLink1);
- m_pBouyLink1->AddLink(m_pBouyLink0);
- AddNewLine(m_pBouyLink0->GetX(),
- m_pBouyLink0->GetZ(),
- m_pBouyLink1->GetX(),
- m_pBouyLink1->GetZ());
- }
- }
- // If they double clicked on something other than a bouy
- // while they were drawing a bouy link line, then abort
- // the link draw.
- else if (m_pBouyLink0 != NULL && m_pBouyLink1 == NULL)
- {
- m_pBouyLink0 = m_pBouyLink1 = NULL;
- }
- // Note that we used the event.
- pie->sUsed = TRUE;
- pie->lUser = 1;
- break;
- }
- case RSP_MB0_DOUBLECLICK:
- {
- SetSel(pthing, phot);
- // Modify.
- ms_pthingSel->EditModify();
- // Size may have changed.
- RRect rc;
- ms_pthingSel->EditRect(&rc);
- // Update hot.
- ms_photSel->m_sX = rc.sX;
- ms_photSel->m_sY = rc.sY;
- ms_photSel->m_sW = rc.sW;
- ms_photSel->m_sH = rc.sH;
- // Note that we used the event.
- pie->sUsed = TRUE;
- pie->lUser = 1;
- break;
- }
- case RSP_MB1_DOUBLECLICK:
- {
- SetSel(pthing, phot);
- // If this is a pylon . . .
- if (ms_pthingSel->GetClassID() == CThing::CPylonID)
- {
- // Enter pylon trigger region edit mode.
- EditPylonTriggerRegion(ms_pthingSel);
- // Note that we used the event.
- pie->sUsed = TRUE;
- pie->lUser = 1;
- }
- break;
- }
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Draw the link between the first bouy selected and the mouse cursor
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void DrawBouyLink( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera) // In: View of prealm.
- {
- short sMouseX;
- short sMouseY;
- short sButtons;
- if (ms_bDrawNetwork && m_pBouyLink0 != NULL && m_pBouyLink1 != NULL &&
- m_pBouyLink0->Visible() && m_pBouyLink1->Visible())
- {
- // These lines show the paths the characters would take so
- // they should be only on the X/Z plane and, therefore, Y
- // is ignored.
- short sBouyLink0X, sBouyLink0Y;
- Maprealm2Screen(
- prealm,
- pcamera,
- m_pBouyLink0->GetX(),
- 0,
- m_pBouyLink0->GetZ(),
- &sBouyLink0X,
- &sBouyLink0Y);
- short sBouyLink1X, sBouyLink1Y;
- Maprealm2Screen(
- prealm,
- pcamera,
- m_pBouyLink1->GetX(),
- 0,
- m_pBouyLink1->GetZ(),
- &sBouyLink1X,
- &sBouyLink1Y);
- rspLine(249, g_pimScreenBuf,
- sBouyLink0X,
- sBouyLink0Y,
- sBouyLink1X,
- sBouyLink1Y);
- }
- else if (m_pBouyLink0 != NULL && m_pBouyLink1 == NULL)
- {
- // These lines show the paths the characters would take so
- // they should be only on the X/Z plane and, therefore, Y
- // is ignored.
- short sBouyLink0X, sBouyLink0Y;
- Maprealm2Screen(
- prealm,
- pcamera,
- m_pBouyLink0->GetX(),
- 0,
- m_pBouyLink0->GetZ(),
- &sBouyLink0X,
- &sBouyLink0Y);
- rspGetMouse(&sMouseX, &sMouseY, &sButtons);
- rspLine(249, g_pimScreenBuf,
- sBouyLink0X,
- sBouyLink0Y,
- sMouseX, sMouseY);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Resets all RHots including and descended from ms_photHood
- // to FRONTMOST_HOT_PRIORITY.
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void ResetHotPriorities(void) // Returns nothing.
- {
- if (ms_photHood != NULL)
- {
- // Set Hood's priority.
- ms_photHood->SetPriority(FRONTMOST_HOT_PRIORITY);
- // Do children.
- RHot* phot = ms_photHood->m_listChildren.GetHead();
- while (phot != NULL)
- {
- phot->SetPriority(FRONTMOST_HOT_PRIORITY);
- phot = ms_photHood->m_listChildren.GetNext();
- }
- // Reset backmost priority.
- ms_sBackPriority = FRONTMOST_HOT_PRIORITY;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // AddNewLine
- ////////////////////////////////////////////////////////////////////////////////
- static void AddNewLine(short sX0, short sY0, short sX1, short sY1)
- {
- LINKLINE newLine;
- // Sort the lines by smaller x. If the X is the same then sort
- // by Y. By presorting the lines before adding them, a line with
- // endpoints (x,y) (a,b) and a line (a,b) (x,y) will only be added to
- // the set once as the line (a,b) (x,y) which saves memory and
- // speeds the drawing.
- if (sX0 == sX1)
- {
- if (sY0 < sY1)
- {
- newLine.sX0 = sX0;
- newLine.sY0 = sY0;
- newLine.sX1 = sX1;
- newLine.sY1 = sY1;
- }
- else
- {
- newLine.sX0 = sX1;
- newLine.sY0 = sY1;
- newLine.sX1 = sX0;
- newLine.sY1 = sY0;
- }
- }
- else
- {
- if (sX0 < sX1)
- {
- newLine.sX0 = sX0;
- newLine.sY0 = sY0;
- newLine.sX1 = sX1;
- newLine.sY1 = sY1;
- }
- else
- {
- newLine.sX0 = sX1;
- newLine.sY0 = sY1;
- newLine.sX1 = sX0;
- newLine.sY1 = sY0;
- }
- }
- // Add the line to the set of lines
- m_NetLines.insert(newLine);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Write a NavNet log file to display the connections.- for debugging purposes
- ////////////////////////////////////////////////////////////////////////////////
- static void NetLog(CNavigationNet* pNavNet)
- {
- /*
- ofstream txtout;
- ofstream routeout;
- CNavigationNet::nodeMap::iterator ibouy;
- CBouy::linkset::iterator ilink;
- UCHAR i;
- UCHAR ucHops;
- txtout.open("c:\\temp\\navnet.txt");
- routeout.open("c:\\temp\\navroute.txt");
- if (txtout.is_open() && routeout.is_open())
- {
- txtout << ";\n";
- txtout << "; NavNet connections file" << endl;
- txtout << ";" << endl;
- txtout << "; Node: Directly connected nodes\n";
- txtout << ";------------------------------------------------------------------\n";
- routeout << ";Bouy Routing Tables" << endl;
- routeout << ";" << endl;
- routeout << ";-----------------------------------------------------------------\n";
- if (pNavNet)
- {
- for (ibouy = pNavNet->m_NodeMap.begin();
- ibouy != pNavNet->m_NodeMap.end(); ibouy++)
- {
- txtout << (USHORT) ((*ibouy).second->m_ucID) << " : ";
- for (ilink = (*ibouy).second->m_apsDirectLinks.begin();
- ilink != (*ibouy).second->m_apsDirectLinks.end(); ilink++)
- {
- txtout << (USHORT) (*ilink)->m_ucID << ", ";
- }
- txtout << endl;
- // Show routing table for reachable links
- routeout << "bouy " << (USHORT) ((*ibouy).second->m_ucID) << endl;
- for (i = 1; i < pNavNet->GetNumNodes(); i++)
- {
- ucHops = (*ibouy).second->NextRouteNode(i);
- if (ucHops < 255)
- {
- routeout << " vialink[" << (USHORT) i << "] = " << (USHORT) ucHops << endl;
- }
- }
-
- }
- }
-
- txtout.close();
- routeout.close();
- }
- else
- {
- TRACE("NetLog: Error opening log file for output\n");
- }
- */
- }
- ////////////////////////////////////////////////////////////////////////////////
- // UpdateNetLines
- ////////////////////////////////////////////////////////////////////////////////
- static void UpdateNetLines(CNavigationNet* pNavNet)
- {
- CNavigationNet::nodeMap::iterator ibouy;
- CBouy* pLinkedBouy = NULL;
- if (pNavNet)
- {
- m_NetLines.erase(m_NetLines.begin(), m_NetLines.end());
- for (ibouy = pNavNet->m_NodeMap.begin();
- ibouy != pNavNet->m_NodeMap.end(); ibouy++)
- {
- pLinkedBouy = (*ibouy).second->m_aplDirectLinks.GetHead();
- while (pLinkedBouy)
- {
- AddNewLine((*ibouy).second->GetX(),
- (*ibouy).second->GetZ(),
- pLinkedBouy->GetX(),
- pLinkedBouy->GetZ());
- pLinkedBouy = (*ibouy).second->m_aplDirectLinks.GetNext();
- }
- }
- }
- else
- {
- m_NetLines.erase(m_NetLines.begin(), m_NetLines.end());
- }
- /*
- CNavigationNet::nodeMap::iterator ibouy;
- CBouy::linkset::iterator ilink;
- if (pNavNet)
- {
- m_NetLines.erase(m_NetLines.begin(), m_NetLines.end());
- for (ibouy = pNavNet->m_NodeMap.begin();
- ibouy != pNavNet->m_NodeMap.end(); ibouy++)
- {
- for (ilink = (*ibouy).second->m_apsDirectLinks.begin();
- ilink != (*ibouy).second->m_apsDirectLinks.end(); ilink++)
- {
- AddNewLine((*ibouy).second->GetX(),
- (*ibouy).second->GetZ(),
- (*ilink)->GetX(),
- (*ilink)->GetZ());
- }
- }
- }
- */
- // NetLog(pNavNet);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // DrawNetwork
- ////////////////////////////////////////////////////////////////////////////////
- static void DrawNetwork( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera) // In: View of prealm.
- {
- lineset::iterator i;
-
- if (ms_bDrawNetwork)
- {
- for (i = m_NetLines.begin(); i != m_NetLines.end(); i++)
- {
- // These lines show the paths the characters would take so
- // they should be only on the X/Z plane and, therefore, Y
- // is ignored.
- short sBouyLink0X, sBouyLink0Y;
- Maprealm2Screen(
- prealm,
- pcamera,
- (*i).sX0,
- 0,
- (*i).sY0,
- &sBouyLink0X,
- &sBouyLink0Y);
- short sBouyLink1X, sBouyLink1Y;
- Maprealm2Screen(
- prealm,
- pcamera,
- (*i).sX1,
- 0,
- (*i).sY1,
- &sBouyLink1X,
- &sBouyLink1Y);
- rspLine(250, g_pimScreenBuf,
- sBouyLink0X,
- sBouyLink0Y,
- sBouyLink1X,
- sBouyLink1Y);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Creates a view and adds it to the list of views.
- ////////////////////////////////////////////////////////////////////////////////
- static short AddView( // Returns 0 on success.
- CRealm* prealm) // In: Realm in which to setup camera.
- {
- static short sNum = 0;
- short sRes = 0; // Assume success.
- RListBox* plb = (RListBox*)ms_pguiCameras->GetItemFromId(GUI_ID_CAMERA_LIST);
- if (plb != NULL)
- {
- View* pview;
- if (CreateView(&pview, prealm) == 0)
- {
- char szTitle[256];
- sprintf(szTitle, "Camera %d", ++sNum);
- RGuiItem* pgui = plb->AddString(szTitle);
- pgui->m_lId = (long)pview;
- plb->AdjustContents();
- pview->pgui->SetText("%s", szTitle);
- pview->pgui->Compose();
- }
- else
- {
- sRes = -2;
- }
- }
- else
- {
- sRes = -1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Kills a view and removes it from the list of views.
- ////////////////////////////////////////////////////////////////////////////////
- static void RemoveView( // Returns nothing.
- View* pview) // In: View to remove or NULL to remove currently
- // selected view.
- {
- RListBox* plb = (RListBox*)ms_pguiCameras->GetItemFromId(GUI_ID_CAMERA_LIST);
- if (plb != NULL)
- {
- RGuiItem* pguiRemove;
- if (pview != NULL)
- {
- pguiRemove = plb->GetItemFromId((long)pview);
- }
- else
- {
- pguiRemove = plb->GetSel();
- }
- if (pguiRemove != NULL)
- {
- KillView((View*)(pguiRemove->m_lId));
- plb->RemoveItem(pguiRemove);
- plb->AdjustContents();
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Removes all current views.
- ////////////////////////////////////////////////////////////////////////////////
- static void RemoveViews(void)
- {
- View* pview = ms_listViews.GetHead();
- while (pview != NULL)
- {
- RemoveView(pview);
- pview = ms_listViews.GetNext();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Creates a new View and adds it to the list of Views.
- ////////////////////////////////////////////////////////////////////////////////
- static short CreateView( // Returns 0 on success.
- View** ppview, // Out: New view, if not NULL.
- CRealm* prealm) // In: Realm in which to setup camera.
- {
- short sRes = 0; // Assume success.
- if (ppview != NULL)
- {
- *ppview = NULL; // Safety.
- }
- // Create view . . .
- View* pview = new View;
- if (pview != NULL)
- {
- // Create and load GUI . . .
- pview->pgui = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, VIEW_GUI_FILE) );
- if (pview->pgui != NULL)
- {
- pview->pgui->GetClient(NULL, NULL, &(pview->sViewW), &(pview->sViewH) );
- // Get the scrollbars.
- pview->psbVert = (RScrollBar*)pview->pgui->GetItemFromId(3);
- pview->psbHorz = (RScrollBar*)pview->pgui->GetItemFromId(4);
- // Adjust dimensions to make scrollbars visible.
- if (pview->psbVert != NULL)
- {
- pview->sViewW -= pview->psbVert->m_im.m_sWidth;
- }
- if (pview->psbHorz != NULL)
- {
- pview->sViewH -= pview->psbHorz->m_im.m_sHeight;
- }
- // Set scrollbar range based on view size and realm size.
- if (pview->psbVert != NULL)
- {
- pview->psbVert->SetRange(0, prealm->m_phood->GetHeight() - pview->sViewH);
- }
- if (pview->psbHorz != NULL)
- {
- pview->psbHorz->SetRange(0, prealm->m_phood->GetWidth() - pview->sViewW);
- }
- // Add to list . . .
- if (ms_listViews.Add(pview) == 0)
- {
- // Activate.
- pview->pgui->SetVisible(TRUE);
- // Succcess.
- if (ppview != NULL)
- {
- *ppview = pview;
- }
- }
- else
- {
- TRACE("CreateView(): Failed to add view to list.\n");
- sRes = -3;
- }
- // If an error occurred after allocating GUI . . .
- if (sRes != 0)
- {
- delete pview->pgui;
- }
- }
- else
- {
- TRACE("CreateView(): Failed to load %s.\n", VIEW_GUI_FILE);
- sRes = -2;
- }
- // If an error occurred after allocating View . . .
- if (sRes != 0)
- {
- delete pview;
- }
- }
- else
- {
- TRACE("CreateView(): Failed to allocate new View.\n");
- sRes = -1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Destroys a View and removes it from the list of Views.
- ////////////////////////////////////////////////////////////////////////////////
- static void KillView( // Returns nothing.
- View* pview) // View to kill.
- {
- // Remove from list.
- ms_listViews.Remove(pview);
- // Delete.
- delete pview;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Draw specified view.
- ////////////////////////////////////////////////////////////////////////////////
- static void DrawView( // Returns nothing.
- View* pview, // View to draw.
- CRealm* prealm) // Realm to draw.
- {
- // Get client.
- short sClientPosX, sClientPosY;
- pview->pgui->GetClient(&sClientPosX, &sClientPosY, NULL, NULL);
-
- // Add in GUI's position.
- sClientPosX += pview->pgui->m_sX;
- sClientPosY += pview->pgui->m_sY;
-
- // Use scrollbars for position.
- short sViewX = 0; // Safety.
- short sViewY = 0; // Safety.
- if (pview->psbVert != NULL)
- {
- sViewY = pview->psbVert->GetPos();
- }
-
- if (pview->psbHorz != NULL)
- {
- sViewX = pview->psbHorz->GetPos();
- }
- // Draw GUI.
- pview->pgui->Draw(g_pimScreenBuf);
-
- // Draw scene.
- pview->cam.Snap(
- pview->sViewW, // In: View's width
- pview->sViewH, // In: View's height
- &(prealm->m_scene), // In: Scene to take picture of
- prealm->m_phood, // In: Da hood.
- sViewX, // In: View's upper left x (in scene coords)
- sViewY, // In: View's upper left y (in scene coords)
- g_pimScreenBuf, // In: Film (where the picture ends up)
- sClientPosX, // In: View's upper left x (in film coords)
- sClientPosY // In: View's upper left y (in film coords)
- );
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Draw all views.
- ////////////////////////////////////////////////////////////////////////////////
- static void DrawViews( // Returns nothing.
- CRealm* prealm) // Realm to draw.
- {
- View* pview = ms_listViews.GetHead();
- while (pview != NULL)
- {
- DrawView(pview, prealm);
- pview = ms_listViews.GetNext();
- }
- ms_pguiCameras->Draw(g_pimScreenBuf);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Clear specified view.
- ////////////////////////////////////////////////////////////////////////////////
- static void ClearGUI( // Returns nothing.
- RGuiItem* pgui) // In: GUI's whose area we should clean.
- {
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- pgui->m_sX,
- pgui->m_sY,
- pgui->m_im.m_sWidth,
- pgui->m_im.m_sHeight);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Clear all views.
- ////////////////////////////////////////////////////////////////////////////////
- static void ClearViews(void) // Returns nothing.
- {
- View* pview = ms_listViews.GetHead();
- while (pview != NULL)
- {
- ClearGUI(pview->pgui);
- pview = ms_listViews.GetNext();
- }
- ClearGUI(ms_pguiCameras);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Do focus hotbox logic and such for GUIs.
- ////////////////////////////////////////////////////////////////////////////////
- static void DoView( // Returns nothing.
- View* pview, // View to do.
- RInputEvent* pie) // Input event to process.
- {
- pview->pgui->m_hot.Do(pie);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Do all views.
- ////////////////////////////////////////////////////////////////////////////////
- static void DoViews(
- RInputEvent* pie) // Input event to process.
- {
- ms_pguiCameras->m_hot.Do(pie);
- View* pview = ms_listViews.GetTail();
- while (pview != NULL)
- {
- DoView(pview, pie);
- pview = ms_listViews.GetPrev();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Draw the map.
- ////////////////////////////////////////////////////////////////////////////////
- static void RefreshMap( // Returns nothing.
- CRealm* prealm) // Realm to map.
- {
- ASSERT(ms_pguiMap != NULL);
- // Get area to draw in.
- if (ms_pguiMapZone != NULL)
- {
- // Clear.
- ms_pguiMapZone->Compose();
- short sClientX, sClientY, sClientW, sClientH;
- ms_pguiMapZone->GetClient(&sClientX, &sClientY, &sClientW, &sClientH);
-
- // Allocate temp camera and film . . .
- CCamera camera;
- RImage imFilm;
- short sViewW = prealm->m_phood->m_pimBackground->m_sWidth;
- short sViewH = prealm->m_phood->m_pimBackground->m_sHeight;
- if (imFilm.CreateImage(
- sViewW,
- sViewH,
- RImage::BMP8) == 0)
- {
- // Take a shot.
- camera.Snap(
- sViewW, // In: View's width
- sViewH, // In: View's height
- &(prealm->m_scene), // In: Scene to take picture of
- prealm->m_phood, // In: Hood for this scene.
- 0, // In: View's upper left x (in scene coords)
- 0, // In: View's upper left y (in scene coords)
- &imFilm, // In: Film (where the picture ends up)
- 0, // In: View's upper left x (in film coords)
- 0); // In: View's upper left y (in film coords)
- // Stretch it as necessary to the map view.
- double dRatioX = (double)sClientW / (double)sViewW;
- double dRatioY = (double)sClientH / (double)sViewH;
- ms_dMapRatio = MIN(dRatioX, dRatioY);
- RRect rcClip(sClientX, sClientY, sClientW, sClientH);
- rspBlitT(
- &imFilm, // Src.
- &(ms_pguiMapZone->m_im), // Dst.
- sClientX, // Dst x.
- sClientY, // Dst y.
- ms_dMapRatio, // Scale x.
- ms_dMapRatio, // Scale y.
- &rcClip); // Dst clip.
- }
- else
- {
- TRACE("RefreshMap(): Failed to allocate image at size of the realm.\n");
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Cancel any thing drag.
- ////////////////////////////////////////////////////////////////////////////////
- static void CancelDrag(CRealm* prealm) // Returns nothing.
- {
- // If there is an item being moved . . .
- if (ms_sMoving != FALSE)
- {
- DelThing(ms_pthingSel, ms_photSel, prealm);
- ms_sMoving = FALSE;
- rspShowMouseCursor();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Place any thing being dragged.
- ////////////////////////////////////////////////////////////////////////////////
- static void DragDrop( // Returns nothing.
- short sDropX, // In: Drop x position.
- short sDropY, // In: Drop y position.
- short sDropZ) // In: Drop z position.
- {
- // If there is an item being moved . . .
- if (ms_sMoving != FALSE)
- {
- ASSERT(ms_pthingSel != NULL);
- ASSERT(ms_photSel != NULL);
- // Final position.
- MoveThing(
- ms_pthingSel,
- ms_photSel,
- sDropX,
- sDropY,
- sDropZ);
- SetSel(NULL, NULL);
- ms_sMoving = FALSE;
- rspShowMouseCursor();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by the menu callback when it wants to tell the editor to continue
- // editting (end the menu).
- ////////////////////////////////////////////////////////////////////////////////
- extern void Edit_Menu_Continue(void)
- {
- StopMenu();
- // Restore our favorite font...size is no matter.
- RGuiItem::ms_print.SetFont(15, &EDITOR_GUI_FONT);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Called by the menu callback when it wants to tell the editor to quit the
- // editor.
- ////////////////////////////////////////////////////////////////////////////////
- extern void Edit_Menu_ExitEditor(void)
- {
- ms_lPressedId = GUI_ID_EXIT;
- StopMenu();
- // Restore our favorite font...size is no matter.
- RGuiItem::ms_print.SetFont(15, &EDITOR_GUI_FONT);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Convert a .RLM filename to a .RGN one.
- ////////////////////////////////////////////////////////////////////////////////
- static void RlmNameToRgnName( // Returns nothing.
- char* pszRealmName, // In: .RLM name.
- char* pszRgnName) // Out: .RGN name.
- {
- short sIndex = strlen(pszRealmName);
- while (sIndex-- >= 0)
- {
- if (pszRealmName[sIndex] == '\\')
- {
- sIndex = strlen(pszRealmName);
- break;
- }
- if (pszRealmName[sIndex] == '.')
- {
- break;
- }
- }
- if (sIndex < 0)
- {
- sIndex = strlen(pszRealmName);
- }
- strncpy(pszRgnName, pszRealmName, sIndex);
- pszRgnName[sIndex] = '\0';
- strcat(pszRgnName, ".rgn");
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Move focus to next item in realm's thing list.
- ////////////////////////////////////////////////////////////////////////////////
- static void NextItem( // Returns nothing.
- CRealm* prealm) // In: The realm we want the next thing in.
- {
- if (ms_pthingSel != NULL)
- {
- // This may make ms_pthingSel NULL.
- SetSel(ms_pthingSel->m_everything.GetNext(), NULL);
- }
- if (ms_pthingSel == NULL)
- {
- SetSel(prealm->m_everythingHead.GetNext(), NULL);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Move focus to previous item in realm's thing list.
- ////////////////////////////////////////////////////////////////////////////////
- static void PrevItem( // Returns nothing.
- CRealm* prealm) // In: The realm we want the next thing in.
- {
- if (ms_pthingSel != NULL)
- {
- // This may make ms_pthingSel NULL.
- SetSel(ms_pthingSel->m_everything.GetPrev(), NULL);
- }
- if (ms_pthingSel == NULL)
- {
- SetSel(prealm->m_everythingTail.GetPrev(), NULL);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Load the trigger regions for the specified realm.
- ////////////////////////////////////////////////////////////////////////////////
- static short LoadTriggerRegions( // Returns 0 on success.
- char* pszRealmName) // In: Name of the REALM (*.RLM) file.
- // The .ext is stripped and .rgn is appended.
- {
- short sRes = 0; // Assume success.
- // Change filename to .RGN name.
- char szRgnName[RSP_MAX_PATH];
- RlmNameToRgnName(pszRealmName, szRgnName);
- RFile file;
- if (file.Open(szRgnName, "rb", RFile::LittleEndian) == 0)
- {
- short i;
- for (i = 0; i < NUM_ELEMENTS(ms_argns) && sRes == 0; i++)
- {
- sRes = ms_argns[i].Load(&file);
- }
- file.Close();
- }
- else
- {
- TRACE("LoadTriggerRegions(): WARNING: \"%s\" could not be opened.\n", szRgnName);
- sRes = 1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Save the trigger regions for the specified realm.
- ////////////////////////////////////////////////////////////////////////////////
- static short SaveTriggerRegions( // Returns 0 on success.
- char* pszRealmName, // In: Name of the REALM (*.RLM) file.
- CRealm* prealm // In: Access of Realm Info
- ) // The .ext is stripped and .rgn is appended.
- {
- short sRes = 0; // Assume success.
- // Change filename to .RGN name.
- char szRgnName[RSP_MAX_PATH];
- RlmNameToRgnName(pszRealmName, szRgnName);
- RFile file;
- if (file.Open(szRgnName, "wb", RFile::LittleEndian) == 0)
- {
- short i;
- for (i = 0; i < NUM_ELEMENTS(ms_argns) && sRes == 0; i++)
- {
- sRes = ms_argns[i].Save(&file);
- }
- file.Close();
- }
- else
- {
- TRACE("SaveTriggerRegions(): Could not open \"%s\" for write.\n", szRgnName);
- sRes = -1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Create an attribute map for the trigger regions for the specified realm.
- // (And attaches it to the Realm for saving...)
- // The current technique is that the CREALM must ALWAYS have a cTrigger in it,
- // which in itself contains the pointer m_pmgi.
- ////////////////////////////////////////////////////////////////////////////////
- static short CreateTriggerRegions( // Returns 0 on success.
- CRealm* prealm // In: Access of Realm Info
- )
- {
- short sRes = 0; // Assume success.
- if (prealm->m_pTriggerMapHolder == NULL)
- {
- short sResult;
- TRACE("CreateTriggerRegions(): No default CThing to hold triggers!\n");
- TRACE("CreateTriggerRegions(): Adding one for your convenience!\n");
- CThing* pThing = NULL;
- RHot* photdummy;
- sResult = CreateNewThing(prealm, CThing::CTriggerID, 0, 0, 0, &pThing, &photdummy);
- if (sResult == 0)
- {
- prealm -> m_pTriggerMap = ((CTrigger*)pThing)->m_pmgi;
- }
- else
- {
- TRACE("CreateTriggerRegions(): I really, REALLY tried, but there won't be trigger info\n");
- return -1;
- }
-
- }
- // REMOVE THE OLD TRIGGER MAP!
- if (prealm->m_pTriggerMap) delete prealm->m_pTriggerMap;
- prealm->m_pTriggerMap = NULL;
- ////////////////////////////////////////////////////////////////////////////////
- // Create, Compress, and Save the trigger attribute map for the specified realm.
- ////////////////////////////////////////////////////////////////////////////////
- RMultiGridIndirect* pTriggers = NULL;
- // Let's try going with a maximum of EIGHT overlapping regions for now.
- // And we'll try 32 x 32 tiles for now. Assume tries largest to smallest.
- pTriggers = CreateRegionMap(prealm->m_phood->GetWidth(),
- prealm->m_phood->GetHeight(),8, 32,32);
- if (!pTriggers)
- {
- TRACE("CreateTriggerRegions(): Could not create region attributes!\n");
- sRes = -1;
- }
- else
- {
- if (StrafeAddRegion(pTriggers,ms_argns))
- {
- TRACE("CreateTriggerRegions(): Problem adding attributes!\n");
- sRes = -1;
- delete pTriggers;
- }
- else
- {
- // Create a seondary palette table index
- for (short i = 0;i < 256; i++)
- {
- prealm->m_asPylonUIDs[i] = 0;
- prealm->m_pTriggerMapHolder->m_ausPylonUIDs[i] = 0;
- if (ms_argns[i].pimRgn)
- {
- prealm->m_asPylonUIDs[i] = ms_argns[i].u16InstanceId;
- // Set into the CThing, thich for now is what REALLY counts!
- prealm->m_pTriggerMapHolder->m_ausPylonUIDs[i] = ms_argns[i].u16InstanceId;
- }
- }
- // again, need interactive logic!
- if (CompressMap(pTriggers,16,16) != SUCCESS)
- {
- TRACE("CreateTriggerRegions(): Problem compressing attributes!\n");
- sRes = -1;
- delete pTriggers;
- }
- else
- {
- // Instead os saving it, make it part of the realm:
- // Then, when the realm is saved, so will it be
- // FINALLY, INSTALL IT INTO THE REALM
- // Add it using the official member:
- prealm->m_pTriggerMapHolder->AddData(pTriggers);
- }
- }
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Change or clear the current pylon being edited.
- ////////////////////////////////////////////////////////////////////////////////
- static void EditPylonTriggerRegion( // Returns nothing.
- CThing* pthingPylon) // In: Pylon whose trigger area we want to
- {
- // If there's a current pylon being edited . . .
- if (ms_pylonEdit != NULL)
- {
- // Remove sprite from scene.
- ms_pylonEdit->m_pRealm->m_scene.RemoveSprite(&ms_spriteTriggerRgn);
- ms_spriteTriggerRgn.m_pImage = NULL;
- // Put it into storage mode.
- ms_argns[ms_pylonEdit->m_ucID].SetMode(TriggerRgn::Storage);
- // Clear.
- ms_pylonEdit = NULL;
- // Show mouse.
- rspShowMouseCursor();
- }
- // If there's a new pylon . . .
- if (pthingPylon != NULL)
- {
- ASSERT(pthingPylon->GetClassID() == CThing::CPylonID);
- CPylon* pylon = (CPylon*)pthingPylon;
- // If the region did not previously exist . . .
- if (ms_argns[pylon->m_ucID].pimRgn == NULL)
- {
- // Set location by mapping 3D pylon position to viewing surface
- // position.
- pthingPylon->m_pRealm->Map3Dto2D(
- pylon->GetX(),
- 0,
- pylon->GetZ(),
- &(ms_argns[pylon->m_ucID].sX),
- &(ms_argns[pylon->m_ucID].sY) );
- ms_argns[pylon->m_ucID].sX -= TriggerRgn::MaxRgnWidth / 2;
- ms_argns[pylon->m_ucID].sY -= TriggerRgn::MaxRgnHeight / 2;
- ms_argns[pylon->m_ucID].u16InstanceId = pylon->GetInstanceID();
- }
-
- // Attempt to put it into edit mode . . .
- if (ms_argns[pylon->m_ucID].SetMode(TriggerRgn::Edit) == 0)
- {
- ms_spriteTriggerRgn.m_pImage = ms_argns[pylon->m_ucID].pimRgn;
- ms_spriteTriggerRgn.m_sLayer = CRealm::LayerSprite16;
- ms_spriteTriggerRgn.m_sPriority = 32767; // Always on top.
- ms_spriteTriggerRgn.m_sX2 = ms_argns[pylon->m_ucID].sX;
- ms_spriteTriggerRgn.m_sY2 = ms_argns[pylon->m_ucID].sY;
- // Add sprite to scene.
- pylon->m_pRealm->m_scene.UpdateSprite(&ms_spriteTriggerRgn);
- // Success. Remember.
- ms_pylonEdit = pylon;
- // Hide mouse.
- rspHideMouseCursor();
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Set the selection to the specified CThing.
- ////////////////////////////////////////////////////////////////////////////////
- static CThing* SetSel( // Returns CThing that previously was selected.
- CThing* pthingSel, // In: CThing to be selected.
- RHot* photSel) // In: Hotbox of CThing to be selected.
- {
- CThing* pthingRes = ms_pthingSel;
- ms_pthingSel = pthingSel;
- ms_photSel = photSel;
- // If this is an actual CThing . . .
- if (ms_pthingSel != NULL)
- {
- // Don't allow GUI focus.
- RGuiItem::SetFocus(NULL);
-
- // If the corresponding hotbox was not specified . . .
- if (photSel == NULL)
- {
- // Get it.
- ms_photSel = ms_pthingSel->m_phot;
- }
- }
- UpdateSelectionInfo(true);
- return pthingRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Delete the specified item.
- ////////////////////////////////////////////////////////////////////////////////
- static void DelThing( // Returns nothing.
- CThing* pthingDel, // In: CThing to be deleted.
- RHot* photDel, // In: Hotbox of CThing to be deleted.
- CRealm* prealm) // In: Current Realm
- {
- if (pthingDel != NULL)
- {
- // If hot not specified . . .
- if (photDel == NULL)
- {
- photDel = pthingDel->m_phot;
- }
- CNavigationNet* pNavNet = NULL;
- switch (pthingDel->GetClassID())
- {
- case CThing::CHoodID:
- // *** LOCALIZE ***
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- "Delete Hood",
- "You may not delete the hood.");
- SetSel(NULL, NULL);
- pthingDel = NULL;
- photDel = NULL;
- break;
- case CThing::CGameEditThingID:
- // *** LOCALIZE ***
- rspMsgBox(
- RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- "Delete Hood",
- "You may not delete the CGameEditThing.");
- SetSel(NULL, NULL);
- pthingDel = NULL;
- photDel = NULL;
- break;
- case CThing::CPylonID:
- // Destroy its associated trigger region.
- ms_argns[((CPylon*)pthingDel)->m_ucID].Destroy();
- break;
- case CThing::CBouyID:
- // If it is a Bouy, unlink the bouy from the network and
- // update the network.
- ((CBouy*) ms_pthingSel)->Unlink();
- pNavNet = prealm->GetCurrentNavNet();
- pNavNet->RemoveBouy(((CBouy*) ms_pthingSel)->m_ucID);
- pNavNet->UpdateRoutingTables();
- // If you deleted one that the connection line was being
- // drawn to, then clear the connection line.
- if ((CBouy*) ms_pthingSel == m_pBouyLink0 ||
- (CBouy*) ms_pthingSel == m_pBouyLink1)
- m_pBouyLink0 = m_pBouyLink1 = NULL;
- // If the network lines are being shown, update them, otherwise
- // they will get updated when view lines is turned on.
- if (ms_bDrawNetwork)
- UpdateNetLines(pNavNet);
- break;
- case CThing::CNavigationNetID:
- // If it is a NavNet, delete all of the Bouys associated
- // with the NavNet. Make sure its not the last NavNet,
- // and make sure there is still a current NavNet for the
- // realm after it is deleted.
- if (prealm->m_asClassNumThings[CThing::CNavigationNetID] > 1)
- {
- // Remove the Net from the list box
- RListBox* plbRemove = (RListBox*) ms_pguiNavNets->GetItemFromId(GUI_ID_NAVNET_LIST);
- plbRemove->RemoveItem(plbRemove->GetItemFromId(ms_pthingSel->GetInstanceID()));
- plbRemove->Compose();
- // Delete the network and select a new current Net if this was the one.
- ((CNavigationNet*) ms_pthingSel)->DeleteNetwork();
- if (ms_pthingSel == prealm->GetCurrentNavNet())
- {
- CListNode<CThing>* pNext = prealm->m_aclassHeads[CThing::CNavigationNetID].m_pnNext;
- bool bSearching = true;
- CNavigationNet* pNet = NULL;
- while (bSearching && pNext->m_powner != NULL)
- {
- pNet = (CNavigationNet*) pNext->m_powner;
- if (ms_pthingSel != pNet)
- {
- pNet->SetAsDefault();
- bSearching = false;
- RListBox* plb = (RListBox*) ms_pguiNavNets->GetItemFromId(GUI_ID_NAVNET_LIST);
- plb->SetSel(plb->GetItemFromId(pNet->GetInstanceID()));
- UpdateNetLines(pNet);
- }
- pNext = pNext->m_pnNext;
- }
- }
- if (ms_bDrawNetwork)
- UpdateNetLines((CNavigationNet*) ms_pthingSel);
- }
- else
- {
- // *** LOCALIZE ***
- rspMsgBox(RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
- "Delete Navigation Net",
- "You may not delete the last remaining Navigation Net.");
- SetSel(NULL, NULL);
- pthingDel = NULL;
- photDel = NULL;
- }
- break;
- }
- // If we still have anything to delete . . .
- if (pthingDel)
- {
- // If there is an editor thing . . .
- if (ms_pgething != NULL)
- {
- // If this item was being tracked by camera . . .
- if (pthingDel->GetInstanceID() == ms_pgething->m_u16CameraTrackId)
- {
- // Done with that.
- ms_pgething->m_u16CameraTrackId = CIdBank::IdNil;
- }
- }
- // If this is the selection . . .
- if (pthingDel == ms_pthingSel)
- {
- SetSel(NULL, NULL);
- }
- }
- // If we were moving . . .
- if (ms_sMoving != FALSE)
- {
- // If nothing left to move . . .
- if (ms_pthingSel == NULL)
- {
- // Stop moving.
- ms_sMoving = FALSE;
- // Show mouse cursor.
- rspShowMouseCursor();
- }
- }
- }
- // Safe if NULL.
- delete pthingDel;
- delete photDel;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Delete all the items in the currently selected class.
- ////////////////////////////////////////////////////////////////////////////////
- static void DelClass( // Returns nothing.
- CThing* pthingDel, // In: CThing to be deleted.
- CRealm* prealm) // In: Current realm
- {
- char szTitle[512];
- sprintf(
- szTitle,
- "Delete entire \"%s\" class",
- (pthingDel != NULL)
- ? CThing::ms_aClassInfo[pthingDel->GetClassID()].pszClassName
- : "CThing"
- );
- // VERIFY . . .
- if (rspMsgBox(
- RSP_MB_ICN_QUERY | RSP_MB_BUT_YESNO,
- szTitle,
- "Are you sure you want to perform this group delete?!"
- ) == RSP_MB_RET_YES)
- {
- CListNode<CThing>* plnDel;
- CListNode<CThing>* plnTail;
- // If thing specified . . .
- if (pthingDel != NULL)
- {
- // Use category of item.
- plnDel = prealm->m_aclassHeads[pthingDel->GetClassID()].m_pnNext;
- plnTail = &(prealm->m_aclassTails[pthingDel->GetClassID()]);
- }
- else
- {
- // Use all CThings.
- plnDel = prealm->m_everythingHead.m_pnNext;
- plnTail = &(prealm->m_everythingTail);
- }
- CListNode<CThing>* plnNext;
- while (plnDel != plnTail)
- {
- plnNext = plnDel->m_pnNext;
- DelThing(plnDel->m_powner, NULL, prealm);
- plnDel = plnNext;
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Delete all but the pylons, bouys, soundthings and soundrelays.
- // This is useful for making a template of a level that is already fully \
- // populated.
- ////////////////////////////////////////////////////////////////////////////////
- static void DelMost( // Returns nothing.
- CRealm* prealm) // In: Current realm
- {
- char szTitle[512];
- sprintf(
- szTitle,
- "Delete Everything except bouys, pylons, warps, soundthings and soundrelays?"
- );
- // VERIFY . . .
- if (rspMsgBox(
- RSP_MB_ICN_QUERY | RSP_MB_BUT_YESNO,
- szTitle,
- "Are you sure you want to perform such a delete?"
- ) == RSP_MB_RET_YES)
- {
- CListNode<CThing>* plnDel;
- CListNode<CThing>* plnTail;
- CThing::ClassIDType classType;
- // Use all CThings.
- plnDel = prealm->m_everythingHead.m_pnNext;
- plnTail = &(prealm->m_everythingTail);
- CListNode<CThing>* plnNext;
- while (plnDel != plnTail)
- {
- plnNext = plnDel->m_pnNext;
- classType = plnDel->m_powner->GetClassID();
- switch (classType)
- {
- default:
- DelThing(plnDel->m_powner, NULL, prealm);
- break;
- case CThing::CHoodID:
- case CThing::CPylonID:
- case CThing::CBouyID:
- case CThing::CNavigationNetID:
- case CThing::CSoundThingID:
- case CThing::CSndRelayID:
- case CThing::CGameEditThingID:
- case CThing::CWarpID:
- break;
- }
- plnDel = plnNext;
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Copy a thing to the paste buffer.
- ////////////////////////////////////////////////////////////////////////////////
- static short CopyItem( // Returns 0 on success.
- CThing* pthingCopy) // In: CThing to copy.
- {
- short sRes = 0; // Assume success.
- // If anything to copy . . .
- if (pthingCopy != NULL)
- {
- // Switch for exceptions by type.
- switch (pthingCopy->GetClassID() )
- {
- case CThing::CBouyID:
- case CThing::CPylonID:
- case CThing::CNavigationNetID:
- case CThing::CHoodID:
- rspMsgBox(
- RSP_MB_ICN_INFO | RSP_MB_BUT_OK,
- "Cannot Copy",
- "Cannot Copy %s",
- CThing::ms_aClassInfo[pthingCopy->GetClassID()].pszClassName);
- break;
- default:
- {
- // If paste buffer open . . .
- if (ms_filePaste.IsOpen() != FALSE)
- {
- ms_filePaste.Close();
- }
- // Open paste buffer.
- if (ms_filePaste.Open(
- PASTE_BUFFER_INITIAL_SIZE,
- PASTE_BUFFER_GROW_SIZE,
- RFile::NeutralEndian) == 0)
- {
- if (pthingCopy->Save(&ms_filePaste, ms_sFileCount--) == 0)
- {
- // Success. Store the type.
- ms_idPaste = pthingCopy->GetClassID();
- }
- else
- {
- TRACE("CopyItem(): pthingCopy->Save() failed.\n");
- sRes = -2;
- }
- }
- else
- {
- TRACE("CopyItem(): Failed to open paste buffer.\n");
- sRes = -1;
- }
- break;
- }
- }
- // If any errors . . .
- if (sRes != 0)
- {
- ms_filePaste.Close();
- }
- }
- else
- {
- sRes = 1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Copy a thing to the paste buffer.
- ////////////////////////////////////////////////////////////////////////////////
- static short PasteItem( // Returns 0 on success.
- CRealm* prealm, // In: The realm to paste into.
- short sX, // In: Location for new thing.
- short sY, // In: Location for new thing.
- short sZ) // In: Location for new thing.
- {
- short sRes = 0; // Assume success.
- // Drop anything we currently are holding onto.
- DragDrop(
- sX,
- sY,
- sZ);
- // If open . . .
- if (ms_filePaste.IsOpen() != FALSE)
- {
- // Go to beginning.
- ms_filePaste.Seek(0, SEEK_SET);
- // Create the thing using the paste buffer . . .
- if (CreateNewThing( // Returns 0 on success.
- prealm, // Realm to create in.
- ms_idPaste, // ID to create.
- sX, // x
- sY, // y
- sZ, // z
- &ms_pthingSel, // New thing.
- &ms_photSel, // New hotbox for thing.
- &ms_filePaste) == 0) // RFile src.
- {
- // Success.
- // Start moving/placing object.
- ms_sMoving = TRUE;
- // Disable drag view scrolling.
- ms_bDragScroll = false;
- // Enter drag. Cheesy...Just need to get this to Bill and
- // Then I'll clean up.
- ms_sDragState = 4;
- if (rspGetMouseCursorShowLevel() > 0)
- {
- rspHideMouseCursor();
- }
- }
- else
- {
- TRACE("PasteItem(): CreateNewThing() failed.\n");
- sRes = -1;
- }
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Map a screen coordinate to a realm coordinate.
- // Note that this function's *psRealmY output is always
- // the height specified by the realm's attribute map
- // at the resulting *psRealmX, *psRealmZ.
- ////////////////////////////////////////////////////////////////////////////////
- static void MapScreen2Realm( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera, // In: View of prealm.
- short sScreenX, // In: Screen x coord.
- short sScreenY, // In: Screen y coord.
- short* psRealmX, // Out: Realm x coord.
- short* psRealmY, // Out: Realm y coord (always via realm's height map).
- short* psRealmZ) // Out: Realm z coord.
- {
- // Get coordinate on 2D viewing plane.
- short sRealmX2 = sScreenX + pcamera->m_sScene2FilmX;
- short sRealmY2 = sScreenY + pcamera->m_sScene2FilmY;
- // If there's a hood . . .
- if (prealm->m_phood != NULL)
- {
- // Map to realm's X/Z plane:
- // Z is stretched.
- prealm->MapY2DtoZ3D(sRealmY2, psRealmZ);
- // X is trivial.
- *psRealmX = sRealmX2;
- // If there is an attribute map . . .
- if (prealm->m_pTerrainMap != NULL)
- {
- // The realm y is the height indicated by the attribute map
- // in the given location on the X/Z plane.
- *psRealmY = prealm->GetHeight(
- *psRealmX,
- *psRealmZ);
- }
- else
- {
- // Safety.
- *psRealmY = 0;
- }
- }
- else
- {
- // Safety.
- *psRealmX = sRealmX2;
- *psRealmY = 0;
- *psRealmZ = sRealmY2;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Map a realm coordinate to a screen coordinate.
- ////////////////////////////////////////////////////////////////////////////////
- static void Maprealm2Screen( // Returns nothing.
- CRealm* prealm, // In: Realm.
- CCamera* pcamera, // In: View of prealm.
- short sRealmX, // In: Realm x coord.
- short sRealmY, // In: Realm y coord.
- short sRealmZ, // In: Realm z coord.
- short* psScreenX, // Out: Screen x coord.
- short* psScreenY) // Out: Screen y coord.
- {
- // Map coordinate onto 2D viewing plane.
- short sViewX2;
- short sViewY2;
- prealm->Map3Dto2D(
- sRealmX,
- sRealmY,
- sRealmZ,
- &sViewX2,
- &sViewY2);
- // Offset to screen.
- *psScreenX = sViewX2 - pcamera->m_sScene2FilmX;
- *psScreenY = sViewY2 - pcamera->m_sScene2FilmY;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Blit attribute areas lit by the specified mask into the specified image.
- ////////////////////////////////////////////////////////////////////////////////
- static void AttribBlit( // Returns nothing.
- RMultiGrid* pmg, // In: Multigrid of attributes.
- U16 u16Mask, // In: Mask of important attributes.
- RImage* pimDst, // In: Destination image.
- short sSrcX, // In: Where in Multigrid to start.
- short sSrcY, // In: Where in Multigrid to start.
- short sW, // In: How much of multigrid to use.
- short sH) // In: How much of multigrid to use.
- {
- // Keep it at the edge of the film.
- ms_spriteAttributes.m_sX2 = sSrcX;
- ms_spriteAttributes.m_sY2 = sSrcY;
- ASSERT(pimDst->m_sDepth == 8);
- ASSERT(pimDst->m_sWidth >= sW);
- ASSERT(pimDst->m_sHeight >= sH);
- // Get dst start.
- U8* pu8RowDst = pimDst->m_pData;
- U8* pu8Dst;
- long lPitch;
- short sGridW, sGridH;
- pmg->GetGridDimensions(&sGridW, &sGridH);
- short sIterX;
- while (sH--)
- {
- lPitch = pimDst->m_lPitch;
- sIterX = sSrcX;
- pu8Dst = pu8RowDst;
- while (lPitch--)
- {
- if (pmg->GetVal(sIterX++, sSrcY, 0x0000) & u16Mask)
- {
- *pu8Dst = SHOW_ATTRIBS_DRAW_INDEX;
- }
- pu8Dst++;
- }
- pu8RowDst += pimDst->m_lPitch;
- sSrcY++;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Callback for attrib mask multibtns.
- ////////////////////////////////////////////////////////////////////////////////
- static void AttribMaskBtnPressed( // Returns nothing.
- RGuiItem* pgui_pmb) // In: Ptr to the pressed GUI (which is a multibtn).
- {
- ASSERT(pgui_pmb->m_type == RGuiItem::MultiBtn);
- RMultiBtn* pmb = (RMultiBtn*)pgui_pmb;
- // Get mask to affect.
- U16* pu16AttribMask = (U16*)(pmb->m_ulUserInstance);
- // Add or subtract mask dependent on state.
- switch (pmb->m_sState)
- {
- case 0: // Pressing.
- break;
- case 1: // Off.
- *pu16AttribMask &= ~pmb->m_ulUserData;
- break;
- case 2: // On.
- *pu16AttribMask |= pmb->m_ulUserData;
- break;
- }
- // If we now have a mask value . . .
- if (*pu16AttribMask)
- {
- // If there's no image . . .
- if (ms_spriteAttributes.m_pImage == NULL)
- {
- short sErr = 0;
- // Create it . . .
- ms_spriteAttributes.m_pImage = new RImage;
- if (ms_spriteAttributes.m_pImage)
- {
- sErr = SizeShowAttribsSprite();
- // If an error occurred after allocating the image . . .
- if (sErr)
- {
- delete ms_spriteAttributes.m_pImage;
- ms_spriteAttributes.m_pImage = NULL;
- }
- }
- else
- {
- TRACE("AttribMaskBtnPressed(): Error allocating RImage.\n");
- sErr = 1;
- }
- // If an error occurred . . .
- if (sErr)
- {
- // Clear mask so we don't use it later.
- *pu16AttribMask = 0;
- }
- }
- }
- else
- {
- // If no more attribute masks . . .
- if (ms_u16TerrainMask == 0 && ms_u16LayerMask == 0)
- {
- // If there is an image, delete it. No longer needed.
- delete ms_spriteAttributes.m_pImage;
- ms_spriteAttributes.m_pImage = NULL;
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Resizes the attribute sprite, if allocated.
- ////////////////////////////////////////////////////////////////////////////////
- static short SizeShowAttribsSprite(void) // Returns 0 on success.
- {
- short sRes = 0; // Assume success.
- if (ms_spriteAttributes.m_pImage)
- {
- ms_spriteAttributes.m_pImage->DestroyData();
- if (ms_spriteAttributes.m_pImage->CreateImage(
- ms_pcameraCur->m_sViewW,
- ms_pcameraCur->m_sViewH,
- RImage::BMP8) == 0)
- {
- ms_spriteAttributes.m_sLayer = CRealm::LayerSprite16;
- ms_spriteAttributes.m_sPriority = 32767; // Always on top.
- }
- else
- {
- TRACE("SizeShowAttribsSprite(): RImage::CreateImage() failed.\n");
- sRes = -1;
- }
- // If an error occurred . . .
- if (sRes)
- {
- delete ms_spriteAttributes.m_pImage;
- ms_spriteAttributes.m_pImage = NULL;
- }
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Our RFile callback
- //
- ////////////////////////////////////////////////////////////////////////////////
- static void MyRFileCallback(long lBytes)
- {
- ms_lFileBytesSoFar += lBytes;
- long lNow = rspGetMilliseconds();
- if ((lNow - ms_lRFileCallbackTime) > MY_RFILE_CALLBACK_INTERVAL)
- {
- // Do an update
- UpdateSystem();
- // Lock the composite buffer for access.
- rspLockBuffer();
- // Clear area. Note that this function locks and unlocks the display
- // when necessary.
- rspRect(
- RSP_BLACK_INDEX,
- g_pimScreenBuf,
- ms_sFileOpTextX,
- ms_sFileOpTextY,
- ms_sFileOpTextW,
- ms_sFileOpTextH);
- // Draw text in cleared area.
- ms_printFile.print(
- g_pimScreenBuf,
- ms_sFileOpTextX,
- ms_sFileOpTextY,
- ms_szFileOpDescriptionFrmt,
- ms_lFileBytesSoFar);
- // Done with buffer other than to update the screen with it.
- rspUnlockBuffer();
- // Update the display.
- rspUpdateDisplay(
- ms_sFileOpTextX,
- ms_sFileOpTextY,
- ms_sFileOpTextW,
- ms_sFileOpTextH);
- // Save new time
- ms_lRFileCallbackTime = rspGetMilliseconds();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Init load/save counter. You should call KillFileCounter() after
- // done with the file access.
- ////////////////////////////////////////////////////////////////////////////////
- static void InitFileCounter( // Returns nothing.
- char* pszDescriptionFrmt) // In: sprintf format for description of
- // operation.
- {
- // Make sure string (with some digits) will fit . . .
- if (strlen(pszDescriptionFrmt) < sizeof(ms_szFileOpDescriptionFrmt) - 10 )
- {
- strcpy(ms_szFileOpDescriptionFrmt, pszDescriptionFrmt);
- }
- else
- {
- strcpy(ms_szFileOpDescriptionFrmt, "Progress: %ld bytes");
- }
- // Hook the RFile callback and reset the timer. The callback does nothing
- // more than call Update() every once in a while, which gives the system
- // a bit of time (very important on Mac) and also allows update events to
- // be processed, which is nice for both Mac and Win32.
- RFile::ms_criticall = MyRFileCallback;
- ms_lRFileCallbackTime = rspGetMilliseconds();
- ms_lFileBytesSoFar = 0;
- // A little feedback would be nice.
- rspSetCursor(RSP_CURSOR_WAIT);
- // Setup printer.
- ms_printFile.SetWordWrap(TRUE);
- ms_printFile.SetJustifyLeft();
- ms_printFile.SetColor(249, 0, 0);
- ms_printFile.SetFont(19, &g_fontBig);
- // Determine size and position of text.
- // Create sample string.
- char szSample[sizeof(ms_szFileOpDescriptionFrmt)];
- sprintf(szSample, ms_szFileOpDescriptionFrmt, LONG_MAX);
- // Just use entire width for now.
- ms_sFileOpTextW = ms_printFile.GetWidth(szSample);
- // Get height.
- ms_printFile.GetPos(NULL, NULL, NULL, &ms_sFileOpTextH);
- ms_sFileOpTextX = PROGRESS_X;
- ms_sFileOpTextY = PROGRESS_Y - (ms_sFileOpTextH + 5);
- RRect rect(ms_sFileOpTextX, ms_sFileOpTextY, ms_sFileOpTextW, ms_sFileOpTextH);
- ms_printFile.SetDestination(g_pimScreenBuf, &rect);
- // Don't need keys that occurred before the operation.
- rspClearAllInputEvents();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Kill load/save counter. Can be called multiple times w/o corresponding
- // Init().
- ////////////////////////////////////////////////////////////////////////////////
- static void KillFileCounter(void) // Returns nothing.
- {
- // Unhook the RFile callback
- RFile::ms_criticall = 0;
- // Restore arrow cursor.
- rspSetCursor(RSP_CURSOR_ARROW);
- // Clear op descriptor.
- ms_szFileOpDescriptionFrmt[0] = '\0';
- // Don't need keys that occurred during the operation.
- rspClearAllInputEvents();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Helper function explicity for UpdateSelectionInfo().
- ////////////////////////////////////////////////////////////////////////////////
- inline
- void SetPosInfo( // Returns nothing.
- RGuiItem* pgui, // In: GUI to update. NULL is safe.
- double dVal) // In: Value to udpate to GUI.
- {
- if (pgui)
- {
- if (dVal != CThing::InvalidPosition)
- {
- pgui->SetText("%g", dVal);
- }
- else
- {
- pgui->SetText("%s", "N/A");
- }
- pgui->Compose();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Update selection info in the info GUI.
- ////////////////////////////////////////////////////////////////////////////////
- static void UpdateSelectionInfo( // Returns nothing.
- bool bTitle /*= false*/) // In: true to update the title info as well.
- {
- if (ms_pguiInfo)
- {
- if (bTitle == true)
- {
- // Update the title info.
- if (ms_pthingSel)
- {
- ms_pguiInfo->SetText(
- "Info for \"%s\" [%u]",
- CThing::ms_aClassInfo[ms_pthingSel->GetClassID()].pszClassName,
- ms_pthingSel->GetInstanceID() );
- }
- else
- {
- ms_pguiInfo->SetText("No selection");
- }
- ms_pguiInfo->Compose();
- }
- // Always update other fields.
- if (ms_pthingSel)
- {
- SetPosInfo(ms_pguiInfoXPos, ms_pthingSel->GetX() );
- SetPosInfo(ms_pguiInfoYPos, ms_pthingSel->GetY() );
- SetPosInfo(ms_pguiInfoZPos, ms_pthingSel->GetZ() );
- }
- else
- {
- SetPosInfo(ms_pguiInfoXPos, CThing::InvalidPosition);
- SetPosInfo(ms_pguiInfoYPos, CThing::InvalidPosition);
- SetPosInfo(ms_pguiInfoZPos, CThing::InvalidPosition);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Get a temporary file name
- //
- ////////////////////////////////////////////////////////////////////////////////
- static short TmpFileName( // Returns 0 if successfull, non-zero otherwise
- char* pszFileName, // Out: Temp file name returned here
- short sMaxSize) // In: Maximum size of file name
- {
- short sResult = 0;
- #if defined(WIN32)
- char szPath[RSP_MAX_PATH];
- ULONG ulLen = GetTempPath(sizeof(szPath), szPath);
- if (ulLen >= sizeof(szPath) )
- {
- TRACE("TmpFileName(): GetTempPath() could not fit the path and filename into our string.\n");
- sResult = -1;
- }
- else if (ulLen == 0)
- {
- TRACE("TmpFileName(): GetTempPath() failed.\n");
- sResult = -1;
- }
- if (GetTempFileName(szPath, "RLM", 0, pszFileName) == FALSE)
- {
- TRACE("TmpFileName(): GetTempFileName() failed.\n");
- sResult = -1;
- }
- #else
- // Impliment for some other system!
- ASSERT(0);
- #endif
- return sResult;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Helper for ShowRealmStatistics() to display an item position or N/A,
- // if invalid.
- ////////////////////////////////////////////////////////////////////////////////
- inline
- void Pos2Str( // Returns nothing.
- double dPos, // In: CThing position.
- char* pszStr) // Out: String representation.
- {
- if (dPos != CThing::InvalidPosition)
- {
- sprintf(pszStr, "%g", dPos);
- }
- else
- {
- strcpy(pszStr, "N/A");
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Show statistics for the specified realm.
- ////////////////////////////////////////////////////////////////////////////////
- static short ShowRealmStatistics( // Returns 0 on success.
- CRealm* prealm, // In: Realm to get stats on.
- CThing** ppthing) // Out: Selected thing, if not NULL.
- {
- short sRes = 0; // Assume success.
- // Store cursor show level so we can restore it when done.
- short sOrigCursorShowLevel = rspGetMouseCursorShowLevel();
- // Set the mouse so we can see it.
- rspSetMouseCursorShowLevel(1);
- // Get GUI . . .
- RGuiItem* pguiRoot = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_VD, REALM_STATISTICS_GUI_FILE) );
- if (pguiRoot)
- {
- // Get list box . . .
- RListBox* plb = (RListBox*)pguiRoot->GetItemFromId(GUI_ID_REALM_STATISTICS);
- if (plb)
- {
- ASSERT(plb->m_type == RGuiItem::ListBox);
- // Go through the list of everything adding each item to the list.
- char szThingDescription[2048];
- char szX[256];
- char szY[256];
- char szZ[256];
- double dX, dY, dZ;
- long lNum = 0;
- CListNode<CThing>* pthingnode = prealm->m_everythingHead.m_pnNext;
- CThing* pthing;
- while (pthingnode != &(prealm->m_everythingTail))
- {
- lNum++;
- pthing = pthingnode->m_powner;
- dX = pthing->GetX();
- dY = pthing->GetY();
- dZ = pthing->GetZ();
- Pos2Str(dX, szX);
- Pos2Str(dY, szY);
- Pos2Str(dZ, szZ);
- sprintf(
- szThingDescription,
- "%ld) \"%s\" ID: %u X: %s Y: %s Z: %s",
- lNum,
- CThing::ms_aClassInfo[pthing->GetClassID()].pszClassName,
- pthing->GetInstanceID(),
- szX,
- szY,
- szZ);
- RGuiItem* pguiThing = plb->AddString(szThingDescription);
- if (pguiThing)
- {
- // Success.
- pguiThing->m_lId = (long)pthing;
- }
- else
- {
- TRACE("ShowRealmStatistics(): Error adding <<%s>> to the list box.\n", szThingDescription);
- sRes = -3;
- }
- pthingnode = pthingnode->m_pnNext;
- }
- // Repaginate now.
- plb->AdjustContents();
- // Display until dismissed.
- CThing::DoGui(pguiRoot);
- if (ppthing)
- {
- // If there's a selection . . .
- RGuiItem* pguiSel = plb->GetSel();
- if (pguiSel)
- {
- *ppthing = (CThing*)(pguiSel->m_lId);
- }
- else
- {
- *ppthing = NULL;
- }
- }
- }
- else
- {
- TRACE("ShowRealmStatistics(): Failed to get realm stats listbox.\n");
- sRes = -2;
- }
- delete pguiRoot;
- pguiRoot = NULL;
- }
- else
- {
- TRACE("ShowRealmStatistics(): Failed to load realm stats GUI.\n");
- sRes = -1;
- }
- // Clear queues.
- rspClearAllInputEvents();
- // Re-init input.
- ClearLocalInput();
- // Restore cursor show level.
- rspSetMouseCursorShowLevel(sOrigCursorShowLevel);
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Callback from realm during time intensive operations.
- ////////////////////////////////////////////////////////////////////////////////
- static bool RealmOpProgress( // Returns true to continue; false to
- // abort operation.
- short sLastItemProcessed, // In: Number of items processed so far.
- short sTotalItemsToProcess) // In: Total items to process.
- {
- static long lLastProgressPos;
- static long lProgressX, lProgressY, lProgressW, lProgressH;
- static long lLastCallTime;
- // Just need to get the key status array once.
- U8* pau8KeyStatus = rspGetKeyStatusArray();
- bool bContinue = true; // Assume we want to continue.
- // If new operation . . .
- if (sLastItemProcessed == 0)
- {
- lLastProgressPos = 0;
- lProgressX = PROGRESS_X;
- lProgressY = PROGRESS_Y;
- lProgressW = PROGRESS_W;
- lProgressH = PROGRESS_H;
- lLastCallTime = 0;
- // Clear key status array.
- memset(pau8KeyStatus, 0, 128);
- // Lock the composite buffer for access.
- rspLockBuffer();
- // Draw initial outline.
- rspRect(
- 1,
- PROGRESS_OUTLINE_COLOR_INDEX,
- g_pimScreenBuf,
- lProgressX - 1,
- lProgressY - 1,
- lProgressW + 2,
- lProgressH + 2);
- // Done with buffer other than to update the screen with it.
- rspUnlockBuffer();
-
- rspUpdateDisplay(
- lProgressX - 1,
- lProgressY - 1,
- lProgressW + 2,
- lProgressH + 2);
- }
- long lNow = rspGetMilliseconds();
- if ((lNow - lLastCallTime) > PROGRESS_CALLBACK_INTERVAL)
- {
- // Do an update
- UpdateSystem();
- // Compute new position.
- long lNewProgressPos;
- if (sTotalItemsToProcess > 0)
- {
- lNewProgressPos = (long)sLastItemProcessed * lProgressW / (long)sTotalItemsToProcess;
- }
- else
- {
- lNewProgressPos = lProgressW;
- }
- // Lock the composite buffer.
- rspLockBuffer();
-
- rspRect(
- PROGRESS_COLOR_INDEX,
- g_pimScreenBuf,
- lProgressX + lLastProgressPos,
- lProgressY,
- lNewProgressPos - lLastProgressPos,
- lProgressH);
- // Done with buffer other than to update the screen with it.
- rspUnlockBuffer();
- // Update display.
- rspUpdateDisplay(
- lProgressX + lLastProgressPos,
- lProgressY,
- lNewProgressPos - lLastProgressPos,
- lProgressH);
- lLastProgressPos = lNewProgressPos;
- // If escape hit . . .
- if (pau8KeyStatus[KEY_ABORT_REALM_OPERATION])
- {
- if (rspMsgBox(
- RSP_MB_ICN_QUERY | RSP_MB_BUT_YESNO,
- g_pszAppName,
- "Are you sure you want to abort this operation?")
- == RSP_MB_RET_YES)
- {
- bContinue = false;
- }
- }
- // Don't use lNow here...let's not count time we spent drawing.
- lLastCallTime = rspGetMilliseconds();
- }
- return bContinue;
- }
- #endif // !defined(EDITOR_DISABLED)
- ////////////////////////////////////////////////////////////////////////////////
- // EOF
- ////////////////////////////////////////////////////////////////////////////////
|