IB_ATM.asm 6.4 KB

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