1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509 |
- //
- // 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"
- #include "WSA.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/REDALERT/WIN32LIB/DrawMisc.cpp#131 $
- ;***************************************************************************
- ;** 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);
- ;
- ; ----------------------------------------------------------------
- */
- #if (0)//ST 5/10/2019
- 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
- }
- }
- #endif
- /*
- ;***************************************************************************
- ;** 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
- }
- }
|