DRAWSHP.ASM 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;***************************************************************************
  19. ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : WWLIB32 *
  23. ;* *
  24. ;* File Name : DRAWSHP.ASM *
  25. ;* *
  26. ;* Programmer : Phil W. Gorrow *
  27. ;* *
  28. ;* Start Date : April 13, 1992 *
  29. ;* *
  30. ;* Last Update : September 14, 1994 [IML] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* Draw_Shape -- Draws a shape at given buffer coordinates and clips *
  35. ;* Not_Supported -- Replacement function for Draw_Shape routines not used*
  36. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  37. ;********************* Model & Processor Directives ************************
  38. IDEAL
  39. P386
  40. MODEL USE32 FLAT
  41. ; this struct is here to remove the hardwire way of programing
  42. ; implemented in the funtion Draw_Shape in ian image of
  43. STRUC VVPC_IMAGE
  44. Off dd ?
  45. Width dd ?
  46. Height dd ?
  47. Page dd ?
  48. ENDS
  49. STRUC GVPC_IMAGE
  50. vvpc VVPC_IMAGE <>
  51. Xpos dd ?
  52. Ypos dd ?
  53. GraphicBuff dd ?
  54. ENDS
  55. ;******************************** Includes *********************************
  56. INCLUDE "shape.inc"
  57. ;****************************** Declarations ********************************
  58. GLOBAL Draw_Shape:NEAR
  59. GLOBAL LCW_Uncompress:NEAR
  60. GLOBAL _ShapeBuffer:DWORD
  61. GLOBAL _ShapeBufferSize:DWORD
  62. GLOBAL MaskPage : dword
  63. GLOBAL BackGroundPage : dword
  64. ;********************************* Data ************************************
  65. DATASEG
  66. ;---------------------------------------------------------------------------
  67. ; Shape buffer & its size, set by Set_Shape_Buffer()
  68. ;---------------------------------------------------------------------------
  69. _ShapeBuffer DD 0
  70. _ShapeBufferSize DD 0
  71. ;---------------------------------------------------------------------------
  72. ; Address of MaskPage & BackGroundPage, set by Init_Priority_System()
  73. ;---------------------------------------------------------------------------
  74. MaskPage DD 0
  75. BackGroundPage DD 0
  76. ;---------------------------------------------------------------------------
  77. ; Predator effect variables
  78. ;---------------------------------------------------------------------------
  79. PredCount DD 0
  80. PredTable DB 1, 3, 2, 5, 4, 3, 2, 1
  81. PredValue DD 1
  82. PartialPred DD 0 ; partially faded predator effect value
  83. PartialCount DD 0
  84. ;---------------------------------------------------------------------------
  85. ; 32 bit versions of 16 bit stack variables
  86. ;---------------------------------------------------------------------------
  87. Flags DD ? ; globally accessible copy of flags
  88. viewport_ptr DD ? ; pointer to upper-left corner of viewport
  89. viewport_width DD ? ; viewport width
  90. viewport_height DD ? ; viewport height
  91. viewport_yadd DD ? ; viewport y add
  92. viewport_x DD ? ; viewport x-coord
  93. viewport_y DD ? ; viewport y-coord
  94. buff_ptr DD ? ; pointer to buffer containing viewport
  95. ;********************************* Code ************************************
  96. CODESEG
  97. ;***************************************************************************
  98. ;* Draw_Shape -- Draws a shape at given buffer coordinates and clips *
  99. ;* *
  100. ;* INPUT: *
  101. ;* DWORD gvp_ptr ; pointer to graphic viewport info *
  102. ;* DWORD shape_ptr ; the shape pointer to draw *
  103. ;* DWORD draw_x ; x-coord of hotspot in viewport *
  104. ;* DWORD draw_y ; y-coord of hotspot in viewport *
  105. ;* DWORD flags ; the flags for drawing the shape *
  106. ;* *
  107. ;* Optional Arguments: If the following flags are used, the given args *
  108. ;* MUST be present. Note that, if more than one one set of args is used, *
  109. ;* they must appear in this order (alphabetical). *
  110. ;* SHAPE_COLOR: DWORD color_table (256 bytes) *
  111. ;* SHAPE_FADING: DWORD fade_table (256 bytes), DWORD fade_count *
  112. ;* SHAPE_GHOST: DWORD is_translucent tbl, DWORD translucent tbl *
  113. ;* SHAPE_PARTIAL: DWORD predator partial_value (0-255) *
  114. ;* SHAPE_PRIORITY: DWORD priority_level *
  115. ;* SHAPE_SCALING: DWORD x_scale, WORD y_scale *
  116. ;* SHAPE_SHADOW: DWORD shadowing_table (256 bytes) *
  117. ;* *
  118. ;* OUTPUT: *
  119. ;* none. *
  120. ;* *
  121. ;* WARNINGS: *
  122. ;* none. *
  123. ;* *
  124. ;*-------------------------------------------------------------------------*
  125. ;* *
  126. ;* File Organization: *
  127. ;* drawshp.asm : this file *
  128. ;* shape.inc : main shape header file; contains declarations for all *
  129. ;* globals, procedures and constants *
  130. ;* ds_table.asm: contains the procedure address tables for LSkipRout, *
  131. ;* RSkipRout, DrawRout, & PixelRout *
  132. ;* ds_l*.asm : left-skip routines *
  133. ;* ds_r*.asm : right-skip routines *
  134. ;* ds_d*.asm : drawing routines *
  135. ;* *
  136. ;*-------------------------------------------------------------------------*
  137. ;* *
  138. ;* Shape format: *
  139. ;* Header: *
  140. ;* UWORD SType (0=normal, 1=16-color, 2=uncompressed, 4=variable-color) *
  141. ;* UBYTE Height *
  142. ;* UWORD Width *
  143. ;* UBYTE unmodified height *
  144. ;* UWORD size of shape in memory, including this header *
  145. ;* UWORD uncompressed data size *
  146. ;* Normal Shape: *
  147. ;* UBYTE [compressed] Shape data *
  148. ;* 16-color shape: *
  149. ;* UBYTE 16-color table *
  150. ;* UBYTE [compressed] Shape data *
  151. ;* variable-color shape: *
  152. ;* UBYTE # colors *
  153. ;* UBYTE color table (variable-length) *
  154. ;* UBYTE [compressed] Shape data *
  155. ;* *
  156. ;*-------------------------------------------------------------------------*
  157. ;* *
  158. ;* Uncompressed shape data format: *
  159. ;* Data is stored as a bitmap, with 0's treated as a special case. Every *
  160. ;* 0 byte is followed by a repetition count byte. Every scan line is *
  161. ;* compressed separately. Thus, the following bitmap results in the *
  162. ;* following shape data: *
  163. ;* 0 0 0 5 6 7 0 0 0 0 *
  164. ;* 0 0 0 5 6 7 0 0 0 0 *
  165. ;* 0 0 0 5 6 7 0 0 0 0 *
  166. ;* *
  167. ;* 0 3 5 6 7 0 4 *
  168. ;* 0 3 5 6 7 0 4 *
  169. ;* 0 3 5 6 7 0 4 *
  170. ;* *
  171. ;*-------------------------------------------------------------------------*
  172. ;* *
  173. ;* How scaling is handled: *
  174. ;* Scaling is done by accumulating the x & y scale values. When the high *
  175. ;* byte of the accumulated value is set, the pixel (for x-scaling) or *
  176. ;* the line (for y-scaling) is drawn. The high byte is then cleared, *
  177. ;* and the low byte is left so roundoffs continue to accumulate. *
  178. ;* *
  179. ;*-------------------------------------------------------------------------*
  180. ;* *
  181. ;* Drawing Procedures: *
  182. ;* *
  183. ;*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
  184. ;* *
  185. ;* RSkipRout: skips given # bytes of data on the right-hand side of a *
  186. ;* shape. Just has to handle changing the current byte offset in the *
  187. ;* shape data buffer, since the draw routine knows where the left-hand *
  188. ;* side of the drawable region is. The routine may skip more bytes than *
  189. ;* it was told if it encounters a run of 0's, but it's assumed that a *
  190. ;* run of 0's will never go past the right edge of a shape. *
  191. ;* Input: *
  192. ;* ECX - number of uncompressed bytes to skip *
  193. ;* ESI - shape buffer data address *
  194. ;* Output: *
  195. ;* ECX - negative # bytes overrun, or 0 *
  196. ;* ESI - updated to the current location in the shape data *
  197. ;* *
  198. ;*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
  199. ;* *
  200. ;* LSkipRout: skips given # bytes of data on the left-hand side of a *
  201. ;* shape. This routine must update the shape data byte offset, and it *
  202. ;* must properly update the current drawing position due to scaling, so *
  203. ;* it's a little more involved than the RSkip routine. The routine may *
  204. ;* skip more bytes than it's told if it encounters a run of 0's. If this *
  205. ;* happens, the draw routine must take these extra bytes into *
  206. ;* consideration. *
  207. ;* Input: *
  208. ;* ECX = number of uncompressed bytes to skip *
  209. ;* ESI = shape (source) buffer data address *
  210. ;* EDI = viewport (destination) address *
  211. ;* [WidthCount] = shape's width in bytes *
  212. ;* Output: *
  213. ;* ECX - negative # pixels (not bytes) overrun, or 0 *
  214. ;* EDX - accumulated XTotal value at new pixel location *
  215. ;* ESI - updated to the current location in the shape data *
  216. ;* EDI - incr/decr by # pixels (not bytes) overrun *
  217. ;* [WidthCount] - decremented by # bytes skipped *
  218. ;* *
  219. ;*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*
  220. ;* *
  221. ;* DrawRout: draws one row of pixels, handles scaling, reversal and *
  222. ;* any per pixel effects like predator, shadow etc. *
  223. ;* EDX must be set up as follows: *
  224. ;* - No scaling: 0 *
  225. ;* - No left-clipping: 0 *
  226. ;* - Left clipping, but no overrun: set to computed initial value for *
  227. ;* that viewport coordinate *
  228. ;* - Left clipping, with overrun: set to XTotal value for that coordinate *
  229. ;* In any case, only the low byte of DL should contain data; the current *
  230. ;* byte in the shapebuffer should always be the first drawable pixel, *
  231. ;* even if it's partially clipped (in which case DL will contain data). *
  232. ;* Input: *
  233. ;* ECX = number of pixels (not bytes) to draw *
  234. ;* EDX = XTotal initializer value *
  235. ;* ESI = shape (source) buffer address *
  236. ;* EDI = viewport (destination) address *
  237. ;* [WidthCount] = remaining bytes on the line *
  238. ;* Output: *
  239. ;* ESI - updated to current location in the shape data *
  240. ;* EDI - incr/decr by # pixels (not bytes) drawn/skipped *
  241. ;* [WidthCount] - decremented by # bytes (not pixels) drawn *
  242. ;* *
  243. ;*-------------------------------------------------------------------------*
  244. ;* *
  245. ;* Algorithm: *
  246. ;* - Initialize globals *
  247. ;* - Pull optional arguments off the stack *
  248. ;* - Set up drawing procedure pointers based on drawing flags *
  249. ;* - Read the values from the shape header *
  250. ;* - Compute the shape's scaled width & height *
  251. ;* - Adjust the shape's drawing coordinates based on centering & *
  252. ;* viewport-relative flag settings *
  253. ;* - Compute the clipped areas of the shape *
  254. ;* - Compute the number of drawn pixels horizontally & vertically *
  255. ;* - Compute the starting drawing offset in the viewport *
  256. ;* - Draw the shape *
  257. ;* *
  258. ;*-------------------------------------------------------------------------*
  259. ;* *
  260. ;* HISTORY: *
  261. ;* 04/13/1992 PWG : Created. *
  262. ;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
  263. ;* 05/26/1994 BR : Converted to 32-bit, restructured quite a bit. *
  264. ;* 08/09/1994 IML : Added C++ style interface. Various optimizations. *
  265. ;* 09/06/1994 IML : Ammendments for integration of p_* and ds_* routines.*
  266. ;* 09/14/1994 IML : Now handles LCW compression. *
  267. ;*=========================================================================*
  268. PROC Draw_Shape C NEAR
  269. USES eax,ebx,ecx,edx,edi,esi
  270. ;--------------------------------------------------------------------
  271. ; Arguments:
  272. ;--------------------------------------------------------------------
  273. ARG gvp_ptr:DWORD ; pointer to graphic viewport info
  274. ARG shape_ptr:DWORD ; the shape pointer to draw
  275. ARG draw_x:DWORD ; the destination x pixel
  276. ARG draw_y:DWORD ; the destination y pixel
  277. ARG flags:DWORD ; the flags for drawing the shape
  278. IF FALSE
  279. ;--------------------------------------------------------------------
  280. ; Define the local stack variables that Draw_Shape needs. These
  281. ; parameters are defined in shape.inc. They're included here
  282. ; just for reference.
  283. ;--------------------------------------------------------------------
  284. ;
  285. ;...................... proc addresses ..............................
  286. ;
  287. LOCAL LSkipRout:DWORD ; pointer to the skip routine
  288. LOCAL RSkipRout:DWORD ; pointer to the skip routine
  289. LOCAL DrawRout:DWORD ; pointer to the draw routine
  290. ;
  291. ;.................... optional arguments ............................
  292. ;
  293. LOCAL ColorTable:DWORD ; ptr to the shapes color table
  294. LOCAL FadingTable:DWORD ; extracted fading table pointer
  295. LOCAL FadingNum:DWORD ; get the number of times to fade
  296. LOCAL IsTranslucent:DWORD ; ptr to "are we translucent?" tbl
  297. LOCAL Translucent:DWORD ; ptr to "ok we are translucent!" tbl
  298. LOCAL PriLevel:BYTE ; the priority level of the object
  299. LOCAL ScaleX:DWORD ; the x increment to scale by
  300. LOCAL ScaleY:DWORD ; the y increment to scale by
  301. LOCAL ShadowingTable:DWORD ; ptr to the shadowing table
  302. ;
  303. ;.................... Shape header values ...........................
  304. ;
  305. LOCAL ShapeType:DWORD ; shape type
  306. LOCAL ShapeWidth:DWORD ; shape's unscaled width
  307. LOCAL ShapeHeight:DWORD ; shape's unscaled height
  308. LOCAL UncompDataLen:DWORD ; uncompressed data length
  309. LOCAL ShapeData:DWORD ; pointer to [compressed] shape data
  310. ;
  311. ;.................. Scaled shape dimensions .........................
  312. ;
  313. LOCAL ScaledWidth:DWORD ; shape's scaled width
  314. LOCAL ScaledHeight:DWORD ; shape's scaled height
  315. ;
  316. ;.................. Pixel clipping variables ........................
  317. ;
  318. LOCAL LeftClipPixels:DWORD ; # left-clipped pixels
  319. LOCAL RightClipPixels:DWORD ; # right-clipped pixels
  320. LOCAL TopClipPixels:DWORD ; # top-clipped pixels
  321. LOCAL BotClipPixels:DWORD ; # bottom-clipped pixels
  322. LOCAL PixelWidth:DWORD ; width of drawable area in pixels
  323. LOCAL PixelHeight:DWORD ; height of drawable area in pixels
  324. ;
  325. ;..................... Drawing variables ............................
  326. ;
  327. LOCAL NumColors:DWORD ; # colors for 16-color shapes
  328. LOCAL StartDraw:DWORD ; ptr to starting draw position
  329. LOCAL NextLine:DWORD ; offset of next drawing line
  330. LOCAL LeftClipBytes:DWORD ; # left-clipped bytes
  331. LOCAL XTotal:DWORD ; accumulated x-pixels for scaling
  332. LOCAL XTotalInit:DWORD ; initial roundoff bits for XTotal
  333. LOCAL YTotal:DWORD ; accumulated y-pixels for scaling
  334. LOCAL HeightCount:DWORD ; height counter for drawing lines
  335. LOCAL LineStart:DWORD ; address of start of line
  336. LOCAL WidthCount:DWORD ; counts down # bytes skipped
  337. LOCAL StashReg:DWORD ; temp variable for draw routines
  338. LOCAL MaskAdjust:DWORD ; priority buffer offset
  339. LOCAL BackAdjust:DWORD ; background buffer offset
  340. LOCAL StashECX:DWORD ; temp variable for ECX register
  341. LOCAL StashEDX:DWORD ; temp variable for EDX register
  342. ENDIF
  343. ;====================================================================
  344. ; Initialization:
  345. ; - allocate space for globals
  346. ; - validate shape pointer
  347. ; - set SHAPE_COMPACT flag if needed
  348. ;====================================================================
  349. ;--------------------------------------------------------------------
  350. ; Allocate stack space for our local variables.
  351. ;--------------------------------------------------------------------
  352. LOCAL Local_Stack:BYTE:Local_Size
  353. ;--------------------------------------------------------------------
  354. ; Make sure the shape pointer is not NULL
  355. ;--------------------------------------------------------------------
  356. cmp [shape_ptr],0 ; compare shape ptr value to NULL
  357. jnz ??valid_shp ; if non-zero, it's valid
  358. jmp ??exit ; otherwise get the heck outta here
  359. ;--------------------------------------------------------------------
  360. ; Move gvp info into local variables
  361. ;--------------------------------------------------------------------
  362. ??valid_shp:
  363. mov edi,[gvp_ptr] ; get pointer to graphic viewport info
  364. mov esi, [(type GVPC_IMAGE ptr edi). vvpc . Off ] ; extract viewport pointer
  365. mov [viewport_ptr],esi
  366. mov ebx,[(type GVPC_IMAGE ptr edi) . vvpc . Width ] ; extract viewport width
  367. mov [viewport_width],ebx
  368. mov eax,[(type GVPC_IMAGE ptr edi) . vvpc . Height ] ; extract viewport height
  369. mov [viewport_height],eax
  370. mov ecx,[(type GVPC_IMAGE ptr edi) . vvpc . Page ] ; calculate y add value
  371. add ecx,ebx
  372. mov [viewport_yadd],ecx
  373. mov eax,[(type GVPC_IMAGE ptr edi) . Xpos ] ; extract viewport x-coord
  374. mov [viewport_x],eax
  375. mov eax, [(type GVPC_IMAGE ptr edi) . Ypos ] ; extract viewport y-coord
  376. mov [viewport_y],eax
  377. mul ecx ; calculate buffer pointer
  378. add eax,[viewport_x]
  379. sub esi,eax
  380. mov [buff_ptr],esi
  381. ;--------------------------------------------------------------------
  382. ; If this shape is a compact shape, set that bit in the flags arg
  383. ;--------------------------------------------------------------------
  384. mov edi,[shape_ptr] ; check for compact shape flag
  385. test [BYTE PTR edi],MAKESHAPE_COMPACT
  386. jz ??do_args ; if not process flags as is
  387. or [flags],SHAPE_COMPACT ; mark it as a compact shape
  388. ;====================================================================
  389. ; Pull off optional arguments:
  390. ; EDI is used as an offset from the 'flags' parameter, to point
  391. ; to the optional argument currently being processed.
  392. ;====================================================================
  393. ??do_args:
  394. mov edi,4 ; optional params start past flags
  395. ;--------------------------------------------------------------------
  396. ; Initialize optional argument values:
  397. ;--------------------------------------------------------------------
  398. mov [ColorTable],0 ; default = NULL
  399. mov [FadingTable],0 ; default = NULL
  400. mov [FadingNum],0 ; default = no fading
  401. mov [IsTranslucent],0 ; default = NULL
  402. mov [Translucent],0 ; default = NULL
  403. mov [PriLevel],0 ; default = no priority
  404. mov [ScaleX],100h ; default = unity X scaling
  405. mov [ScaleY],100h ; default = unity Y scaling
  406. mov [ShadowingTable],0 ; default = NULL
  407. ;--------------------------------------------------------------------
  408. ; SHAPE_COLOR: DWORD color_table[256]
  409. ;--------------------------------------------------------------------
  410. ??color:
  411. test [flags],SHAPE_COLOR ; does it have a color table
  412. jz ??fading ; if not skip to fading
  413. or [flags],SHAPE_COMPACT ; mark it as a compact shape
  414. ; (for remapping purposes only)
  415. mov eax,[flags + edi]
  416. mov [ColorTable],eax ; save address of color table
  417. add edi,4 ; point to next optional argument
  418. ;--------------------------------------------------------------------
  419. ; SHAPE_FADING: DWORD fade_table[256], DWORD fade_count
  420. ;--------------------------------------------------------------------
  421. ??fading:
  422. test [flags],SHAPE_FADING ; are we fading this shape
  423. jz ??ghost ; skip to ghosting check
  424. mov eax,[flags + edi]
  425. mov [FadingTable],eax ; save address of fading tbl
  426. mov eax,[flags + edi + 4] ; get fade num
  427. add edi,8 ; next argument
  428. cmp eax,0 ; check if it's 0
  429. jnz ??set_fading ; if not, store fade num
  430. and [flags],NOT SHAPE_FADING ; otherwise, don't fade
  431. ??set_fading:
  432. mov [FadingNum],eax
  433. ;--------------------------------------------------------------------
  434. ; SHAPE_GHOST: DWORD is_translucent tbl, DWORD translucent tbl
  435. ;--------------------------------------------------------------------
  436. ??ghost:
  437. test [flags],SHAPE_GHOST ; are we ghosting this shape
  438. jz ??init_predator ; skip to predator check
  439. mov eax,[flags + edi]
  440. mov [IsTranslucent],eax ; save ptr to is_trans. tbl
  441. mov eax,[flags + edi + 4]
  442. mov [Translucent],eax ; save ptr to translucent tbl
  443. add edi,8 ; next argument
  444. ;--------------------------------------------------------------------
  445. ; SHAPE_PREDATOR: Initialize the predator effect variables
  446. ;--------------------------------------------------------------------
  447. ??init_predator:
  448. test [flags],SHAPE_PREDATOR ; is predator effect on
  449. jz ??partial ; if not skip to partial
  450. inc [PredCount] ; the pred table is byte aligned
  451. and [PredCount],PRED_MASK ; keep entries within bounds
  452. mov eax,[PredCount]
  453. mov al,[BYTE PTR PredTable + eax]
  454. mov [PredValue],eax ; put the pred value cs
  455. mov [PartialCount],0 ; clear the partial count
  456. mov [PartialPred],100h ; init partial to off
  457. ;--------------------------------------------------------------------
  458. ; SHAPE_PARTIAL: DWORD partial_pred_value (0-255)
  459. ;--------------------------------------------------------------------
  460. ??partial:
  461. test [flags],SHAPE_PARTIAL ; is this a partial pred?
  462. jz ??priority ; if not check priority
  463. mov eax,[flags + edi] ; pull the partial value
  464. mov [PartialPred],eax ; store it off
  465. add edi,4 ; next argument
  466. ;--------------------------------------------------------------------
  467. ; SHAPE_PRIORITY: DWORD priority_level
  468. ;--------------------------------------------------------------------
  469. ??priority:
  470. test [flags],SHAPE_PRIORITY ; is this a priority draw
  471. jz ??scale ; if not skip to scale
  472. mov eax,[flags + edi]
  473. mov [PriLevel],al ; store priority level
  474. add edi,4 ; next argument
  475. mov eax,[MaskPage] ; calculate priority buffer
  476. sub eax,[buff_ptr] ; offset
  477. mov [MaskAdjust],eax
  478. mov eax,[BackGroundPage] ; calculate background buffer
  479. sub eax,[buff_ptr] ; offset
  480. mov [BackAdjust],eax
  481. ;--------------------------------------------------------------------
  482. ; SHAPE_SCALING: DWORD x_scale, WORD y_scale
  483. ;--------------------------------------------------------------------
  484. ??scale:
  485. test [flags],SHAPE_SCALING ; are we scaling this shape.
  486. jz ??shadow ; if not then skip scale y value
  487. mov eax,[flags + edi]
  488. mov [ScaleX],eax
  489. mov eax,[flags + edi + 4]
  490. mov [ScaleY],eax
  491. add edi,8 ; next argument
  492. ;--------------------------------------------------------------------
  493. ; SHAPE_SHADOW: DWORD shadow_table[256]
  494. ;--------------------------------------------------------------------
  495. ??shadow:
  496. test [flags],SHAPE_SHADOW ; are we ghosting this shape
  497. jz short ??get_header ; if not then skip
  498. mov eax,[flags + edi]
  499. mov [ShadowingTable],eax ; save address of shadow table
  500. add edi,4 ; next argument
  501. ??get_header:
  502. ;====================================================================
  503. ; Get Shape header values
  504. ;====================================================================
  505. mov esi,[shape_ptr] ; prepare to read header
  506. movzx eax,[WORD PTR esi]
  507. mov [ShapeType],eax ; extract shape type
  508. movzx eax,[BYTE PTR esi + 2]
  509. mov [ShapeHeight],eax
  510. movzx eax,[WORD PTR esi + 3] ; extract shape height
  511. mov [ShapeWidth],eax
  512. movzx eax,[WORD PTR esi + 8] ; extract uncompressed data length
  513. mov [UncompDataLen],eax
  514. add esi,10 ; reposition index
  515. ;--------------------------------------------------------------------
  516. ; Now get NumColors, ColorTable address, & data pointer:
  517. ; <16-color shape:
  518. ; shape.Colortable[0] = # colors
  519. ; shape data is after that many colors
  520. ; 16-color shape:
  521. ; shape.Colortable[] contains colors
  522. ; shape data is after those colors
  523. ; default 256-color shape:
  524. ; shape data starts at shape.Colortable[0]
  525. ; Note: ColorTable is set only if flags & SHAPE_COLOR is 0; otherwise,
  526. ; the color table was passed in & we already have a pointer to it
  527. ;--------------------------------------------------------------------
  528. ;
  529. ;....................... <16-color shape: ...........................
  530. ;
  531. test [ShapeType],MAKESHAPE_VARIABLE
  532. jz ??check_16
  533. movzx eax,[BYTE PTR esi] ; read # colors
  534. mov [NumColors],eax ; save # colors
  535. inc esi
  536. test [flags],SHAPE_COLOR ; don't set ColorTable if
  537. jnz ??norm_get_data_addr ; it was passed in
  538. mov [ColorTable],esi ; save color table pointer
  539. ??norm_get_data_addr:
  540. add esi,[NumColors] ; skip past color data
  541. mov [ShapeData],esi ; set data address
  542. jmp ??setup_procs
  543. ;....................... 16-color shape: ............................
  544. ??check_16:
  545. test [ShapeType],MAKESHAPE_COMPACT
  546. jz ??256_get_data_addr
  547. mov [NumColors],16 ; save # colors
  548. test [flags],SHAPE_COLOR ; don't set ColorTable if
  549. jnz ??16_get_data_addr ; it was passed in
  550. mov [ColorTable],esi ; save color table pointer
  551. ??16_get_data_addr:
  552. add esi,[NumColors] ; skip past color data
  553. mov [ShapeData],esi ; set data address
  554. jmp ??setup_procs
  555. ;
  556. ;....................... 256-color shape: ...........................
  557. ;
  558. ??256_get_data_addr:
  559. mov [ShapeData],esi ; set data address
  560. ;====================================================================
  561. ; Set up the drawing procedure addresses
  562. ;====================================================================
  563. ;--------------------------------------------------------------------
  564. ; This code uses HORZ_REV, VERT_REV, & SCALING flags as an
  565. ; offset into the LSkipTable, RSkipTable, and DrawTable. These
  566. ; flags combined have values from 00h-07h, so each table must have
  567. ; at least 8 entries.
  568. ;--------------------------------------------------------------------
  569. ??setup_procs:
  570. mov ebx,[flags] ; load flags value
  571. and ebx,07h ; clip high bits
  572. add ebx,ebx ; mult by 4 to get DWORD offset
  573. add ebx,ebx
  574. mov eax,[LSkipTable + ebx] ; get table value
  575. mov [LSkipRout],eax ; store it in the function pointer
  576. mov eax,[RSkipTable + ebx] ; get table value
  577. mov [RSkipRout],eax ; store it in the function pointer
  578. mov eax,[DrawTable + ebx] ; get table value
  579. mov [DrawRout],eax ; store it in the function pointer
  580. ??compute_scalevals:
  581. ;====================================================================
  582. ; Now compute scaled width & height. If the shape scales down to 0
  583. ; either horizontally or vertically, exit.
  584. ;====================================================================
  585. test [flags],SHAPE_SCALING ; skip if no scaling
  586. jz ??no_scaling
  587. ;
  588. ;........................ scaled width: .............................
  589. ;
  590. mov eax,[ShapeWidth] ; get byte width
  591. mov ebx,[ScaleX] ; prepare for register mul
  592. mul ebx ; EDX:EAX = result
  593. shrd eax,edx,8 ; EAX = result rounded down
  594. or eax,eax
  595. jz ??exit ; exit if EAX is 0
  596. mov [ScaledWidth],eax ; save the scaled width
  597. ;
  598. ;........................ scaled height: ............................
  599. ;
  600. mov eax,[ShapeHeight] ; get byte height
  601. mov ebx,[ScaleY] ; prepare for register mul
  602. mul ebx ; EDX:EAX = result
  603. shrd eax,edx,8 ; EAX = result rounded down
  604. or eax,eax
  605. jz ??exit ; exit if EAX is 0
  606. mov [ScaledHeight],eax ; save the scaled height
  607. jmp ??handle_centering
  608. ;
  609. ;......................... no scaling: ..............................
  610. ;
  611. ??no_scaling:
  612. mov eax,[ShapeWidth]
  613. mov [ScaledWidth],eax ; pixel width = byte width
  614. mov eax,[ShapeHeight]
  615. mov [ScaledHeight],eax ; pixel height = byte height
  616. ;====================================================================
  617. ; Allow for SHAPE_CENTER by adjusting the draw_x & draw_y arguments:
  618. ; draw_x -= ScaledWidth / 2
  619. ; draw_y -= ScaledHeight / 2
  620. ;====================================================================
  621. ??handle_centering:
  622. ;
  623. ;........................ adjust draw_x .............................
  624. ;
  625. test [flags],SHAPE_CENTER ; skip if not centered
  626. jz ??handle_vp_rel
  627. mov eax,[draw_x] ; load in draw_x
  628. mov edx,[ScaledWidth] ; load in ScaledWidth
  629. shr edx,1 ; divide it by 2
  630. sub eax,edx ; subract it from eax
  631. mov [draw_x],eax ; store it back into draw_x
  632. ;
  633. ;........................ adjust draw_y .............................
  634. ;
  635. mov eax,[draw_y] ; load in draw_y
  636. mov edx,[ScaledHeight] ; load in ScaledHeight
  637. shr edx,1 ; divide it by 2
  638. sub eax,edx ; subract it from eax
  639. mov [draw_y],eax ; store it back into draw_y
  640. ;====================================================================
  641. ; Allow for SHAPE_VIEWPORT_REL by adjusting draw_x & draw_y by the
  642. ; viewport's coordinates
  643. ;====================================================================
  644. ??handle_vp_rel:
  645. test [flags],SHAPE_VIEWPORT_REL ; skip if not vp-relative
  646. jz ??compute_horz_clip
  647. mov eax,[viewport_x]
  648. add [draw_x],eax ; draw_x += viewport_x
  649. mov eax,[viewport_y]
  650. add [draw_y],eax ; draw_y += viewport_y
  651. ;====================================================================
  652. ; Now that we have the scaled size and adjusted x & y drawing
  653. ; coordinates, we can compute the clipped areas of the shape:
  654. ; LeftClipPixels = viewport_x - draw_x
  655. ; - if negative, set to 0
  656. ; RightClipPixels = (draw_x + ScaledWidth) -
  657. ; (viewport_x + viewport_width)
  658. ; - if negative, set to 0
  659. ;
  660. ; TopClipPixels = viewport_y - draw_y
  661. ; - if negative, set to 0
  662. ; BotClipPixels = (draw_y + ScaledHeight) -
  663. ; (viewport_y + viewport_height)
  664. ; - if negative, set to 0
  665. ;====================================================================
  666. ??compute_horz_clip:
  667. ;
  668. ;...................... left-clipped pixels .........................
  669. ;
  670. mov eax,[viewport_x]
  671. sub eax,[draw_x] ; EAX = viewport_x - draw_x
  672. jge ??set_left_clip
  673. mov eax,0 ; if EAX<0, set to 0
  674. ??set_left_clip:
  675. mov [LeftClipPixels],eax ; store # left-clipped pixels
  676. ;
  677. ;...................... right-clipped pixels ........................
  678. ;
  679. mov eax,[draw_x]
  680. add eax,[ScaledWidth] ; EAX = draw_x + ScaledWidth
  681. mov edx,[viewport_x]
  682. add edx,[viewport_width] ; EDX = viewport_x + viewport_width
  683. sub eax,edx
  684. jge ??set_right_clip
  685. mov eax,0 ; if EAX<0, set to 0
  686. ??set_right_clip:
  687. mov [RightClipPixels],eax ; store # right-clipped pixels
  688. ;
  689. ;...................... top-clipped pixels ..........................
  690. ;
  691. ??compute_vert_clip:
  692. mov eax,[viewport_y]
  693. sub eax,[draw_y] ; EAX = viewport_y - draw_y
  694. jge ??set_top_clip
  695. mov eax,0 ; if EAX<0, set to 0
  696. ??set_top_clip:
  697. mov [TopClipPixels],eax ; store # top-clipped pixels
  698. ;
  699. ;.................... bottom-clipped pixels .........................
  700. ;
  701. mov eax,[draw_y]
  702. add eax,[ScaledHeight] ; EAX = draw_y + ScaledHeight
  703. mov edx,[viewport_y]
  704. add edx,[viewport_height] ; EDX = viewport_y + viewport_height
  705. sub eax,edx
  706. jge ??set_bottom_clip
  707. mov eax,0 ; if EAX<0, set to 0
  708. ??set_bottom_clip:
  709. mov [BotClipPixels],eax ; store # bottom-clipped pixels
  710. ;====================================================================
  711. ; Now compute the number of pixels actually drawn, horizontally and
  712. ; vertically; exit if either is <= 0
  713. ;====================================================================
  714. ??compute_drawn_pixels:
  715. ;
  716. ;.................... pixel width of drawn area .....................
  717. ;
  718. mov eax,[ScaledWidth] ; get total width in pixels
  719. sub eax,[LeftClipPixels] ; subtract off left-clipped pixels
  720. sub eax,[RightClipPixels] ; subtract off right-clipped pixels
  721. jle ??exit ; exit if no horizontal pixels drawn
  722. mov [PixelWidth],eax ; store drawn pixel width
  723. ;
  724. ;.................... pixel height of drawn area ....................
  725. ;
  726. mov eax,[ScaledHeight] ; get total height in pixels
  727. sub eax,[TopClipPixels] ; subtract off top-clipped pixels
  728. sub eax,[BotClipPixels] ; subtract off bottom-clipped pixels
  729. jle ??exit ; exit if no horizontal pixels drawn
  730. mov [PixelHeight],eax ; store drawn pixel height
  731. ;====================================================================
  732. ; So, we're actually going to draw something; if (ShapeType &
  733. ; MAKESHAPE_NOCOMP == 0) decompress the shape data into _ShapeBuffer:
  734. ; LCW_Uncompress(ShapeData, _ShapeBuffer, UncompDataLen);
  735. ; shape.DataLength
  736. ; &_ShapeBuffer
  737. ; &(shape's data)
  738. ; - otherwise the shape data is already uncompressed
  739. ;====================================================================
  740. test [ShapeType],MAKESHAPE_NOCOMP
  741. jnz ??uncompressed
  742. mov eax,[UncompDataLen]
  743. push eax ; push arg 3
  744. mov eax,[_ShapeBuffer]
  745. push eax ; push arg 2
  746. mov eax,[ShapeData]
  747. push eax ; push arg 1
  748. call LCW_Uncompress ; call routine
  749. add esp,12 ; restore stack
  750. mov eax,[_ShapeBuffer]
  751. mov [ShapeData],eax
  752. jmp ??copy_flags
  753. ??uncompressed:
  754. ; mov eax,[ShapeData] ; set up pointer to shape data
  755. ; mov [_ShapeBuffer],eax
  756. ;--------------------------------------------------------------------
  757. ; Set the global Flags variable
  758. ;--------------------------------------------------------------------
  759. ??copy_flags:
  760. mov eax,[flags]
  761. mov [Flags],eax
  762. ;====================================================================
  763. ; Now compute the actual buffer offset where drawing (not skipping)
  764. ; will begin
  765. ;====================================================================
  766. ;--------------------------------------------------------------------
  767. ; First, compute the x & y offsets of the shape's clipped upper-left
  768. ; corner, relative to the viewport's upper-left corner:
  769. ; x-offset = draw_x + LeftClipPixels - viewport_x
  770. ; y-offset = draw_y + TopClipPixels - viewport_y
  771. ;--------------------------------------------------------------------
  772. mov ebx,[draw_x]
  773. add ebx,[LeftClipPixels]
  774. sub ebx,[viewport_x] ; EBX = viewport x-offset
  775. mov eax,[draw_y]
  776. add eax,[TopClipPixels]
  777. sub eax,[viewport_y] ; EAX = viewport y-offset
  778. ;--------------------------------------------------------------------
  779. ; Then, adjust the viewport offsets due to horizontal & vertical
  780. ; reversal:
  781. ; if HORZ_REV, x-offset += (PixelWidth - 1)
  782. ; if VERT_REV, y-offset += (PixelHeight - 1)
  783. ;--------------------------------------------------------------------
  784. ;
  785. ;................. Adjust for horizontal reversal ...................
  786. ;
  787. test [flags],SHAPE_HORZ_REV
  788. jz ??adjust_vert_offset
  789. add ebx,[PixelWidth]
  790. dec ebx ; EBX = true x-offset
  791. ;
  792. ;................ Swap LeftClip & RightClip pixels ..................
  793. ;
  794. mov edx,[LeftClipPixels] ; exchange left & right-clipped pixels
  795. xchg edx,[RightClipPixels]
  796. mov [LeftClipPixels],edx
  797. ;
  798. ;.................. Adjust for vertical reversal ....................
  799. ;
  800. ??adjust_vert_offset:
  801. test [flags],SHAPE_VERT_REV
  802. jz ??adjust_pointer
  803. add eax,[PixelHeight]
  804. dec eax ; EAX = true y-offset
  805. ;
  806. ;.................. Swap TopClip & BotClip pixels ...................
  807. ;
  808. mov edx,[TopClipPixels]
  809. xchg edx,[BotClipPixels]
  810. mov [TopClipPixels],edx
  811. ;--------------------------------------------------------------------
  812. ; Now, adjust the starting position pointer:
  813. ;--------------------------------------------------------------------
  814. ??adjust_pointer: ;!!!!!!! convert to register mul for speed !!!!!!!!
  815. add ebx,[viewport_ptr] ; add initial ptr to x-offset
  816. mul [viewport_yadd] ; convert y-offset (EAX) to bytes
  817. add ebx,eax ; add those bytes in
  818. mov [StartDraw],ebx ; store the starting pointer
  819. ;--------------------------------------------------------------------
  820. ; Finally, if VERT_REV, negate yadd to move up not down:
  821. ;--------------------------------------------------------------------
  822. test [flags],SHAPE_VERT_REV
  823. jz ??init_xtotal
  824. neg [viewport_yadd] ; move up, not down
  825. ;====================================================================
  826. ; Initialize the horizontal scale accumulation value:
  827. ; If there are any left-clipped pixels, the scale accumulator will
  828. ; have to be initialized with the value it >would< have by stepping
  829. ; over that many pixels. This initial value can be computed by
  830. ; dividing the # of left-clipped pixels by the x-scale value itself,
  831. ; picking off the remainder from this division & negating it. This
  832. ; sets the low byte of the remainder to the correct accumulation
  833. ; value (the high bytes will be garbage).
  834. ; (The alternative to this approach would be to multiply the
  835. ; scale factor by the # clipped bytes, which is the result of the
  836. ; division; however, negating the remainder is much faster than
  837. ; the multiply would be.)
  838. ;====================================================================
  839. ??init_xtotal:
  840. mov edx,0 ; prepare for divide
  841. mov eax,[LeftClipPixels] ; get # left-clipped pixels
  842. shl eax,8 ; multiply by 100h
  843. mov ebx,[ScaleX] ; load ScaleX value
  844. div bx ; 16-bit div: AX = rslt, DX = rem
  845. mov [LeftClipBytes],eax ; save # left-clipped bytes
  846. neg edx ; generate roundoff bits
  847. and edx,0Fh ; only save low byte
  848. mov [XTotalInit],edx ; save initial roundoff value
  849. ;====================================================================
  850. ; Initialize drawing variables:
  851. ;====================================================================
  852. mov esi,[ShapeData] ; ESI = shape buffer starting point
  853. mov edi,[StartDraw] ; EDI = drawing address
  854. mov [YTotal],0 ; initialize accumulated scale
  855. ;====================================================================
  856. ; Clip the top-clipped lines. The object here is to set ESI to the
  857. ; first drawable line in the _ShapeBuffer, and YTotal to:
  858. ; high byte = # times to draw that line,
  859. ; low byte = roundoff bits
  860. ;
  861. ; - Initialize values (ESI, HeightCount, YTotal)
  862. ; - Skip loop if no top lines to clip
  863. ; - Loop:
  864. ; - save this line's byte position in _ShapeBuffer, in case we
  865. ; overrun
  866. ; - call RSkipRout with ECX set to # bytes to skip (one row)
  867. ; - accumulate ScaleY into YTotal
  868. ; - if high byte is non-zero, there are that many drawn lines:
  869. ; - decrement HeightCount by that many lines
  870. ; - clear the high byte in YTotal, but keep the roundoff bits
  871. ; - if HeightCount > 0, loop again to clip more lines
  872. ; - if HeightCount is 0, start drawing:
  873. ; - ESI points to first non-clipped line in _ShapeBuffer
  874. ; - YTotal contains 0 in high byte, roundoff bits in low byte
  875. ; - otherwise, we've clipped too many lines:
  876. ; - put ESI back to the line we just clipped
  877. ; - set high byte of YTotal to # lines overrun
  878. ; - subtract ScaleY from YTotal, to set it up for drawing loop
  879. ;====================================================================
  880. ;
  881. ;..................... skip if nothing to clip ......................
  882. ;
  883. mov eax,[TopClipPixels]
  884. cmp eax,0 ; see if any top-clipped pixels
  885. jz ??draw_loop ; if not, skip this
  886. mov [HeightCount],eax ; save off # lines to clip
  887. ??clip_y_loop:
  888. ;
  889. ;...................... skip this row of bytes ......................
  890. ;
  891. mov [LineStart],esi ; save this line's byte position
  892. mov ecx,[ShapeWidth] ; set up ECX for RSkipRout
  893. call [RSkipRout] ; skip 'ShapeWidth' bytes
  894. ;
  895. ;............... see if this row would have been drawn ..............
  896. ;
  897. mov eax,[ScaleY]
  898. add [YTotal],eax ; accumulate scale factor
  899. test [YTotal],0FF00h ; check to see if we draw the line
  900. jz ??clip_y_loop ; if not loop again
  901. ;
  902. ;...................... decrement HeightCount .......................
  903. ;
  904. mov eax,0 ; clear EAX
  905. xchg al,[BYTE PTR YTotal+1] ; get # lines, clear it in YTotal
  906. sub [HeightCount],eax ; subtract # drawn lines from HtCt
  907. jg ??clip_y_loop ; if more lines remain, loop again
  908. jns ??draw_loop ; is exactly 0; we're done clipping
  909. ;
  910. ;....................... adjust for overrun .........................
  911. ;
  912. mov esi,[LineStart] ; point ESI back to this line
  913. mov eax,[HeightCount]
  914. neg eax ; EAX = # lines overrun
  915. shl eax,8 ; multiply by 100h
  916. add eax,[YTotal] ; add in roundoff bits
  917. sub eax,[ScaleY] ; adjust down by y-scale
  918. mov [YTotal],eax ; store in YTotal
  919. ;====================================================================
  920. ; The drawing loop (at long last!):
  921. ; - Accumulate YTotal; if high byte is 0, skip this row of bytes &
  922. ; loop again
  923. ; - Skip left-clipped pixels:
  924. ; - If we've skipped all the bytes on the line, just go to the
  925. ; next line
  926. ; - Draw middle pixels:
  927. ; - Add the shape's pixel width to ECX (which could be negative
  928. ; if we left-skipped into the drawable area)
  929. ; - If ECX is still 0, there are no pixels to draw
  930. ; - Otherwise, leave ECX as is & draw the pixels
  931. ; - Skip right-clipped pixels:
  932. ; - Add # right-clipped pixels to ECX (which could be negative if
  933. ; the draw routine uncompressed 0's into the right-clipped
  934. ; region)
  935. ; - if ECX > 0, skip the remaining bytes
  936. ; - Go to the next line:
  937. ; - point EDI to the start of the next line in the viewport
  938. ; - decrement the height counter, exit if it's 0
  939. ; - decrement YTotal's high byte
  940. ; - if it's 0, go to the loop top
  941. ; - otherwise, reset ESI to this line's start & redraw the line,
  942. ; starting at left-clipped pixels
  943. ; (NOTE: why not start drawing at middle pixels??????????)
  944. ;====================================================================
  945. ??draw_loop:
  946. ;
  947. ;................... accumulate YTotal & test it ....................
  948. ;
  949. mov eax,[ScaleY] ; get y scaling factor
  950. add [YTotal],eax ; accumulate YTotal
  951. test [YTotal],0FF00h ; see if we need to draw anything
  952. jnz ??draw_line ; draw this line
  953. ;
  954. ;......................... skip this line ...........................
  955. ;
  956. mov ecx,[ShapeWidth] ; load shape's width in bytes
  957. call [RSkipRout] ; skip this row & loop again
  958. jmp ??draw_loop
  959. ;
  960. ;--------------------- start drawing this line ----------------------
  961. ;
  962. ??draw_line:
  963. mov [LineStart],esi ; save current byte position
  964. ;....................................................................
  965. ; Skip left-clipped pixels:
  966. ; - initialize [WidthCount] to total shape width in bytes
  967. ; - set ECX to # >bytes< to clip
  968. ; When LSkipRout returns:
  969. ; - ECX will contain # >pixels< overrun
  970. ; - EDX will contain the XTotal init value
  971. ; - [WidthCount] will be decremented by total bytes skipped
  972. ;....................................................................
  973. ??draw_left:
  974. mov eax,[ShapeWidth] ; load shape width
  975. mov [WidthCount],eax ; set up for LSkipRout
  976. mov ecx,[LeftClipBytes] ; bytes, not pixels!
  977. call [LSkipRout] ; skip the bytes
  978. cmp [WidthCount],0
  979. jz ??next_line ; The whole line was 0's
  980. ;....................................................................
  981. ; Draw middle pixels:
  982. ; - add PixelWidth to ECX (which may be negative)
  983. ; - if ECX is 0, don't bother drawing
  984. ; When DrawRout returns:
  985. ; - ECX will contain # >pixels< overrun
  986. ; - [WidthCount] will be decremented by # bytes drawn
  987. ;....................................................................
  988. ??draw_middle:
  989. add ecx,[PixelWidth] ; since ECX could overrun, add width
  990. jle ??draw_right ; if ECX<=0, no middle pixels to draw
  991. call [DrawRout] ; draw the pixels
  992. ;
  993. ;................... skip past right-clipped pixels .................
  994. ;
  995. ??draw_right:
  996. mov ecx,[WidthCount] ; ECX = remaining # bytes
  997. jecxz ??next_line ; don't bother if no bytes remain
  998. call [RSkipRout] ; skip right-clipped bytes
  999. ;
  1000. ;----------------------- go to the next line ------------------------
  1001. ;
  1002. ??next_line:
  1003. ;
  1004. ;................. adjust EDI to start of next line .................
  1005. ;
  1006. mov eax,[viewport_yadd] ; get yadd
  1007. add [StartDraw],eax ; add it to this line's position
  1008. mov edi,[StartDraw] ; EDI = next line
  1009. ;
  1010. ;................. decrement our pixel row counter ..................
  1011. ;
  1012. dec [PixelHeight] ; count down a line
  1013. jz ??exit ; we're done!
  1014. ;
  1015. ;.................. decrement YTotal's high byte ....................
  1016. ;
  1017. dec [BYTE PTR YTotal + 1] ; decrement high byte
  1018. jz ??draw_loop ; draw next line if 0
  1019. ;
  1020. ;....................... re-draw this line ..........................
  1021. ;
  1022. mov esi,[LineStart] ; reset to this line's start
  1023. jmp ??draw_left ; redraw this line
  1024. ??exit:
  1025. ret
  1026. ENDP Draw_Shape
  1027. ;***************************************************************************
  1028. ;* Not_Supported -- Replacement function for Draw_Shape routines not used. *
  1029. ;* *
  1030. ;* INPUT: *
  1031. ;* none. *
  1032. ;* *
  1033. ;* OUTPUT: *
  1034. ;* none. *
  1035. ;* *
  1036. ;* WARNINGS: *
  1037. ;* none. *
  1038. ;* *
  1039. ;* HISTORY: *
  1040. ;* 08/24/1993 SKB : Created. *
  1041. ;*=========================================================================*
  1042. PROC Not_Supported NOLANGUAGE NEAR
  1043. ret
  1044. ENDP Not_Supported
  1045. END
  1046. ;************************** End of drawshp.asm *****************************
  1047.