softraster.cpp 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Optimize this file for speed
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. // /Oa assume no aliasing
  8. // /Ow assume aliasing across function calls
  9. // /Og global optimization
  10. // /Ot fast code sequences
  11. //
  12. #ifndef _DEBUG
  13. #pragma optimize("t", on)
  14. #pragma inline_depth(255)
  15. //#pragma inline_recursion(off)
  16. #endif
  17. //////////////////////////////////////////////////////////////////////////////
  18. //
  19. // Fast floating point routines
  20. //
  21. //////////////////////////////////////////////////////////////////////////////
  22. //////////////////////////////////////////////////////////////////////////////
  23. //
  24. // Reinterpret casts
  25. //
  26. //////////////////////////////////////////////////////////////////////////////
  27. __forceinline float& AsFloat(DWORD& value) { return *(float *)(&value); }
  28. __forceinline float& AsFloat(int& value) { return *(float *)(&value); }
  29. __forceinline int& AsInt (float& value) { return *(int *)(&value); }
  30. __forceinline DWORD& AsDWORD(float& value) { return *(DWORD *)(&value); }
  31. // VS.Net 2003 port
  32. #if _MSC_VER >= 1300
  33. __forceinline void swap(float& x, float& y)
  34. #else
  35. __forceinline void swap<float>(float& x, float& y)
  36. #endif
  37. {
  38. DWORD temp(AsDWORD(x));
  39. AsDWORD(x) = AsDWORD(y);
  40. AsDWORD(y) = temp;
  41. }
  42. //////////////////////////////////////////////////////////////////////////////
  43. //
  44. // FPU Control word functions
  45. //
  46. //////////////////////////////////////////////////////////////////////////////
  47. class ControlWordBase {};
  48. typedef TBitMask<ControlWordBase, WORD> ControlWord;
  49. class ControlWordExceptions : public ControlWord { public: ControlWordExceptions () : ControlWord(0x003f) {} };
  50. class ControlWordPrecision : public ControlWord { public: ControlWordPrecision () : ControlWord(0x0300) {} };
  51. class ControlWordRounding : public ControlWord { public: ControlWordRounding () : ControlWord(0x0c00) {} };
  52. __forceinline ControlWord GetControlWord()
  53. {
  54. WORD w;
  55. __asm {
  56. fstcw w
  57. }
  58. ControlWord cw;
  59. cw.SetWord(w);
  60. return cw;
  61. }
  62. __forceinline void SetControlWord(const ControlWord& cw)
  63. {
  64. WORD w = cw.GetWord();
  65. __asm {
  66. // fnclex // safe?
  67. fldcw w
  68. }
  69. }
  70. void AssertChopRound()
  71. {
  72. ZAssert(GetControlWord().Test(ControlWordRounding()));
  73. }
  74. void AssertRound()
  75. {
  76. ZAssert(!GetControlWord().Test(ControlWordRounding()));
  77. }
  78. ControlWord g_cw;
  79. void InitializeControlWord()
  80. {
  81. g_cw = GetControlWord();
  82. ControlWord cw = g_cw;
  83. cw.Clear(ControlWordRounding());
  84. cw.Clear(ControlWordPrecision());
  85. SetControlWord(cw);
  86. }
  87. void RestoreControlWord()
  88. {
  89. SetControlWord(g_cw);
  90. }
  91. //////////////////////////////////////////////////////////////////////////////
  92. //
  93. // Approximate tranesdental functions
  94. //
  95. //////////////////////////////////////////////////////////////////////////////
  96. #define INT32_FLOAT_ONE 0x3f800000
  97. #define FLOAT_EXPSCALE ((float)0x00800000)
  98. __forceinline float ApproximateLN(float f)
  99. {
  100. return (float)(AsInt(f) - INT32_FLOAT_ONE) * float(1.0 / (double)FLOAT_EXPSCALE);
  101. }
  102. __forceinline float ApproximatePow2(float f)
  103. {
  104. INT32 i = (INT32)(f * FLOAT_EXPSCALE) + INT32_FLOAT_ONE;
  105. return AsFloat(i);
  106. }
  107. __forceinline float ApproximateInv(float f)
  108. {
  109. INT32 i = (INT32_FLOAT_ONE << 1) - AsInt(f);
  110. return AsFloat(i);
  111. }
  112. __forceinline float ApproximateSqrt(float f)
  113. {
  114. INT32 i = (AsInt(f) >> 1) + (INT32_FLOAT_ONE >> 1);
  115. return AsFloat(i);
  116. }
  117. /* !!! alternate version what's the difference
  118. __forceinline float ApproximateSqrt(float f)
  119. {
  120. INT32 i = INT32_float_ONE + (INT32_float_ONE >> 1) - (AsInt(f) >> 1);
  121. return ASfloat(i);
  122. }
  123. */
  124. __forceinline float ApproximatePow(float f, float exp)
  125. {
  126. INT32 i = (INT32)(exp * (AsInt(f) - INT32_FLOAT_ONE)) + INT32_FLOAT_ONE;
  127. return AsFloat(i);
  128. }
  129. /* !!! such a thing exists look at math.asm
  130. float ApproximateInvSqrt(float value)
  131. {
  132. }
  133. */
  134. //////////////////////////////////////////////////////////////////////////////
  135. //
  136. // Fast floating point
  137. //
  138. //////////////////////////////////////////////////////////////////////////////
  139. __forceinline DWORD MakeDWORD(float value)
  140. {
  141. return DWORD(value);
  142. }
  143. __forceinline float Abs(float f)
  144. {
  145. DWORD i = AsDWORD(f) & 0x7fffffff;
  146. return AsFloat(i);
  147. }
  148. __forceinline float Negate(float f)
  149. {
  150. DWORD i = AsDWORD(f) ^ 0x80000000;
  151. return AsFloat(i);
  152. }
  153. //////////////////////////////////////////////////////////////////////////////
  154. //
  155. // Overlapped Divide
  156. //
  157. //////////////////////////////////////////////////////////////////////////////
  158. __forceinline void StartDivide(float numerator, float denominator)
  159. {
  160. _asm {
  161. fld numerator
  162. fdiv denominator
  163. }
  164. }
  165. __forceinline void StartDivide(float numerator, int denominator)
  166. {
  167. _asm {
  168. fld numerator
  169. fidiv denominator
  170. }
  171. }
  172. __forceinline float EndDivide()
  173. {
  174. float result;
  175. _asm {
  176. fstp result
  177. }
  178. return result;
  179. }
  180. //////////////////////////////////////////////////////////////////////////////
  181. //
  182. // Comparison
  183. //
  184. //////////////////////////////////////////////////////////////////////////////
  185. __forceinline bool GPositiveGreater (float a, float b) { return AsInt(a) > AsInt(b); }
  186. __forceinline bool GPositiveLess (float a, float b) { return AsInt(a) < AsInt(b); }
  187. __forceinline bool GPositiveEqual (float a, float b) { return AsInt(a) == AsInt(b); }
  188. __forceinline bool GPositiveGreateEqual(float a, float b) { return AsInt(a) >= AsInt(b); }
  189. __forceinline bool GPositiveLessEqual (float a, float b) { return AsInt(a) <= AsInt(b); }
  190. __forceinline bool GPositiveNotEqual (float a, float b) { return AsInt(a) != AsInt(b); }
  191. __forceinline bool GreaterZero (float a) { return AsInt(a) > 0; }
  192. __forceinline bool LessZero (float a) { return AsDWORD(a) > 0x80000000; }
  193. __forceinline bool GreaterEqualZero(float a) { return AsDWORD(a) <= 0x80000000; }
  194. __forceinline bool LessEqualZero (float a) { return AsInt(a) <= 0; }
  195. __forceinline bool EqualZero (float a) { return (AsDWORD(a) & 0x7fffffff) == 0; }
  196. __forceinline bool NotEqualZero (float a) { return (AsDWORD(a) & 0x7fffffff) != 0; }
  197. //////////////////////////////////////////////////////////////////////////////
  198. //
  199. // Constants
  200. //
  201. //////////////////////////////////////////////////////////////////////////////
  202. //////////////////////////////////////////////////////////////////////////////
  203. //
  204. // Fixed Point Template
  205. //
  206. //////////////////////////////////////////////////////////////////////////////
  207. template<class Type, bool t_bSigned, int t_integerBits, bool t_bAssert = false>
  208. class TFixed {
  209. private:
  210. Type m_value;
  211. public:
  212. //////////////////////////////////////////////////////////////////////////////
  213. //
  214. // Static functions
  215. //
  216. //////////////////////////////////////////////////////////////////////////////
  217. __forceinline static Type MaxValue()
  218. {
  219. if (t_bSigned) {
  220. return int(PowerOf2(t_integerBits - 1)) - 1;
  221. } else {
  222. return PowerOf2(t_integerBits) - 1;
  223. }
  224. }
  225. __forceinline static Type MinValue()
  226. {
  227. if (t_bSigned) {
  228. return -int(PowerOf2(t_integerBits - 1));
  229. } else {
  230. return 0;
  231. }
  232. }
  233. __forceinline static int FractionBits()
  234. {
  235. return 32 - t_integerBits;
  236. }
  237. __forceinline static float Scale()
  238. {
  239. return float(PowerOf2(FractionBits()));
  240. }
  241. //////////////////////////////////////////////////////////////////////////////
  242. //
  243. // Constructors
  244. //
  245. //////////////////////////////////////////////////////////////////////////////
  246. __forceinline TFixed()
  247. {
  248. }
  249. __forceinline TFixed(const TFixed& x) :
  250. m_value(x.m_value)
  251. {
  252. }
  253. __forceinline TFixed(float x)
  254. {
  255. if (t_bAssert) {
  256. ZAssert(x <= float(MaxValue()));
  257. ZAssert(x >= float(MinValue()));
  258. }
  259. if (t_bSigned) {
  260. m_value = MakeInt(x * Scale());
  261. } else {
  262. m_value = MakeDWORD(x * Scale());
  263. }
  264. }
  265. __forceinline TFixed(Type x)
  266. {
  267. if (t_bAssert) {
  268. ZAssert(x <= MaxValue());
  269. }
  270. if (t_bSigned) {
  271. ZAssert(x >= MinValue());
  272. }
  273. m_value = x << FractionBits();
  274. }
  275. __forceinline TFixed(Type x, int shift)
  276. {
  277. int bits = shift + FractionBits();
  278. if (bits == 0) {
  279. m_value = x;
  280. } else if (bits > 0) {
  281. m_value = x << bits ;
  282. } else {
  283. m_value = x >> (-bits);
  284. }
  285. }
  286. //////////////////////////////////////////////////////////////////////////////
  287. //
  288. // Conversions
  289. //
  290. //////////////////////////////////////////////////////////////////////////////
  291. __forceinline float GetFloat() const
  292. {
  293. return float(m_value) / Scale();
  294. }
  295. __forceinline Type GetInteger(int shift = 0, bool bAlwaysRight = false) const
  296. {
  297. int bits = shift - FractionBits();
  298. if (bAlwaysRight || (bits < 0)) {
  299. return m_value >> (-bits);
  300. } else if (bits == 0) {
  301. return m_value;
  302. } else {
  303. return m_value << bits ;
  304. }
  305. }
  306. __forceinline const Type& GetFixed() const
  307. {
  308. return m_value;
  309. }
  310. //////////////////////////////////////////////////////////////////////////////
  311. //
  312. // Operators
  313. //
  314. //////////////////////////////////////////////////////////////////////////////
  315. __forceinline TFixed& operator+=(const TFixed<int, t_bSigned, t_integerBits, t_bAssert>& x)
  316. {
  317. m_value += x.GetFixed();
  318. return *this;
  319. }
  320. __forceinline TFixed& operator+=(const TFixed<DWORD, t_bSigned, t_integerBits, t_bAssert>& x)
  321. {
  322. m_value += x.GetFixed();
  323. return *this;
  324. }
  325. __forceinline TFixed& operator-=(const TFixed& x)
  326. {
  327. m_value -= x.m_value;
  328. return *this;
  329. }
  330. __forceinline friend TFixed operator+(const TFixed& x, const TFixed& y)
  331. {
  332. return TFixed(x.m_value + y.m_value, -FractionBits());
  333. }
  334. __forceinline friend TFixed operator-(const TFixed& x, const TFixed& y)
  335. {
  336. return TFixed(x.m_value - y.m_value, -FractionBits());
  337. }
  338. __forceinline friend TFixed operator*(const TFixed& x, const TFixed& y)
  339. {
  340. return TFixed(x.m_value * y.m_value, -2 * FractionBits());
  341. }
  342. __forceinline friend TFixed operator*(const TFixed& x, Type y)
  343. {
  344. return TFixed(x.m_value * y, -FractionBits());
  345. }
  346. __forceinline friend TFixed operator<<(const TFixed& x, int shift)
  347. {
  348. return TFixed(x.m_value, shift - FractionBits());
  349. }
  350. __forceinline friend TFixed operator>>(const TFixed& x, int shift)
  351. {
  352. return TFixed(x.m_value, FractionBits() - shift);
  353. }
  354. };
  355. //////////////////////////////////////////////////////////////////////////////
  356. //
  357. // Fixed Point Macros
  358. //
  359. //////////////////////////////////////////////////////////////////////////////
  360. typedef TFixed<int, true, 12> Fixed;
  361. typedef TFixed<DWORD, true, 2> FixedZ;
  362. typedef TFixed<int, true, 2> FixedDZ;
  363. typedef TFixed<DWORD, true, 16> Fixed1616;
  364. typedef TFixed<int, true, 16> FixedD1616;
  365. typedef TFixed<DWORD, true, 2> Fixed131;
  366. typedef TFixed<int, true, 2> FixedD131;
  367. //////////////////////////////////////////////////////////////////////////////
  368. //
  369. // Colors
  370. //
  371. //////////////////////////////////////////////////////////////////////////////
  372. /*
  373. Color555
  374. 10-14 0x00007c00 5 Red
  375. 5- 9 0x000003e0 5 Green
  376. 0- 4 0x0000001f 5 Blue
  377. Color565
  378. 11-15 0x0000f800 5 Red
  379. 5-10 0x000007e0 6 Green
  380. 0- 4 0x0000001f 5 Blue
  381. ColorE
  382. 30-31 0xa0000000 2 Unused
  383. 20-29 0x3ff00000 5.5 Red
  384. 10-19 0x000ffa00 5.5 Green
  385. 0- 9 0x000003ff 5.5 Blue
  386. */
  387. #define Color555RMask 0x7c00
  388. #define Color555GMask 0x03e0
  389. #define Color555BMask 0x001f
  390. #define Color555RShift 15
  391. #define Color555GShift 10
  392. #define Color555BShift 5
  393. #define Color565RMask 0xf800
  394. #define Color565GMask 0x07e0
  395. #define Color565BMask 0x001f
  396. #define Color565RShift 16
  397. #define Color565GShift 11
  398. #define Color565BShift 5
  399. #define ColorERMask 0x3fe00000
  400. #define ColorEGMask 0x000ff800
  401. #define ColorEBMask 0x000003ff
  402. #define ColorERShift 30
  403. #define ColorEGShift 20
  404. #define ColorEBShift 10
  405. #define ColorERSaturationMask 0xc0000000
  406. #define ColorEGSaturationMask 0x00100000
  407. #define ColorEBSaturationMask 0x00000400
  408. #define ColorESaturationMask (ColorERSaturationMask | ColorEGSaturationMask | ColorEBSaturationMask)
  409. typedef WORD Color555;
  410. typedef WORD Color565;
  411. typedef DWORD ColorE;
  412. const float g_componentFloatToIntScale = 255.0f / 256.0f;
  413. //////////////////////////////////////////////////////////////////////////////
  414. //
  415. // Fixed1616 functions
  416. //
  417. //////////////////////////////////////////////////////////////////////////////
  418. template<class Type>
  419. __forceinline Type ShiftLeft(Type value, int shift)
  420. {
  421. if (shift >= 0) {
  422. return value << shift;
  423. } else {
  424. return value >> (-shift);
  425. }
  426. }
  427. //////////////////////////////////////////////////////////////////////////////
  428. //
  429. // Color565 Helpers
  430. //
  431. //////////////////////////////////////////////////////////////////////////////
  432. __forceinline Fixed1616 GetR(const Color565& color) { return Fixed1616(color & Color565RMask, -Color565RShift); }
  433. __forceinline Fixed1616 GetG(const Color565& color) { return Fixed1616(color & Color565GMask, -Color565GShift); }
  434. __forceinline Fixed1616 GetB(const Color565& color) { return Fixed1616(color & Color565BMask, -Color565BShift); }
  435. __forceinline Color565 MakeColor565(const Fixed1616& r, const Fixed1616& g, const Fixed1616& b)
  436. {
  437. DWORD r565 = r.GetInteger(Color565RShift) & Color565RMask;
  438. DWORD g565 = g.GetInteger(Color565GShift) & Color565GMask;
  439. DWORD b565 = b.GetInteger(Color565BShift) & Color565BMask;
  440. return Color565(r565 | g565 | b565);
  441. }
  442. __forceinline Color565 operator*(Color565 color, const Fixed1616& i)
  443. {
  444. /*
  445. return
  446. MakeColor565(
  447. (GetR(color) * i1616),
  448. (GetG(color) * i1616),
  449. (GetB(color) * i1616)
  450. );
  451. */
  452. DWORD r565 = ((GetR(color).GetFixed() * i.GetFixed()) >> 32 - Color565RShift) & Color565RMask;
  453. DWORD g565 = ((GetG(color).GetFixed() * i.GetFixed()) >> 32 - Color565GShift) & Color565GMask;
  454. DWORD b565 = ((GetB(color).GetFixed() * i.GetFixed()) >> 32 - Color565BShift) & Color565BMask;
  455. return Color565(r565 | g565 | b565);
  456. }
  457. __forceinline Color565 operator*(Color565 color, const Fixed131& i)
  458. {
  459. return color * Fixed1616(i.GetFixed(), -i.FractionBits());
  460. }
  461. //////////////////////////////////////////////////////////////////////////////
  462. //
  463. // ColorE Helpers
  464. //
  465. //////////////////////////////////////////////////////////////////////////////
  466. __forceinline Fixed1616 GetR(const ColorE& color) { return Fixed1616(color & ColorERMask, -ColorERShift); }
  467. __forceinline Fixed1616 GetG(const ColorE& color) { return Fixed1616(color & ColorEGMask, -ColorEGShift); }
  468. __forceinline Fixed1616 GetB(const ColorE& color) { return Fixed1616(color & ColorEBMask, -ColorEBShift); }
  469. __forceinline ColorE MakeColorE(const Fixed1616& r, const Fixed1616& g, const Fixed1616& b)
  470. {
  471. return
  472. (r.GetInteger(ColorERShift) & ColorERMask)
  473. | (g.GetInteger(ColorEGShift) & ColorEGMask)
  474. | (b.GetInteger(ColorEBShift) & ColorEBMask);
  475. }
  476. __forceinline ColorE Color555ToColorE(Color555 color)
  477. {
  478. DWORD dw = color;
  479. return
  480. ColorE(
  481. ShiftLeft(dw & Color555RMask, ColorERShift - Color555RShift)
  482. | ShiftLeft(dw & Color555GMask, ColorEGShift - Color555GShift)
  483. | ShiftLeft(dw & Color555BMask, ColorEBShift - Color555BShift)
  484. );
  485. }
  486. __forceinline Color555 ColorEToColor555(ColorE color)
  487. {
  488. DWORD dw = color;
  489. return
  490. Color555(
  491. (ShiftLeft(dw, Color555RShift - ColorERShift) & Color555RMask)
  492. | (ShiftLeft(dw, Color555GShift - ColorEGShift) & Color555GMask)
  493. | (ShiftLeft(dw, Color555BShift - ColorEBShift) & Color555BMask)
  494. );
  495. }
  496. __forceinline ColorE Color565ToColorE(Color565 color)
  497. {
  498. DWORD dw = color;
  499. return
  500. ColorE(
  501. ShiftLeft(dw & Color565RMask, ColorERShift - Color565RShift)
  502. | ShiftLeft(dw & Color565GMask, ColorEGShift - Color565GShift)
  503. | ShiftLeft(dw & Color565BMask, ColorEBShift - Color565BShift)
  504. );
  505. }
  506. __forceinline Color565 ColorEToColor565(ColorE color)
  507. {
  508. DWORD dw = color;
  509. return
  510. Color565(
  511. (ShiftLeft(dw, Color565RShift - ColorERShift) & Color565RMask)
  512. | (ShiftLeft(dw, Color565GShift - ColorEGShift) & Color565GMask)
  513. | (ShiftLeft(dw, Color565BShift - ColorEBShift) & Color565BMask)
  514. );
  515. }
  516. __forceinline ColorE operator*(ColorE colorE, const Fixed1616& i)
  517. {
  518. /*
  519. return
  520. MakeColorE(
  521. GetR(colorE) * i,
  522. GetG(colorE) * i,
  523. GetB(colorE) * i
  524. );
  525. */
  526. DWORD r = ((GetR(colorE).GetFixed() * i.GetFixed()) >> 32 - ColorERShift) & ColorERMask;
  527. DWORD g = ((GetG(colorE).GetFixed() * i.GetFixed()) >> 32 - ColorEGShift) & ColorEGMask;
  528. DWORD b = ((GetB(colorE).GetFixed() * i.GetFixed()) >> 32 - ColorEBShift) & ColorEBMask;
  529. return ColorE(r | g | b);
  530. }
  531. __forceinline ColorE operator*(ColorE colorE, const Fixed131& i)
  532. {
  533. return colorE * Fixed1616(i.GetFixed(), -i.FractionBits());
  534. }
  535. //////////////////////////////////////////////////////////////////////////////
  536. //
  537. // Constants
  538. //
  539. //////////////////////////////////////////////////////////////////////////////
  540. #define ChunkSize 16
  541. #define MaxChunkPasses 10
  542. //////////////////////////////////////////////////////////////////////////////
  543. //
  544. //
  545. //
  546. //////////////////////////////////////////////////////////////////////////////
  547. class SoftwareRasterizer : public Rasterizer {
  548. private:
  549. //////////////////////////////////////////////////////////////////////////////
  550. //
  551. // Types
  552. //
  553. //////////////////////////////////////////////////////////////////////////////
  554. typedef void (SoftwareRasterizer::*PFNDrawTriangle)(
  555. const VertexScreen* pva,
  556. const VertexScreen* pvb,
  557. const VertexScreen* pvc
  558. );
  559. typedef void (SoftwareRasterizer::*PFNDrawLine)(
  560. const VertexScreen* pva,
  561. const VertexScreen* pvb
  562. );
  563. typedef void (SoftwareRasterizer::*PFNDrawPoint)(
  564. const VertexScreen* pva
  565. );
  566. typedef void (SoftwareRasterizer::*PFNFillSubTriangle)(
  567. const int ymin,
  568. const int ymax
  569. );
  570. typedef void (SoftwareRasterizer::*PFNFillChunk)();
  571. //////////////////////////////////////////////////////////////////////////////
  572. //
  573. // Pipeline
  574. //
  575. //////////////////////////////////////////////////////////////////////////////
  576. bool m_bUpdatePointers;
  577. bool m_bColorKeyOn;
  578. PFNDrawTriangle m_pfnDrawTriangle;
  579. PFNDrawLine m_pfnDrawLine;
  580. PFNDrawPoint m_pfnDrawPoint;
  581. PFNFillSubTriangle m_pfnFillSubTriangle;
  582. //////////////////////////////////////////////////////////////////////////////
  583. //
  584. // Plane deltas
  585. //
  586. //////////////////////////////////////////////////////////////////////////////
  587. float m_floatdudx;
  588. float m_floatdudy;
  589. float m_floatdvdx;
  590. float m_floatdvdy;
  591. float m_floatdidx;
  592. float m_floatdidy;
  593. float m_floatdzdx;
  594. float m_floatdzdy;
  595. Fixed m_dudx;
  596. Fixed m_dvdx;
  597. FixedD131 m_didx;
  598. FixedDZ m_dzdx;
  599. //////////////////////////////////////////////////////////////////////////////
  600. //
  601. // Edge deltas
  602. //
  603. //////////////////////////////////////////////////////////////////////////////
  604. int m_xmin ;
  605. int m_dxmindyLittle;
  606. int m_dxmindyBig ;
  607. float m_xminFrac ;
  608. float m_dxmindyFrac ;
  609. int m_xmax ;
  610. int m_dxmaxdyLittle;
  611. int m_dxmaxdyBig ;
  612. float m_xmaxFrac ;
  613. float m_dxmaxdyFrac ;
  614. Fixed m_u ;
  615. Fixed m_dudyLittle ;
  616. Fixed m_dudyBig ;
  617. Fixed m_v ;
  618. Fixed m_dvdyLittle ;
  619. Fixed m_dvdyBig ;
  620. Fixed131 m_i ;
  621. FixedD131 m_didyLittle ;
  622. FixedD131 m_didyBig ;
  623. FixedZ m_z ;
  624. FixedDZ m_dzdyLittle ;
  625. FixedDZ m_dzdyBig ;
  626. //////////////////////////////////////////////////////////////////////////////
  627. //
  628. // Performance
  629. //
  630. //////////////////////////////////////////////////////////////////////////////
  631. float m_pixels;
  632. //////////////////////////////////////////////////////////////////////////////
  633. //
  634. // Render state
  635. //
  636. //////////////////////////////////////////////////////////////////////////////
  637. bool m_bZTest;
  638. bool m_bZWrite;
  639. bool m_bDither;
  640. bool m_bLinearFilter;
  641. bool m_bPerspectiveCorrection;
  642. bool m_bColorKeyEnabled;
  643. ShadeMode m_shadeMode;
  644. BlendMode m_blendMode;
  645. WrapMode m_wrapMode;
  646. CullMode m_cullMode;
  647. Rect m_rectClip;
  648. ColorE m_colorE;
  649. Fixed1616 m_colorR;
  650. Fixed1616 m_colorG;
  651. Fixed1616 m_colorB;
  652. Fixed1616 m_colorA;
  653. Fixed1616 m_colorInvA;
  654. //////////////////////////////////////////////////////////////////////////////
  655. //
  656. // Surface
  657. //
  658. //////////////////////////////////////////////////////////////////////////////
  659. Surface* m_psurface;
  660. BYTE* m_pbSurface;
  661. DWORD m_pitchSurface;
  662. WinPoint m_sizeSurface;
  663. bool m_b565;
  664. //////////////////////////////////////////////////////////////////////////////
  665. //
  666. // ZBuffer
  667. //
  668. //////////////////////////////////////////////////////////////////////////////
  669. BYTE* m_pbZBuffer;
  670. DWORD m_pitchZBuffer;
  671. //////////////////////////////////////////////////////////////////////////////
  672. //
  673. // Texture
  674. //
  675. //////////////////////////////////////////////////////////////////////////////
  676. TRef<Surface> m_psurfaceTexture;
  677. BYTE* m_pbTexture;
  678. DWORD m_pitchTexture;
  679. WinPoint m_sizeTexture;
  680. float m_uscale;
  681. float m_vscale;
  682. DWORD m_ushift;
  683. DWORD m_vshift;
  684. DWORD m_umask;
  685. DWORD m_vmask;
  686. bool m_bColorKey;
  687. //////////////////////////////////////////////////////////////////////////////
  688. //
  689. // Members
  690. //
  691. //////////////////////////////////////////////////////////////////////////////
  692. bool m_bInScene;
  693. public:
  694. //////////////////////////////////////////////////////////////////////////////
  695. //
  696. // Constructor
  697. //
  698. //////////////////////////////////////////////////////////////////////////////
  699. SoftwareRasterizer(PrivateSurface* psurface) :
  700. m_psurface(psurface),
  701. m_pixels(0),
  702. m_bInScene(false),
  703. m_bUpdatePointers(true),
  704. m_bZTest(false),
  705. m_bZWrite(false),
  706. m_bDither(false),
  707. m_bLinearFilter(false),
  708. m_bPerspectiveCorrection(false),
  709. m_bColorKeyEnabled(false),
  710. m_shadeMode(ShadeModeCopy),
  711. m_blendMode(BlendModeSource),
  712. m_wrapMode(WrapModeNone),
  713. m_cullMode(CullModeNone),
  714. m_pbSurface(NULL),
  715. m_pbZBuffer(NULL),
  716. m_pbTexture(NULL),
  717. m_pitchZBuffer(0)
  718. {
  719. PixelFormat* ppf = m_psurface->GetPixelFormat();
  720. ZAssert(ppf->RedSize() == 0x1f);
  721. ZAssert(ppf->BlueSize() == 0x1f);
  722. if (ppf->GreenSize() == 0x1f) {
  723. m_b565 = false;
  724. } else {
  725. ZAssert(ppf->GreenSize() == 0x3f);
  726. m_b565 = true;
  727. }
  728. }
  729. ~SoftwareRasterizer()
  730. {
  731. if (m_pbZBuffer) {
  732. delete m_pbZBuffer;
  733. }
  734. }
  735. bool IsValid()
  736. {
  737. return true;
  738. }
  739. //////////////////////////////////////////////////////////////////////////////
  740. //
  741. // Termination
  742. //
  743. //////////////////////////////////////////////////////////////////////////////
  744. void Terminate()
  745. {
  746. }
  747. //////////////////////////////////////////////////////////////////////////////
  748. //
  749. // Scene
  750. //
  751. //////////////////////////////////////////////////////////////////////////////
  752. void BeginScene()
  753. {
  754. m_bInScene = true;
  755. m_pbSurface = m_psurface->GetWritablePointer();
  756. m_pitchSurface = m_psurface->GetPitch();
  757. m_sizeSurface = m_psurface->GetSize();
  758. UpdateZBuffer();
  759. UpdateTextureInfo();
  760. m_bUpdatePointers = true;
  761. }
  762. void EndScene()
  763. {
  764. m_bInScene = false;
  765. m_psurface->ReleasePointer();
  766. if (m_psurfaceTexture) {
  767. m_psurfaceTexture->ReleasePointer();
  768. }
  769. }
  770. //////////////////////////////////////////////////////////////////////////////
  771. //
  772. // Viewport
  773. //
  774. //////////////////////////////////////////////////////////////////////////////
  775. void SetClipRect(const Rect& rectClip)
  776. {
  777. m_rectClip = rectClip;
  778. }
  779. void ClearZBuffer()
  780. {
  781. if (m_pbZBuffer) {
  782. memset(
  783. m_pbZBuffer,
  784. 0xff,
  785. m_pitchSurface
  786. * m_sizeSurface.Y()
  787. );
  788. }
  789. }
  790. //////////////////////////////////////////////////////////////////////////////
  791. //
  792. // Attributes
  793. //
  794. //////////////////////////////////////////////////////////////////////////////
  795. bool Has3DAcceleration()
  796. {
  797. return false;
  798. }
  799. Point GetSurfaceSize()
  800. {
  801. return Point::Cast(m_psurface->GetSize());
  802. }
  803. //////////////////////////////////////////////////////////////////////////////
  804. //
  805. // State
  806. //
  807. //////////////////////////////////////////////////////////////////////////////
  808. void SetTexture(Surface* psurfaceTextureArg)
  809. {
  810. if (m_bInScene && m_psurfaceTexture) {
  811. m_psurfaceTexture->ReleasePointer();
  812. }
  813. CastTo(m_psurfaceTexture, psurfaceTextureArg);
  814. if (m_bInScene) {
  815. UpdateTextureInfo();
  816. }
  817. m_bUpdatePointers = true;
  818. }
  819. void SetShadeMode(ShadeMode shadeMode)
  820. {
  821. m_shadeMode = shadeMode;
  822. m_bUpdatePointers = true;
  823. }
  824. void SetBlendMode(BlendMode blendMode)
  825. {
  826. m_blendMode = blendMode;
  827. m_bUpdatePointers = true;
  828. }
  829. void SetWrapMode(WrapMode wrapMode)
  830. {
  831. m_wrapMode = wrapMode;
  832. m_bUpdatePointers = true;
  833. }
  834. void SetCullMode(CullMode cullMode)
  835. {
  836. m_cullMode = cullMode;
  837. m_bUpdatePointers = true;
  838. }
  839. void SetZTest(bool bZTest)
  840. {
  841. m_bZTest = bZTest;
  842. m_bUpdatePointers = true;
  843. }
  844. void SetZWrite(bool bZWrite)
  845. {
  846. m_bZWrite = bZWrite;
  847. m_bUpdatePointers = true;
  848. }
  849. void SetLinearFilter(bool bLinearFilter)
  850. {
  851. m_bLinearFilter = bLinearFilter;
  852. m_bUpdatePointers = true;
  853. }
  854. void SetPerspectiveCorrection(bool bPerspectiveCorrection)
  855. {
  856. m_bPerspectiveCorrection = bPerspectiveCorrection;
  857. m_bUpdatePointers = true;
  858. }
  859. void SetDither(bool bDither)
  860. {
  861. m_bDither = bDither;
  862. m_bUpdatePointers = true;
  863. }
  864. void SetColorKey(bool bColorKey)
  865. {
  866. m_bColorKeyEnabled = bColorKey;
  867. m_bUpdatePointers = true;
  868. }
  869. void SetColor(const D3DCOLOR& color)
  870. {
  871. m_colorA = Fixed1616(color & 0xff000000, -32);
  872. m_colorR = Fixed1616(color & 0x00ff0000, -24);
  873. m_colorG = Fixed1616(color & 0x0000ff00, -16);
  874. m_colorB = Fixed1616(color & 0x000000ff, - 8);
  875. m_colorInvA = Fixed1616(255 - (color >> 24), - 8);
  876. m_colorE = MakeColorE(m_colorR, m_colorG, m_colorB);
  877. }
  878. void SetColor(const Color& color)
  879. {
  880. m_colorR = Fixed1616(color.GetRed () * g_componentFloatToIntScale);
  881. m_colorG = Fixed1616(color.GetGreen() * g_componentFloatToIntScale);
  882. m_colorB = Fixed1616(color.GetBlue () * g_componentFloatToIntScale);
  883. m_colorA = Fixed1616(color.GetAlpha() * g_componentFloatToIntScale);
  884. m_colorInvA = Fixed1616(1.0f - color.GetAlpha());
  885. m_colorE = MakeColorE(m_colorR, m_colorG, m_colorB);
  886. }
  887. //////////////////////////////////////////////////////////////////////////////
  888. //
  889. // Chunk Pass Members
  890. //
  891. //////////////////////////////////////////////////////////////////////////////
  892. PFNFillChunk m_ppfnFillChunk[MaxChunkPasses];
  893. int m_passCount;
  894. WORD m_wZBufferMask;
  895. int m_count;
  896. ColorE m_pcolorEChunk[ChunkSize];
  897. ColorE m_pcolorEDest[ChunkSize];
  898. BYTE* m_pzChunk;
  899. BYTE* m_pdest;
  900. Fixed m_uChunk;
  901. Fixed m_vChunk;
  902. Fixed131 m_iChunk;
  903. FixedZ m_zChunk;
  904. //////////////////////////////////////////////////////////////////////////////
  905. //
  906. // Chunk Pass Helpers
  907. //
  908. //////////////////////////////////////////////////////////////////////////////
  909. __forceinline int MakeIndex(int index)
  910. {
  911. return index + ChunkSize;
  912. }
  913. //////////////////////////////////////////////////////////////////////////////
  914. //
  915. // This function works for both CK and not CK since Blend11 with a black
  916. // source pixel is the same as color keying.
  917. //
  918. //////////////////////////////////////////////////////////////////////////////
  919. void CopyTextureZTestZWriteBlend11()
  920. {
  921. Color565* pcolor565 = (Color565*)m_pdest;
  922. Fixed u = m_uChunk;
  923. Fixed v = m_vChunk;
  924. FixedZ z = m_zChunk;
  925. WORD* pz = (WORD*)m_pzChunk;
  926. int index = m_count;
  927. do {
  928. WORD zs = WORD(z.GetInteger(16));
  929. WORD zd = pz[MakeIndex(index)];
  930. if (zs <= zd) {
  931. DWORD xt = ((u.GetFixed() >> Fixed::FractionBits()) & m_umask) << 1;
  932. DWORD yt = ((v.GetFixed() >> Fixed::FractionBits()) & m_vmask) << (m_ushift + 1);
  933. Color565 color565T = *(Color565*)(m_pbTexture + xt + yt);
  934. if (color565T != 0) {
  935. pz[MakeIndex(index)] = zs;
  936. Color565 color565D = pcolor565[MakeIndex(index)];
  937. ColorE colorET = Color565ToColorE(color565T);
  938. ColorE colorED = Color565ToColorE(color565D);
  939. ColorE colorE = Blend11(colorET, colorED);
  940. Color565 color565 = ColorEToColor565(colorE);
  941. pcolor565[MakeIndex(index)] = color565;
  942. }
  943. }
  944. z += m_dzdx;
  945. u += m_dudx;
  946. v += m_dvdx;
  947. index ++;
  948. } while (index < 0);
  949. }
  950. //////////////////////////////////////////////////////////////////////////////
  951. //
  952. // This function works for both CK and not CK since Blend11 with a black
  953. // source pixel is the same as color keying.
  954. //
  955. //////////////////////////////////////////////////////////////////////////////
  956. void FlatTextureZTestZWriteBlend11()
  957. {
  958. Color565* pcolor565 = (Color565*)m_pdest;
  959. Fixed u = m_uChunk;
  960. Fixed v = m_vChunk;
  961. FixedZ z = m_zChunk;
  962. WORD* pz = (WORD*)m_pzChunk;
  963. int index = m_count;
  964. do {
  965. WORD zs = WORD(z.GetInteger(16));
  966. WORD zd = pz[MakeIndex(index)];
  967. if (zs <= zd) {
  968. DWORD xt = ((u.GetFixed() >> Fixed::FractionBits()) & m_umask) << 1;
  969. DWORD yt = ((v.GetFixed() >> Fixed::FractionBits()) & m_vmask) << (m_ushift + 1);
  970. Color565 color565T = *(Color565*)(m_pbTexture + xt + yt);
  971. if (color565T != 0) {
  972. pz[MakeIndex(index)] = zs;
  973. Color565 color565D = pcolor565[MakeIndex(index)];
  974. ColorE colorET = FlatShade(Color565ToColorE(color565T));
  975. ColorE colorED = Color565ToColorE(color565D);
  976. ColorE colorE = Blend11(colorET, colorED);
  977. Color565 color565 = ColorEToColor565(colorE);
  978. pcolor565[MakeIndex(index)] = color565;
  979. }
  980. }
  981. z += m_dzdx;
  982. u += m_dudx;
  983. v += m_dvdx;
  984. index ++;
  985. } while (index < 0);
  986. }
  987. //////////////////////////////////////////////////////////////////////////////
  988. //
  989. // This function works for both CK and not CK since Blend11 with a black
  990. // source pixel is the same as color keying.
  991. //
  992. //////////////////////////////////////////////////////////////////////////////
  993. void FlatBlend1InvA()
  994. {
  995. Color565* pcolor565 = (Color565*)m_pdest;
  996. int index = m_count;
  997. do {
  998. Color565 color565D = pcolor565[MakeIndex(index)];
  999. ColorE colorD = Color565ToColorE(color565D);
  1000. ColorE colorE = m_colorE + colorD * m_colorInvA;
  1001. Color565 color565 = ColorEToColor565(colorE);
  1002. pcolor565[MakeIndex(index)] = color565;
  1003. index ++;
  1004. } while (index < 0);
  1005. }
  1006. //////////////////////////////////////////////////////////////////////////////
  1007. //
  1008. //
  1009. //
  1010. //////////////////////////////////////////////////////////////////////////////
  1011. void CopyTextureZTestZWriteAndColorKey()
  1012. {
  1013. Color565* pcolor565 = (Color565*)m_pdest;
  1014. Fixed u = m_uChunk;
  1015. Fixed v = m_vChunk;
  1016. FixedZ z = m_zChunk;
  1017. WORD* pz = (WORD*)m_pzChunk;
  1018. int index = m_count;
  1019. do {
  1020. WORD zs = WORD(z.GetInteger(16));
  1021. WORD zd = pz[MakeIndex(index)];
  1022. if (zs <= zd) {
  1023. DWORD xt = (u.GetInteger(1) & m_umask);
  1024. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1025. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1026. if (color565 != 0) {
  1027. pz[MakeIndex(index)] = zs;
  1028. pcolor565[MakeIndex(index)] = color565;
  1029. }
  1030. }
  1031. z += m_dzdx;
  1032. u += m_dudx;
  1033. v += m_dvdx;
  1034. index ++;
  1035. } while (index < 0);
  1036. }
  1037. //////////////////////////////////////////////////////////////////////////////
  1038. //
  1039. //
  1040. //
  1041. //////////////////////////////////////////////////////////////////////////////
  1042. void CopyTextureZWriteAndColorKey()
  1043. {
  1044. Color565* pcolor565 = (Color565*)m_pdest;
  1045. Fixed u = m_uChunk;
  1046. Fixed v = m_vChunk;
  1047. FixedZ z = m_zChunk;
  1048. WORD* pz = (WORD*)m_pzChunk;
  1049. WORD mask = m_wZBufferMask;
  1050. int index = m_count;
  1051. do {
  1052. WORD zs = WORD(z.GetInteger(16));
  1053. WORD zd = pz[MakeIndex(index)];
  1054. if (zs <= zd) {
  1055. DWORD xt = (u.GetInteger(1) & m_umask);
  1056. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1057. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1058. if (color565 != 0) {
  1059. if ((mask & 1) == 0) {
  1060. WORD zs = WORD(z.GetInteger(16));
  1061. pz[MakeIndex(index)] = zs;
  1062. pcolor565[MakeIndex(index)] = color565;
  1063. }
  1064. }
  1065. }
  1066. mask = mask >> 1;
  1067. z += m_dzdx;
  1068. u += m_dudx;
  1069. v += m_dvdx;
  1070. index ++;
  1071. } while (index < 0);
  1072. }
  1073. //////////////////////////////////////////////////////////////////////////////
  1074. //
  1075. //
  1076. //
  1077. //////////////////////////////////////////////////////////////////////////////
  1078. void LoadColor565Texture()
  1079. {
  1080. ColorE* pcolorE = m_pcolorEChunk;
  1081. Fixed u = m_uChunk;
  1082. Fixed v = m_vChunk;
  1083. int index = m_count;
  1084. do {
  1085. DWORD xt = (u.GetInteger(1) & m_umask);
  1086. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1087. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1088. ColorE colorE = Color565ToColorE(color565);
  1089. pcolorE[MakeIndex(index)] = colorE;
  1090. u += m_dudx;
  1091. v += m_dvdx;
  1092. index ++;
  1093. } while (index < 0);
  1094. }
  1095. //////////////////////////////////////////////////////////////////////////////
  1096. //
  1097. //
  1098. //
  1099. //////////////////////////////////////////////////////////////////////////////
  1100. void Load565Dest()
  1101. {
  1102. ColorE* pcolorE = m_pcolorEDest;
  1103. Color565* pcolor565 = (Color565*)m_pdest;
  1104. int index = m_count;
  1105. do {
  1106. Color565 color565 = pcolor565[MakeIndex(index)];
  1107. ColorE colorE = Color565ToColorE(color565);
  1108. pcolorE[MakeIndex(index)] = colorE;
  1109. index ++;
  1110. } while (index < 0);
  1111. }
  1112. //////////////////////////////////////////////////////////////////////////////
  1113. //
  1114. //
  1115. //
  1116. //////////////////////////////////////////////////////////////////////////////
  1117. void Load555Dest()
  1118. {
  1119. ColorE* pcolorE = m_pcolorEDest;
  1120. Color555* pcolor555 = (Color555*)m_pdest;
  1121. int index = m_count;
  1122. do {
  1123. Color555 color555 = pcolor555[MakeIndex(index)];;
  1124. ColorE colorE = Color555ToColorE(color555);
  1125. pcolorE[MakeIndex(index)] = colorE;
  1126. index ++;
  1127. } while (index < 0);
  1128. }
  1129. //////////////////////////////////////////////////////////////////////////////
  1130. //
  1131. //
  1132. //
  1133. //////////////////////////////////////////////////////////////////////////////
  1134. void LoadFlatColor()
  1135. {
  1136. ColorE* pcolorE = m_pcolorEChunk;
  1137. int index = m_count;
  1138. do {
  1139. pcolorE[MakeIndex(index)] = m_colorE;
  1140. index ++;
  1141. } while (index < 0);
  1142. }
  1143. //////////////////////////////////////////////////////////////////////////////
  1144. //
  1145. //
  1146. //
  1147. //////////////////////////////////////////////////////////////////////////////
  1148. void CopyTextureZTestZWriteFlat()
  1149. {
  1150. Color565* pcolor565 = (Color565*)m_pdest;
  1151. Fixed u = m_uChunk;
  1152. Fixed v = m_vChunk;
  1153. FixedZ z = m_zChunk;
  1154. WORD* pz = (WORD*)m_pzChunk;
  1155. int index = m_count;
  1156. do {
  1157. WORD zs = WORD(z.GetInteger(16));
  1158. WORD zd = pz[MakeIndex(index)];
  1159. if (zs <= zd) {
  1160. DWORD xt = (u.GetInteger(1) & m_umask);
  1161. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1162. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1163. pz[MakeIndex(index)] = zs;
  1164. pcolor565[MakeIndex(index)] =
  1165. MakeColor565(
  1166. GetR(color565) * m_colorR,
  1167. GetG(color565) * m_colorG,
  1168. GetB(color565) * m_colorB
  1169. );
  1170. }
  1171. z += m_dzdx;
  1172. u += m_dudx;
  1173. v += m_dvdx;
  1174. index ++;
  1175. } while (index < 0);
  1176. }
  1177. //////////////////////////////////////////////////////////////////////////////
  1178. //
  1179. //
  1180. //
  1181. //////////////////////////////////////////////////////////////////////////////
  1182. void CopyTextureZTestZWriteFlatAndColorKey()
  1183. {
  1184. Color565* pcolor565 = (Color565*)m_pdest;
  1185. Fixed u = m_uChunk;
  1186. Fixed v = m_vChunk;
  1187. FixedZ z = m_zChunk;
  1188. WORD* pz = (WORD*)m_pzChunk;
  1189. int index = m_count;
  1190. do {
  1191. WORD zs = WORD(z.GetInteger(16));
  1192. WORD zd = pz[MakeIndex(index)];
  1193. if (zs <= zd) {
  1194. DWORD xt = (u.GetInteger(1) & m_umask);
  1195. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1196. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1197. if (color565 != 0) {
  1198. pz[MakeIndex(index)] = zs;
  1199. pcolor565[MakeIndex(index)] =
  1200. MakeColor565(
  1201. GetR(color565) * m_colorR,
  1202. GetG(color565) * m_colorG,
  1203. GetB(color565) * m_colorB
  1204. );
  1205. }
  1206. }
  1207. z += m_dzdx;
  1208. u += m_dudx;
  1209. v += m_dvdx;
  1210. index ++;
  1211. } while (index < 0);
  1212. }
  1213. //////////////////////////////////////////////////////////////////////////////
  1214. //
  1215. //
  1216. //
  1217. //////////////////////////////////////////////////////////////////////////////
  1218. ColorE FlatShade(const ColorE& colorS)
  1219. {
  1220. return
  1221. MakeColorE(
  1222. GetR(colorS) * m_colorR,
  1223. GetG(colorS) * m_colorG,
  1224. GetB(colorS) * m_colorB
  1225. );
  1226. }
  1227. //////////////////////////////////////////////////////////////////////////////
  1228. //
  1229. //
  1230. //
  1231. //////////////////////////////////////////////////////////////////////////////
  1232. void FlatShade()
  1233. {
  1234. ColorE* pcolorE = m_pcolorEChunk;
  1235. WORD mask = m_wZBufferMask;
  1236. int index = m_count;
  1237. do {
  1238. if ((mask & 1) == 0) {
  1239. pcolorE[MakeIndex(index)] = FlatShade(pcolorE[MakeIndex(index)]);
  1240. }
  1241. mask = mask >> 1;
  1242. index ++;
  1243. } while (index < 0);
  1244. }
  1245. //////////////////////////////////////////////////////////////////////////////
  1246. //
  1247. //
  1248. //
  1249. //////////////////////////////////////////////////////////////////////////////
  1250. void CopyTextureZTestZWriteGouraud()
  1251. {
  1252. Color565* pcolor565 = (Color565*)m_pdest;
  1253. Fixed u = m_uChunk;
  1254. Fixed v = m_vChunk;
  1255. Fixed131 i = m_iChunk;
  1256. FixedZ z = m_zChunk;
  1257. WORD* pz = (WORD*)m_pzChunk;
  1258. int index = m_count;
  1259. do {
  1260. WORD zs = WORD(z.GetInteger(16));
  1261. WORD zd = pz[MakeIndex(index)];
  1262. if (zs <= zd) {
  1263. pz[MakeIndex(index)] = zs;
  1264. DWORD xt = (u.GetInteger(1) & m_umask);
  1265. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1266. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1267. pcolor565[MakeIndex(index)] = color565 * i;
  1268. }
  1269. z += m_dzdx;
  1270. u += m_dudx;
  1271. v += m_dvdx;
  1272. i += m_didx;
  1273. index ++;
  1274. } while (index < 0);
  1275. }
  1276. //////////////////////////////////////////////////////////////////////////////
  1277. //
  1278. //
  1279. //
  1280. //////////////////////////////////////////////////////////////////////////////
  1281. void CopyTextureZTestZWriteGouraudAndColorKey()
  1282. {
  1283. Color565* pcolor565 = (Color565*)m_pdest;
  1284. Fixed u = m_uChunk;
  1285. Fixed v = m_vChunk;
  1286. Fixed131 i = m_iChunk;
  1287. FixedZ z = m_zChunk;
  1288. WORD* pz = (WORD*)m_pzChunk;
  1289. int index = m_count;
  1290. do {
  1291. WORD zs = WORD(z.GetInteger(16));
  1292. WORD zd = pz[MakeIndex(index)];
  1293. if (zs <= zd) {
  1294. DWORD xt = (u.GetInteger(1) & m_umask);
  1295. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1296. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1297. if (color565 != 0) {
  1298. pz[MakeIndex(index)] = zs;
  1299. pcolor565[MakeIndex(index)] = color565 * i;
  1300. }
  1301. }
  1302. z += m_dzdx;
  1303. u += m_dudx;
  1304. v += m_dvdx;
  1305. i += m_didx;
  1306. index ++;
  1307. } while (index < 0);
  1308. }
  1309. //////////////////////////////////////////////////////////////////////////////
  1310. //
  1311. //
  1312. //
  1313. //////////////////////////////////////////////////////////////////////////////
  1314. void GouraudShade()
  1315. {
  1316. ColorE* pcolorE = m_pcolorEChunk;
  1317. Fixed131 i = m_iChunk;
  1318. WORD mask = m_wZBufferMask;
  1319. int index = m_count;
  1320. do {
  1321. if ((mask & 1) == 0) {
  1322. ColorE colorS = pcolorE[MakeIndex(index)];
  1323. pcolorE[MakeIndex(index)] = colorS * i;
  1324. }
  1325. mask = mask >> 1;
  1326. i += m_didx;
  1327. index ++;
  1328. } while (index < 0);
  1329. }
  1330. //////////////////////////////////////////////////////////////////////////////
  1331. //
  1332. //
  1333. //
  1334. //////////////////////////////////////////////////////////////////////////////
  1335. void LoadGouraudColor()
  1336. {
  1337. ColorE* pcolorE = m_pcolorEChunk;
  1338. Fixed131 i = m_iChunk;
  1339. WORD mask = m_wZBufferMask;
  1340. int index = m_count;
  1341. do {
  1342. if ((mask & 1) == 0) {
  1343. Fixed1616 i1616 = Fixed1616(i.GetFixed(), -i.FractionBits());
  1344. pcolorE[MakeIndex(index)] = MakeColorE(i1616, i1616, i1616);
  1345. }
  1346. mask = mask >> 1;
  1347. i += m_didx;
  1348. index ++;
  1349. } while (index < 0);
  1350. }
  1351. //////////////////////////////////////////////////////////////////////////////
  1352. //
  1353. //
  1354. //
  1355. //////////////////////////////////////////////////////////////////////////////
  1356. ColorE Blend11(const ColorE& c1, const ColorE& c2)
  1357. {
  1358. ColorE color = c1 + c2;
  1359. if ((color & ColorESaturationMask) != 0) {
  1360. if ((color & ColorERSaturationMask) != 0) {
  1361. color |= ColorERMask;
  1362. }
  1363. if ((color & ColorEGSaturationMask) != 0) {
  1364. color |= ColorEGMask;
  1365. }
  1366. if ((color & ColorEBSaturationMask) != 0) {
  1367. color |= ColorEBMask;
  1368. }
  1369. }
  1370. return color;
  1371. }
  1372. //////////////////////////////////////////////////////////////////////////////
  1373. //
  1374. //
  1375. //
  1376. //////////////////////////////////////////////////////////////////////////////
  1377. void Blend11()
  1378. {
  1379. ColorE* pcolorE = m_pcolorEChunk;
  1380. ColorE* pcolorEDest = m_pcolorEDest;
  1381. WORD mask = m_wZBufferMask;
  1382. int index = m_count;
  1383. do {
  1384. if ((mask & 1) == 0) {
  1385. ColorE colorS = pcolorE [MakeIndex(index)];
  1386. ColorE colorD = pcolorEDest[MakeIndex(index)];
  1387. ColorE color = Blend11(colorS, colorD);
  1388. pcolorE[MakeIndex(index)] = color;
  1389. }
  1390. mask = mask >> 1;
  1391. index ++;
  1392. } while (index < 0);
  1393. }
  1394. //////////////////////////////////////////////////////////////////////////////
  1395. //
  1396. //
  1397. //
  1398. //////////////////////////////////////////////////////////////////////////////
  1399. void Blend1InvA()
  1400. {
  1401. ColorE* pcolorE = m_pcolorEChunk;
  1402. ColorE* pcolorEDest = m_pcolorEDest;
  1403. WORD mask = m_wZBufferMask;
  1404. int index = m_count;
  1405. do {
  1406. if ((mask & 1) == 0) {
  1407. ColorE colorS = pcolorE [MakeIndex(index)];
  1408. ColorE colorD = pcolorEDest[MakeIndex(index)];
  1409. pcolorE[MakeIndex(index)] = colorS + colorD * m_colorInvA;
  1410. }
  1411. mask = mask >> 1;
  1412. index ++;
  1413. } while (index < 0);
  1414. }
  1415. //////////////////////////////////////////////////////////////////////////////
  1416. //
  1417. //
  1418. //
  1419. //////////////////////////////////////////////////////////////////////////////
  1420. void CopyToColor565Destination()
  1421. {
  1422. ColorE* pcolorE = m_pcolorEChunk;
  1423. Color565* pcolor565 = (Color565*)m_pdest;
  1424. WORD mask = m_wZBufferMask;
  1425. int index = m_count;
  1426. if (mask == 0) {
  1427. do {
  1428. pcolor565[MakeIndex(index)] = ColorEToColor565(pcolorE[MakeIndex(index)]);
  1429. index++;
  1430. } while (index < 0);
  1431. } else {
  1432. do {
  1433. if ((mask & 1) == 0) {
  1434. pcolor565[MakeIndex(index)] = ColorEToColor565(pcolorE[MakeIndex(index)]);
  1435. }
  1436. mask = mask >> 1;
  1437. index ++;
  1438. } while (index < 0);
  1439. }
  1440. }
  1441. //////////////////////////////////////////////////////////////////////////////
  1442. //
  1443. //
  1444. //
  1445. //////////////////////////////////////////////////////////////////////////////
  1446. void CopyToColor555Destination()
  1447. {
  1448. ColorE* pcolorE = m_pcolorEChunk;
  1449. Color555* pcolor555 = (Color555*)m_pdest;
  1450. WORD mask = m_wZBufferMask;
  1451. int index = m_count;
  1452. if (mask == 0) {
  1453. do {
  1454. pcolor555[MakeIndex(index)] = ColorEToColor555(pcolorE[MakeIndex(index)]);
  1455. index++;
  1456. } while (index < 0);
  1457. } else {
  1458. do {
  1459. if ((mask & 1) == 0) {
  1460. pcolor555[MakeIndex(index)] = ColorEToColor555(pcolorE[MakeIndex(index)]);
  1461. }
  1462. mask = mask >> 1;
  1463. index++;
  1464. } while (index < 0);
  1465. }
  1466. }
  1467. //////////////////////////////////////////////////////////////////////////////
  1468. //
  1469. //
  1470. //
  1471. //////////////////////////////////////////////////////////////////////////////
  1472. void ZTestAndWrite()
  1473. {
  1474. FixedZ z = m_zChunk;
  1475. WORD* pz = (WORD*)m_pzChunk;
  1476. WORD bit = 1;
  1477. int index = m_count;
  1478. do {
  1479. WORD zs = WORD(z.GetInteger(16));
  1480. WORD zd = pz[MakeIndex(index)];
  1481. if (zs <= zd) {
  1482. pz[MakeIndex(index)] = zs;
  1483. } else {
  1484. m_wZBufferMask |= bit;
  1485. }
  1486. bit = bit << 1;
  1487. z += m_dzdx;
  1488. index ++;
  1489. } while (index < 0);
  1490. }
  1491. //////////////////////////////////////////////////////////////////////////////
  1492. //
  1493. //
  1494. //
  1495. //////////////////////////////////////////////////////////////////////////////
  1496. void ZTest()
  1497. {
  1498. FixedZ z = m_zChunk;
  1499. WORD* pz = (WORD*)m_pzChunk;
  1500. WORD bit = 1;
  1501. int index = m_count;
  1502. do {
  1503. WORD zs = WORD(z.GetInteger(16));
  1504. WORD zd = pz[MakeIndex(index)];
  1505. if (!(zs <= zd)) {
  1506. m_wZBufferMask |= bit;
  1507. }
  1508. bit = bit << 1;
  1509. z += m_dzdx;
  1510. index ++;
  1511. } while (index < 0);
  1512. }
  1513. //////////////////////////////////////////////////////////////////////////////
  1514. //
  1515. //
  1516. //
  1517. //////////////////////////////////////////////////////////////////////////////
  1518. void ZWrite()
  1519. {
  1520. FixedZ z = m_zChunk;
  1521. WORD* pz = (WORD*)m_pzChunk;
  1522. WORD mask = m_wZBufferMask;
  1523. int index = m_count;
  1524. do {
  1525. if ((mask & 1) == 0) {
  1526. WORD zs = WORD(z.GetInteger(16));
  1527. pz[MakeIndex(index)] = zs;
  1528. }
  1529. mask = mask >> 1;
  1530. z += m_dzdx;
  1531. index ++;
  1532. } while (index < 0);
  1533. }
  1534. //////////////////////////////////////////////////////////////////////////////
  1535. //
  1536. //
  1537. //
  1538. //////////////////////////////////////////////////////////////////////////////
  1539. void ColorKeyTest()
  1540. {
  1541. ColorE* pcolorE = m_pcolorEChunk;
  1542. WORD bit = 1;
  1543. int index = m_count;
  1544. do {
  1545. ColorE colorE = pcolorE[MakeIndex(index)];
  1546. if (colorE == 0) {
  1547. m_wZBufferMask |= bit;
  1548. }
  1549. bit = bit << 1;
  1550. index ++;
  1551. } while (index < 0);
  1552. }
  1553. //////////////////////////////////////////////////////////////////////////////
  1554. //
  1555. //
  1556. //
  1557. //////////////////////////////////////////////////////////////////////////////
  1558. void DoPasses()
  1559. {
  1560. for(int pass = 0; pass < m_passCount; pass++) {
  1561. (this->*(m_ppfnFillChunk[pass]))();
  1562. if (m_wZBufferMask == 0xffff) {
  1563. break;
  1564. }
  1565. }
  1566. }
  1567. //////////////////////////////////////////////////////////////////////////////
  1568. //
  1569. //
  1570. //
  1571. //////////////////////////////////////////////////////////////////////////////
  1572. void FillSubTriangleMultiPassChunk(
  1573. const int ymin,
  1574. const int ymax
  1575. ) {
  1576. //
  1577. // fill the triangle
  1578. //
  1579. BYTE* pscan = m_pbSurface + ymin * m_pitchSurface;
  1580. BYTE* pzscan = m_pbZBuffer + ymin * m_pitchSurface;
  1581. for (int y = ymin; y < ymax; y++) {
  1582. int count = m_xmax - m_xmin;
  1583. if (count > 0) {
  1584. //
  1585. // Initial values
  1586. //
  1587. m_pdest = pscan + m_xmin * 2;
  1588. m_pzChunk = pzscan + m_xmin * 2;
  1589. m_uChunk = m_u;
  1590. m_vChunk = m_v;
  1591. m_iChunk = m_i;
  1592. m_zChunk = m_z;
  1593. //
  1594. // ChunkSize pixel chunks
  1595. //
  1596. m_count = -ChunkSize;
  1597. while (count >= ChunkSize) {
  1598. m_wZBufferMask = 0;
  1599. DoPasses();
  1600. m_pdest += 2 * ChunkSize;
  1601. m_pzChunk += 2 * ChunkSize;
  1602. m_uChunk += m_dudx * ChunkSize;
  1603. m_vChunk += m_dvdx * ChunkSize;
  1604. m_iChunk += m_didx * ChunkSize;
  1605. m_zChunk += m_dzdx * ChunkSize;
  1606. count -= ChunkSize;
  1607. }
  1608. //
  1609. // Remaining pixels
  1610. //
  1611. if (count > 0) {
  1612. int delta = ChunkSize - count;
  1613. m_count = -count;
  1614. m_pdest -= 2 * delta;
  1615. m_pzChunk -= 2 * delta;
  1616. m_wZBufferMask = 0;
  1617. DoPasses();
  1618. }
  1619. }
  1620. //
  1621. // y++
  1622. //
  1623. pscan += m_pitchSurface;
  1624. pzscan += m_pitchSurface;
  1625. m_xminFrac += m_dxmindyFrac;
  1626. if (m_xminFrac >= 0) {
  1627. m_xminFrac -= 1;
  1628. m_xmin += m_dxmindyBig;
  1629. m_u += m_dudyBig;
  1630. m_v += m_dvdyBig;
  1631. m_i += m_didyBig;
  1632. m_z += m_dzdyBig;
  1633. } else {
  1634. m_xmin += m_dxmindyLittle;
  1635. m_u += m_dudyLittle;
  1636. m_v += m_dvdyLittle;
  1637. m_i += m_didyLittle;
  1638. m_z += m_dzdyLittle;
  1639. }
  1640. m_xmaxFrac += m_dxmaxdyFrac;
  1641. if (m_xmaxFrac >= 0) {
  1642. m_xmaxFrac -= 1;
  1643. m_xmax += m_dxmaxdyBig;
  1644. } else {
  1645. m_xmax += m_dxmaxdyLittle;
  1646. }
  1647. }
  1648. }
  1649. //////////////////////////////////////////////////////////////////////////////
  1650. //
  1651. //
  1652. //
  1653. //////////////////////////////////////////////////////////////////////////////
  1654. void FillSubTriangleMultiPass(
  1655. const int ymin,
  1656. const int ymax
  1657. ) {
  1658. //
  1659. // fill the triangle
  1660. //
  1661. BYTE* pscan = m_pbSurface + ymin * m_pitchSurface;
  1662. BYTE* pzscan = m_pbZBuffer + ymin * m_pitchSurface;
  1663. for (int y = ymin; y < ymax; y++) {
  1664. int count = m_xmax - m_xmin;
  1665. if (count > 0) {
  1666. //
  1667. // Initial values
  1668. //
  1669. m_pdest = pscan + m_xmin * 2;
  1670. m_pzChunk = pzscan + m_xmin * 2;
  1671. m_uChunk = m_u;
  1672. m_vChunk = m_v;
  1673. m_iChunk = m_i;
  1674. m_zChunk = m_z;
  1675. //
  1676. // Call the scan routine
  1677. //
  1678. int delta = ChunkSize - count;
  1679. m_count = -count;
  1680. m_pdest -= 2 * delta;
  1681. m_pzChunk -= 2 * delta;
  1682. DoPasses();
  1683. }
  1684. //
  1685. // y++
  1686. //
  1687. pscan += m_pitchSurface;
  1688. pzscan += m_pitchSurface;
  1689. m_xminFrac += m_dxmindyFrac;
  1690. if (m_xminFrac >= 0) {
  1691. m_xminFrac -= 1;
  1692. m_xmin += m_dxmindyBig;
  1693. m_u += m_dudyBig;
  1694. m_v += m_dvdyBig;
  1695. m_i += m_didyBig;
  1696. m_z += m_dzdyBig;
  1697. } else {
  1698. m_xmin += m_dxmindyLittle;
  1699. m_u += m_dudyLittle;
  1700. m_v += m_dvdyLittle;
  1701. m_i += m_didyLittle;
  1702. m_z += m_dzdyLittle;
  1703. }
  1704. m_xmaxFrac += m_dxmaxdyFrac;
  1705. if (m_xmaxFrac >= 0) {
  1706. m_xmaxFrac -= 1;
  1707. m_xmax += m_dxmaxdyBig;
  1708. } else {
  1709. m_xmax += m_dxmaxdyLittle;
  1710. }
  1711. }
  1712. }
  1713. //////////////////////////////////////////////////////////////////////////////
  1714. //
  1715. //
  1716. //
  1717. //////////////////////////////////////////////////////////////////////////////
  1718. void FillSubTriangleTextureZTestZWriteAndColorKey(
  1719. const int ymin,
  1720. const int ymax
  1721. ) {
  1722. //
  1723. // fill the triangle
  1724. //
  1725. BYTE* pscan = m_pbSurface + ymin * m_pitchSurface;
  1726. BYTE* pzscan = m_pbZBuffer + ymin * m_pitchSurface;
  1727. for (int y = ymin; y < ymax; y++) {
  1728. int count = m_xmax - m_xmin;
  1729. if (count > 0) {
  1730. //
  1731. // Initial values
  1732. //
  1733. Color565* pcolor565 = (Color565*)(pscan + m_xmin * 2);
  1734. WORD* pz = (WORD*)(pzscan + m_xmin * 2);
  1735. Fixed u = m_u;
  1736. Fixed v = m_v;
  1737. FixedZ z = m_z;
  1738. //
  1739. // Call the scan routine
  1740. //
  1741. int index = 0;
  1742. if (m_bColorKeyOn) {
  1743. do {
  1744. WORD zs = WORD(z.GetInteger(16));
  1745. WORD zd = pz[index];
  1746. if (zs <= zd) {
  1747. DWORD xt = (u.GetInteger(1) & m_umask);
  1748. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1749. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1750. if (color565 != 0) {
  1751. pz[index] = zs;
  1752. pcolor565[index] = color565;
  1753. }
  1754. }
  1755. z += m_dzdx;
  1756. u += m_dudx;
  1757. v += m_dvdx;
  1758. index ++;
  1759. } while (index < count);
  1760. } else {
  1761. do {
  1762. WORD zs = WORD(z.GetInteger(16));
  1763. WORD zd = pz[index];
  1764. if (zs <= zd) {
  1765. DWORD xt = (u.GetInteger(1) & m_umask);
  1766. DWORD yt = (v.GetInteger(m_ushift + 1, true) & m_vmask);
  1767. Color565 color565 = *(Color565*)(m_pbTexture + xt + yt);
  1768. pz[index] = zs;
  1769. pcolor565[index] = color565;
  1770. }
  1771. z += m_dzdx;
  1772. u += m_dudx;
  1773. v += m_dvdx;
  1774. index ++;
  1775. } while (index < count);
  1776. }
  1777. }
  1778. //
  1779. // y++
  1780. //
  1781. pscan += m_pitchSurface;
  1782. pzscan += m_pitchSurface;
  1783. m_xminFrac += m_dxmindyFrac;
  1784. if (m_xminFrac >= 0) {
  1785. m_xminFrac -= 1;
  1786. m_xmin += m_dxmindyBig;
  1787. m_u += m_dudyBig;
  1788. m_v += m_dvdyBig;
  1789. m_z += m_dzdyBig;
  1790. } else {
  1791. m_xmin += m_dxmindyLittle;
  1792. m_u += m_dudyLittle;
  1793. m_v += m_dvdyLittle;
  1794. m_z += m_dzdyLittle;
  1795. }
  1796. m_xmaxFrac += m_dxmaxdyFrac;
  1797. if (m_xmaxFrac >= 0) {
  1798. m_xmaxFrac -= 1;
  1799. m_xmax += m_dxmaxdyBig;
  1800. } else {
  1801. m_xmax += m_dxmaxdyLittle;
  1802. }
  1803. }
  1804. }
  1805. //////////////////////////////////////////////////////////////////////////////
  1806. //
  1807. //
  1808. //
  1809. //////////////////////////////////////////////////////////////////////////////
  1810. void FillSubTriangleNoop(
  1811. const int ymin,
  1812. const int ymax
  1813. ) {
  1814. }
  1815. //////////////////////////////////////////////////////////////////////////////
  1816. //
  1817. //
  1818. //
  1819. //////////////////////////////////////////////////////////////////////////////
  1820. void UpdateZBuffer()
  1821. {
  1822. if (m_psurface->GetSurfaceType().Test(SurfaceTypeZBuffer())) {
  1823. if (m_pitchZBuffer != m_pitchSurface) {
  1824. m_pitchZBuffer = m_pitchSurface;
  1825. if (m_pbZBuffer) {
  1826. delete m_pbZBuffer;
  1827. }
  1828. m_pbZBuffer =
  1829. new BYTE[
  1830. m_pitchSurface
  1831. * m_sizeSurface.Y()
  1832. ];
  1833. }
  1834. } else {
  1835. if (m_pbZBuffer) {
  1836. delete m_pbZBuffer;
  1837. }
  1838. m_pbZBuffer = NULL;
  1839. }
  1840. }
  1841. //////////////////////////////////////////////////////////////////////////////
  1842. //
  1843. //
  1844. //
  1845. //////////////////////////////////////////////////////////////////////////////
  1846. void UpdateTextureInfo()
  1847. {
  1848. if (m_psurfaceTexture) {
  1849. m_pbTexture = m_psurfaceTexture->GetWritablePointer();
  1850. m_pitchTexture = m_psurfaceTexture->GetPitch();
  1851. m_sizeTexture = m_psurfaceTexture->GetSize();
  1852. m_uscale = (float)m_sizeTexture.X();
  1853. m_vscale = (float)m_sizeTexture.Y();
  1854. m_ushift = GetShift(m_sizeTexture.X());
  1855. m_vshift = GetShift(m_sizeTexture.Y());
  1856. m_umask = MakeMask(m_ushift, 1);
  1857. m_vmask = MakeMask(m_vshift, m_ushift + 1);
  1858. m_bColorKey = m_psurfaceTexture->HasColorKey();
  1859. }
  1860. }
  1861. //////////////////////////////////////////////////////////////////////////////
  1862. //
  1863. //
  1864. //
  1865. //////////////////////////////////////////////////////////////////////////////
  1866. void CalcXMin(
  1867. const VertexScreen* pva,
  1868. const VertexScreen* pvb,
  1869. const int ymin
  1870. ) {
  1871. //
  1872. // calculate ydelta
  1873. //
  1874. const float qdy = 1 / (pvb->y - pva->y);
  1875. const float yDelta = (float(ymin) + 0.5f) - pva->y;
  1876. //
  1877. // calculate dxmindy
  1878. //
  1879. const float dxmindy = (pvb->x - pva->x) * qdy;
  1880. const float xminIntercept = pva->x + dxmindy * yDelta;
  1881. m_xmin = MakeInt(xminIntercept);
  1882. const float xDelta = (float(m_xmin) + 0.5f) - pva->x;
  1883. if (GreaterEqualZero(dxmindy)) {
  1884. m_dxmindyLittle = MakeInt(dxmindy - 0.5f);
  1885. m_dxmindyBig = m_dxmindyLittle + 1;
  1886. m_dxmindyFrac = dxmindy - float(m_dxmindyLittle);
  1887. m_xminFrac = xminIntercept - (float(m_xmin) + 0.5f);
  1888. } else {
  1889. m_dxmindyLittle = MakeInt(dxmindy + 0.5f);
  1890. m_dxmindyBig = m_dxmindyLittle - 1;
  1891. m_dxmindyFrac = float(m_dxmindyLittle) - dxmindy;
  1892. m_xminFrac = (float(m_xmin) - 0.5f) - xminIntercept;
  1893. }
  1894. //
  1895. // calculate qu, qv, and qw deltas
  1896. //
  1897. m_dudyLittle = Fixed(m_uscale * (m_floatdudy + m_floatdudx * m_dxmindyLittle));
  1898. m_dvdyLittle = Fixed(m_vscale * (m_floatdvdy + m_floatdvdx * m_dxmindyLittle));
  1899. m_didyLittle = FixedD131(m_floatdidy + m_floatdidx * m_dxmindyLittle);
  1900. m_dzdyLittle = FixedDZ (m_floatdzdy + m_floatdzdx * m_dxmindyLittle);
  1901. if (m_dxmindyBig >= 0) {
  1902. m_dudyBig = m_dudyLittle + m_dudx;
  1903. m_dvdyBig = m_dvdyLittle + m_dvdx;
  1904. m_didyBig = m_didyLittle + m_didx;
  1905. m_dzdyBig = m_dzdyLittle + m_dzdx;
  1906. } else {
  1907. m_dudyBig = m_dudyLittle - m_dudx;
  1908. m_dvdyBig = m_dvdyLittle - m_dvdx;
  1909. m_didyBig = m_didyLittle - m_didx;
  1910. m_dzdyBig = m_dzdyLittle - m_dzdx;
  1911. }
  1912. //
  1913. // Initial values
  1914. //
  1915. m_u = Fixed(m_uscale * (pva->u + m_floatdudy * yDelta + m_floatdudx * xDelta));
  1916. m_v = Fixed(m_vscale * (pva->v + m_floatdvdy * yDelta + m_floatdvdx * xDelta));
  1917. m_i =
  1918. Fixed131(
  1919. (float(pva->color & 0xff) * g_componentFloatToIntScale / 255.0f)
  1920. + m_floatdidy * yDelta
  1921. + m_floatdidx * xDelta
  1922. );
  1923. m_z = FixedZ(pva->z + m_floatdzdy * yDelta + m_floatdzdx * xDelta);
  1924. }
  1925. //////////////////////////////////////////////////////////////////////////////
  1926. //
  1927. //
  1928. //
  1929. //////////////////////////////////////////////////////////////////////////////
  1930. void CalcXMax(
  1931. const VertexScreen* pva,
  1932. const VertexScreen* pvb,
  1933. const int ymax
  1934. ) {
  1935. //
  1936. // calculate ydelta
  1937. //
  1938. const float qdy = 1 / (pvb->y - pva->y);
  1939. const float yDelta = (float(ymax) + 0.5f) - pva->y;
  1940. //
  1941. // calculate dxmaxdy
  1942. //
  1943. const float dxmaxdy = (pvb->x - pva->x) * qdy;
  1944. const float xmaxIntercept = pva->x + dxmaxdy * yDelta;
  1945. m_xmax = MakeInt(xmaxIntercept);
  1946. if (GreaterEqualZero(dxmaxdy)) {
  1947. m_dxmaxdyLittle = MakeInt(dxmaxdy - 0.5f);
  1948. m_dxmaxdyBig = m_dxmaxdyLittle + 1;
  1949. m_dxmaxdyFrac = dxmaxdy - float(m_dxmaxdyLittle);
  1950. m_xmaxFrac = xmaxIntercept - (float(m_xmax) + 0.5f);
  1951. } else {
  1952. m_dxmaxdyLittle = MakeInt(dxmaxdy + 0.5f);
  1953. m_dxmaxdyBig = m_dxmaxdyLittle - 1;
  1954. m_dxmaxdyFrac = float(m_dxmaxdyLittle) - dxmaxdy;
  1955. m_xmaxFrac = (float(m_xmax) - 0.5f) - xmaxIntercept;
  1956. }
  1957. }
  1958. //////////////////////////////////////////////////////////////////////////////
  1959. //
  1960. // Calculate Interpolants
  1961. //
  1962. //////////////////////////////////////////////////////////////////////////////
  1963. void CalculateInterpolants(
  1964. const VertexScreen* pva,
  1965. const VertexScreen* pvb,
  1966. const VertexScreen* pvc,
  1967. float xabn,
  1968. float yabn,
  1969. float xacn,
  1970. float yacn
  1971. ) {
  1972. float uab = pvb->u - pva->u;
  1973. float uac = pvc->u - pva->u;
  1974. m_floatdudy = uab * xacn - uac * xabn;
  1975. m_floatdudx = uac * yabn - uab * yacn;
  1976. m_dudx = Fixed(m_uscale * m_floatdudx);
  1977. float vab = pvb->v - pva->v;
  1978. float vac = pvc->v - pva->v;
  1979. m_floatdvdy = vab * xacn - vac * xabn;
  1980. m_floatdvdx = vac * yabn - vab * yacn;
  1981. m_dvdx = Fixed(m_vscale * m_floatdvdx);
  1982. int ia = int(pva->color & 0xff);
  1983. int ib = int(pvb->color & 0xff);
  1984. int ic = int(pvc->color & 0xff);
  1985. float iab = (float(ib - ia) * g_componentFloatToIntScale / 255.0f);
  1986. float iac = (float(ic - ia) * g_componentFloatToIntScale / 255.0f);
  1987. m_floatdidy = iab * xacn - iac * xabn;
  1988. m_floatdidx = iac * yabn - iab * yacn;
  1989. m_didx = FixedD131(m_floatdidx);
  1990. float zab = pvb->z - pva->z;
  1991. float zac = pvc->z - pva->z;
  1992. m_floatdzdy = zab * xacn - zac * xabn;
  1993. m_floatdzdx = zac * yabn - zab * yacn;
  1994. m_dzdx = FixedDZ(m_floatdzdx);
  1995. }
  1996. //////////////////////////////////////////////////////////////////////////////
  1997. //
  1998. //
  1999. //
  2000. //////////////////////////////////////////////////////////////////////////////
  2001. void DrawFlatTriangle(
  2002. const VertexScreen* pva,
  2003. const VertexScreen* pvb,
  2004. const VertexScreen* pvc
  2005. ) {
  2006. SetColor(pva->color);
  2007. DrawTriangle(pva, pvb, pvc);
  2008. }
  2009. //////////////////////////////////////////////////////////////////////////////
  2010. //
  2011. //
  2012. //
  2013. //////////////////////////////////////////////////////////////////////////////
  2014. void DrawTriangle(
  2015. const VertexScreen* pva,
  2016. const VertexScreen* pvb,
  2017. const VertexScreen* pvc
  2018. ) {
  2019. //
  2020. // Get int y coordinates
  2021. //
  2022. float ya = pva->y;
  2023. float yb = pvb->y;
  2024. float yc = pvc->y;
  2025. int iya;
  2026. int iyb;
  2027. int iyc;
  2028. MakeIntMacro(ya, iya);
  2029. MakeIntMacro(yb, iyb);
  2030. MakeIntMacro(yc, iyc);
  2031. {
  2032. //
  2033. // If the triangle has zero height there is nothing to draw.
  2034. //
  2035. int idyab = (iyb - iya);
  2036. int idyac = (iyc - iya);
  2037. int idybc = (iyc - iyb);
  2038. if (idyab == 0 && idyac == 0 && idybc == 0) {
  2039. return;
  2040. }
  2041. }
  2042. //
  2043. // Get int x coordinates
  2044. //
  2045. {
  2046. float xa = pva->x;
  2047. float xb = pvb->x;
  2048. float xc = pvc->x;
  2049. int ixa;
  2050. int ixb;
  2051. int ixc;
  2052. MakeIntMacro(xa, ixa);
  2053. MakeIntMacro(xb, ixb);
  2054. MakeIntMacro(xc, ixc);
  2055. int idxab = (ixb - ixa);
  2056. int idxac = (ixc - ixa);
  2057. int idxbc = (ixc - ixb);
  2058. //
  2059. // If the triangle has zero width there is nothing to draw.
  2060. //
  2061. if (idxab == 0 && idxac == 0 && idxbc == 0) {
  2062. return;
  2063. }
  2064. }
  2065. //
  2066. // Calculate the triangles area
  2067. //
  2068. float xab = pvb->x - pva->x;
  2069. float yab = pvb->y - pva->y;
  2070. float xac = pvc->x - pva->x;
  2071. float yac = pvc->y - pva->y;
  2072. float area = yab * xac - yac * xab;
  2073. //
  2074. // Figure out which vertex is topmost.
  2075. //
  2076. const VertexScreen* pvaDraw;
  2077. const VertexScreen* pvbDraw;
  2078. const VertexScreen* pvcDraw;
  2079. if (iya <= iyc && iya <= iyb) {
  2080. pvaDraw = pva;
  2081. pvbDraw = pvb;
  2082. pvcDraw = pvc;
  2083. } else if (iyc < iya && iyc < iyb) {
  2084. pvaDraw = pvc;
  2085. pvbDraw = pva;
  2086. pvcDraw = pvb;
  2087. int i = iya;
  2088. iya = iyc;
  2089. iyc = iyb;
  2090. iyb = i;
  2091. } else {
  2092. pvaDraw = pvb;
  2093. pvbDraw = pvc;
  2094. pvcDraw = pva;
  2095. int i = iya;
  2096. iya = iyb;
  2097. iyb = iyc;
  2098. iyc = i;
  2099. }
  2100. //
  2101. // If area is negative switch from ccw to cw
  2102. //
  2103. if (GreaterZero(area)) {
  2104. if (m_cullMode == CullModeCCW) {
  2105. return;
  2106. }
  2107. m_pixels += area;
  2108. } else {
  2109. if (m_cullMode == CullModeCW) {
  2110. return;
  2111. }
  2112. m_pixels -= area;
  2113. swap(pvbDraw, pvcDraw);
  2114. swap(iyb, iyc);
  2115. }
  2116. //
  2117. // Calculate the interpolants
  2118. //
  2119. float qarea = 1 / area;
  2120. float xabn = xab * qarea;
  2121. float yabn = yab * qarea;
  2122. float xacn = xac * qarea;
  2123. float yacn = yac * qarea;
  2124. CalculateInterpolants(pva, pvb, pvc, xabn, yabn, xacn, yacn);
  2125. //
  2126. // Draw the subtriangles
  2127. //
  2128. if (iya == iyb) {
  2129. CalcXMin(pvbDraw, pvcDraw, iyb);
  2130. CalcXMax(pvaDraw, pvcDraw, iya);
  2131. (this->*m_pfnFillSubTriangle)(iyb, iyc);
  2132. } else if (iya == iyc) {
  2133. CalcXMin(pvaDraw, pvbDraw, iya);
  2134. CalcXMax(pvcDraw, pvbDraw, iyc);
  2135. (this->*m_pfnFillSubTriangle)(iya, iyb);
  2136. } else if (iyb == iyc) {
  2137. CalcXMin(pvaDraw, pvbDraw, iya);
  2138. CalcXMax(pvaDraw, pvcDraw, iya);
  2139. (this->*m_pfnFillSubTriangle)(iya, iyb);
  2140. } else if (iyb < iyc) {
  2141. CalcXMin(pvaDraw, pvbDraw, iya);
  2142. CalcXMax(pvaDraw, pvcDraw, iya);
  2143. (this->*m_pfnFillSubTriangle)(iya, iyb);
  2144. CalcXMin(pvbDraw, pvcDraw, iyb);
  2145. (this->*m_pfnFillSubTriangle)(iyb, iyc);
  2146. } else {
  2147. CalcXMin(pvaDraw, pvbDraw, iya);
  2148. CalcXMax(pvaDraw, pvcDraw, iya);
  2149. (this->*m_pfnFillSubTriangle)(iya, iyc);
  2150. CalcXMax(pvcDraw, pvbDraw, iyc);
  2151. (this->*m_pfnFillSubTriangle)(iyc, iyb);
  2152. }
  2153. }
  2154. //////////////////////////////////////////////////////////////////////////////
  2155. //
  2156. //
  2157. //
  2158. //////////////////////////////////////////////////////////////////////////////
  2159. void DrawLine(
  2160. const VertexScreen* pva,
  2161. const VertexScreen* pvb
  2162. ) {
  2163. ZAssert(pva->color == pvb->color);
  2164. //
  2165. // snap to pixel centers
  2166. //
  2167. int xstart = FloorInt(pva->x);
  2168. int ystart = FloorInt(pva->y);
  2169. int xend = FloorInt(pvb->x);
  2170. int yend = FloorInt(pvb->y);
  2171. int xdelta = xend - xstart;
  2172. int ydelta = yend - ystart;
  2173. int error;
  2174. int ddestMajor;
  2175. int ddestMinor;
  2176. int derrorMajor;
  2177. int derrorMinor;
  2178. int count;
  2179. if (abs(xdelta) >= abs(ydelta)) {
  2180. //
  2181. // Handle zero sized lines
  2182. //
  2183. if (xdelta == 0) {
  2184. return;
  2185. }
  2186. //
  2187. // Mostly horizontal line
  2188. //
  2189. count = abs(xdelta);
  2190. if (ydelta > 0) {
  2191. ddestMinor = m_pitchSurface;
  2192. derrorMajor = ydelta;
  2193. } else {
  2194. ddestMinor = -int(m_pitchSurface);
  2195. derrorMajor = -ydelta;
  2196. }
  2197. if (xdelta > 0) {
  2198. ddestMajor = 2;
  2199. derrorMinor = -xdelta;
  2200. error = -xdelta / 2;
  2201. } else {
  2202. ddestMajor = -2;
  2203. derrorMinor = xdelta;
  2204. error = xdelta / 2;
  2205. }
  2206. } else {
  2207. //
  2208. // Mostly Vertical line.
  2209. //
  2210. count = abs(ydelta);
  2211. if (xdelta > 0) {
  2212. ddestMinor = 2;
  2213. derrorMajor = xdelta;
  2214. } else {
  2215. ddestMinor = -2;
  2216. derrorMajor = -xdelta;
  2217. }
  2218. if (ydelta > 0) {
  2219. ddestMajor = m_pitchSurface;
  2220. derrorMinor = -ydelta;
  2221. error = -ydelta / 2;
  2222. } else {
  2223. ddestMajor = -int(m_pitchSurface);
  2224. derrorMinor = ydelta;
  2225. error = ydelta / 2;
  2226. }
  2227. }
  2228. //
  2229. // Minor steps include major steps
  2230. //
  2231. derrorMinor += derrorMajor;
  2232. ddestMinor += ddestMajor;
  2233. //
  2234. // Draw the pixels
  2235. //
  2236. if (count > 0) {
  2237. //
  2238. // Get a pixel value from a D3DColor
  2239. //
  2240. WORD pixel;
  2241. if (m_b565) {
  2242. pixel =
  2243. (WORD)(
  2244. ((pva->color >> 8) & 0xf800)
  2245. | ((pva->color >> 5) & 0x07e0)
  2246. | ((pva->color >> 3) & 0x001f)
  2247. );
  2248. } else {
  2249. pixel =
  2250. (WORD)(
  2251. ((pva->color >> 9) & 0x7c00)
  2252. | ((pva->color >> 6) & 0x03e0)
  2253. | ((pva->color >> 3) & 0x001f)
  2254. );
  2255. }
  2256. //
  2257. // Pre make the first major step
  2258. //
  2259. error += derrorMajor;
  2260. //
  2261. // Starting address
  2262. //
  2263. BYTE* pdest =
  2264. m_pbSurface
  2265. + xstart * 2
  2266. + ystart * m_pitchSurface;
  2267. //
  2268. // Loop through the pixels
  2269. //
  2270. do {
  2271. *(WORD*)pdest = pixel;
  2272. if (error > 0) {
  2273. pdest += ddestMinor;
  2274. error += derrorMinor;
  2275. } else {
  2276. pdest += ddestMajor;
  2277. error += derrorMajor;
  2278. }
  2279. count--;
  2280. } while (count > 0);
  2281. }
  2282. }
  2283. //////////////////////////////////////////////////////////////////////////////
  2284. //
  2285. // This code is subpixel accurate but sometimes doesn't draw the last pixel when it should
  2286. //
  2287. //////////////////////////////////////////////////////////////////////////////
  2288. /*
  2289. void DrawLine(
  2290. const VertexScreen* pva,
  2291. const VertexScreen* pvb
  2292. ) {
  2293. ZAssert(pva->color == pvb->color);
  2294. WORD color = WORD(pva->color);
  2295. float xdelta = pvb->x - pva->x;
  2296. float ydelta = pvb->y - pva->y;
  2297. if (abs(xdelta) >= abs(ydelta)) {
  2298. //
  2299. // Handle zero sized line.
  2300. //
  2301. if (xdelta == 0.0f) {
  2302. return;
  2303. }
  2304. //
  2305. // Mostly horizontal line
  2306. //
  2307. int xstart = FloorInt(pva->x);
  2308. int xend = FloorInt(pvb->x);
  2309. int ystart = FloorInt(pva->y);
  2310. int ddestdx;
  2311. int ddestdy;
  2312. if (xend > xstart) {
  2313. ddestdx = 2;
  2314. } else {
  2315. ddestdx = -2;
  2316. xdelta = -xdelta;
  2317. }
  2318. float slope = ydelta / xdelta;
  2319. float e;
  2320. if (slope == 0) {
  2321. e = 0;
  2322. } else {
  2323. //
  2324. // x distance from end point to starting pixel center
  2325. //
  2326. float xdeltaCenter = (float(xstart) + 0.5f - pva->x);
  2327. //
  2328. // y intercept of pixel x center line
  2329. //
  2330. float ycenter = pva->y + slope * xdeltaCenter;
  2331. //
  2332. // error
  2333. //
  2334. if (slope > 0) {
  2335. //
  2336. // error = distance of intercept from pixel max
  2337. //
  2338. e = ycenter - (float(ystart) + 1.0f);
  2339. ddestdy = m_pitchSurface;
  2340. } else {
  2341. //
  2342. // error = distance of intercept from pixel min
  2343. //
  2344. e = float(ystart) - ycenter;
  2345. slope = -slope;
  2346. ddestdy = -FloorInt(m_pitchSurface);
  2347. }
  2348. }
  2349. //
  2350. // Draw the pixels
  2351. //
  2352. BYTE* pdest =
  2353. m_pbSurface
  2354. + xstart * 2
  2355. + ystart * m_pitchSurface;
  2356. int count = abs(xend - xstart);
  2357. while (count > 0) {
  2358. *(WORD*)pdest = color;
  2359. pdest += ddestdx;
  2360. e += slope;
  2361. if (e > 0) {
  2362. pdest += ddestdy;
  2363. e -= 1;
  2364. }
  2365. count--;
  2366. }
  2367. } else {
  2368. //
  2369. // Mostly Vertical line.
  2370. //
  2371. int xstart = FloorInt(pva->x);
  2372. int ystart = FloorInt(pva->y);
  2373. int yend = FloorInt(pvb->y);
  2374. int ddestdx;
  2375. int ddestdy;
  2376. if (yend > ystart) {
  2377. ddestdy = m_pitchSurface;
  2378. } else {
  2379. ddestdy = -FloorInt(m_pitchSurface);
  2380. ydelta = -ydelta;
  2381. }
  2382. float slope = xdelta / ydelta;
  2383. float e;
  2384. if (slope == 0) {
  2385. e = 0;
  2386. } else {
  2387. //
  2388. // y distance from end point to starting pixel center
  2389. //
  2390. float ydeltaCenter = (float(ystart) + 0.5f - pva->y);
  2391. //
  2392. // x intercept of pixel x center line
  2393. //
  2394. float xcenter = pva->x + slope * ydeltaCenter;
  2395. //
  2396. // error
  2397. //
  2398. if (slope > 0) {
  2399. //
  2400. // error = distance of intercept from pixel max
  2401. //
  2402. e = xcenter - (float(xstart) + 1.0f);
  2403. ddestdx = 2;
  2404. } else {
  2405. //
  2406. // error = distance of intercept from pixel min
  2407. //
  2408. e = float(xstart) - xcenter;
  2409. slope = -slope;
  2410. ddestdx = -2;
  2411. }
  2412. }
  2413. //
  2414. // Draw the pixels
  2415. //
  2416. BYTE* pdest =
  2417. m_pbSurface
  2418. + xstart * 2
  2419. + ystart * m_pitchSurface;
  2420. int count = abs(yend - ystart);
  2421. while (count > 0) {
  2422. *(WORD*)pdest = color;
  2423. pdest += ddestdy;
  2424. e += slope;
  2425. if (e > 0) {
  2426. pdest += ddestdx;
  2427. e -= 1;
  2428. }
  2429. count--;
  2430. }
  2431. }
  2432. }
  2433. */
  2434. //////////////////////////////////////////////////////////////////////////////
  2435. //
  2436. //
  2437. //
  2438. //////////////////////////////////////////////////////////////////////////////
  2439. void DrawPoint(
  2440. const VertexScreen* pva
  2441. ) {
  2442. }
  2443. //////////////////////////////////////////////////////////////////////////////
  2444. //
  2445. //
  2446. //
  2447. //////////////////////////////////////////////////////////////////////////////
  2448. bool ShouldZTest()
  2449. {
  2450. return (m_pbZBuffer != NULL) && m_bZTest;
  2451. }
  2452. bool ShouldZWrite()
  2453. {
  2454. return (m_pbZBuffer != NULL) && m_bZWrite;
  2455. }
  2456. void UpdatePointers()
  2457. {
  2458. if (m_bUpdatePointers) {
  2459. m_bUpdatePointers = false;
  2460. //
  2461. // Primitives
  2462. //
  2463. m_pfnDrawTriangle = DrawTriangle;
  2464. m_pfnDrawLine = DrawLine;
  2465. m_pfnDrawPoint = DrawPoint;
  2466. switch (m_shadeMode) {
  2467. case ShadeModeFlat:
  2468. m_pfnDrawTriangle = DrawFlatTriangle;
  2469. break;
  2470. case ShadeModeNone:
  2471. case ShadeModeCopy:
  2472. case ShadeModeGouraud:
  2473. m_pfnDrawTriangle = DrawTriangle;
  2474. break;
  2475. }
  2476. //
  2477. // Is ColorKey on?
  2478. //
  2479. m_bColorKeyOn =
  2480. m_bColorKeyEnabled
  2481. && m_psurfaceTexture != NULL
  2482. && m_psurfaceTexture->HasColorKey();
  2483. if (m_bColorKeyOn) {
  2484. ZAssert(m_psurfaceTexture->GetColorKey() == Color::Black());
  2485. }
  2486. //
  2487. // Subtriangles
  2488. //
  2489. m_passCount = 0;
  2490. if (m_shadeMode == ShadeModeNone) {
  2491. m_pfnFillSubTriangle = FillSubTriangleNoop;
  2492. return;
  2493. } else if (m_psurfaceTexture == NULL) {
  2494. if (
  2495. m_blendMode == BlendModeSourceAlpha
  2496. && m_shadeMode == ShadeModeFlat
  2497. && !ShouldZTest()
  2498. && !ShouldZWrite()
  2499. && m_b565
  2500. ) {
  2501. m_pfnFillSubTriangle = FillSubTriangleMultiPass;
  2502. m_ppfnFillChunk[m_passCount++] = FlatBlend1InvA;
  2503. return;
  2504. }
  2505. } else if (
  2506. (m_pbZBuffer != NULL)
  2507. && ShouldZTest()
  2508. && ShouldZWrite()
  2509. && m_b565
  2510. ) {
  2511. //
  2512. // Fast paths
  2513. //
  2514. m_pfnFillSubTriangle = FillSubTriangleMultiPass;
  2515. if (m_blendMode == BlendModeSource) {
  2516. if (m_shadeMode == ShadeModeCopy) {
  2517. m_pfnFillSubTriangle = FillSubTriangleTextureZTestZWriteAndColorKey;
  2518. } else {
  2519. //
  2520. // Multi pass
  2521. //
  2522. switch (m_shadeMode) {
  2523. case ShadeModeFlat:
  2524. if (m_bColorKeyOn) {
  2525. m_ppfnFillChunk[m_passCount++] = CopyTextureZTestZWriteFlatAndColorKey;
  2526. } else {
  2527. m_ppfnFillChunk[m_passCount++] = CopyTextureZTestZWriteFlat;
  2528. }
  2529. break;
  2530. case ShadeModeGouraud:
  2531. if (m_bColorKeyOn) {
  2532. m_ppfnFillChunk[m_passCount++] = CopyTextureZTestZWriteGouraudAndColorKey;
  2533. } else {
  2534. m_ppfnFillChunk[m_passCount++] = CopyTextureZTestZWriteGouraud;
  2535. }
  2536. break;
  2537. default:
  2538. ZBadCase();
  2539. }
  2540. }
  2541. return;
  2542. } else if (m_blendMode == BlendModeAdd) {
  2543. switch (m_shadeMode) {
  2544. case ShadeModeCopy:
  2545. m_ppfnFillChunk[m_passCount++] = CopyTextureZTestZWriteBlend11;
  2546. return;
  2547. case ShadeModeFlat:
  2548. if (m_bColorKeyOn) {
  2549. m_ppfnFillChunk[m_passCount++] = FlatTextureZTestZWriteBlend11;
  2550. return;
  2551. }
  2552. }
  2553. }
  2554. }
  2555. //
  2556. // Chunked multi pass
  2557. //
  2558. m_pfnFillSubTriangle = FillSubTriangleMultiPassChunk;
  2559. //
  2560. // ZTest
  2561. //
  2562. if (ShouldZTest()) {
  2563. m_ppfnFillChunk[m_passCount++] = ZTest;
  2564. }
  2565. //
  2566. // Source color
  2567. //
  2568. if (m_psurfaceTexture) {
  2569. //
  2570. // Texture
  2571. //
  2572. m_ppfnFillChunk[m_passCount++] = LoadColor565Texture;
  2573. //
  2574. // Color key
  2575. //
  2576. if (m_bColorKeyOn) {
  2577. m_ppfnFillChunk[m_passCount++] = ColorKeyTest;
  2578. }
  2579. //
  2580. // Shading
  2581. //
  2582. switch (m_shadeMode) {
  2583. case ShadeModeCopy:
  2584. break;
  2585. case ShadeModeFlat:
  2586. m_ppfnFillChunk[m_passCount++] = FlatShade;
  2587. break;
  2588. case ShadeModeGouraud:
  2589. case ShadeModeGlobalColor:
  2590. m_ppfnFillChunk[m_passCount++] = GouraudShade;
  2591. break;
  2592. }
  2593. } else {
  2594. //
  2595. // No texture shading
  2596. //
  2597. switch (m_shadeMode) {
  2598. case ShadeModeGlobalColor:
  2599. // !!! ZUnimplemented();
  2600. // fall through to flat shading
  2601. case ShadeModeCopy:
  2602. case ShadeModeFlat:
  2603. m_ppfnFillChunk[m_passCount++] = LoadFlatColor;
  2604. break;
  2605. case ShadeModeGouraud:
  2606. m_ppfnFillChunk[m_passCount++] = LoadGouraudColor;
  2607. break;
  2608. }
  2609. }
  2610. //
  2611. // Alpha Blending
  2612. //
  2613. if (
  2614. m_blendMode == BlendModeAdd
  2615. || m_blendMode == BlendModeSourceAlpha
  2616. ) {
  2617. if (m_b565) {
  2618. m_ppfnFillChunk[m_passCount++] = Load565Dest;
  2619. } else {
  2620. m_ppfnFillChunk[m_passCount++] = Load555Dest;
  2621. }
  2622. if (m_blendMode == BlendModeAdd) {
  2623. m_ppfnFillChunk[m_passCount++] = Blend11;
  2624. } else {
  2625. m_ppfnFillChunk[m_passCount++] = Blend1InvA;
  2626. }
  2627. };
  2628. //
  2629. // Pixel store
  2630. //
  2631. if (m_b565) {
  2632. m_ppfnFillChunk[m_passCount++] = CopyToColor565Destination;
  2633. } else {
  2634. m_ppfnFillChunk[m_passCount++] = CopyToColor555Destination;
  2635. }
  2636. //
  2637. // ZWrite
  2638. //
  2639. if (ShouldZWrite()) {
  2640. m_ppfnFillChunk[m_passCount++] = ZWrite;
  2641. }
  2642. ZAssert(m_passCount <= MaxChunkPasses);
  2643. }
  2644. }
  2645. //////////////////////////////////////////////////////////////////////////////
  2646. //
  2647. // Debug
  2648. //
  2649. //////////////////////////////////////////////////////////////////////////////
  2650. void CheckVertices(const VertexScreen* pvertex, int vcount)
  2651. {
  2652. /*
  2653. #ifdef _DEBUG
  2654. {
  2655. float error = 0.5f;
  2656. for (int index = 0; index < vcount; index++) {
  2657. ZAssert(pvertex[index].x >= m_rectClip.XMin() - error);
  2658. ZAssert(pvertex[index].x <= m_rectClip.XMax() + error);
  2659. ZAssert(pvertex[index].y >= m_rectClip.YMin() - error);
  2660. ZAssert(pvertex[index].y <= m_rectClip.YMax() + error);
  2661. ZAssert(pvertex[index].z >= 0.0f - error);
  2662. ZAssert(pvertex[index].z <= 1.0f + error);
  2663. }
  2664. }
  2665. #endif
  2666. */
  2667. VertexScreen* pcheck = (VertexScreen*)pvertex;
  2668. for (int index = 0; index < vcount; index++) {
  2669. if (pcheck[index].x < m_rectClip.XMin()) {
  2670. pcheck[index].x = m_rectClip.XMin();
  2671. } else if (pcheck[index].x > m_rectClip.XMax()) {
  2672. pcheck[index].x = m_rectClip.XMax();
  2673. }
  2674. if (pcheck[index].y < m_rectClip.YMin()) {
  2675. pcheck[index].y = m_rectClip.YMin();
  2676. } else if (pcheck[index].y > m_rectClip.YMax()) {
  2677. pcheck[index].y = m_rectClip.YMax();
  2678. }
  2679. if (pcheck[index].z < 0) {
  2680. pcheck[index].z = 0;
  2681. } else if (pcheck[index].z > 1) {
  2682. pcheck[index].z = 1;
  2683. }
  2684. }
  2685. }
  2686. void CheckIndices(const WORD* pindex, int icount, int vcount)
  2687. {
  2688. #ifdef _DEBUG
  2689. for (int index = 0; index < icount; index++) {
  2690. ZAssert(pindex[index] >=0 && pindex[index] < vcount);
  2691. }
  2692. #endif
  2693. }
  2694. //////////////////////////////////////////////////////////////////////////////
  2695. //
  2696. // Rendering
  2697. //
  2698. //////////////////////////////////////////////////////////////////////////////
  2699. void DrawTriangles(const VertexScreen* pvertex, int vcount, const WORD* pindex, int icount)
  2700. {
  2701. InitializeControlWord();
  2702. CheckVertices(pvertex, vcount);
  2703. CheckIndices(pindex, icount, vcount);
  2704. UpdatePointers();
  2705. for(int index = 0; index < icount; index += 3) {
  2706. (this->*m_pfnDrawTriangle)(
  2707. &(pvertex[pindex[index ]]),
  2708. &(pvertex[pindex[index + 1]]),
  2709. &(pvertex[pindex[index + 2]])
  2710. );
  2711. }
  2712. RestoreControlWord();
  2713. }
  2714. void DrawLines(const VertexScreen* pvertex, int vcount, const WORD* pindex, int icount)
  2715. {
  2716. InitializeControlWord();
  2717. CheckVertices(pvertex, vcount);
  2718. CheckIndices(pindex, icount, vcount);
  2719. UpdatePointers();
  2720. for(int index = 0; index < icount; index += 2) {
  2721. (this->*m_pfnDrawLine)(
  2722. &(pvertex[pindex[index ]]),
  2723. &(pvertex[pindex[index + 1]])
  2724. );
  2725. }
  2726. }
  2727. void DrawPoints(const VertexScreen* pvertex, int vcount)
  2728. {
  2729. CheckVertices(pvertex, vcount);
  2730. if (m_b565) {
  2731. // 565
  2732. for (int index = 0; index < vcount; index++) {
  2733. BYTE* ppixel =
  2734. m_pbSurface
  2735. + FloorInt(pvertex[index].x) * 2
  2736. + FloorInt(pvertex[index].y) * m_pitchSurface;
  2737. DWORD color = pvertex[index].color;
  2738. WORD pixel =
  2739. (WORD)(
  2740. ((color >> 8) & 0xf800)
  2741. | ((color >> 5) & 0x07e0)
  2742. | ((color >> 3) & 0x001f)
  2743. );
  2744. *(WORD*)(ppixel) = pixel;
  2745. }
  2746. } else {
  2747. // 555
  2748. for (int index = 0; index < vcount; index++) {
  2749. BYTE* ppixel =
  2750. m_pbSurface
  2751. + FloorInt(pvertex[index].x) * 2
  2752. + FloorInt(pvertex[index].y) * m_pitchSurface;
  2753. DWORD color = pvertex[index].color;
  2754. WORD
  2755. pixel =
  2756. (WORD)(
  2757. ((color >> 9) & 0x7c00)
  2758. | ((color >> 6) & 0x03e0)
  2759. | ((color >> 3) & 0x001f)
  2760. );
  2761. *(WORD*)(ppixel) = pixel;
  2762. }
  2763. }
  2764. }
  2765. };
  2766. TRef<Rasterizer> CreateSoftwareRasterizer(PrivateSurface* psurface)
  2767. {
  2768. return new SoftwareRasterizer(psurface);
  2769. }