IB_TM3.asm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. ; Seven Kingdoms: Ancient Adversaries
  2. ;
  3. ; Copyright 1997,1998 Enlight Software Ltd.
  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 2 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. ;Filename : IB_TM3.ASM
  19. ;Description : Diagonal mirror-blt a bitmap to the display surface buffer with color key transparency handling
  20. INCLUDE IMGFUN.inc
  21. INCLUDE COLCODE.inc
  22. .CODE
  23. ;-------- BEGIN OF FUNCTION IMBbltTransHVMirror ----------
  24. ;
  25. ; Diagonal mirror-blt an non-compressed bitmap on image buffer.
  26. ; It handles color key transparency. The color key code is 255.
  27. ;
  28. ; Syntax : IMBbltTransHVMirror( imageBuf, pitch, x, y, bitmapPtr )
  29. ;
  30. ; char *imageBuf - the pointer to the display surface buffer
  31. ; int x,y - where to put the image on the surface buffer
  32. ; char *bitmapPtr - the pointer to the bitmap buffer
  33. ;
  34. ;-------------------------------------------------
  35. ;
  36. ; Format of the bitmap data :
  37. ;
  38. ; <short> width
  39. ; <short> height
  40. ; <char..> bitmap image
  41. ;
  42. ;-------------------------------------------------
  43. PUBLIC IMGbltTransHVMirror
  44. IMGbltTransHVMirror PROC imageBuf, pitch, x, y, bitmapPtr
  45. STARTPROC
  46. MOV EAX, imageBuf ; store the address of the image buffer to a variable
  47. MOV image_buf, EAX
  48. ;------ get the bitmap width and height -----;
  49. MOV AX , DS
  50. MOV ES , AX
  51. MOV ESI, bitmapPtr
  52. XOR EAX, EAX
  53. LODSW ; get bitmap width
  54. MOV EBX, EAX
  55. LODSW ; get bitmap height
  56. MOV ECX, EAX
  57. MOV EDX, pitch ; EDX = lineDiff
  58. ADD EDX, EBX ; lineDiff = pitch + bitmap_width
  59. CLD ; clear direction flag for MOVSB
  60. ;------- pixels copying loop --------;
  61. ADD y, ECX ; set y to the last line of the bitmap (y2)
  62. DEC y
  63. CALC_ADDR EDI, x, y, pitch ; Get the offset to the image buffer address
  64. ADD ESI, EBX ; HVMirror-blitting, advance one line in the source data and then move backwards pixel by pixel
  65. @@moreLines:
  66. PUSH ECX
  67. MOV ECX, EBX ; ECX is the line pixel counter
  68. SHR ECX, 2
  69. JZ SHORT @@nextScan
  70. ;-----------------------------------------------------------------------//
  71. ; The idea here is to not branch very often so we unroll the loop by four
  72. ; and try to not branch when a whole run of pixels is either transparent
  73. ; or not transparent.
  74. ;
  75. ; There are two loops. One loop is for a run of pixels equal to the
  76. ; transparent color, the other is for runs of pixels we need to store.
  77. ;
  78. ; When we detect a "bad" pixel we jump to the same position in the
  79. ; other loop.
  80. ;
  81. ; Here is the loop we will stay in as long as we encounter a "transparent"
  82. ; pixel in the source.
  83. ;-----------------------------------------------------------------------//
  84. align 4
  85. @@same:
  86. sub esi,4 ; mirror-blitting, backward 4 bytes in the source data
  87. mov al, ds:[esi+3]
  88. cmp al, TRANSPARENT_CODE
  89. jne short @@diff0
  90. @@same0:
  91. mov al, ds:[esi+2]
  92. cmp al, TRANSPARENT_CODE
  93. jne short @@diff1
  94. @@same1:
  95. mov al, ds:[esi+1]
  96. cmp al, TRANSPARENT_CODE
  97. jne short @@diff2
  98. @@same2:
  99. mov al, ds:[esi]
  100. cmp al, TRANSPARENT_CODE
  101. jne short @@diff3
  102. @@same3:
  103. add edi,4
  104. dec ecx
  105. jnz short @@same
  106. jz short @@nextScan
  107. ;-----------------------------------------------------------------------//
  108. ; Here is the loop we will stay in as long as
  109. ; we encounter a "non transparent" pixel in the source.
  110. ;-----------------------------------------------------------------------//
  111. align 4
  112. @@diff:
  113. sub esi,4 ; mirror-blitting, backward 4 bytes in the source data
  114. mov al, ds:[esi+3]
  115. cmp al, TRANSPARENT_CODE
  116. je short @@same0
  117. @@diff0:
  118. mov es:[edi],al
  119. mov al, ds:[esi+2]
  120. cmp al, TRANSPARENT_CODE
  121. je short @@same1
  122. @@diff1:
  123. mov es:[edi+1],al
  124. mov al, ds:[esi+1]
  125. cmp al, TRANSPARENT_CODE
  126. je short @@same2
  127. @@diff2:
  128. mov es:[edi+2],al
  129. mov al, ds:[esi]
  130. cmp al, TRANSPARENT_CODE
  131. je short @@same3
  132. @@diff3:
  133. mov es:[edi+3],al
  134. add edi,4
  135. dec ecx
  136. jnz short @@diff
  137. jz short @@nextScan
  138. ;-----------------------------------------------------------------------//
  139. ; We are at the end of a scan, check for odd leftover pixels to do
  140. ; and go to the next scan.
  141. ;-----------------------------------------------------------------------//
  142. align 4
  143. @@nextScan:
  144. mov ecx,ebx ; ebx = bitmap width
  145. and ecx,11b ; if its pixel count is an odd number
  146. jnz short @@oddStuff
  147. ;-----------------------------------------------------------------------//
  148. ; move on to the start of the next line
  149. ;-----------------------------------------------------------------------//
  150. @@nextScan1:
  151. sub edi, edx ; edx = lineDiff, SUB instead of ADD because of vertically mirroring
  152. add esi, ebx ; esi: advance to the last pixel of the next line, edx = bitmap width x 2
  153. add esi, ebx
  154. pop ecx
  155. loop @@moreLines
  156. jmp short @@end
  157. ;-----------------------------------------------------------------------//
  158. ; If the width is not a multiple of 4 we will come here to clean up
  159. ; the last few pixels
  160. ;-----------------------------------------------------------------------//
  161. @@oddStuff:
  162. inc ecx
  163. @@oddLoop:
  164. dec ecx
  165. jz short @@nextScan1
  166. mov al, ds:[esi]
  167. dec esi ; mirror-blitting, backward one byte in the source data
  168. inc edi
  169. cmp al, TRANSPARENT_CODE
  170. je short @@oddLoop
  171. mov es:[edi-1],al
  172. jmp short @@oddLoop
  173. @@end: ENDPROC
  174. IMGbltTransHVMirror ENDP
  175. ;----------- END OF FUNCTION IMGbltTransHVMirror ----------
  176. END