| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
- // software: you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation,
- // either version 3 of the License, or (at your option) any later version.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /*
- **
- **
- ** Misc asm functions from ww lib
- ** ST - 12/19/2018 1:20PM
- **
- **
- **
- **
- **
- **
- **
- **
- **
- **
- **
- */
- #include "gbuffer.h"
- #include "MISC.H"
- IconCacheClass::IconCacheClass (void)
- {
- IsCached =FALSE;
- SurfaceLost =FALSE;
- DrawFrequency =0;
- CacheSurface =NULL;
- IconSource =NULL;
- }
- IconCacheClass::~IconCacheClass (void)
- {
- }
- IconCacheClass CachedIcons[MAX_CACHED_ICONS];
- extern "C"{
- IconSetType IconSetList[MAX_ICON_SETS];
- short IconCacheLookup[MAX_LOOKUP_ENTRIES];
- }
- int CachedIconsDrawn=0; //Counter of number of cache hits
- int UnCachedIconsDrawn=0; //Counter of number of cache misses
- BOOL CacheMemoryExhausted; //Flag set if we have run out of video RAM
- void Invalidate_Cached_Icons (void) {}
- void Restore_Cached_Icons (void) {}
- void Register_Icon_Set (void *icon_data , BOOL pre_cache) {};
- //
- // Prototypes for assembly language procedures in STMPCACH.ASM
- //
- extern "C" void __cdecl Clear_Icon_Pointers (void) {};
- extern "C" void __cdecl Cache_Copy_Icon (void const *icon_ptr ,void * , int) {};
- extern "C" int __cdecl Is_Icon_Cached (void const *icon_data , int icon) {return -1;};
- extern "C" int __cdecl Get_Icon_Index (void *icon_ptr) {return 0;};
- extern "C" int __cdecl Get_Free_Index (void) {return 0;};
- extern "C" BOOL __cdecl Cache_New_Icon (int icon_index, void *icon_ptr) {return -1;};
- extern "C" int __cdecl Get_Free_Cache_Slot(void) {return -1;}
- void IconCacheClass::Draw_It (LPDIRECTDRAWSURFACE dest_surface , int x_pixel, int y_pixel, int window_left , int window_top , int window_width , int window_height) {}
- extern int CachedIconsDrawn;
- extern int UnCachedIconsDrawn;
- extern "C" void __cdecl Set_Font_Palette_Range(void const *palette, INT start_idx, INT end_idx)
- {
- }
- /*
- ;***************************************************************************
- ;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport *
- ;* *
- ;* INPUT: WORD sx_pixel - the starting x pixel position *
- ;* WORD sy_pixel - the starting y pixel position *
- ;* WORD dx_pixel - the destination x pixel position *
- ;* WORD dy_pixel - the destination y pixel position *
- ;* WORD color - the color of the line to draw *
- ;* *
- ;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel *
- ;* with the graphic viewport it has been assigned to. *
- ;* *
- ;* HISTORY: *
- ;* 06/16/1994 PWG : Created. *
- ;* 08/30/1994 IML : Fixed clipping bug. *
- ;*=========================================================================*
- PROC Buffer_Draw_Line C NEAR
- USES eax,ebx,ecx,edx,esi,edi
- */
- void __cdecl Buffer_Draw_Line(void *this_object, int sx, int sy, int dx, int dy, unsigned char color)
- {
- unsigned int clip_min_x;
- unsigned int clip_max_x;
- unsigned int clip_min_y;
- unsigned int clip_max_y;
- unsigned int clip_var;
- unsigned int accum;
- unsigned int bpr;
-
- static int _one_time_init = 0;
- //clip_tbl DD nada,a_up,a_dwn,nada
- // DD a_lft,a_lft,a_dwn,nada
- // DD a_rgt,a_up,a_rgt,nada
- // DD nada,nada,nada,nada
- static void *_clip_table [4*4] = {0};
- unsigned int int_color = color;
- unsigned int x1_pixel = (unsigned int) sx;
- unsigned int y1_pixel = (unsigned int) sy;
- unsigned int x2_pixel = (unsigned int) dx;
- unsigned int y2_pixel = (unsigned int) dy;
- __asm {
- mov eax,_one_time_init
- and eax,eax
- jnz init_done
- call do_init
- init_done:
-
- //;*==================================================================
- //;* Take care of find the clip minimum and maximums
- //;*==================================================================
- mov ebx,[this_object]
- xor eax,eax
- mov [clip_min_x],eax
- mov [clip_min_y],eax
- mov eax,[ebx]GraphicViewPortClass.Width
- mov [clip_max_x],eax
- add eax,[ebx]GraphicViewPortClass.XAdd
- add eax,[ebx]GraphicViewPortClass.Pitch
- mov [bpr],eax
- mov eax,[ebx]GraphicViewPortClass.Height
- mov [clip_max_y],eax
- //;*==================================================================
- //;* Adjust max pixels as they are tested inclusively.
- //;*==================================================================
- dec [clip_max_x]
- dec [clip_max_y]
- //;*==================================================================
- //;* Set the registers with the data for drawing the line
- //;*==================================================================
- mov eax,[x1_pixel] //; eax = start x pixel position
- mov ebx,[y1_pixel] //; ebx = start y pixel position
- mov ecx,[x2_pixel] //; ecx = dest x pixel position
- mov edx,[y2_pixel] //; edx = dest y pixel position
- //;*==================================================================
- //;* This is the section that "pushes" the line into bounds.
- //;* I have marked the section with PORTABLE start and end to signify
- //;* how much of this routine is 100% portable between graphics modes.
- //;* It was just as easy to have variables as it would be for constants
- //;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used
- //;* to clip the line (default is the screen)
- //;* PORTABLE start
- //;*==================================================================
- cmp eax,[clip_min_x]
- jl short clip_it
- cmp eax,[clip_max_x]
- jg short clip_it
- cmp ebx,[clip_min_y]
- jl short clip_it
- cmp ebx,[clip_max_y]
- jg short clip_it
- cmp ecx,[clip_min_x]
- jl short clip_it
- cmp ecx,[clip_max_x]
- jg short clip_it
- cmp edx,[clip_min_y]
- jl short clip_it
- cmp edx,[clip_max_y]
- jle short on_screen
- //;*==================================================================
- //;* Takes care off clipping the line.
- //;*==================================================================
- clip_it:
- call set_bits
- xchg eax,ecx
- xchg ebx,edx
- mov edi,esi
- call set_bits
- mov [clip_var],edi
- or [clip_var],esi
- jz short on_screen
- test edi,esi
- jne short off_screen
- shl esi,2
- //call [clip_tbl+esi]
- call [_clip_table+esi]
- jc clip_it
- xchg eax,ecx
- xchg ebx,edx
- shl edi,2
- //call [clip_tbl+edi]
- call [_clip_table+edi]
- jmp clip_it
- on_screen:
- jmp draw_it
- off_screen:
- jmp and_out
- //;*==================================================================
- //;* Jump table for clipping conditions
- //;*==================================================================
- //clip_tbl DD nada,a_up,a_dwn,nada
- // DD a_lft,a_lft,a_dwn,nada
- // DD a_rgt,a_up,a_rgt,nada
- // DD nada,nada,nada,nada
- nada:
- clc
- ret
- a_up:
- mov esi,[clip_min_y]
- call clip_vert
- stc
- ret
- a_dwn:
- mov esi,[clip_max_y]
- neg esi
- neg ebx
- neg edx
- call clip_vert
- neg ebx
- neg edx
- stc
- ret
- //;*==================================================================
- //;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)]
- //;*==================================================================
- clip_vert:
- push edx
- push eax
- mov [clip_var],edx //; clip_var = yb
- sub [clip_var],ebx //; clip_var = (yb-ya)
- neg eax //; eax=-xa
- add eax,ecx //; (ebx-xa)
- mov edx,esi //; edx=miny
- sub edx,ebx //; edx=(miny-ya)
- imul edx
- idiv [clip_var]
- pop edx
- add eax,edx
- pop edx
- mov ebx,esi
- ret
- a_lft:
- mov esi,[clip_min_x]
- call clip_horiz
- stc
- ret
- a_rgt:
- mov esi,[clip_max_x]
- neg eax
- neg ecx
- neg esi
- call clip_horiz
- neg eax
- neg ecx
- stc
- ret
- //;*==================================================================
- //;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)]
- //;*==================================================================
- clip_horiz:
- push edx
- mov [clip_var],ecx //; clip_var = xb
- sub [clip_var],eax //; clip_var = (xb-xa)
- sub edx,ebx //; edx = (yb-ya)
- neg eax //; eax = -xa
- add eax,esi //; eax = (minx-xa)
- imul edx //; eax = (minx-xa)(yb-ya)
- idiv [clip_var] //; eax = (minx-xa)(yb-ya)/(xb-xa)
- add ebx,eax //; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)]
- pop edx
- mov eax,esi
- ret
- //;*==================================================================
- //;* Sets the condition bits
- //;*==================================================================
- set_bits:
- xor esi,esi
- cmp ebx,[clip_min_y] //; if y >= top its not up
- jge short a_not_up
- or esi,1
- a_not_up:
- cmp ebx,[clip_max_y] //; if y <= bottom its not down
- jle short a_not_down
- or esi,2
- a_not_down:
- cmp eax,[clip_min_x] //; if x >= left its not left
- jge short a_not_left
- or esi,4
- a_not_left:
- cmp eax,[clip_max_x] //; if x <= right its not right
- jle short a_not_right
- or esi,8
- a_not_right:
- ret
- //;*==================================================================
- //;* Draw the line to the screen.
- //;* PORTABLE end
- //;*==================================================================
- draw_it:
- sub edx,ebx //; see if line is being draw down
- jnz short not_hline //; if not then its not a hline
- jmp short hline //; do special case h line
- not_hline:
- jg short down //; if so there is no need to rev it
- neg edx //; negate for actual pixel length
- xchg eax,ecx //; swap x's to rev line draw
- sub ebx,edx //; get old edx
- down:
- push edx
- push eax
- mov eax,[bpr]
- mul ebx
- mov ebx,eax
- mov eax,[this_object]
- add ebx,[eax]GraphicViewPortClass.Offset
- pop eax
- pop edx
- mov esi,1 //; assume a right mover
- sub ecx,eax //; see if line is right
- jnz short not_vline //; see if its a vertical line
- jmp vline
- not_vline:
- jg short right //; if so, the difference = length
- //left:
- neg ecx //; else negate for actual pixel length
- neg esi //; negate counter to move left
- right:
- cmp ecx,edx //; is it a horiz or vert line
- jge short horiz //; if ecx > edx then |x|>|y| or horiz
- //vert:
- xchg ecx,edx //; make ecx greater and edx lesser
- mov edi,ecx //; set greater
- mov [accum],ecx //; set accumulator to 1/2 greater
- shr [accum],1
- //;*==================================================================
- //;* at this point ...
- //;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater;
- //;* esi=adder; accum=accumulator
- //;* in a vertical loop the adder is conditional and the inc constant
- //;*==================================================================
- //vert_loop:
- add ebx,eax
- mov eax,[int_color]
- v_midloop:
- mov [ebx],al
- dec ecx
- jl and_out
- add ebx,[bpr]
- sub [accum],edx //; sub the lesser
- jge v_midloop //; any line could be new
- add [accum],edi //; add greater for new accum
- add ebx,esi //; next pixel over
- jmp v_midloop
- horiz:
- mov edi,ecx //; set greater
- mov [accum],ecx //; set accumulator to 1/2 greater
- shr [accum],1
- //;*==================================================================
- //;* at this point ...
- //;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater;
- //;* esi=adder; accum=accumulator
- //;* in a vertical loop the adder is conditional and the inc constant
- //;*==================================================================
- //horiz_loop:
- add ebx,eax
- mov eax,[int_color]
- h_midloop:
- mov [ebx],al
- dec ecx //; dec counter
- jl and_out //; end of line
- add ebx,esi
- sub [accum],edx //; sub the lesser
- jge h_midloop
- add [accum],edi //; add greater for new accum
- add ebx,[bpr] //; goto next line
- jmp h_midloop
- //;*==================================================================
- //;* Special case routine for horizontal line draws
- //;*==================================================================
- hline:
- cmp eax,ecx //; make eax < ecx
- jl short hl_ac
- xchg eax,ecx
- hl_ac:
- sub ecx,eax //; get len
- inc ecx
- push edx
- push eax
- mov eax,[bpr]
- mul ebx
- mov ebx,eax
- mov eax,[this_object]
- add ebx,[eax]GraphicViewPortClass.Offset
- pop eax
- pop edx
- add ebx,eax
- mov edi,ebx
- cmp ecx,15
- jg big_line
- mov al,[color]
- rep stosb //; write as many words as possible
- jmp short and_out //; get outt
- big_line:
- mov al,[color]
- mov ah,al
- mov ebx,eax
- shl eax,16
- mov ax,bx
- test edi,3
- jz aligned
- mov [edi],al
- inc edi
- dec ecx
- test edi,3
- jz aligned
- mov [edi],al
- inc edi
- dec ecx
- test edi,3
- jz aligned
- mov [edi],al
- inc edi
- dec ecx
- aligned:
- mov ebx,ecx
- shr ecx,2
- rep stosd
- mov ecx,ebx
- and ecx,3
- rep stosb
- jmp and_out
- //;*==================================================================
- //;* a special case routine for vertical line draws
- //;*==================================================================
- vline:
- mov ecx,edx //; get length of line to draw
- inc ecx
- add ebx,eax
- mov eax,[int_color]
- vl_loop:
- mov [ebx],al //; store bit
- add ebx,[bpr]
- dec ecx
- jnz vl_loop
- jmp and_out
- do_init:
- mov edi, offset _clip_table
-
- lea esi, nada
- mov [edi], esi
- mov [edi+12], esi
- lea esi, a_up
- mov [edi+4], esi
- lea esi, a_dwn
- mov [edi+8], esi
- add edi, 16
-
- lea esi, a_lft
- mov [edi], esi
- mov [edi+4], esi
- lea esi, a_dwn
- mov [edi+8], esi
- lea esi, nada
- mov [edi+12], esi
- add edi, 16
- lea esi, a_rgt
- mov [edi], esi
- mov [edi+8], esi
- lea esi, a_up
- mov [edi+4], esi
- lea esi, nada
- mov [edi+12], esi
- add edi, 16
- lea esi, nada
- mov [edi], esi
- mov [edi+4], esi
- mov [edi+8], esi
- mov [edi+12], esi
-
- mov [_one_time_init], 1
- ret
- and_out:
- }
- }
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood 32 bit Library *
- ;* *
- ;* File Name : DRAWLINE.ASM *
- ;* *
- ;* Programmer : Phil W. Gorrow *
- ;* *
- ;* Start Date : June 16, 1994 *
- ;* *
- ;* Last Update : August 30, 1994 [IML] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* VVC::Scale -- Scales a virtual viewport to another virtual viewport *
- ;* Normal_Draw -- jump loc for drawing scaled line of normal pixel *
- ;* __DRAW_LINE -- Assembly routine to draw a line *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- INCLUDE ".\drawbuff.inc"
- INCLUDE ".\gbuffer.inc"
- CODESEG
- */
- /*
- ;***************************************************************************
- ;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport *
- ;* *
- ;* INPUT: WORD sx_pixel - the starting x pixel position *
- ;* WORD sy_pixel - the starting y pixel position *
- ;* WORD dx_pixel - the destination x pixel position *
- ;* WORD dy_pixel - the destination y pixel position *
- ;* WORD color - the color of the line to draw *
- ;* *
- ;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel *
- ;* with the graphic viewport it has been assigned to. *
- ;* *
- ;* HISTORY: *
- ;* 06/16/1994 PWG : Created. *
- ;* 08/30/1994 IML : Fixed clipping bug. *
- ;*=========================================================================*
- PROC Buffer_Draw_Line C NEAR
- USES eax,ebx,ecx,edx,esi,edi
- ;*==================================================================
- ;* Define the arguements that the function takes.
- ;*==================================================================
- ARG this_object:DWORD ; associated graphic view port
- ARG x1_pixel:DWORD ; the start x pixel position
- ARG y1_pixel:DWORD ; the start y pixel position
- ARG x2_pixel:DWORD ; the dest x pixel position
- ARG y2_pixel:DWORD ; the dest y pixel position
- ARG color:DWORD ; the color we are drawing
- ;*==================================================================
- ;* Define the local variables that we will use on the stack
- ;*==================================================================
- LOCAL clip_min_x:DWORD
- LOCAL clip_max_x:DWORD
- LOCAL clip_min_y:DWORD
- LOCAL clip_max_y:DWORD
- LOCAL clip_var:DWORD
- LOCAL accum:DWORD
- LOCAL bpr:DWORD
- ;*==================================================================
- ;* Take care of find the clip minimum and maximums
- ;*==================================================================
- mov ebx,[this_object]
- xor eax,eax
- mov [clip_min_x],eax
- mov [clip_min_y],eax
- mov eax,[(GraphicViewPort ebx).GVPWidth]
- mov [clip_max_x],eax
- add eax,[(GraphicViewPort ebx).GVPXAdd]
- add eax,[(GraphicViewPort ebx).GVPPitch]
- mov [bpr],eax
- mov eax,[(GraphicViewPort ebx).GVPHeight]
- mov [clip_max_y],eax
- ;*==================================================================
- ;* Adjust max pixels as they are tested inclusively.
- ;*==================================================================
- dec [clip_max_x]
- dec [clip_max_y]
- ;*==================================================================
- ;* Set the registers with the data for drawing the line
- ;*==================================================================
- mov eax,[x1_pixel] ; eax = start x pixel position
- mov ebx,[y1_pixel] ; ebx = start y pixel position
- mov ecx,[x2_pixel] ; ecx = dest x pixel position
- mov edx,[y2_pixel] ; edx = dest y pixel position
- ;*==================================================================
- ;* This is the section that "pushes" the line into bounds.
- ;* I have marked the section with PORTABLE start and end to signify
- ;* how much of this routine is 100% portable between graphics modes.
- ;* It was just as easy to have variables as it would be for constants
- ;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used
- ;* to clip the line (default is the screen)
- ;* PORTABLE start
- ;*==================================================================
- cmp eax,[clip_min_x]
- jl short ??clip_it
- cmp eax,[clip_max_x]
- jg short ??clip_it
- cmp ebx,[clip_min_y]
- jl short ??clip_it
- cmp ebx,[clip_max_y]
- jg short ??clip_it
- cmp ecx,[clip_min_x]
- jl short ??clip_it
- cmp ecx,[clip_max_x]
- jg short ??clip_it
- cmp edx,[clip_min_y]
- jl short ??clip_it
- cmp edx,[clip_max_y]
- jle short ??on_screen
- ;*==================================================================
- ;* Takes care off clipping the line.
- ;*==================================================================
- ??clip_it:
- call NEAR PTR ??set_bits
- xchg eax,ecx
- xchg ebx,edx
- mov edi,esi
- call NEAR PTR ??set_bits
- mov [clip_var],edi
- or [clip_var],esi
- jz short ??on_screen
- test edi,esi
- jne short ??off_screen
- shl esi,2
- call [DWORD PTR cs:??clip_tbl+esi]
- jc ??clip_it
- xchg eax,ecx
- xchg ebx,edx
- shl edi,2
- call [DWORD PTR cs:??clip_tbl+edi]
- jmp ??clip_it
- ??on_screen:
- jmp ??draw_it
- ??off_screen:
- jmp ??out
- ;*==================================================================
- ;* Jump table for clipping conditions
- ;*==================================================================
- ??clip_tbl DD ??nada,??a_up,??a_dwn,??nada
- DD ??a_lft,??a_lft,??a_dwn,??nada
- DD ??a_rgt,??a_up,??a_rgt,??nada
- DD ??nada,??nada,??nada,??nada
- ??nada:
- clc
- retn
- ??a_up:
- mov esi,[clip_min_y]
- call NEAR PTR ??clip_vert
- stc
- retn
- ??a_dwn:
- mov esi,[clip_max_y]
- neg esi
- neg ebx
- neg edx
- call NEAR PTR ??clip_vert
- neg ebx
- neg edx
- stc
- retn
- ;*==================================================================
- ;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)]
- ;*==================================================================
- ??clip_vert:
- push edx
- push eax
- mov [clip_var],edx ; clip_var = yb
- sub [clip_var],ebx ; clip_var = (yb-ya)
- neg eax ; eax=-xa
- add eax,ecx ; (ebx-xa)
- mov edx,esi ; edx=miny
- sub edx,ebx ; edx=(miny-ya)
- imul edx
- idiv [clip_var]
- pop edx
- add eax,edx
- pop edx
- mov ebx,esi
- retn
- ??a_lft:
- mov esi,[clip_min_x]
- call NEAR PTR ??clip_horiz
- stc
- retn
- ??a_rgt:
- mov esi,[clip_max_x]
- neg eax
- neg ecx
- neg esi
- call NEAR PTR ??clip_horiz
- neg eax
- neg ecx
- stc
- retn
- ;*==================================================================
- ;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)]
- ;*==================================================================
- ??clip_horiz:
- push edx
- mov [clip_var],ecx ; clip_var = xb
- sub [clip_var],eax ; clip_var = (xb-xa)
- sub edx,ebx ; edx = (yb-ya)
- neg eax ; eax = -xa
- add eax,esi ; eax = (minx-xa)
- imul edx ; eax = (minx-xa)(yb-ya)
- idiv [clip_var] ; eax = (minx-xa)(yb-ya)/(xb-xa)
- add ebx,eax ; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)]
- pop edx
- mov eax,esi
- retn
- ;*==================================================================
- ;* Sets the condition bits
- ;*==================================================================
- ??set_bits:
- xor esi,esi
- cmp ebx,[clip_min_y] ; if y >= top its not up
- jge short ??a_not_up
- or esi,1
- ??a_not_up:
- cmp ebx,[clip_max_y] ; if y <= bottom its not down
- jle short ??a_not_down
- or esi,2
- ??a_not_down:
- cmp eax,[clip_min_x] ; if x >= left its not left
- jge short ??a_not_left
- or esi,4
- ??a_not_left:
- cmp eax,[clip_max_x] ; if x <= right its not right
- jle short ??a_not_right
- or esi,8
- ??a_not_right:
- retn
- ;*==================================================================
- ;* Draw the line to the screen.
- ;* PORTABLE end
- ;*==================================================================
- ??draw_it:
- sub edx,ebx ; see if line is being draw down
- jnz short ??not_hline ; if not then its not a hline
- jmp short ??hline ; do special case h line
- ??not_hline:
- jg short ??down ; if so there is no need to rev it
- neg edx ; negate for actual pixel length
- xchg eax,ecx ; swap x's to rev line draw
- sub ebx,edx ; get old edx
- ??down:
- push edx
- push eax
- mov eax,[bpr]
- mul ebx
- mov ebx,eax
- mov eax,[this_object]
- add ebx,[(GraphicViewPort eax).GVPOffset]
- pop eax
- pop edx
- mov esi,1 ; assume a right mover
- sub ecx,eax ; see if line is right
- jnz short ??not_vline ; see if its a vertical line
- jmp ??vline
- ??not_vline:
- jg short ??right ; if so, the difference = length
- ??left:
- neg ecx ; else negate for actual pixel length
- neg esi ; negate counter to move left
- ??right:
- cmp ecx,edx ; is it a horiz or vert line
- jge short ??horiz ; if ecx > edx then |x|>|y| or horiz
- ??vert:
- xchg ecx,edx ; make ecx greater and edx lesser
- mov edi,ecx ; set greater
- mov [accum],ecx ; set accumulator to 1/2 greater
- shr [accum],1
- ;*==================================================================
- ;* at this point ...
- ;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater;
- ;* esi=adder; accum=accumulator
- ;* in a vertical loop the adder is conditional and the inc constant
- ;*==================================================================
- ??vert_loop:
- add ebx,eax
- mov eax,[color]
- ??v_midloop:
- mov [ebx],al
- dec ecx
- jl ??out
- add ebx,[bpr]
- sub [accum],edx ; sub the lesser
- jge ??v_midloop ; any line could be new
- add [accum],edi ; add greater for new accum
- add ebx,esi ; next pixel over
- jmp ??v_midloop
- ??horiz:
- mov edi,ecx ; set greater
- mov [accum],ecx ; set accumulator to 1/2 greater
- shr [accum],1
- ;*==================================================================
- ;* at this point ...
- ;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater;
- ;* esi=adder; accum=accumulator
- ;* in a vertical loop the adder is conditional and the inc constant
- ;*==================================================================
- ??horiz_loop:
- add ebx,eax
- mov eax,[color]
- ??h_midloop:
- mov [ebx],al
- dec ecx ; dec counter
- jl ??out ; end of line
- add ebx,esi
- sub [accum],edx ; sub the lesser
- jge ??h_midloop
- add [accum],edi ; add greater for new accum
- add ebx,[bpr] ; goto next line
- jmp ??h_midloop
- ;*==================================================================
- ;* Special case routine for horizontal line draws
- ;*==================================================================
- ??hline:
- cmp eax,ecx ; make eax < ecx
- jl short ??hl_ac
- xchg eax,ecx
- ??hl_ac:
- sub ecx,eax ; get len
- inc ecx
- push edx
- push eax
- mov eax,[bpr]
- mul ebx
- mov ebx,eax
- mov eax,[this_object]
- add ebx,[(GraphicViewPort eax).GVPOffset]
- pop eax
- pop edx
- add ebx,eax
- mov edi,ebx
- cmp ecx,15
- jg ??big_line
- mov al,[byte color]
- rep stosb ; write as many words as possible
- jmp short ??out ; get outt
- ??big_line:
- mov al,[byte color]
- mov ah,al
- mov ebx,eax
- shl eax,16
- mov ax,bx
- test edi,3
- jz ??aligned
- mov [edi],al
- inc edi
- dec ecx
- test edi,3
- jz ??aligned
- mov [edi],al
- inc edi
- dec ecx
- test edi,3
- jz ??aligned
- mov [edi],al
- inc edi
- dec ecx
- ??aligned:
- mov ebx,ecx
- shr ecx,2
- rep stosd
- mov ecx,ebx
- and ecx,3
- rep stosb
- jmp ??out
- ;*==================================================================
- ;* a special case routine for vertical line draws
- ;*==================================================================
- ??vline:
- mov ecx,edx ; get length of line to draw
- inc ecx
- add ebx,eax
- mov eax,[color]
- ??vl_loop:
- mov [ebx],al ; store bit
- add ebx,[bpr]
- dec ecx
- jnz ??vl_loop
- ??out:
- ret
- ENDP Buffer_Draw_Line
- */
- /*
- ;***************************************************************************
- ;* GVPC::FILL_RECT -- Fills a rectangular region of a graphic view port *
- ;* *
- ;* INPUT: WORD the left hand x pixel position of region *
- ;* WORD the upper x pixel position of region *
- ;* WORD the right hand x pixel position of region *
- ;* WORD the lower x pixel position of region *
- ;* UBYTE the color (optional) to clear the view port to *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* NOTE: This function is optimized to handle viewport with no XAdd *
- ;* value. It also handles DWORD aligning the destination *
- ;* when speed can be gained by doing it. *
- ;* HISTORY: *
- ;* 06/07/1994 PWG : Created. *
- ;*=========================================================================*
- */
- /*
- ;******************************************************************************
- ; Much testing was done to determine that only when there are 14 or more bytes
- ; being copied does it speed the time it takes to do copies in this algorithm.
- ; For this reason and because 1 and 2 byte copies crash, is the special case
- ; used. SKB 4/21/94. Tested on 486 66mhz. Copied by PWG 6/7/04.
- */
- #define OPTIMAL_BYTE_COPY 14
- void __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color)
- {
- /*
- ;*===================================================================
- ;* define the arguements that our function takes.
- ;*===================================================================
- ARG this_object:DWORD ; this is a member function
- ARG x1_pixel:WORD
- ARG y1_pixel:WORD
- ARG x2_pixel:WORD
- ARG y2_pixel:WORD
- ARG color:BYTE ; what color should we clear to
- */
-
- void *this_object = thisptr;
- int x1_pixel = sx;
- int y1_pixel = sy;
- int x2_pixel = dx;
- int y2_pixel = dy;
-
- /*
- ;*===================================================================
- ; Define some locals so that we can handle things quickly
- ;*===================================================================
- LOCAL VPwidth:DWORD ; the width of the viewport
- LOCAL VPheight:DWORD ; the height of the viewport
- LOCAL VPxadd:DWORD ; the additional x offset of viewport
- LOCAL VPbpr:DWORD ; the number of bytes per row of viewport
- */
- int VPwidth;
- int VPheight;
- int VPxadd;
- int VPbpr;
- int local_ebp; // Can't use ebp
- __asm {
- ;*===================================================================
- ;* save off the viewport characteristics on the stack
- ;*===================================================================
- mov ebx,[this_object] ; get a pointer to viewport
- mov eax,[ebx]GraphicViewPortClass.Width ; get width from viewport
- mov ecx,[ebx]GraphicViewPortClass.Height ; get height from viewport
- mov edx,[ebx]GraphicViewPortClass.XAdd ; get xadd from viewport
- add edx,[ebx]GraphicViewPortClass.Pitch ; extra pitch of direct draw surface
- mov [VPwidth],eax ; store the width of locally
- mov [VPheight],ecx
- mov [VPxadd],edx
- add eax,edx
- mov [VPbpr],eax
- ;*===================================================================
- ;* move the important parameters into local registers
- ;*===================================================================
- mov eax,[x1_pixel]
- mov ebx,[y1_pixel]
- mov ecx,[x2_pixel]
- mov edx,[y2_pixel]
- ;*===================================================================
- ;* Convert the x2 and y2 pixel to a width and height
- ;*===================================================================
- cmp eax,ecx
- jl no_swap_x
- xchg eax,ecx
- no_swap_x:
- sub ecx,eax
- cmp ebx,edx
- jl no_swap_y
- xchg ebx,edx
- no_swap_y:
- sub edx,ebx
- inc ecx
- inc edx
- ;*===================================================================
- ;* Bounds check source X.
- ;*===================================================================
- cmp eax, [VPwidth] ; compare with the max
- jge done ; starts off screen, then later
- jb short sx_done ; if it's not negative, it's ok
- ;------ Clip source X to left edge of screen.
- add ecx, eax ; Reduce width (add in negative src X).
- xor eax, eax ; Clip to left of screen.
- sx_done:
- ;*===================================================================
- ;* Bounds check source Y.
- ;*===================================================================
- cmp ebx, [VPheight] ; compare with the max
- jge done ; starts off screen, then later
- jb short sy_done ; if it's not negative, it's ok
- ;------ Clip source Y to top edge of screen.
- add edx, ebx ; Reduce height (add in negative src Y).
- xor ebx, ebx ; Clip to top of screen.
- sy_done:
- ;*===================================================================
- ;* Bounds check width versus width of source and dest view ports
- ;*===================================================================
- push ebx ; save off ebx for later use
- mov ebx,[VPwidth] ; get the source width
- sub ebx, eax ; Maximum allowed pixel width (given coordinates).
- sub ebx, ecx ; Pixel width undershoot.
- jns short width_ok ; if not signed no adjustment necessary
- add ecx, ebx ; Reduce width to screen limits.
- width_ok:
- pop ebx ; restore ebx to old value
- ;*===================================================================
- ;* Bounds check height versus height of source view port
- ;*===================================================================
- push eax ; save of eax for later use
- mov eax, [VPheight] ; get the source height
- sub eax, ebx ; Maximum allowed pixel height (given coordinates).
- sub eax, edx ; Pixel height undershoot.
- jns short height_ok ; if not signed no adjustment necessary
- add edx, eax ; Reduce height to screen limits.
- height_ok:
- pop eax ; restore eax to old value
- ;*===================================================================
- ;* Perform the last minute checks on the width and height
- ;*===================================================================
- or ecx,ecx
- jz done
- or edx,edx
- jz done
- cmp ecx,[VPwidth]
- ja done
- cmp edx,[VPheight]
- ja done
- ;*===================================================================
- ;* Get the offset into the virtual viewport.
- ;*===================================================================
- xchg edi,eax ; save off the contents of eax
- xchg esi,edx ; and edx for size test
- mov eax,ebx ; move the y pixel into eax
- mul [VPbpr] ; multiply by bytes per row
- add edi,eax ; add the result into the x position
- mov ebx,[this_object]
- add edi,[ebx]GraphicViewPortClass.Offset
- mov edx,esi ; restore edx back to real value
- mov eax,ecx ; store total width in ecx
- sub eax,[VPwidth] ; modify xadd value to include clipped
- sub [VPxadd],eax ; width bytes (subtract a negative number)
- ;*===================================================================
- ; Convert the color byte to a DWORD for fast storing
- ;*===================================================================
- mov al,[color] ; get color to clear to
- mov ah,al ; extend across WORD
- mov ebx,eax ; extend across DWORD in
- shl eax,16 ; several steps
- mov ax,bx
- ;*===================================================================
- ; If there is no row offset then adjust the width to be the size of
- ; the entire viewport and adjust the height to be 1
- ;*===================================================================
- mov esi,[VPxadd]
- or esi,esi ; set the flags for esi
- jnz row_by_row_aligned ; and act on them
- xchg eax,ecx ; switch bit pattern and width
- mul edx ; multiply by edx to get size
- xchg eax,ecx ; switch size and bit pattern
- mov edx,1 ; only 1 line off view port size to do
- ;*===================================================================
- ; Find out if we should bother to align the row.
- ;*===================================================================
- row_by_row_aligned:
- mov [local_ebp],ecx ; width saved in ebp
- cmp ecx,OPTIMAL_BYTE_COPY ; is it worth aligning them?
- jl row_by_row ; if not then skip
- ;*===================================================================
- ; Figure out the alignment offset if there is any
- ;*===================================================================
- mov ebx,edi ; get output position
- and ebx,3 ; is there a remainder?
- jz aligned_loop ; if not we are aligned
- xor ebx,3 ; find number of align bytes
- inc ebx ; this number is off by one
- sub [local_ebp],ebx ; subtract from width
- ;*===================================================================
- ; Now that we have the alignment offset copy each row
- ;*===================================================================
- aligned_loop:
- mov ecx,ebx ; get number of bytes to align
- rep stosb ; and move them over
- mov ecx,[local_ebp] ; get number of aligned bytes
- shr ecx,2 ; convert to DWORDS
- rep stosd ; and move them over
- mov ecx,[local_ebp] ; get number of aligned bytes
- and ecx,3 ; find the remainder
- rep stosb ; and move it over
- add edi,esi ; fix the line offset
- dec edx ; decrement the height
- jnz aligned_loop ; if more to do than do it
- jmp done ; we are all done
- ;*===================================================================
- ; If not enough bytes to bother aligning copy each line across a byte
- ; at a time.
- ;*===================================================================
- row_by_row:
- mov ecx,[local_ebp] ; get total width in bytes
- rep stosb ; store the width
- add edi,esi ; handle the xadd
- dec edx ; decrement the height
- jnz row_by_row ; if any left then next line
- done:
- }
- }
- /*
- ;***************************************************************************
- ;* VVPC::CLEAR -- Clears a virtual viewport instance *
- ;* *
- ;* INPUT: UBYTE the color (optional) to clear the view port to *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* NOTE: This function is optimized to handle viewport with no XAdd *
- ;* value. It also handles DWORD aligning the destination *
- ;* when speed can be gained by doing it. *
- ;* HISTORY: *
- ;* 06/07/1994 PWG : Created. *
- ;* 08/23/1994 SKB : Clear the direction flag to always go forward. *
- ;*=========================================================================*
- */
- void __cdecl Buffer_Clear(void *this_object, unsigned char color)
- {
- unsigned int local_color = color;
- __asm {
- cld ; always go forward
- mov ebx,[this_object] ; get a pointer to viewport
- mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset
- mov edx,[ebx]GraphicViewPortClass.Height ; get height from viewport
- mov esi,[ebx]GraphicViewPortClass.Width ; get width from viewport
- //push [dword (GraphicViewPort ebx).GVPPitch] ; extra pitch of direct draw surface
- push [ebx]GraphicViewPortClass.Pitch
- mov ebx,[ebx]GraphicViewPortClass.XAdd ; esi = add for each line
- add ebx,[esp] ; Yes, I know its nasty but
- add esp,4 ; it works!
- ;*===================================================================
- ; Convert the color byte to a DWORD for fast storing
- ;*===================================================================
- mov al,[color] ; get color to clear to
- mov ah,al ; extend across WORD
- mov ecx,eax ; extend across DWORD in
- shl eax,16 ; several steps
- mov ax,cx
- ;*===================================================================
- ; Find out if we should bother to align the row.
- ;*===================================================================
- cmp esi , OPTIMAL_BYTE_COPY ; is it worth aligning them?
- jl byte_by_byte ; if not then skip
- ;*===================================================================
- ; Figure out the alignment offset if there is any
- ;*===================================================================
- push ebx
-
- dword_aligned_loop:
- mov ecx , edi
- mov ebx , esi
- neg ecx
- and ecx , 3
- sub ebx , ecx
- rep stosb
- mov ecx , ebx
- shr ecx , 2
- rep stosd
- mov ecx , ebx
- and ecx , 3
- rep stosb
- add edi , [ esp ]
- dec edx ; decrement the height
- jnz dword_aligned_loop ; if more to do than do it
- pop eax
- jmp done
- //ret
- ;*===================================================================
- ; If not enough bytes to bother aligning copy each line across a byte
- ; at a time.
- ;*===================================================================
- byte_by_byte:
- mov ecx,esi ; get total width in bytes
- rep stosb ; store the width
- add edi,ebx ; handle the xadd
- dec edx ; decrement the height
- jnz byte_by_byte ; if any left then next line
- done:
- }
- }
- BOOL __cdecl Linear_Blit_To_Linear( void *this_object, void * dest, int x_pixel, int y_pixel, int dest_x0, int dest_y0, int pixel_width, int pixel_height, BOOL trans)
- {
- /*
- ;*===================================================================
- ;* define the arguements that our function takes.
- ;*===================================================================
- ARG this_object :DWORD ; this is a member function
- ARG dest :DWORD ; what are we blitting to
- ARG x_pixel :DWORD ; x pixel position in source
- ARG y_pixel :DWORD ; y pixel position in source
- ARG dest_x0 :dword
- ARG dest_y0 :dword
- ARG pixel_width :DWORD ; width of rectangle to blit
- ARG pixel_height:DWORD ; height of rectangle to blit
- ARG trans :DWORD ; do we deal with transparents?
- ;*===================================================================
- ; Define some locals so that we can handle things quickly
- ;*===================================================================
- LOCAL x1_pixel :dword
- LOCAL y1_pixel :dword
- LOCAL dest_x1 : dword
- LOCAL dest_y1 : dword
- LOCAL scr_ajust_width:DWORD
- LOCAL dest_ajust_width:DWORD
- LOCAL source_area : dword
- LOCAL dest_area : dword
- */
-
- int x1_pixel;
- int y1_pixel;
- int dest_x1;
- int dest_y1;
- int scr_adjust_width;
- int dest_adjust_width;
- int source_area;
- int dest_area;
-
- __asm {
-
- ;This Clipping algorithm is a derivation of the very well known
- ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency
- ;it is probably the most commontly implemented algorithm both in software
- ;and hardware for clipping lines, rectangles, and convex polygons against
- ;a rectagular clipping window. For reference see
- ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes
- ; pages 113 to 177".
- ; Briefly consist in computing the Sutherland code for both end point of
- ; the rectangle to find out if the rectangle is:
- ; - trivially accepted (no further clipping test, display rectangle)
- ; - trivially rejected (return with no action)
- ; - retangle must be iteratively clipped again edges of the clipping window
- ; and the remaining retangle is display.
- ; Clip Source Rectangle against source Window boundaries.
- mov esi,[this_object] ; get ptr to src
- xor ecx,ecx ; Set sutherland code to zero
- xor edx,edx ; Set sutherland code to zero
- ; compute the difference in the X axis and get the bit signs into ecx , edx
- mov edi,[esi]GraphicViewPortClass.Width ; get width into register
- mov ebx,[x_pixel] ; Get first end point x_pixel into register
- mov eax,[x_pixel] ; Get second end point x_pixel into register
- add ebx,[pixel_width] ; second point x1_pixel = x + width
- shld ecx, eax,1 ; the sign bit of x_pixel is sutherland code0 bit4
- mov [x1_pixel],ebx ; save second for future use
- inc edi ; move the right edge by one unit
- shld edx,ebx,1 ; the sign bit of x1_pixel is sutherland code0 bit4
- sub eax,edi ; compute the difference x0_pixel - width
- sub ebx,edi ; compute the difference x1_pixel - width
- shld ecx,eax,1 ; the sign bit of the difference is sutherland code0 bit3
- shld edx,ebx,1 ; the sign bit of the difference is sutherland code0 bit3
- ; the following code is just a repeticion of the above code
- ; in the Y axis.
- mov edi,[esi]GraphicViewPortClass.Height ; get height into register
- mov ebx,[y_pixel]
- mov eax,[y_pixel]
- add ebx,[pixel_height]
- shld ecx,eax,1
- mov [y1_pixel ],ebx
- inc edi
- shld edx,ebx,1
- sub eax,edi
- sub ebx,edi
- shld ecx,eax,1
- shld edx,ebx,1
- ; Here we have the to Sutherland code into cl and dl
- xor cl,5 ; bit 2 and 0 are complented, reverse then
- xor dl,5 ; bit 2 and 0 are complented, reverse then
- mov al,cl ; save code1 in case we have to clip iteratively
- test dl,cl ; if any bit in code0 and its counter bit
- jnz real_out ; in code1 is set then the rectangle in outside
- or al,dl ; if all bit of code0 the counter bit in
- jz clip_against_dest ; in code1 is set to zero, then all
- ; end points of the rectangle are
- ; inside the clipping window
- ; if we are here the polygon have to be clip iteratively
- test cl,1000b ; if bit 4 in code0 is set then
- jz scr_left_ok ; x_pixel is smaller than zero
- mov [x_pixel],0 ; set x_pixel to cero.
- scr_left_ok:
- test cl,0010b ; if bit 2 in code0 is set then
- jz scr_bottom_ok ; y_pixel is smaller than zero
- mov [ y_pixel ],0 ; set y_pixel to cero.
- scr_bottom_ok:
- test dl,0100b ; if bit 3 in code1 is set then
- jz scr_right_ok ; x1_pixel is greater than the width
- mov eax,[esi]GraphicViewPortClass.Width ; get width into register
- mov [ x1_pixel ],eax ; set x1_pixel to width.
- scr_right_ok:
- test dl,0001b ; if bit 0 in code1 is set then
- jz clip_against_dest ; y1_pixel is greater than the width
- mov eax,[esi]GraphicViewPortClass.Height ; get height into register
- mov [ y1_pixel ],eax ; set y1_pixel to height.
- ; Clip Source Rectangle against destination Window boundaries.
- clip_against_dest:
- ; build the destination rectangle before clipping
- ; dest_x1 = dest_x0 + ( x1_pixel - x_pixel )
- ; dest_y1 = dest_y0 + ( y1_pixel - y_pixel )
- mov eax,[dest_x0] ; get dest_x0 into eax
- mov ebx,[dest_y0] ; get dest_y0 into ebx
- sub eax,[x_pixel] ; subtract x_pixel from eax
- sub ebx,[y_pixel] ; subtract y_pixel from ebx
- add eax,[x1_pixel] ; add x1_pixel to eax
- add ebx,[y1_pixel] ; add y1_pixel to ebx
- mov [dest_x1],eax ; save eax into dest_x1
- mov [dest_y1],ebx ; save eax into dest_y1
- ; The followin code is a repeticion of the Sutherland clipping
- ; descrived above.
- mov esi,[dest] ; get ptr to src
- xor ecx,ecx
- xor edx,edx
- mov edi,[esi]GraphicViewPortClass.Width ; get width into register
- mov eax,[dest_x0]
- mov ebx,[dest_x1]
- shld ecx,eax,1
- inc edi
- shld edx,ebx,1
- sub eax,edi
- sub ebx,edi
- shld ecx,eax,1
- shld edx,ebx,1
- mov edi,[esi]GraphicViewPortClass.Height ; get height into register
- mov eax,[dest_y0]
- mov ebx,[dest_y1]
- shld ecx,eax,1
- inc edi
- shld edx,ebx,1
- sub eax,edi
- sub ebx,edi
- shld ecx,eax,1
- shld edx,ebx,1
- xor cl,5
- xor dl,5
- mov al,cl
- test dl,cl
- jnz real_out
- or al,dl
- jz do_blit
- test cl,1000b
- jz dest_left_ok
- mov eax,[ dest_x0 ]
- mov [ dest_x0 ],0
- sub [ x_pixel ],eax
- dest_left_ok:
- test cl,0010b
- jz dest_bottom_ok
- mov eax,[ dest_y0 ]
- mov [ dest_y0 ],0
- sub [ y_pixel ],eax
- dest_bottom_ok:
- test dl,0100b
- jz dest_right_ok
- mov ebx,[esi]GraphicViewPortClass.Width ; get width into register
- mov eax,[ dest_x1 ]
- mov [ dest_x1 ],ebx
- sub eax,ebx
- sub [ x1_pixel ],eax
- dest_right_ok:
- test dl,0001b
- jz do_blit
- mov ebx,[esi]GraphicViewPortClass.Height ; get width into register
- mov eax,[ dest_y1 ]
- mov [ dest_y1 ],ebx
- sub eax,ebx
- sub [ y1_pixel ],eax
- ; Here is where we do the actual blit
- do_blit:
- cld
- mov ebx,[this_object]
- mov esi,[ebx]GraphicViewPortClass.Offset
- mov eax,[ebx]GraphicViewPortClass.XAdd
- add eax,[ebx]GraphicViewPortClass.Width
- add eax,[ebx]GraphicViewPortClass.Pitch
- mov ecx,eax
- mul [y_pixel]
- add esi,[x_pixel]
- mov [source_area],ecx
- add esi,eax
- add ecx,[x_pixel ]
- sub ecx,[x1_pixel ]
- mov [scr_adjust_width ],ecx
- mov ebx,[dest]
- mov edi,[ebx]GraphicViewPortClass.Offset
- mov eax,[ebx]GraphicViewPortClass.XAdd
- add eax,[ebx]GraphicViewPortClass.Width
- add eax,[ebx]GraphicViewPortClass.Pitch
- mov ecx,eax
- mul [ dest_y0 ]
- add edi,[ dest_x0 ]
- mov [ dest_area ],ecx
- add edi,eax
- mov eax,[ dest_x1 ]
- sub eax,[ dest_x0 ]
- jle real_out
- sub ecx,eax
- mov [ dest_adjust_width ],ecx
- mov edx,[ dest_y1 ]
- sub edx,[ dest_y0 ]
- jle real_out
- cmp esi,edi
- jz real_out
- jl backupward_blit
- ; ********************************************************************
- ; Forward bitblit
- test [ trans ],1
- jnz forward_Blit_trans
- ; the inner loop is so efficient that
- ; the optimal consept no longer apply because
- ; the optimal byte have to by a number greather than 9 bytes
- cmp eax,10
- jl forward_loop_bytes
- forward_loop_dword:
- mov ecx,edi
- mov ebx,eax
- neg ecx
- and ecx,3
- sub ebx,ecx
- rep movsb
- mov ecx,ebx
- shr ecx,2
- rep movsd
- mov ecx,ebx
- and ecx,3
- rep movsb
- add esi,[ scr_adjust_width ]
- add edi,[ dest_adjust_width ]
- dec edx
- jnz forward_loop_dword
- jmp real_out //ret
- forward_loop_bytes:
- mov ecx,eax
- rep movsb
- add esi,[ scr_adjust_width ]
- add edi,[ dest_adjust_width ]
- dec edx
- jnz forward_loop_bytes
- jmp real_out
- forward_Blit_trans:
- mov ecx,eax
- and ecx,01fh
- lea ecx,[ ecx + ecx * 4 ]
- neg ecx
- shr eax,5
- lea ecx,[ transp_reference + ecx * 2 ]
- mov [ y1_pixel ],ecx
- forward_loop_trans:
- mov ecx,eax
- jmp [ y1_pixel ]
- forward_trans_line:
- //REPT 32
- //local transp_pixel
- //No REPT in msvc inline assembly.
- // Save ECX and use as counter instead. ST - 12/19/2018 5:41PM
- push ecx
- mov ecx, 32
- rept_loop:
- mov bl,[ esi ]
- test bl,bl
- jz transp_pixel
- mov [ edi ],bl
- transp_pixel:
- inc esi
- inc edi
- dec ecx //ST - 12/19/2018 5:44PM
- jnz rept_loop //ST - 12/19/2018 5:44PM
- pop ecx //ST - 12/19/2018 5:44PM
- //ENDM
- transp_reference:
- dec ecx
- jge forward_trans_line
- add esi,[ scr_adjust_width ]
- add edi,[ dest_adjust_width ]
- dec edx
- jnz forward_loop_trans
- jmp real_out //ret
- ; ************************************************************************
- ; backward bitblit
- backupward_blit:
- mov ebx,[ source_area ]
- dec edx
- add esi,eax
- imul ebx,edx
- std
- lea esi,[ esi + ebx - 1 ]
- mov ebx,[ dest_area ]
- add edi,eax
- imul ebx,edx
- lea edi,[ edi + ebx - 1]
- test [ trans ],1
- jnz backward_Blit_trans
- cmp eax,15
- jl backward_loop_bytes
- backward_loop_dword:
- push edi
- push esi
- lea ecx,[edi+1]
- mov ebx,eax
- and ecx,3 ; Get non aligned bytes.
- sub ebx,ecx ; remove that from the total size to be copied later.
- rep movsb ; do the copy.
- sub esi,3
- mov ecx,ebx ; Get number of bytes left.
- sub edi,3
- shr ecx,2 ; Do 4 bytes at a time.
- rep movsd ; do the dword copy.
- mov ecx,ebx
- add esi,3
- add edi,3
- and ecx,03h
- rep movsb ; finnish the remaining bytes.
- pop esi
- pop edi
- sub esi,[ source_area ]
- sub edi,[ dest_area ]
- dec edx
- jge backward_loop_dword
- cld
- jmp real_out //ret
- backward_loop_bytes:
- push edi
- mov ecx,eax ; remove that from the total size to be copied later.
- push esi
- rep movsb ; do the copy.
- pop esi
- pop edi
- sub esi,[ source_area ]
- sub edi,[ dest_area ]
- dec edx
- jge backward_loop_bytes
- cld
- jmp real_out //ret
- backward_Blit_trans:
- mov ecx,eax
- and ecx,01fh
- lea ecx,[ ecx + ecx * 4 ]
- neg ecx
- shr eax,5
- lea ecx,[ back_transp_reference + ecx * 2 ]
- mov [ y1_pixel ],ecx
- backward_loop_trans:
- mov ecx,eax
- push edi
- push esi
- jmp [ y1_pixel ]
- backward_trans_line:
- //REPT 32
- //local transp_pixel2
- //No REPT in msvc inline assembly.
- // Save ECX and use as counter instead. ST - 12/19/2018 5:41PM
- push ecx
- mov ecx, 32
- rept_loop2:
- mov bl,[ esi ]
- test bl,bl
- jz transp_pixel2
- mov [ edi ],bl
- transp_pixel2:
- dec esi
- dec edi
- dec ecx //ST - 12/19/2018 5:44PM
- jnz rept_loop2 //ST - 12/19/2018 5:44PM
- pop ecx //ST - 12/19/2018 5:44PM
-
- //ENDM
-
- back_transp_reference:
- dec ecx
- jge backward_trans_line
- pop esi
- pop edi
- sub esi,[ source_area ]
- sub edi,[ dest_area ]
- dec edx
- jge backward_loop_trans
- cld
- //ret
- real_out:
- }
- }
- /*
- ;***************************************************************************
- ;* VVC::SCALE -- Scales a virtual viewport to another virtual viewport *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;* 06/16/1994 PWG : Created. *
- ;*=========================================================================*
- PROC Linear_Scale_To_Linear C NEAR
- USES eax,ebx,ecx,edx,esi,edi
- */
- // Ran out of registers so had to use ebp. ST - 12/19/2018 6:22PM
- #pragma warning (push)
- #pragma warning (disable : 4731)
- BOOL __cdecl Linear_Scale_To_Linear(void *this_object, void *dest, int src_x, int src_y, int dst_x, int dst_y, int src_width, int src_height, int dst_width, int dst_height, BOOL trans, char *remap)
- {
- /*
- ;*===================================================================
- ;* Define the arguements that our function takes.
- ;*===================================================================
- ARG this_object:DWORD ; pointer to source view port
- ARG dest:DWORD ; pointer to destination view port
- ARG src_x:DWORD ; source x offset into view port
- ARG src_y:DWORD ; source y offset into view port
- ARG dst_x:DWORD ; dest x offset into view port
- ARG dst_y:DWORD ; dest y offset into view port
- ARG src_width:DWORD ; width of source rectangle
- ARG src_height:DWORD ; height of source rectangle
- ARG dst_width:DWORD ; width of dest rectangle
- ARG dst_height:DWORD ; width of dest height
- ARG trans:DWORD ; is this transparent?
- ARG remap:DWORD ; pointer to table to remap source
- ;*===================================================================
- ;* Define local variables to hold the viewport characteristics
- ;*===================================================================
- local src_x0 : dword
- local src_y0 : dword
- local src_x1 : dword
- local src_y1 : dword
- local dst_x0 : dword
- local dst_y0 : dword
- local dst_x1 : dword
- local dst_y1 : dword
- local src_win_width : dword
- local dst_win_width : dword
- local dy_intr : dword
- local dy_frac : dword
- local dy_acc : dword
- local dx_frac : dword
- local counter_x : dword
- local counter_y : dword
- local remap_counter :dword
- local entry : dword
- */
-
- int src_x0;
- int src_y0;
- int src_x1;
- int src_y1;
- int dst_x0;
- int dst_y0;
- int dst_x1;
- int dst_y1;
- int src_win_width;
- int dst_win_width;
- int dy_intr;
- int dy_frac;
- int dy_acc;
- int dx_frac;
- int counter_x;
- int counter_y;
- int remap_counter;
- int entry;
-
-
- __asm {
-
- ;*===================================================================
- ;* Check for scale error when to or from size 0,0
- ;*===================================================================
- cmp [dst_width],0
- je all_done
- cmp [dst_height],0
- je all_done
- cmp [src_width],0
- je all_done
- cmp [src_height],0
- je all_done
- mov eax , [ src_x ]
- mov ebx , [ src_y ]
- mov [ src_x0 ] , eax
- mov [ src_y0 ] , ebx
- add eax , [ src_width ]
- add ebx , [ src_height ]
- mov [ src_x1 ] , eax
- mov [ src_y1 ] , ebx
- mov eax , [ dst_x ]
- mov ebx , [ dst_y ]
- mov [ dst_x0 ] , eax
- mov [ dst_y0 ] , ebx
- add eax , [ dst_width ]
- add ebx , [ dst_height ]
- mov [ dst_x1 ] , eax
- mov [ dst_y1 ] , ebx
- ; Clip Source Rectangle against source Window boundaries.
- mov esi , [ this_object ] ; get ptr to src
- xor ecx , ecx
- xor edx , edx
- mov edi , [esi]GraphicViewPortClass.Width ; get width into register
- mov eax , [ src_x0 ]
- mov ebx , [ src_x1 ]
- shld ecx , eax , 1
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- mov edi,[esi]GraphicViewPortClass.Height ; get height into register
- mov eax , [ src_y0 ]
- mov ebx , [ src_y1 ]
- shld ecx , eax , 1
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- xor cl , 5
- xor dl , 5
- mov al , cl
- test dl , cl
- jnz all_done
- or al , dl
- jz clip_against_dest
- mov bl , dl
- test cl , 1000b
- jz src_left_ok
- xor eax , eax
- mov [ src_x0 ] , eax
- sub eax , [ src_x ]
- imul [ dst_width ]
- idiv [ src_width ]
- add eax , [ dst_x ]
- mov [ dst_x0 ] , eax
- src_left_ok:
- test cl , 0010b
- jz src_bottom_ok
- xor eax , eax
- mov [ src_y0 ] , eax
- sub eax , [ src_y ]
- imul [ dst_height ]
- idiv [ src_height ]
- add eax , [ dst_y ]
- mov [ dst_y0 ] , eax
- src_bottom_ok:
- test bl , 0100b
- jz src_right_ok
- mov eax , [esi]GraphicViewPortClass.Width ; get width into register
- mov [ src_x1 ] , eax
- sub eax , [ src_x ]
- imul [ dst_width ]
- idiv [ src_width ]
- add eax , [ dst_x ]
- mov [ dst_x1 ] , eax
- src_right_ok:
- test bl , 0001b
- jz clip_against_dest
- mov eax , [esi]GraphicViewPortClass.Height ; get width into register
- mov [ src_y1 ] , eax
- sub eax , [ src_y ]
- imul [ dst_height ]
- idiv [ src_height ]
- add eax , [ dst_y ]
- mov [ dst_y1 ] , eax
- ; Clip destination Rectangle against source Window boundaries.
- clip_against_dest:
- mov esi , [ dest ] ; get ptr to src
- xor ecx , ecx
- xor edx , edx
- mov edi , [esi]GraphicViewPortClass.Width ; get width into register
- mov eax , [ dst_x0 ]
- mov ebx , [ dst_x1 ]
- shld ecx , eax , 1
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- mov edi,[esi]GraphicViewPortClass.Height ; get height into register
- mov eax , [ dst_y0 ]
- mov ebx , [ dst_y1 ]
- shld ecx , eax , 1
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- xor cl , 5
- xor dl , 5
- mov al , cl
- test dl , cl
- jnz all_done
- or al , dl
- jz do_scaling
- mov bl , dl
- test cl , 1000b
- jz dst_left_ok
- xor eax , eax
- mov [ dst_x0 ] , eax
- sub eax , [ dst_x ]
- imul [ src_width ]
- idiv [ dst_width ]
- add eax , [ src_x ]
- mov [ src_x0 ] , eax
- dst_left_ok:
- test cl , 0010b
- jz dst_bottom_ok
- xor eax , eax
- mov [ dst_y0 ] , eax
- sub eax , [ dst_y ]
- imul [ src_height ]
- idiv [ dst_height ]
- add eax , [ src_y ]
- mov [ src_y0 ] , eax
- dst_bottom_ok:
- test bl , 0100b
- jz dst_right_ok
- mov eax , [esi]GraphicViewPortClass.Width ; get width into register
- mov [ dst_x1 ] , eax
- sub eax , [ dst_x ]
- imul [ src_width ]
- idiv [ dst_width ]
- add eax , [ src_x ]
- mov [ src_x1 ] , eax
- dst_right_ok:
- test bl , 0001b
- jz do_scaling
- mov eax , [esi]GraphicViewPortClass.Height ; get width into register
- mov [ dst_y1 ] , eax
- sub eax , [ dst_y ]
- imul [ src_height ]
- idiv [ dst_height ]
- add eax , [ src_y ]
- mov [ src_y1 ] , eax
- do_scaling:
- cld
- mov ebx , [ this_object ]
- mov esi , [ebx]GraphicViewPortClass. Offset
- mov eax , [ebx]GraphicViewPortClass. XAdd
- add eax , [ebx]GraphicViewPortClass. Width
- add eax , [ebx]GraphicViewPortClass. Pitch
- mov [ src_win_width ] , eax
- mul [ src_y0 ]
- add esi , [ src_x0 ]
- add esi , eax
- mov ebx , [ dest ]
- mov edi , [ebx]GraphicViewPortClass. Offset
- mov eax , [ebx]GraphicViewPortClass. XAdd
- add eax , [ebx]GraphicViewPortClass. Width
- add eax , [ebx]GraphicViewPortClass. Pitch
- mov [ dst_win_width ] , eax
- mul [ dst_y0 ]
- add edi , [ dst_x0 ]
- add edi , eax
- mov eax , [ src_height ]
- xor edx , edx
- mov ebx , [ dst_height ]
- idiv [ dst_height ]
- imul eax , [ src_win_width ]
- neg ebx
- mov [ dy_intr ] , eax
- mov [ dy_frac ] , edx
- mov [ dy_acc ] , ebx
- mov eax , [ src_width ]
- xor edx , edx
- shl eax , 16
- idiv [ dst_width ]
- xor edx , edx
- shld edx , eax , 16
- shl eax , 16
- mov ecx , [ dst_y1 ]
- mov ebx , [ dst_x1 ]
- sub ecx , [ dst_y0 ]
- jle all_done
- sub ebx , [ dst_x0 ]
- jle all_done
- mov [ counter_y ] , ecx
- cmp [ trans ] , 0
- jnz transparency
- cmp [ remap ] , 0
- jnz normal_remap
- ; *************************************************************************
- ; normal scale
- mov ecx , ebx
- and ecx , 01fh
- lea ecx , [ ecx + ecx * 2 ]
- shr ebx , 5
- neg ecx
- mov [ counter_x ] , ebx
- lea ecx , [ ref_point + ecx + ecx * 2 ]
- mov [ entry ] , ecx
- outter_loop:
- push esi
- push edi
- xor ecx , ecx
- mov ebx , [ counter_x ]
- jmp [ entry ]
- inner_loop:
- // REPT not supported for inline asm. ST - 12/19/2018 6:11PM
- //REPT 32
- push ebx //ST - 12/19/2018 6:11PM
- mov ebx,32 //ST - 12/19/2018 6:11PM
- rept_loop:
- mov cl , [ esi ]
- add ecx , eax
- adc esi , edx
- mov [ edi ] , cl
- inc edi
- dec ebx //ST - 12/19/2018 6:11PM
- jnz rept_loop //ST - 12/19/2018 6:11PM
- pop ebx //ST - 12/19/2018 6:11PM
- //ENDM
- ref_point:
- dec ebx
- jge inner_loop
- pop edi
- pop esi
- add edi , [ dst_win_width ]
- add esi , [ dy_intr ]
- mov ebx , [ dy_acc ]
- add ebx , [ dy_frac ]
- jle skip_line
- add esi , [ src_win_width ]
- sub ebx , [ dst_height ]
- skip_line:
- dec [ counter_y ]
- mov [ dy_acc ] , ebx
- jnz outter_loop
- jmp all_done //ret
- ; *************************************************************************
- ; normal scale with remap
- normal_remap:
- mov ecx , ebx
- mov [ dx_frac ], eax
- and ecx , 01fh
- mov eax , [ remap ]
- shr ebx , 5
- imul ecx , - 13
- mov [ counter_x ] , ebx
- lea ecx , [ remapref_point + ecx ]
- mov [ entry ] , ecx
- remapoutter_loop:
- mov ebx , [ counter_x ]
- push esi
- mov [ remap_counter ] , ebx
- push edi
- xor ecx , ecx
- xor ebx , ebx
- jmp [ entry ]
- remapinner_loop:
- // REPT not supported for inline asm. ST - 12/19/2018 6:11PM
- //REPT 32
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- mov bl , [ esi ]
- add ecx , [ dx_frac ]
- adc esi , edx
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- inc edi
- //ENDM
- remapref_point:
- dec [ remap_counter ]
- jge remapinner_loop
- pop edi
- pop esi
- add edi , [ dst_win_width ]
- add esi , [ dy_intr ]
- mov ebx , [ dy_acc ]
- add ebx , [ dy_frac ]
- jle remapskip_line
- add esi , [ src_win_width ]
- sub ebx , [ dst_height ]
- remapskip_line:
- dec [ counter_y ]
- mov [ dy_acc ] , ebx
- jnz remapoutter_loop
- jmp all_done //ret
- ;****************************************************************************
- ; scale with trnsparency
- transparency:
- cmp [ remap ] , 0
- jnz trans_remap
- ; *************************************************************************
- ; normal scale with transparency
- mov ecx , ebx
- and ecx , 01fh
- imul ecx , -13
- shr ebx , 5
- mov [ counter_x ] , ebx
- lea ecx , [ trans_ref_point + ecx ]
- mov [ entry ] , ecx
- trans_outter_loop:
- xor ecx , ecx
- push esi
- push edi
- mov ebx , [ counter_x ]
- jmp [ entry ]
- trans_inner_loop:
-
- // REPT not supported for inline asm. ST - 12/19/2018 6:11PM
- //REPT 32
- push ebx //ST - 12/19/2018 6:11PM
- mov ebx,32 //ST - 12/19/2018 6:11PM
- rept_loop2:
-
- mov cl , [ esi ]
- test cl , cl
- jz trans_pixel
- mov [ edi ] , cl
- trans_pixel:
- add ecx , eax
- adc esi , edx
- inc edi
-
- dec ebx //ST - 12/19/2018 6:11PM
- jnz rept_loop2 //ST - 12/19/2018 6:11PM
- pop ebx //ST - 12/19/2018 6:11PM
-
- //ENDM
- trans_ref_point:
- dec ebx
- jge trans_inner_loop
- pop edi
- pop esi
- add edi , [ dst_win_width ]
- add esi , [ dy_intr ]
- mov ebx , [ dy_acc ]
- add ebx , [ dy_frac ]
- jle trans_skip_line
- add esi , [ src_win_width ]
- sub ebx , [ dst_height ]
- trans_skip_line:
- dec [ counter_y ]
- mov [ dy_acc ] , ebx
- jnz trans_outter_loop
- jmp all_done //ret
- ; *************************************************************************
- ; normal scale with remap
- trans_remap:
- mov ecx , ebx
- mov [ dx_frac ], eax
- and ecx , 01fh
- mov eax , [ remap ]
- shr ebx , 5
- imul ecx , - 17
- mov [ counter_x ] , ebx
- lea ecx , [ trans_remapref_point + ecx ]
- mov [ entry ] , ecx
- trans_remapoutter_loop:
- mov ebx , [ counter_x ]
- push esi
- mov [ remap_counter ] , ebx
- push edi
- xor ecx , ecx
- xor ebx , ebx
- jmp [ entry ]
-
-
- trans_remapinner_loop:
- // REPT not supported for inline asm. ST - 12/19/2018 6:11PM
- //REPT 32
- // Run out of registers so use ebp
- push ebp //ST - 12/19/2018 6:11PM
- mov ebp,32 //ST - 12/19/2018 6:11PM
- rept_loop3:
- mov bl , [ esi ]
- test bl , bl
- jz trans_pixel2
- mov cl , [ eax + ebx ]
- mov [ edi ] , cl
- trans_pixel2:
- add ecx , [ dx_frac ]
- adc esi , edx
- inc edi
-
- dec ebp //ST - 12/19/2018 6:11PM
- jnz rept_loop3 //ST - 12/19/2018 6:11PM
- pop ebp //ST - 12/19/2018 6:11PM
- //ENDM
- trans_remapref_point:
- dec [ remap_counter ]
- jge trans_remapinner_loop
- pop edi
- pop esi
- add edi , [ dst_win_width ]
- add esi , [ dy_intr ]
- mov ebx , [ dy_acc ]
- add ebx , [ dy_frac ]
- jle trans_remapskip_line
- add esi , [ src_win_width ]
- sub ebx , [ dst_height ]
- trans_remapskip_line:
- dec [ counter_y ]
- mov [ dy_acc ] , ebx
- jnz trans_remapoutter_loop
- //ret
- all_done:
- }
- }
- #pragma warning (pop)
- unsigned int LastIconset = 0;
- unsigned int StampPtr = 0; // DD 0 ; Pointer to icon data.
- unsigned int IsTrans = 0; // DD 0 ; Pointer to transparent icon flag table.
- unsigned int MapPtr = 0; // DD 0 ; Pointer to icon map.
- unsigned int IconWidth = 0; // DD 0 ; Width of icon in pixels.
- unsigned int IconHeight = 0; // DD 0 ; Height of icon in pixels.
- unsigned int IconSize = 0; // DD 0 ; Number of bytes for each icon data.
- unsigned int IconCount = 0; // DD 0 ; Number of icons in the set.
- #if (0)
- LastIconset DD 0 ; Pointer to last iconset initialized.
- StampPtr DD 0 ; Pointer to icon data.
- IsTrans DD 0 ; Pointer to transparent icon flag table.
- MapPtr DD 0 ; Pointer to icon map.
- IconWidth DD 0 ; Width of icon in pixels.
- IconHeight DD 0 ; Height of icon in pixels.
- IconSize DD 0 ; Number of bytes for each icon data.
- IconCount DD 0 ; Number of icons in the set.
- GLOBAL C Buffer_Draw_Stamp:near
- GLOBAL C Buffer_Draw_Stamp_Clip:near
- ; 256 color icon system.
- #endif
- /*
- ;***********************************************************
- ; INIT_STAMPS
- ;
- ; VOID cdecl Init_Stamps(VOID *icondata);
- ;
- ; This routine initializes the stamp data.
- ; Bounds Checking: NONE
- ;
- ;*
- */
- extern "C" void __cdecl Init_Stamps(unsigned int icondata)
- {
- __asm {
- pushad // ST - 12/20/2018 10:30AM
-
- ; Verify legality of parameter.
- cmp [icondata],0
- je short fini
- ; Don't initialize if already initialized to this set (speed reasons).
- mov edi,[icondata]
- cmp [LastIconset],edi
- je short fini
- mov [LastIconset],edi
- ; Record number of icons in set.
- movzx eax,[edi]IControl_Type.Count
- mov [IconCount],eax
- ; Record width of icon.
- movzx eax,[edi]IControl_Type.Width
- mov [IconWidth],eax
- ; Record height of icon.
- movzx ebx,[edi]IControl_Type.Height
- mov [IconHeight],ebx
- ; Record size of icon (in bytes).
- mul ebx
- mov [IconSize],eax
- ; Record hard pointer to icon map data.
- mov eax,[edi]IControl_Type.Map
- add eax,edi
- mov [MapPtr],eax
- //nomap:
- ; Record hard pointer to icon data.
- mov eax,edi
- add eax,[edi]IControl_Type.Icons
- mov [StampPtr],eax
- ; Record the transparent table.
- mov eax,edi
- add eax,[edi]IControl_Type.TransFlag
- mov [IsTrans],eax
- fini:
- popad // ST - 12/20/2018 10:30AM
- }
- }
- /*
- ;***********************************************************
- ;***********************************************************
- ; DRAW_STAMP
- ;
- ; VOID cdecl Buffer_Draw_Stamp(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap);
- ;
- ; This routine renders the icon at the given coordinate.
- ;
- ; The remap table is a 256 byte simple pixel translation table to use when
- ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
- ; remap valid colors to be invisible (for special effect reasons).
- ; This routine is fastest when no remap table is passed in.
- ;*
- */
- void __cdecl Buffer_Draw_Stamp(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap)
- {
- unsigned int modulo = 0;
- unsigned int iwidth = 0;
- unsigned char doremap = 0;
- /*
- PROC Buffer_Draw_Stamp C near
- ARG this_object:DWORD ; this is a member function
- ARG icondata:DWORD ; Pointer to icondata.
- ARG icon:DWORD ; Icon number to draw.
- ARG x_pixel:DWORD ; X coordinate of icon.
- ARG y_pixel:DWORD ; Y coordinate of icon.
- ARG remap:DWORD ; Remap table.
- LOCAL modulo:DWORD ; Modulo to get to next row.
- LOCAL iwidth:DWORD ; Icon width (here for speedy access).
- LOCAL doremap:BYTE ; Should remapping occur?
- */
-
- __asm {
- pushad
- cmp [icondata],0
- je proc_out
- ; Initialize the stamp data if necessary.
- mov eax,[icondata]
- cmp [LastIconset],eax
- je short noreset
- push eax
- call Init_Stamps
- pop eax // Clean up stack. ST - 12/20/2018 10:42AM
- noreset:
- ; Determine if the icon number requested is actually in the set.
- ; Perform the logical icon to actual icon number remap if necessary.
- mov ebx,[icon]
- cmp [MapPtr],0
- je short notmap
- mov edi,[MapPtr]
- mov bl,[edi+ebx]
- notmap:
- cmp ebx,[IconCount]
- jae proc_out
- mov [icon],ebx ; Updated icon number.
- ; If the remap table pointer passed in is NULL, then flag this condition
- ; so that the faster (non-remapping) icon draw loop will be used.
- cmp [remap],0
- setne [doremap]
- ; Get pointer to position to render icon. EDI = ptr to destination page.
- mov ebx,[this_object]
- mov edi,[ebx]GraphicViewPortClass.Offset
- mov eax,[ebx]GraphicViewPortClass.Width
- add eax,[ebx]GraphicViewPortClass.XAdd
- add eax,[ebx]GraphicViewPortClass.Pitch
- push eax ; save viewport full width for lower
- mul [y_pixel]
- add edi,eax
- add edi,[x_pixel]
- ; Determine row modulo for advancing to next line.
- pop eax ; retrieve viewport width
- sub eax,[IconWidth]
- mov [modulo],eax
- ; Setup some working variables.
- mov ecx,[IconHeight] ; Row counter.
- mov eax,[IconWidth]
- mov [iwidth],eax ; Stack copy of byte width for easy BP access.
- ; Fetch pointer to start of icon's data. ESI = ptr to icon data.
- mov eax,[icon]
- mul [IconSize]
- mov esi,[StampPtr]
- add esi,eax
- ; Determine whether simple icon draw is sufficient or whether the
- ; extra remapping icon draw is needed.
- cmp [BYTE PTR doremap],0
- je short istranscheck
- ;************************************************************
- ; Complex icon draw -- extended remap.
- ; EBX = Palette pointer (ready for XLAT instruction).
- ; EDI = Pointer to icon destination in page.
- ; ESI = Pointer to icon data.
- ; ECX = Number of pixel rows.
- ;;; mov edx,[remap]
- mov ebx,[remap]
- xor eax,eax
- xrowloop:
- push ecx
- mov ecx,[iwidth]
- xcolumnloop:
- lodsb
- ;;; mov ebx,edx
- ;;; add ebx,eax
- ;;; mov al,[ebx] ; New real color to draw.
- xlatb
- or al,al
- jz short xskip1 ; Transparency skip check.
- mov [edi],al
- xskip1:
- inc edi
- loop xcolumnloop
- pop ecx
- add edi,[modulo]
- loop xrowloop
- jmp short proc_out
- ;************************************************************
- ; Check to see if transparent or generic draw is necessary.
- istranscheck:
- mov ebx,[IsTrans]
- add ebx,[icon]
- cmp [BYTE PTR ebx],0
- jne short rowloop
- ;************************************************************
- ; Fast non-transparent icon draw routine.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- mov ebx,ecx
- shr ebx,2
- mov edx,[modulo]
- mov eax,[iwidth]
- shr eax,2
- loop1:
- mov ecx,eax
- rep movsd
- add edi,edx
- mov ecx,eax
- rep movsd
- add edi,edx
- mov ecx,eax
- rep movsd
- add edi,edx
- mov ecx,eax
- rep movsd
- add edi,edx
- dec ebx
- jnz loop1
- jmp short proc_out
- ;************************************************************
- ; Transparent icon draw routine -- no extended remap.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- rowloop:
- push ecx
- mov ecx,[iwidth]
- columnloop:
- lodsb
- or al,al
- jz short skip1 ; Transparency check.
- mov [edi],al
- skip1:
- inc edi
- loop columnloop
- pop ecx
- add edi,[modulo]
- loop rowloop
- ; Cleanup and exit icon drawing routine.
- proc_out:
- popad
- //ret
- }
- }
- /*
- ;***********************************************************
- ; DRAW_STAMP_CLIP
- ;
- ; VOID cdecl MCGA_Draw_Stamp_Clip(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap, LONG min_x, LONG min_y, LONG max_x, LONG max_y);
- ;
- ; This routine renders the icon at the given coordinate.
- ;
- ; The remap table is a 256 byte simple pixel translation table to use when
- ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
- ; remap valid colors to be invisible (for special effect reasons).
- ; This routine is fastest when no remap table is passed in.
- ;*
- */
- void __cdecl Buffer_Draw_Stamp_Clip(void const *this_object, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int min_x, int min_y, int max_x, int max_y)
- {
-
-
- unsigned int modulo = 0;
- unsigned int iwidth = 0;
- unsigned int skip = 0;
- unsigned char doremap = 0;
-
-
- /*
- ARG this_object:DWORD ; this is a member function
- ARG icondata:DWORD ; Pointer to icondata.
- ARG icon:DWORD ; Icon number to draw.
- ARG x_pixel:DWORD ; X coordinate of icon.
- ARG y_pixel:DWORD ; Y coordinate of icon.
- ARG remap:DWORD ; Remap table.
- ARG min_x:DWORD ; Clipping rectangle boundary
- ARG min_y:DWORD ; Clipping rectangle boundary
- ARG max_x:DWORD ; Clipping rectangle boundary
- ARG max_y:DWORD ; Clipping rectangle boundary
- LOCAL modulo:DWORD ; Modulo to get to next row.
- LOCAL iwidth:DWORD ; Icon width (here for speedy access).
- LOCAL skip:DWORD ; amount to skip per row of icon data
- LOCAL doremap:BYTE ; Should remapping occur?
- */
- __asm {
- pushad
- cmp [icondata],0
- je proc_out
- ; Initialize the stamp data if necessary.
- mov eax,[icondata]
- cmp [LastIconset],eax
- je short noreset2
- push eax
- call Init_Stamps
- pop eax // Clean up stack. ST - 12/20/2018 10:42AM
- noreset2:
- ; Determine if the icon number requested is actually in the set.
- ; Perform the logical icon to actual icon number remap if necessary.
- mov ebx,[icon]
- cmp [MapPtr],0
- je short notmap2
- mov edi,[MapPtr]
- mov bl,[edi+ebx]
- notmap2:
- cmp ebx,[IconCount]
- jae proc_out
- mov [icon],ebx ; Updated icon number.
- ; Setup some working variables.
- mov ecx,[IconHeight] ; Row counter.
- mov eax,[IconWidth]
- mov [iwidth],eax ; Stack copy of byte width for easy BP access.
- ; Fetch pointer to start of icon's data. ESI = ptr to icon data.
- mov eax,[icon]
- mul [IconSize]
- mov esi,[StampPtr]
- add esi,eax
- ; Update the clipping window coordinates to be valid maxes instead of width & height
- ; , and change the coordinates to be window-relative
- mov ebx,[min_x]
- add [max_x],ebx
- add [x_pixel],ebx ; make it window-relative
- mov ebx,[min_y]
- add [max_y],ebx
- add [y_pixel],ebx ; make it window-relative
- ; See if the icon is within the clipping window
- ; First, verify that the icon position is less than the maximums
- mov ebx,[x_pixel]
- cmp ebx,[max_x]
- jge proc_out
- mov ebx,[y_pixel]
- cmp ebx,[max_y]
- jge proc_out
- ; Now verify that the icon position is >= the minimums
- add ebx,[IconHeight]
- cmp ebx,[min_y]
- jle proc_out
- mov ebx,[x_pixel]
- add ebx,[IconWidth]
- cmp ebx,[min_x]
- jle proc_out
- ; Now, clip the x, y, width, and height variables to be within the
- ; clipping rectangle
- mov ebx,[x_pixel]
- cmp ebx,[min_x]
- jge nominxclip
- ; x < minx, so must clip
- mov ebx,[min_x]
- sub ebx,[x_pixel]
- add esi,ebx ; source ptr += (minx - x)
- sub [iwidth],ebx ; icon width -= (minx - x)
- mov ebx,[min_x]
- mov [x_pixel],ebx
- nominxclip:
- mov eax,[IconWidth]
- sub eax,[iwidth]
- mov [skip],eax
- ; Check for x+width > max_x
- mov eax,[x_pixel]
- add eax,[iwidth]
- cmp eax,[max_x]
- jle nomaxxclip
- ; x+width is greater than max_x, so must clip width down
- mov eax,[iwidth] ; eax = old width
- mov ebx,[max_x]
- sub ebx,[x_pixel]
- mov [iwidth],ebx ; iwidth = max_x - xpixel
- sub eax,ebx
- add [skip],eax ; skip += (old width - iwidth)
- nomaxxclip:
- ; check if y < miny
- mov eax,[min_y]
- cmp eax,[y_pixel] ; if(miny <= y_pixel), no clip needed
- jle nominyclip
- sub eax,[y_pixel]
- sub ecx,eax ; height -= (miny - y)
- mul [IconWidth]
- add esi,eax ; icon source ptr += (width * (miny - y))
- mov eax,[min_y]
- mov [y_pixel],eax ; y = miny
- nominyclip:
- ; check if (y+height) > max y
- mov eax,[y_pixel]
- add eax,ecx
- cmp eax,[max_y] ; if (y + height <= max_y), no clip needed
- jle nomaxyclip
- mov ecx,[max_y] ; height = max_y - y_pixel
- sub ecx,[y_pixel]
- nomaxyclip:
- ; If the remap table pointer passed in is NULL, then flag this condition
- ; so that the faster (non-remapping) icon draw loop will be used.
- cmp [remap],0
- setne [doremap]
- ; Get pointer to position to render icon. EDI = ptr to destination page.
- mov ebx,[this_object]
- mov edi,[ebx]GraphicViewPortClass.Offset
- mov eax,[ebx]GraphicViewPortClass.Width
- add eax,[ebx]GraphicViewPortClass.XAdd
- add eax,[ebx]GraphicViewPortClass.Pitch
- push eax ; save viewport full width for lower
- mul [y_pixel]
- add edi,eax
- add edi,[x_pixel]
- ; Determine row modulo for advancing to next line.
- pop eax ; retrieve viewport width
- sub eax,[iwidth]
- mov [modulo],eax
- ; Determine whether simple icon draw is sufficient or whether the
- ; extra remapping icon draw is needed.
- cmp [BYTE PTR doremap],0
- je short istranscheck2
- ;************************************************************
- ; Complex icon draw -- extended remap.
- ; EBX = Palette pointer (ready for XLAT instruction).
- ; EDI = Pointer to icon destination in page.
- ; ESI = Pointer to icon data.
- ; ECX = Number of pixel rows.
- mov ebx,[remap]
- xor eax,eax
- xrowloopc:
- push ecx
- mov ecx,[iwidth]
- xcolumnloopc:
- lodsb
- xlatb
- or al,al
- jz short xskip1c ; Transparency skip check.
- mov [edi],al
- xskip1c:
- inc edi
- loop xcolumnloopc
- pop ecx
- add edi,[modulo]
- add esi,[skip]
- loop xrowloopc
- jmp short proc_out
- ;************************************************************
- ; Check to see if transparent or generic draw is necessary.
- istranscheck2:
- mov ebx,[IsTrans]
- add ebx,[icon]
- cmp [BYTE PTR ebx],0
- jne short rowloopc
- ;************************************************************
- ; Fast non-transparent icon draw routine.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- mov ebx,ecx
- mov edx,[modulo]
- mov eax,[iwidth]
- ;
- ; Optimise copy by dword aligning the destination
- ;
- loop1c:
- push eax
- //rept 3 // No rept in inline asm. ST - 12/20/2018 10:43AM
- test edi,3
- jz aligned
- movsb
- dec eax
- jz finishedit
- test edi,3
- jz aligned
- movsb
- dec eax
- jz finishedit
- test edi,3
- jz aligned
- movsb
- dec eax
- jz finishedit
- //endm
- aligned:
- mov ecx,eax
- shr ecx,2
- rep movsd
- mov ecx,eax
- and ecx,3
- rep movsb
- finishedit:
- add edi,edx
- add esi,[skip]
- pop eax
- dec ebx
- jnz loop1c
- jmp short proc_out
- ;************************************************************
- ; Transparent icon draw routine -- no extended remap.
- ; ES:DI = Pointer to icon destination in page.
- ; DS:SI = Pointer to icon data.
- ; CX = Number of pixel rows.
- rowloopc:
- push ecx
- mov ecx,[iwidth]
- columnloopc:
- lodsb
- or al,al
- jz short skip1c ; Transparency check.
- mov [edi],al
- skip1c:
- inc edi
- loop columnloopc
- pop ecx
- add edi,[modulo]
- add esi,[skip]
- loop rowloopc
- ; Cleanup and exit icon drawing routine.
- proc_out:
- popad
- //ret
- }
- }
- VOID __cdecl Buffer_Draw_Line(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color);
- VOID __cdecl Buffer_Fill_Rect(void *thisptr, int sx, int sy, int dx, int dy, unsigned char color);
- VOID __cdecl Buffer_Remap(void * thisptr, int sx, int sy, int width, int height, void *remap);
- VOID __cdecl Buffer_Fill_Quad(void * thisptr, VOID *span_buff, int x0, int y0, int x1, int y1,
- int x2, int y2, int x3, int y3, int color);
- void __cdecl Buffer_Draw_Stamp(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap);
- void __cdecl Buffer_Draw_Stamp_Clip(void const *thisptr, void const *icondata, int icon, int x_pixel, int y_pixel, void const *remap, int ,int,int,int);
- void * __cdecl Get_Font_Palette_Ptr ( void );
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood 32 bit Library *
- ;* *
- ;* File Name : REMAP.ASM *
- ;* *
- ;* Programmer : Phil W. Gorrow *
- ;* *
- ;* Start Date : July 1, 1994 *
- ;* *
- ;* Last Update : July 1, 1994 [PWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- */
- VOID __cdecl Buffer_Remap(void * this_object, int sx, int sy, int width, int height, void *remap)
- {
- /*
- PROC Buffer_Remap C NEAR
- USES eax,ebx,ecx,edx,esi,edi
- ;*===================================================================
- ;* Define the arguements that our function takes.
- ;*===================================================================
- ARG this_object:DWORD
- ARG x0_pixel:DWORD
- ARG y0_pixel:DWORD
- ARG region_width:DWORD
- ARG region_height:DWORD
- ARG remap :DWORD
- ;*===================================================================
- ; Define some locals so that we can handle things quickly
- ;*===================================================================
- local x1_pixel : DWORD
- local y1_pixel : DWORD
- local win_width : dword
- local counter_x : dword
- */
- unsigned int x0_pixel = (unsigned int) sx;
- unsigned int y0_pixel = (unsigned int) sy;
- unsigned int region_width = (unsigned int) width;
- unsigned int region_height = (unsigned int) height;
- unsigned int x1_pixel = 0;
- unsigned int y1_pixel = 0;
- unsigned int win_width = 0;
- unsigned int counter_x = 0;
- __asm {
-
- cmp [ remap ] , 0
- jz real_out
- ; Clip Source Rectangle against source Window boundaries.
- mov esi , [ this_object ] ; get ptr to src
- xor ecx , ecx
- xor edx , edx
- mov edi , [esi]GraphicViewPortClass.Width ; get width into register
- mov ebx , [ x0_pixel ]
- mov eax , [ x0_pixel ]
- add ebx , [ region_width ]
- shld ecx , eax , 1
- mov [ x1_pixel ] , ebx
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- mov edi,[esi]GraphicViewPortClass.Height ; get height into register
- mov ebx , [ y0_pixel ]
- mov eax , [ y0_pixel ]
- add ebx , [ region_height ]
- shld ecx , eax , 1
- mov [ y1_pixel ] , ebx
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- xor cl , 5
- xor dl , 5
- mov al , cl
- test dl , cl
- jnz real_out
- or al , dl
- jz do_remap
- test cl , 1000b
- jz scr_left_ok
- mov [ x0_pixel ] , 0
- scr_left_ok:
- test cl , 0010b
- jz scr_bottom_ok
- mov [ y0_pixel ] , 0
- scr_bottom_ok:
- test dl , 0100b
- jz scr_right_ok
- mov eax , [esi]GraphicViewPortClass.Width ; get width into register
- mov [ x1_pixel ] , eax
- scr_right_ok:
- test dl , 0001b
- jz do_remap
- mov eax , [esi]GraphicViewPortClass.Height ; get width into register
- mov [ y1_pixel ] , eax
- do_remap:
- cld
- mov edi , [esi]GraphicViewPortClass.Offset
- mov eax , [esi]GraphicViewPortClass.XAdd
- mov ebx , [ x1_pixel ]
- add eax , [esi]GraphicViewPortClass.Width
- add eax , [esi]GraphicViewPortClass.Pitch
- mov esi , eax
- mul [ y0_pixel ]
- add edi , [ x0_pixel ]
- sub ebx , [ x0_pixel ]
- jle real_out
- add edi , eax
- sub esi , ebx
- mov ecx , [ y1_pixel ]
- sub ecx , [ y0_pixel ]
- jle real_out
- mov eax , [ remap ]
- mov [ counter_x ] , ebx
- xor edx , edx
- outer_loop:
- mov ebx , [ counter_x ]
- inner_loop:
- mov dl , [ edi ]
- mov dl , [ eax + edx ]
- mov [ edi ] , dl
- inc edi
- dec ebx
- jnz inner_loop
- add edi , esi
- dec ecx
- jnz outer_loop
- real_out:
- // ret
- }
- }
- /*
- ; **************************************************************************
- ; ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S *
- ; **************************************************************************
- ; * *
- ; * Project Name : WSA Support routines *
- ; * *
- ; * File Name : XORDELTA.ASM *
- ; * *
- ; * Programmer : Scott K. Bowen *
- ; * *
- ; * Last Update :May 23, 1994 [SKB] *
- ; * *
- ; *------------------------------------------------------------------------*
- ; * Functions: *
- ;* Apply_XOR_Delta -- Apply XOR delta data to a buffer. *
- ;* Apply_XOR_Delta_To_Page_Or_Viewport -- Calls the copy or the XOR funti*
- ;* Copy_Delta_buffer -- Copies XOR Delta Data to a section of a page. *
- ;* XOR_Delta_Buffer -- Xor's the data in a XOR Delta format to a page. *
- ; * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
- IDEAL
- P386
- MODEL USE32 FLAT
- */
- /*
- LOCALS ??
- ; These are used to call Apply_XOR_Delta_To_Page_Or_Viewport() to setup flags parameter. If
- ; These change, make sure and change their values in wsa.cpp.
- DO_XOR equ 0
- DO_COPY equ 1
- TO_VIEWPORT equ 0
- TO_PAGE equ 2
- ;
- ; Routines defined in this module
- ;
- ;
- ; UWORD Apply_XOR_Delta(UWORD page_seg, BYTE *delta_ptr);
- ; PUBLIC Apply_XOR_Delta_To_Page_Or_Viewport(UWORD page_seg, BYTE *delta_ptr, WORD width, WORD copy)
- ;
- ; PROC C XOR_Delta_Buffer
- ; PROC C Copy_Delta_Buffer
- ;
- GLOBAL C Apply_XOR_Delta:NEAR
- GLOBAL C Apply_XOR_Delta_To_Page_Or_Viewport:NEAR
- */
- #define DO_XOR 0
- #define DO_COPY 1
- #define TO_VIEWPORT 0
- #define TO_PAGE 2
- void __cdecl XOR_Delta_Buffer(int nextrow);
- void __cdecl Copy_Delta_Buffer(int nextrow);
- /*
- ;***************************************************************************
- ;* APPLY_XOR_DELTA -- Apply XOR delta data to a linear buffer. *
- ;* AN example of this in C is at the botton of the file commented out. *
- ;* *
- ;* INPUT: BYTE *target - destination buffer. *
- ;* BYTE *delta - xor data to be delta uncompress. *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;* 05/23/1994 SKB : Created. *
- ;*=========================================================================*
- */
- unsigned int __cdecl Apply_XOR_Delta(char *target, char *delta)
- {
- /*
- PROC Apply_XOR_Delta C near
- USES ebx,ecx,edx,edi,esi
- ARG target:DWORD ; pointers.
- ARG delta:DWORD ; pointers.
- */
-
- __asm {
-
- ; Optimized for 486/pentium by rearanging instructions.
- mov edi,[target] ; get our pointers into offset registers.
- mov esi,[delta]
- cld ; make sure we go forward
- xor ecx,ecx ; use cx for loop
- top_loop:
- xor eax,eax ; clear out eax.
- mov al,[esi] ; get delta source byte
- inc esi
- test al,al ; check for a SHORTDUMP ; check al incase of sign value.
- je short_run
- js check_others
- ;
- ; SHORTDUMP
- ;
- mov ecx,eax ; stick count in cx
- dump_loop:
- mov al,[esi] ;get delta XOR byte
- xor [edi],al ; xor that byte on the dest
- inc esi
- inc edi
- dec ecx
- jnz dump_loop
- jmp top_loop
- ;
- ; SHORTRUN
- ;
- short_run:
- mov cl,[esi] ; get count
- inc esi ; inc delta source
- do_run:
- mov al,[esi] ; get XOR byte
- inc esi
- run_loop:
- xor [edi],al ; xor that byte.
- inc edi ; go to next dest pixel
- dec ecx ; one less to go.
- jnz run_loop
- jmp top_loop
- ;
- ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP
- ;
- check_others:
- sub eax,080h ; opcode -= 0x80
- jnz do_skip ; if zero then get next word, otherwise use remainder.
- mov ax,[esi]
- lea esi,[esi+2] ; get word code in ax
- test ax,ax ; set flags. (not 32bit register so neg flag works)
- jle not_long_skip
- ;
- ; SHORTSKIP AND LONGSKIP
- ;
- do_skip:
- add edi,eax ; do the skip.
- jmp top_loop
- not_long_skip:
- jz stop ; long count of zero means stop
- sub eax,08000h ; opcode -= 0x8000
- test eax,04000h ; is it a LONGRUN (code & 0x4000)?
- je long_dump
- ;
- ; LONGRUN
- ;
- sub eax,04000h ; opcode -= 0x4000
- mov ecx,eax ; use cx as loop count
- jmp do_run ; jump to run code.
- ;
- ; LONGDUMP
- ;
- long_dump:
- mov ecx,eax ; use cx as loop count
- jmp dump_loop ; go to the dump loop.
- stop:
- }
- }
- /*
- ;----------------------------------------------------------------------------
- ;***************************************************************************
- ;* APPLY_XOR_DELTA_To_Page_Or_Viewport -- Calls the copy or the XOR funtion. *
- ;* *
- ;* *
- ;* This funtion is call to either xor or copy XOR_Delta data onto a *
- ;* page instead of a buffer. The routine will set up the registers *
- ;* need for the actual routines that will perform the copy or xor. *
- ;* *
- ;* The registers are setup as follows : *
- ;* es:edi - destination segment:offset onto page. *
- ;* ds:esi - source buffer segment:offset of delta data. *
- ;* dx,cx,ax - are all zeroed out before entry. *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;* 03/09/1992 SB : Created. *
- ;*=========================================================================*
- */
- void __cdecl Apply_XOR_Delta_To_Page_Or_Viewport(void *target, void *delta, int width, int nextrow, int copy)
- {
- /*
- USES ebx,ecx,edx,edi,esi
- ARG target:DWORD ; pointer to the destination buffer.
- ARG delta:DWORD ; pointer to the delta buffer.
- ARG width:DWORD ; width of animation.
- ARG nextrow:DWORD ; Page/Buffer width - anim width.
- ARG copy:DWORD ; should it be copied or xor'd?
- */
-
- __asm {
- mov edi,[target] ; Get the target pointer.
- mov esi,[delta] ; Get the destination pointer.
- xor eax,eax ; clear eax, later put them into ecx and edx.
- cld ; make sure we go forward
- mov ebx,[nextrow] ; get the amount to add to get to next row from end. push it later...
- mov ecx,eax ; use cx for loop
- mov edx,eax ; use dx to count the relative column.
- push ebx ; push nextrow onto the stack for Copy/XOR_Delta_Buffer.
- mov ebx,[width] ; bx will hold the max column for speed compares
- ; At this point, all the registers have been set up. Now call the correct function
- ; to either copy or xor the data.
- cmp [copy],DO_XOR ; Do we want to copy or XOR
- je xorfunct ; Jump to XOR if not copy
- call Copy_Delta_Buffer ; Call the function to copy the delta buffer.
- jmp didcopy ; jump past XOR
- xorfunct:
- call XOR_Delta_Buffer ; Call funtion to XOR the deltat buffer.
- didcopy:
- pop ebx ; remove the push done to pass a value.
- }
- }
- /*
- ;----------------------------------------------------------------------------
- ;***************************************************************************
- ;* XOR_DELTA_BUFFER -- Xor's the data in a XOR Delta format to a page. *
- ;* This will only work right if the page has the previous data on it. *
- ;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. *
- ;* The registers must be setup as follows : *
- ;* *
- ;* INPUT: *
- ;* es:edi - destination segment:offset onto page. *
- ;* ds:esi - source buffer segment:offset of delta data. *
- ;* edx,ecx,eax - are all zeroed out before entry. *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;* 03/09/1992 SB : Created. *
- ;*=========================================================================*
- */
- void __cdecl XOR_Delta_Buffer(int nextrow)
- {
- /*
- ARG nextrow:DWORD
- */
-
- __asm {
- top_loop:
- xor eax,eax ; clear out eax.
- mov al,[esi] ; get delta source byte
- inc esi
- test al,al ; check for a SHORTDUMP ; check al incase of sign value.
- je short_run
- js check_others
- ;
- ; SHORTDUMP
- ;
- mov ecx,eax ; stick count in cx
- dump_loop:
- mov al,[esi] ; get delta XOR byte
- xor [edi],al ; xor that byte on the dest
- inc esi
- inc edx ; increment our count on current column
- inc edi
- cmp edx,ebx ; are we at the final column
- jne end_col1 ; if not the jmp over the code
- sub edi,edx ; get our column back to the beginning.
- xor edx,edx ; zero out our column counter
- add edi,[nextrow] ; jump to start of next row
- end_col1:
- dec ecx
- jnz dump_loop
- jmp top_loop
- ;
- ; SHORTRUN
- ;
- short_run:
- mov cl,[esi] ; get count
- inc esi ; inc delta source
- do_run:
- mov al,[esi] ; get XOR byte
- inc esi
- run_loop:
- xor [edi],al ; xor that byte.
- inc edx ; increment our count on current column
- inc edi ; go to next dest pixel
- cmp edx,ebx ; are we at the final column
- jne end_col2 ; if not the jmp over the code
- sub edi,ebx ; get our column back to the beginning.
- xor edx,edx ; zero out our column counter
- add edi,[nextrow] ; jump to start of next row
- end_col2:
- dec ecx
- jnz run_loop
- jmp top_loop
- ;
- ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP
- ;
- check_others:
- sub eax,080h ; opcode -= 0x80
- jnz do_skip ; if zero then get next word, otherwise use remainder.
- mov ax,[esi] ; get word code in ax
- lea esi,[esi+2]
- test ax,ax ; set flags. (not 32bit register so neg flag works)
- jle not_long_skip
- ;
- ; SHORTSKIP AND LONGSKIP
- ;
- do_skip:
- sub edi,edx ; go back to beginning or row.
- add edx,eax ; incriment our count on current row
- recheck3:
- cmp edx,ebx ; are we past the end of the row
- jb end_col3 ; if not the jmp over the code
- sub edx,ebx ; Subtract width from the col counter
- add edi,[nextrow] ; jump to start of next row
- jmp recheck3 ; jump up to see if we are at the right row
- end_col3:
- add edi,edx ; get to correct position in row.
- jmp top_loop
- not_long_skip:
- jz stop ; long count of zero means stop
- sub eax,08000h ; opcode -= 0x8000
- test eax,04000h ; is it a LONGRUN (code & 0x4000)?
- je long_dump
- ;
- ; LONGRUN
- ;
- sub eax,04000h ; opcode -= 0x4000
- mov ecx,eax ; use cx as loop count
- jmp do_run ; jump to run code.
- ;
- ; LONGDUMP
- ;
- long_dump:
- mov ecx,eax ; use cx as loop count
- jmp dump_loop ; go to the dump loop.
- stop:
- }
- }
- /*
- ;----------------------------------------------------------------------------
- ;***************************************************************************
- ;* COPY_DELTA_BUFFER -- Copies XOR Delta Data to a section of a page. *
- ;* This function should only be called by XOR_Delta_Buffer_To_Page_Or_Viewport. *
- ;* The registers must be setup as follows : *
- ;* *
- ;* INPUT: *
- ;* es:edi - destination segment:offset onto page. *
- ;* ds:esi - source buffer segment:offset of delta data. *
- ;* dx,cx,ax - are all zeroed out before entry. *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;* 03/09/1992 SB : Created. *
- ;*=========================================================================*
- */
- void __cdecl Copy_Delta_Buffer(int nextrow)
- {
- /*
- ARG nextrow:DWORD
- */
-
- __asm {
-
- top_loop:
- xor eax,eax ; clear out eax.
- mov al,[esi] ; get delta source byte
- inc esi
- test al,al ; check for a SHORTDUMP ; check al incase of sign value.
- je short_run
- js check_others
- ;
- ; SHORTDUMP
- ;
- mov ecx,eax ; stick count in cx
- dump_loop:
- mov al,[esi] ; get delta XOR byte
- mov [edi],al ; store that byte on the dest
- inc edx ; increment our count on current column
- inc esi
- inc edi
- cmp edx,ebx ; are we at the final column
- jne end_col1 ; if not the jmp over the code
- sub edi,edx ; get our column back to the beginning.
- xor edx,edx ; zero out our column counter
- add edi,[nextrow] ; jump to start of next row
- end_col1:
- dec ecx
- jnz dump_loop
- jmp top_loop
- ;
- ; SHORTRUN
- ;
- short_run:
- mov cl,[esi] ; get count
- inc esi ; inc delta source
- do_run:
- mov al,[esi] ; get XOR byte
- inc esi
- run_loop:
- mov [edi],al ; store the byte (instead of XOR against current color)
- inc edx ; increment our count on current column
- inc edi ; go to next dest pixel
- cmp edx,ebx ; are we at the final column
- jne end_col2 ; if not the jmp over the code
- sub edi,ebx ; get our column back to the beginning.
- xor edx,edx ; zero out our column counter
- add edi,[nextrow] ; jump to start of next row
- end_col2:
- dec ecx
- jnz run_loop
- jmp top_loop
- ;
- ; By now, we know it must be a LONGDUMP, SHORTSKIP, LONGRUN, or LONGSKIP
- ;
- check_others:
- sub eax,080h ; opcode -= 0x80
- jnz do_skip ; if zero then get next word, otherwise use remainder.
- mov ax,[esi] ; get word code in ax
- lea esi,[esi+2]
- test ax,ax ; set flags. (not 32bit register so neg flag works)
- jle not_long_skip
- ;
- ; SHORTSKIP AND LONGSKIP
- ;
- do_skip:
- sub edi,edx ; go back to beginning or row.
- add edx,eax ; incriment our count on current row
- recheck3:
- cmp edx,ebx ; are we past the end of the row
- jb end_col3 ; if not the jmp over the code
- sub edx,ebx ; Subtract width from the col counter
- add edi,[nextrow] ; jump to start of next row
- jmp recheck3 ; jump up to see if we are at the right row
- end_col3:
- add edi,edx ; get to correct position in row.
- jmp top_loop
- not_long_skip:
- jz stop ; long count of zero means stop
- sub eax,08000h ; opcode -= 0x8000
- test eax,04000h ; is it a LONGRUN (code & 0x4000)?
- je long_dump
- ;
- ; LONGRUN
- ;
- sub eax,04000h ; opcode -= 0x4000
- mov ecx,eax ; use cx as loop count
- jmp do_run ; jump to run code.
- ;
- ; LONGDUMP
- ;
- long_dump:
- mov ecx,eax ; use cx as loop count
- jmp dump_loop ; go to the dump loop.
- stop:
- }
- }
- /*
- ;----------------------------------------------------------------------------
- */
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood Library *
- ;* *
- ;* File Name : FADING.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : August 20, 1993 *
- ;* *
- ;* Last Update : August 20, 1993 [JLB] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- GLOBAL C Build_Fading_Table :NEAR
- CODESEG
- ;***********************************************************
- ; BUILD_FADING_TABLE
- ;
- ; void *Build_Fading_Table(void *palette, void *dest, long int color, long int frac);
- ;
- ; This routine will create the fading effect table used to coerce colors
- ; from toward a common value. This table is used when Fading_Effect is
- ; active.
- ;
- ; Bounds Checking: None
- ;*
- */
- void * __cdecl Build_Fading_Table(void const *palette, void const *dest, long int color, long int frac)
- {
- /*
- PROC Build_Fading_Table C near
- USES ebx, ecx, edi, esi
- ARG palette:DWORD
- ARG dest:DWORD
- ARG color:DWORD
- ARG frac:DWORD
- LOCAL matchvalue:DWORD ; Last recorded match value.
- LOCAL targetred:BYTE ; Target gun red.
- LOCAL targetgreen:BYTE ; Target gun green.
- LOCAL targetblue:BYTE ; Target gun blue.
- LOCAL idealred:BYTE
- LOCAL idealgreen:BYTE
- LOCAL idealblue:BYTE
- LOCAL matchcolor:BYTE ; Tentative match color.
- */
-
- int matchvalue = 0; //:DWORD ; Last recorded match value.
- unsigned char targetred = 0; //BYTE ; Target gun red.
- unsigned char targetgreen = 0; //BYTE ; Target gun green.
- unsigned char targetblue = 0; //BYTE ; Target gun blue.
- unsigned char idealred = 0; //BYTE
- unsigned char idealgreen = 0; //BYTE
- unsigned char idealblue = 0; //BYTE
- unsigned char matchcolor = 0; //:BYTE ; Tentative match color.
-
- __asm {
- cld
- ; If the source palette is NULL, then just return with current fading table pointer.
- cmp [palette],0
- je fini
- cmp [dest],0
- je fini
- ; Fractions above 255 become 255.
- mov eax,[frac]
- cmp eax,0100h
- jb short ok
- mov [frac],0FFh
- ok:
- ; Record the target gun values.
- mov esi,[palette]
- mov ebx,[color]
- add esi,ebx
- add esi,ebx
- add esi,ebx
- lodsb
- mov [targetred],al
- lodsb
- mov [targetgreen],al
- lodsb
- mov [targetblue],al
- ; Main loop.
- xor ebx,ebx ; Remap table index.
- ; Transparent black never gets remapped.
- mov edi,[dest]
- mov [edi],bl
- inc edi
- ; EBX = source palette logical number (1..255).
- ; EDI = running pointer into dest remap table.
- mainloop:
- inc ebx
- mov esi,[palette]
- add esi,ebx
- add esi,ebx
- add esi,ebx
- mov edx,[frac]
- shr edx,1
- ; new = orig - ((orig-target) * fraction);
- lodsb ; orig
- mov dh,al ; preserve it for later.
- sub al,[targetred] ; al = (orig-target)
- imul dl ; ax = (orig-target)*fraction
- shl ax,1
- sub dh,ah ; dh = orig - ((orig-target) * fraction)
- mov [idealred],dh ; preserve ideal color gun value.
- lodsb ; orig
- mov dh,al ; preserve it for later.
- sub al,[targetgreen] ; al = (orig-target)
- imul dl ; ax = (orig-target)*fraction
- shl ax,1
- sub dh,ah ; dh = orig - ((orig-target) * fraction)
- mov [idealgreen],dh ; preserve ideal color gun value.
- lodsb ; orig
- mov dh,al ; preserve it for later.
- sub al,[targetblue] ; al = (orig-target)
- imul dl ; ax = (orig-target)*fraction
- shl ax,1
- sub dh,ah ; dh = orig - ((orig-target) * fraction)
- mov [idealblue],dh ; preserve ideal color gun value.
- ; Sweep through the entire existing palette to find the closest
- ; matching color. Never matches with color 0.
- mov eax,[color]
- mov [matchcolor],al ; Default color (self).
- mov [matchvalue],-1 ; Ridiculous match value init.
- mov ecx,255
- mov esi,[palette] ; Pointer to original palette.
- add esi,3
- ; BH = color index.
- mov bh,1
- innerloop:
- ; Recursion through the fading table won't work if a color is allowed
- ; to remap to itself. Prevent this from occuring.
- add esi,3
- cmp bh,bl
- je short notclose
- sub esi,3
- xor edx,edx ; Comparison value starts null.
- mov eax,edx
- ; Build the comparison value based on the sum of the differences of the color
- ; guns squared.
- lodsb
- sub al,[idealred]
- mov ah,al
- imul ah
- add edx,eax
- lodsb
- sub al,[idealgreen]
- mov ah,al
- imul ah
- add edx,eax
- lodsb
- sub al,[idealblue]
- mov ah,al
- imul ah
- add edx,eax
- jz short perfect ; If perfect match found then quit early.
- cmp edx,[matchvalue]
- ja short notclose
- mov [matchvalue],edx ; Record new possible color.
- mov [matchcolor],bh
- notclose:
- inc bh ; Checking color index.
- loop innerloop
- mov bh,[matchcolor]
- perfect:
- mov [matchcolor],bh
- xor bh,bh ; Make BX valid main index again.
- ; When the loop exits, we have found the closest match.
- mov al,[matchcolor]
- stosb
- cmp ebx,255
- jne mainloop
- fini:
- mov eax,[dest]
- // ret
- }
- }
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood Library *
- ;* *
- ;* File Name : PAL.ASM *
- ;* *
- ;* Programmer : Joe L. Bostic *
- ;* *
- ;* Start Date : May 30, 1992 *
- ;* *
- ;* Last Update : April 27, 1994 [BR] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* Set_Palette_Range -- Sets changed values in the palette. *
- ;* Bump_Color -- adjusts specified color in specified palette *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- ;********************** Model & Processor Directives ************************
- IDEAL
- P386
- MODEL USE32 FLAT
- ;include "keyboard.inc"
- FALSE = 0
- TRUE = 1
- ;****************************** Declarations ********************************
- GLOBAL C Set_Palette_Range:NEAR
- GLOBAL C Bump_Color:NEAR
- GLOBAL C CurrentPalette:BYTE:768
- GLOBAL C PaletteTable:byte:1024
- ;********************************** Data ************************************
- LOCALS ??
- DATASEG
- CurrentPalette DB 768 DUP(255) ; copy of current values of DAC regs
- PaletteTable DB 1024 DUP(0)
- IFNDEF LIB_EXTERNS_RESOLVED
- VertBlank DW 0 ; !!!! this should go away
- ENDIF
- ;********************************** Code ************************************
- CODESEG
- */
- extern "C" unsigned char CurrentPalette[768] = {255}; // DB 768 DUP(255) ; copy of current values of DAC regs
- extern "C" unsigned char PaletteTable[1024] = {0}; // DB 1024 DUP(0)
- /*
- ;***************************************************************************
- ;* SET_PALETTE_RANGE -- Sets a palette range to the new pal *
- ;* *
- ;* INPUT: *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* PROTO: *
- ;* *
- ;* WARNINGS: This routine is optimized for changing a small number of *
- ;* colors in the palette.
- ;* *
- ;* HISTORY: *
- ;* 03/07/1995 PWG : Created. *
- ;*=========================================================================*
- */
- void __cdecl Set_Palette_Range(void *palette)
- {
- memcpy(CurrentPalette, palette, 768);
- Set_DD_Palette(palette);
- /*
- PROC Set_Palette_Range C NEAR
- ARG palette:DWORD
- GLOBAL Set_DD_Palette_:near
- GLOBAL Wait_Vert_Blank_:near
-
- pushad
- mov esi,[palette]
- mov ecx,768/4
- mov edi,offset CurrentPalette
- cld
- rep movsd
- ;call Wait_Vert_Blank_
- mov eax,[palette]
- push eax
- call Set_DD_Palette_
- pop eax
- popad
- ret
- */
- }
- /*
- ;***************************************************************************
- ;* Bump_Color -- adjusts specified color in specified palette *
- ;* *
- ;* INPUT: *
- ;* VOID *palette - palette to modify *
- ;* WORD changable - color # to change *
- ;* WORD target - color to bend toward *
- ;* *
- ;* OUTPUT: *
- ;* *
- ;* WARNINGS: *
- ;* *
- ;* HISTORY: *
- ;* 04/27/1994 BR : Converted to 32-bit. *
- ;*=========================================================================*
- ; BOOL cdecl Bump_Color(VOID *palette, WORD changable, WORD target);
- */
- BOOL __cdecl Bump_Color(void *pal, int color, int desired)
- {
- /*
- PROC Bump_Color C NEAR
- USES ebx,ecx,edi,esi
- ARG pal:DWORD, color:WORD, desired:WORD
- LOCAL changed:WORD ; Has palette changed?
- */
-
- short short_color = (short) color;
- short short_desired = (short) desired;
- bool changed = false;
-
- __asm {
- mov edi,[pal] ; Original palette pointer.
- mov esi,edi
- mov eax,0
- mov ax,[short_color]
- add edi,eax
- add edi,eax
- add edi,eax ; Offset to changable color.
- mov ax,[short_desired]
- add esi,eax
- add esi,eax
- add esi,eax ; Offset to target color.
- mov [changed],FALSE ; Presume no change.
- mov ecx,3 ; Three color guns.
- ; Check the color gun.
- colorloop:
- mov al,[BYTE PTR esi]
- sub al,[BYTE PTR edi] ; Carry flag is set if subtraction needed.
- jz short gotit
- mov [changed],TRUE
- inc [BYTE PTR edi] ; Presume addition.
- jnc short gotit ; oops, subtraction needed so dec twice.
- dec [BYTE PTR edi]
- dec [BYTE PTR edi]
- gotit:
- inc edi
- inc esi
- loop colorloop
- movzx eax,[changed]
- }
- }
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
- ;***************************************************************************
- ;* *
- ;* Project Name : GraphicViewPortClass *
- ;* *
- ;* File Name : PUTPIXEL.ASM *
- ;* *
- ;* Programmer : Phil Gorrow *
- ;* *
- ;* Start Date : June 7, 1994 *
- ;* *
- ;* Last Update : June 8, 1994 [PWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* VVPC::Put_Pixel -- Puts a pixel on a virtual viewport *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- INCLUDE ".\drawbuff.inc"
- INCLUDE ".\gbuffer.inc"
- CODESEG
- */
- /*
- ;***************************************************************************
- ;* VVPC::PUT_PIXEL -- Puts a pixel on a virtual viewport *
- ;* *
- ;* INPUT: WORD the x position for the pixel relative to the upper *
- ;* left corner of the viewport *
- ;* WORD the y pos for the pixel relative to the upper left *
- ;* corner of the viewport *
- ;* UBYTE the color of the pixel to write *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNING: If pixel is to be placed outside of the viewport then *
- ;* this routine will abort. *
- ;* *
- ;* HISTORY: *
- ;* 06/08/1994 PWG : Created. *
- ;*=========================================================================*
- PROC Buffer_Put_Pixel C near
- USES eax,ebx,ecx,edx,edi
- */
- void __cdecl Buffer_Put_Pixel(void * this_object, int x_pixel, int y_pixel, unsigned char color)
- {
-
- /*
- ARG this_object:DWORD ; this is a member function
- ARG x_pixel:DWORD ; x position of pixel to set
- ARG y_pixel:DWORD ; y position of pixel to set
- ARG color:BYTE ; what color should we clear to
- */
-
- __asm {
-
-
- ;*===================================================================
- ; Get the viewport information and put bytes per row in ecx
- ;*===================================================================
- mov ebx,[this_object] ; get a pointer to viewport
- xor eax,eax
- mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset
- mov ecx,[ebx]GraphicViewPortClass.Height ; edx = height of viewport
- mov edx,[ebx]GraphicViewPortClass.Width ; ecx = width of viewport
- ;*===================================================================
- ; Verify that the X pixel offset if legal
- ;*===================================================================
- mov eax,[x_pixel] ; find the x position
- cmp eax,edx ; is it out of bounds
- jae short done ; if so then get out
- add edi,eax ; otherwise add in offset
- ;*===================================================================
- ; Verify that the Y pixel offset if legal
- ;*===================================================================
- mov eax,[y_pixel] ; get the y position
- cmp eax,ecx ; is it out of bounds
- jae done ; if so then get out
- add edx,[ebx]GraphicViewPortClass.XAdd ; otherwise find bytes per row
- add edx,[ebx]GraphicViewPortClass.Pitch ; add in direct draw pitch
- mul edx ; offset = bytes per row * y
- add edi,eax ; add it into the offset
- ;*===================================================================
- ; Write the pixel to the screen
- ;*===================================================================
- mov al,[color] ; read in color value
- mov [edi],al ; write it to the screen
- done:
- }
- }
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Support Library *
- ;* *
- ;* File Name : cliprect.asm *
- ;* *
- ;* Programmer : Julio R Jerez *
- ;* *
- ;* Start Date : Mar, 2 1995 *
- ;* *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* int Clip_Rect ( int * x , int * y , int * dw , int * dh , *
- ;* int width , int height ) ; *
- ;* int Confine_Rect ( int * x , int * y , int * dw , int * dh , *
- ;* int width , int height ) ; *
- ;* *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- GLOBAL C Clip_Rect :NEAR
- GLOBAL C Confine_Rect :NEAR
- CODESEG
- ;***************************************************************************
- ;* Clip_Rect -- clip a given rectangle against a given window *
- ;* *
- ;* INPUT: &x , &y , &w , &h -> Pointer to rectangle being clipped *
- ;* width , height -> dimension of clipping window *
- ;* *
- ;* OUTPUT: a) Zero if the rectangle is totally contained by the *
- ;* clipping window. *
- ;* b) A negative value if the rectangle is totally outside the *
- ;* the clipping window *
- ;* c) A positive value if the rectangle was clipped against the *
- ;* clipping window, also the values pointed by x, y, w, h will *
- ;* be modified to new clipped values *
- ;* *
- ;* 05/03/1995 JRJ : added comment *
- ;*=========================================================================*
- ; int Clip_Rect (int* x, int* y, int* dw, int* dh, int width, int height); *
- */
- extern "C" int __cdecl Clip_Rect ( int * x , int * y , int * w , int * h , int width , int height )
- {
- /*
- PROC Clip_Rect C near
- uses ebx,ecx,edx,esi,edi
- arg x:dword
- arg y:dword
- arg w:dword
- arg h:dword
- arg width:dword
- arg height:dword
- */
- __asm {
- ;This Clipping algorithm is a derivation of the very well known
- ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency
- ;it is probably the most commontly implemented algorithm both in software
- ;and hardware for clipping lines, rectangles, and convex polygons against
- ;a rectagular clipping window. For reference see
- ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes
- ; pages 113 to 177".
- ; Briefly consist in computing the Sutherland code for both end point of
- ; the rectangle to find out if the rectangle is:
- ; - trivially accepted (no further clipping test, return the oroginal data)
- ; - trivially rejected (return with no action, return error code)
- ; - retangle must be iteratively clipped again edges of the clipping window
- ; and return the clipped rectangle
- ; get all four pointer into regisnters
- mov esi,[x] ; esi = pointer to x
- mov edi,[y] ; edi = pointer to x
- mov eax,[w] ; eax = pointer to dw
- mov ebx,[h] ; ebx = pointer to dh
- ; load the actual data into reg
- mov esi,[esi] ; esi = x0
- mov edi,[edi] ; edi = y0
- mov eax,[eax] ; eax = dw
- mov ebx,[ebx] ; ebx = dh
- ; create a wire frame of the type [x0,y0] , [x1,y1]
- add eax,esi ; eax = x1 = x0 + dw
- add ebx,edi ; ebx = y1 = y0 + dh
- ; we start we suthenland code0 and code1 set to zero
- xor ecx,ecx ; cl = sutherland boolean code0
- xor edx,edx ; dl = sutherland boolean code0
- ; now we start computing the to suthenland boolean code for x0 , x1
- shld ecx,esi,1 ; bit3 of code0 = sign bit of (x0 - 0)
- shld edx,eax,1 ; bit3 of code1 = sign bit of (x1 - 0)
- sub esi,[width] ; get the difference (x0 - (width + 1))
- sub eax,[width] ; get the difference (x1 - (width + 1))
- dec esi
- dec eax
- shld ecx,esi,1 ; bit2 of code0 = sign bit of (x0 - (width + 1))
- shld edx,eax,1 ; bit2 of code1 = sign bit of (x0 - (width + 1))
- ; now we start computing the to suthenland boolean code for y0 , y1
- shld ecx,edi,1 ; bit1 of code0 = sign bit of (y0 - 0)
- shld edx,ebx,1 ; bit1 of code1 = sign bit of (y0 - 0)
- sub edi,[height] ; get the difference (y0 - (height + 1))
- sub ebx,[height] ; get the difference (y1 - (height + 1))
- dec edi
- dec ebx
- shld ecx,edi,1 ; bit0 of code0 = sign bit of (y0 - (height + 1))
- shld edx,ebx,1 ; bit0 of code1 = sign bit of (y1 - (height + 1))
- ; Bit 2 and 0 of cl and bl are complemented
- xor cl,5 ; reverse bit2 and bit0 in code0
- xor dl,5 ; reverse bit2 and bit0 in code1
- ; now perform the rejection test
- mov eax,-1 ; set return code to false
- mov bl,cl ; save code0 for future use
- test dl,cl ; if any two pair of bit in code0 and code1 is set
- jnz clip_out ; then rectangle is outside the window
- ; now perform the aceptance test
- xor eax,eax ; set return code to true
- or bl,dl ; if all pair of bits in code0 and code1 are reset
- jz clip_out ; then rectangle is insize the window. '
- ; we need to clip the rectangle iteratively
- mov eax,-1 ; set return code to false
- test cl,1000b ; if bit3 of code0 is set then the rectangle
- jz left_ok ; spill out the left edge of the window
- mov edi,[x] ; edi = a pointer to x0
- mov ebx,[w] ; ebx = a pointer to dw
- mov esi,[edi] ; esi = x0
- mov [dword ptr edi],0 ; set x0 to 0 "this the left edge value"
- add [ebx],esi ; adjust dw by x0, since x0 must be negative
- left_ok:
- test cl,0010b ; if bit1 of code0 is set then the rectangle
- jz bottom_ok ; spill out the bottom edge of the window
- mov edi,[y] ; edi = a pointer to y0
- mov ebx,[h] ; ebx = a pointer to dh
- mov esi,[edi] ; esi = y0
- mov [dword ptr edi],0 ; set y0 to 0 "this the bottom edge value"
- add [ebx],esi ; adjust dh by y0, since y0 must be negative
- bottom_ok:
- test dl,0100b ; if bit2 of code1 is set then the rectangle
- jz right_ok ; spill out the right edge of the window
- mov edi,[w] ; edi = a pointer to dw
- mov esi,[x] ; esi = a pointer to x
- mov ebx,[width] ; ebx = the width of the window
- sub ebx,[esi] ; the new dw is the difference (width-x0)
- mov [edi],ebx ; adjust dw to (width - x0)
- jle clip_out ; if (width-x0) = 0 then the clipped retangle
- ; has no width we are done
- right_ok:
- test dl,0001b ; if bit0 of code1 is set then the rectangle
- jz clip_ok ; spill out the top edge of the window
- mov edi,[h] ; edi = a pointer to dh
- mov esi,[y] ; esi = a pointer to y0
- mov ebx,[height] ; ebx = the height of the window
- sub ebx,[esi] ; the new dh is the difference (height-y0)
- mov [edi],ebx ; adjust dh to (height-y0)
- jle clip_out ; if (width-x0) = 0 then the clipped retangle
- ; has no width we are done
- clip_ok:
- mov eax,1 ; signal the calling program that the rectangle was modify
- clip_out:
- //ret
- }
- //ENDP Clip_Rect
- }
- /*
- ;***************************************************************************
- ;* Confine_Rect -- clip a given rectangle against a given window *
- ;* *
- ;* INPUT: &x,&y,w,h -> Pointer to rectangle being clipped *
- ;* width,height -> dimension of clipping window *
- ;* *
- ;* OUTPUT: a) Zero if the rectangle is totally contained by the *
- ;* clipping window. *
- ;* c) A positive value if the rectangle was shifted in position *
- ;* to fix inside the clipping window, also the values pointed *
- ;* by x, y, will adjusted to a new values *
- ;* *
- ;* NOTE: this function make not attempt to verify if the rectangle is *
- ;* bigger than the clipping window and at the same time wrap around*
- ;* it. If that is the case the result is meaningless *
- ;*=========================================================================*
- ; int Confine_Rect (int* x, int* y, int dw, int dh, int width, int height); *
- */
- extern "C" int __cdecl Confine_Rect ( int * x , int * y , int w , int h , int width , int height )
- {
-
- /*
- PROC Confine_Rect C near
- uses ebx, esi,edi
- arg x:dword
- arg y:dword
- arg w:dword
- arg h:dword
- arg width :dword
- arg height:dword
- */
- __asm {
-
- xor eax,eax
- mov ebx,[x]
- mov edi,[w]
- mov esi,[ebx]
- add edi,[ebx]
- sub edi,[width]
- neg esi
- dec edi
- test esi,edi
- jl x_axix_ok
- mov eax,1
- test esi,esi
- jl shift_right
- mov [dword ptr ebx],0
- jmp x_axix_ok
- shift_right:
- inc edi
- sub [ebx],edi
- x_axix_ok:
- mov ebx,[y]
- mov edi,[h]
- mov esi,[ebx]
- add edi,[ebx]
- sub edi,[height]
- neg esi
- dec edi
- test esi,edi
- jl confi_out
- mov eax,1
- test esi,esi
- jl shift_top
- mov [dword ptr ebx],0
- //ret
- jmp confi_out
- shift_top:
- inc edi
- sub [ebx],edi
- confi_out:
- //ret
- //ENDP Confine_Rect
- }
- }
- /*
- ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/WIN32LIB/DrawMisc.cpp#139 $
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Library routine *
- ;* *
- ;* File Name : UNCOMP.ASM *
- ;* *
- ;* Programmer : Christopher Yates *
- ;* *
- ;* Last Update : 20 August, 1990 [CY] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* *
- ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); *
- ;* *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- GLOBAL C LCW_Uncompress :NEAR
- CODESEG
- ; ----------------------------------------------------------------
- ;
- ; Here are prototypes for the routines defined within this module:
- ;
- ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length);
- ;
- ; ----------------------------------------------------------------
- */
- extern "C" unsigned long __cdecl LCW_Uncompress(void *source, void *dest, unsigned long length_)
- {
- //PROC LCW_Uncompress C near
- //
- // USES ebx,ecx,edx,edi,esi
- //
- // ARG source:DWORD
- // ARG dest:DWORD
- // ARG length:DWORD
- //;LOCALS
- // LOCAL a1stdest:DWORD
- // LOCAL maxlen:DWORD
- // LOCAL lastbyte:DWORD
- // LOCAL lastcom:DWORD
- // LOCAL lastcom1:DWORD
-
- unsigned long a1stdest;
- unsigned long maxlen;
- unsigned long lastbyte;
- //unsigned long lastcom;
- //unsigned long lastcom1;
- __asm {
- mov edi,[dest]
- mov esi,[source]
- mov edx,[length_]
- ;
- ;
- ; uncompress data to the following codes in the format b = byte, w = word
- ; n = byte code pulled from compressed data
- ; Bit field of n command description
- ; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3
- ; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes
- ; n=11xxxxxx,w1 med run run x+3 bytes from offset w1
- ; n=11111111,w1,w2 long copy copy w1 bytes from offset w2
- ; n=11111110,w1,b1 long run run byte b1 for w1 bytes
- ; n=10000000 end end of data reached
- ;
- mov [a1stdest],edi
- add edx,edi
- mov [lastbyte],edx
- cld ; make sure all lod and sto are forward
- mov ebx,esi ; save the source offset
- loop_label:
- mov eax,[lastbyte]
- sub eax,edi ; get the remaining byte to uncomp
- jz short out_label ; were done
- mov [maxlen],eax ; save for string commands
- mov esi,ebx ; mov in the source index
- xor eax,eax
- mov al,[esi]
- inc esi
- test al,al ; see if its a short run
- js short notshort
- mov ecx,eax ;put count nibble in cl
- mov ah,al ; put rel offset high nibble in ah
- and ah,0Fh ; only 4 bits count
- shr cl,4 ; get run -3
- add ecx,3 ; get actual run length
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short rsok ; if not, its ok
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- rsok:
- mov al,[esi] ; get rel offset low byte
- lea ebx,[esi+1] ; save the source offset
- mov esi,edi ; get the current dest
- sub esi,eax ; get relative offset
- rep movsb
- jmp loop_label
- notshort:
- test al,40h ; is it a length?
- jne short notlength ; if not it could be med or long run
- cmp al,80h ; is it the end?
- je short out_label ; if so its over
- mov cl,al ; put the byte in count register
- and ecx,3Fh ; and off the extra bits
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short lenok ; if not, its ok
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- lenok:
- rep movsb
- mov ebx,esi ; save the source offset
- jmp loop_label
- out_label:
- mov eax,edi
- sub eax,[a1stdest]
- jmp label_exit
- notlength:
- mov cl,al ; get the entire code
- and ecx,3Fh ; and off all but the size -3
- add ecx,3 ; add 3 for byte count
- cmp al,0FEh
- jne short notrunlength
- xor ecx,ecx
- mov cx,[esi]
- xor eax,eax
- mov al,[esi+2]
- lea ebx,[esi+3] ;save the source offset
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short runlenok ; if not, its ok
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- runlenok:
- test ecx,0ffe0h
- jnz dont_use_stosb
- rep stosb
- jmp loop_label
- dont_use_stosb:
- mov ah,al
- mov edx,eax
- shl eax,16
- or eax,edx
- test edi,3
- jz aligned
- mov [edi],eax
- mov edx,edi
- and edi,0fffffffch
- lea edi,[edi+4]
- and edx,3
- dec dl
- xor dl,3
- sub ecx,edx
- aligned:
- mov edx,ecx
- shr ecx,2
- rep stosd
- and edx,3
- jz loop_label
- mov ecx,edx
- rep stosb
- jmp loop_label
- notrunlength:
- cmp al,0FFh ; is it a long run?
- jne short notlong ; if not use the code as the size
- xor ecx,ecx
- xor eax,eax
- mov cx,[esi] ; if so, get the size
- lea esi,[esi+2]
- notlong:
- mov ax,[esi] ;get the real index
- add eax,[a1stdest] ;add in the 1st index
- lea ebx,[esi+2] ;save the source offset
- cmp ecx,[maxlen] ;compare for overrun
- mov esi,eax ;use eax as new source
- jbe short runok ; if not, its ok
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- runok:
- test ecx,0ffe0h
- jnz dont_use_movsb
- rep movsb
- jmp loop_label
- dont_use_movsb:
- lea edx,[edi+0fffffffch]
- cmp esi,edx
- ja use_movsb
- test edi,3
- jz aligned2
- mov eax,[esi]
- mov [edi],eax
- mov edx,edi
- and edi,0fffffffch
- lea edi,[edi+4]
- and edx,3
- dec dl
- xor dl,3
- sub ecx,edx
- add esi,edx
- aligned2:
- mov edx,ecx
- shr ecx,2
- and edx,3
- rep movsd
- mov ecx,edx
- use_movsb:
- rep movsb
- jmp loop_label
- label_exit:
- mov eax,edi
- mov ebx,[dest]
- sub eax,ebx
- //ret
- }
- }
- /*
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood 32 bit Library *
- ;* *
- ;* File Name : TOPAGE.ASM *
- ;* *
- ;* Programmer : Phil W. Gorrow *
- ;* *
- ;* Start Date : June 8, 1994 *
- ;* *
- ;* Last Update : June 15, 1994 [PWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* Buffer_To_Page -- Copies a linear buffer to a virtual viewport *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- TRANSP equ 0
- INCLUDE ".\drawbuff.inc"
- INCLUDE ".\gbuffer.inc"
- CODESEG
- ;***************************************************************************
- ;* VVC::TOPAGE -- Copies a linear buffer to a virtual viewport *
- ;* *
- ;* INPUT: WORD x_pixel - x pixel on viewport to copy from *
- ;* WORD y_pixel - y pixel on viewport to copy from *
- ;* WORD pixel_width - the width of copy region *
- ;* WORD pixel_height - the height of copy region *
- ;* BYTE * src - buffer to copy from *
- ;* VVPC * dest - virtual viewport to copy to *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNINGS: Coordinates and dimensions will be adjusted if they exceed *
- ;* the boundaries. In the event that no adjustment is *
- ;* possible this routine will abort. If the size of the *
- ;* region to copy exceeds the size passed in for the buffer *
- ;* the routine will automatically abort. *
- ;* *
- ;* HISTORY: *
- ;* 06/15/1994 PWG : Created. *
- ;*=========================================================================*
- */
- extern "C" long __cdecl Buffer_To_Page(int x_pixel, int y_pixel, int pixel_width, int pixel_height, void *src, void *dest)
- {
- /*
- PROC Buffer_To_Page C near
- USES eax,ebx,ecx,edx,esi,edi
- ;*===================================================================
- ;* define the arguements that our function takes.
- ;*===================================================================
- ARG x_pixel :DWORD ; x pixel position in source
- ARG y_pixel :DWORD ; y pixel position in source
- ARG pixel_width :DWORD ; width of rectangle to blit
- ARG pixel_height:DWORD ; height of rectangle to blit
- ARG src :DWORD ; this is a member function
- ARG dest :DWORD ; what are we blitting to
- ; ARG trans :DWORD ; do we deal with transparents?
- ;*===================================================================
- ; Define some locals so that we can handle things quickly
- ;*===================================================================
- LOCAL x1_pixel :dword
- LOCAL y1_pixel :dword
- local scr_x : dword
- local scr_y : dword
- LOCAL dest_ajust_width:DWORD
- LOCAL scr_ajust_width:DWORD
- LOCAL dest_area : dword
- */
- unsigned long x1_pixel;
- unsigned long y1_pixel;
- unsigned long scr_x;
- unsigned long scr_y;
- unsigned long dest_ajust_width;
- unsigned long scr_ajust_width;
- //unsigned long dest_area;
- __asm {
-
- cmp [ src ] , 0
- jz real_out
- ; Clip dest Rectangle against source Window boundaries.
- mov [ scr_x ] , 0
- mov [ scr_y ] , 0
- mov esi , [ dest ] ; get ptr to dest
- xor ecx , ecx
- xor edx , edx
- mov edi , [esi]GraphicViewPortClass.Width ; get width into register
- mov ebx , [ x_pixel ]
- mov eax , [ x_pixel ]
- add ebx , [ pixel_width ]
- shld ecx , eax , 1
- mov [ x1_pixel ] , ebx
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- mov edi, [esi]GraphicViewPortClass.Height ; get height into register
- mov ebx , [ y_pixel ]
- mov eax , [ y_pixel ]
- add ebx , [ pixel_height ]
- shld ecx , eax , 1
- mov [ y1_pixel ] , ebx
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- xor cl , 5
- xor dl , 5
- mov al , cl
- test dl , cl
- jnz real_out
- or al , dl
- jz do_blit
- test cl , 1000b
- jz dest_left_ok
- mov eax , [ x_pixel ]
- neg eax
- mov [ x_pixel ] , 0
- mov [ scr_x ] , eax
- dest_left_ok:
- test cl , 0010b
- jz dest_bottom_ok
- mov eax , [ y_pixel ]
- neg eax
- mov [ y_pixel ] , 0
- mov [ scr_y ] , eax
- dest_bottom_ok:
- test dl , 0100b
- jz dest_right_ok
- mov eax , [esi]GraphicViewPortClass.Width ; get width into register
- mov [ x1_pixel ] , eax
- dest_right_ok:
- test dl , 0001b
- jz do_blit
- mov eax , [esi]GraphicViewPortClass.Height ; get width into register
- mov [ y1_pixel ] , eax
- do_blit:
- cld
- mov eax , [esi]GraphicViewPortClass.XAdd
- add eax , [esi]GraphicViewPortClass.Width
- add eax , [esi]GraphicViewPortClass.Pitch
- mov edi , [esi]GraphicViewPortClass.Offset
- mov ecx , eax
- mul [ y_pixel ]
- add edi , [ x_pixel ]
- add edi , eax
- add ecx , [ x_pixel ]
- sub ecx , [ x1_pixel ]
- mov [ dest_ajust_width ] , ecx
- mov esi , [ src ]
- mov eax , [ pixel_width ]
- sub eax , [ x1_pixel ]
- add eax , [ x_pixel ]
- mov [ scr_ajust_width ] , eax
- mov eax , [ scr_y ]
- mul [ pixel_width ]
- add eax , [ scr_x ]
- add esi , eax
- mov edx , [ y1_pixel ]
- mov eax , [ x1_pixel ]
- sub edx , [ y_pixel ]
- jle real_out
- sub eax , [ x_pixel ]
- jle real_out
- ; ********************************************************************
- ; Forward bitblit only
- //IF TRANSP
- // test [ trans ] , 1
- // jnz forward_Blit_trans
- //ENDIF
- ; the inner loop is so efficient that
- ; the optimal consept no longer apply because
- ; the optimal byte have to by a number greather than 9 bytes
- cmp eax , 10
- jl forward_loop_bytes
- forward_loop_dword:
- mov ecx , edi
- mov ebx , eax
- neg ecx
- and ecx , 3
- sub ebx , ecx
- rep movsb
- mov ecx , ebx
- shr ecx , 2
- rep movsd
- mov ecx , ebx
- and ecx , 3
- rep movsb
- add esi , [ scr_ajust_width ]
- add edi , [ dest_ajust_width ]
- dec edx
- jnz forward_loop_dword
- jmp real_out //ret
- forward_loop_bytes:
- mov ecx , eax
- rep movsb
- add esi , [ scr_ajust_width ]
- add edi , [ dest_ajust_width ]
- dec edx ; decrement the height
- jnz forward_loop_bytes
- // ret
- //IF TRANSP
- //
- //
- //forward_Blit_trans:
- //
- //
- // mov ecx , eax
- // and ecx , 01fh
- // lea ecx , [ ecx + ecx * 4 ]
- // neg ecx
- // shr eax , 5
- // lea ecx , [ transp_reference + ecx * 2 ]
- // mov [ y1_pixel ] , ecx
- //
- //
- //forward_loop_trans:
- // mov ecx , eax
- // jmp [ y1_pixel ]
- //forward_trans_line:
- // REPT 32
- // local transp_pixel
- // mov bl , [ esi ]
- // inc esi
- // test bl , bl
- // jz transp_pixel
- // mov [ edi ] , bl
- // transp_pixel:
- // inc edi
- // ENDM
- // transp_reference:
- // dec ecx
- // jge forward_trans_line
- // add esi , [ scr_ajust_width ]
- // add edi , [ dest_ajust_width ]
- // dec edx
- // jnz forward_loop_trans
- // ret
- //ENDIF
- real_out:
- //ret
- }
- }
- //ENDP Buffer_To_Page
- //END
- /*
- ;***************************************************************************
- ;* VVPC::GET_PIXEL -- Gets a pixel from the current view port *
- ;* *
- ;* INPUT: WORD the x pixel on the screen. *
- ;* WORD the y pixel on the screen. *
- ;* *
- ;* OUTPUT: UBYTE the pixel at the specified location *
- ;* *
- ;* WARNING: If pixel is to be placed outside of the viewport then *
- ;* this routine will abort. *
- ;* *
- ;* HISTORY: *
- ;* 06/07/1994 PWG : Created. *
- ;*=========================================================================*
- PROC Buffer_Get_Pixel C near
- USES ebx,ecx,edx,edi
- ARG this_object:DWORD ; this is a member function
- ARG x_pixel:DWORD ; x position of pixel to set
- ARG y_pixel:DWORD ; y position of pixel to set
- */
- extern "C" int __cdecl Buffer_Get_Pixel(void * this_object, int x_pixel, int y_pixel)
- {
- __asm {
- ;*===================================================================
- ; Get the viewport information and put bytes per row in ecx
- ;*===================================================================
- mov ebx,[this_object] ; get a pointer to viewport
- xor eax,eax
- mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset
- mov ecx,[ebx]GraphicViewPortClass.Height ; edx = height of viewport
- mov edx,[ebx]GraphicViewPortClass.Width ; ecx = width of viewport
- ;*===================================================================
- ; Verify that the X pixel offset if legal
- ;*===================================================================
- mov eax,[x_pixel] ; find the x position
- cmp eax,edx ; is it out of bounds
- jae short exit_label ; if so then get out
- add edi,eax ; otherwise add in offset
- ;*===================================================================
- ; Verify that the Y pixel offset if legal
- ;*===================================================================
- mov eax,[y_pixel] ; get the y position
- cmp eax,ecx ; is it out of bounds
- jae exit_label ; if so then get out
- add edx,[ebx]GraphicViewPortClass.XAdd ; otherwise find bytes per row
- add edx,[ebx]GraphicViewPortClass.Pitch ; otherwise find bytes per row
- mul edx ; offset = bytes per row * y
- add edi,eax ; add it into the offset
- ;*===================================================================
- ; Write the pixel to the screen
- ;*===================================================================
- xor eax,eax ; clear the word
- mov al,[edi] ; read in the pixel
- exit_label:
- //ret
- //ENDP Buffer_Get_Pixel
- }
- }
|