MCOCKPIT.C 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/main/rcs/mcockpit.c $
  15. * $Revision: 2.0 $
  16. * $Author: john $
  17. * $Date: 1995/02/27 11:30:20 $
  18. *
  19. * File to make the cockpit.inc source code file.
  20. *
  21. * $Log: mcockpit.c $
  22. * Revision 2.0 1995/02/27 11:30:20 john
  23. * New version 2.0, which has no anonymous unions, builds with
  24. * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  25. *
  26. * Revision 1.8 1994/05/30 19:27:57 john
  27. * Moved functionality of mcockpit into 2d, ibitblt.
  28. *
  29. * Revision 1.7 1994/05/11 11:36:08 john
  30. * Neatend up; took out debugging lines.
  31. *
  32. * Revision 1.6 1994/05/11 11:19:19 john
  33. * Made cockpit code be created at runtime.
  34. *
  35. * Revision 1.5 1994/01/28 17:40:22 john
  36. * *** empty log message ***
  37. *
  38. * Revision 1.4 1994/01/26 18:14:10 john
  39. * Printed out x,y,w,h;
  40. *
  41. * Revision 1.3 1994/01/25 11:45:00 john
  42. * Took out graphics.
  43. *
  44. * Revision 1.2 1994/01/24 18:55:40 john
  45. * initial version.
  46. *
  47. * Revision 1.1 1994/01/24 18:31:21 john
  48. * Initial revision
  49. *
  50. *
  51. */
  52. #pragma off (unreferenced)
  53. static char rcsid[] = "$Id: mcockpit.c 2.0 1995/02/27 11:30:20 john Exp $";
  54. #pragma on (unreferenced)
  55. /*
  56. #include <conio.h>
  57. #include <dos.h>
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include "types.h"
  61. #include "gr.h"
  62. #include "iff.h"
  63. #include "mem.h"
  64. #include "screens.h"
  65. #include "mcockpit.h"
  66. #define MODE_NONE 0
  67. #define MODE_SKIP 1
  68. #define MODE_DRAW 2
  69. #define OPCODE_ADD 0x81
  70. #define OPCODE_ESI 0xC6 // Followed by a dword (add esi, ????)
  71. #define OPCODE_EDI 0xC7 // Followed by a dword (add edi, ????)
  72. #define OPCODE_MOV_ECX 0xB9 // Followed by a dword (mov ecx,????)
  73. #define OPCODE_MOVSB 0xA4 // movsb
  74. #define OPCODE_16BIT 0x66 // movsw
  75. #define OPCODE_MOVSD 0xA5 // movsd
  76. #define OPCODE_REP 0xF3 // rep
  77. #define OPCODE_RET 0xC3 // ret
  78. ubyte *Code_pointer = NULL;
  79. int Code_counter = 0;
  80. void move_and_count( int dsource, int ddest, int ecx )
  81. {
  82. int blocks;
  83. if ( ecx <= 0 )
  84. return;
  85. if ( dsource > 0 )
  86. Code_counter+=6; // ADD ESI, dsource
  87. if ( ddest > 0 )
  88. Code_counter+=6; // ADD EDI, ddest
  89. while ( ecx > 0 ) {
  90. switch(ecx) {
  91. case 1: Code_counter++; ecx = 0; break; // MOVSB
  92. case 2: Code_counter+=2; ecx = 0; break; // MOVSW
  93. case 3: Code_counter+=3; ecx = 0; break; // MOVSW, MOVSB
  94. case 4: Code_counter++; ecx = 0; break; // MOVSD
  95. default:
  96. blocks = ecx / 4;
  97. if ( blocks == 1 )
  98. Code_counter++; // MOVSD
  99. else
  100. Code_counter+=7;
  101. ecx -= blocks*4;
  102. }
  103. }
  104. }
  105. void move_and_draw( int dsource, int ddest, int ecx )
  106. {
  107. int blocks;
  108. int * iptr;
  109. if ( ecx <= 0 )
  110. return;
  111. if ( dsource > 0 ) {
  112. // ADD ESI, dsource
  113. *Code_pointer++ = OPCODE_ADD;
  114. *Code_pointer++ = OPCODE_ESI;
  115. iptr = (int *)Code_pointer;
  116. *iptr++ = dsource;
  117. Code_pointer = (ubyte *)iptr;
  118. }
  119. if ( ddest > 0 ) {
  120. // ADD EDI, ddest
  121. *Code_pointer++ = OPCODE_ADD;
  122. *Code_pointer++ = OPCODE_EDI;
  123. iptr = (int *)Code_pointer;
  124. *iptr++ = ddest;
  125. Code_pointer = (ubyte *)iptr;
  126. }
  127. while ( ecx > 0 ) {
  128. switch( ecx ) {
  129. case 1:
  130. // MOVSB
  131. *Code_pointer++ = OPCODE_MOVSB;
  132. ecx = 0;
  133. break;
  134. case 2:
  135. // MOVSW
  136. *Code_pointer++ = OPCODE_16BIT;
  137. *Code_pointer++ = OPCODE_MOVSD;
  138. ecx = 0;
  139. break;
  140. case 3:
  141. // MOVSW, MOVSB
  142. *Code_pointer++ = OPCODE_16BIT;
  143. *Code_pointer++ = OPCODE_MOVSD;
  144. *Code_pointer++ = OPCODE_MOVSB;
  145. ecx = 0;
  146. break;
  147. case 4:
  148. // MOVSD
  149. *Code_pointer++ = OPCODE_MOVSD;
  150. ecx = 0;
  151. break;
  152. default:
  153. blocks = ecx / 4;
  154. if ( blocks == 1 ) {
  155. // MOVSD
  156. *Code_pointer++ = OPCODE_MOVSD;
  157. } else {
  158. // MOV ECX, blocks
  159. *Code_pointer++ = OPCODE_MOV_ECX;
  160. iptr = (int *)Code_pointer;
  161. *iptr++ = blocks;
  162. Code_pointer = (ubyte *)iptr;
  163. // REP MOVSD
  164. *Code_pointer++ = OPCODE_REP;
  165. *Code_pointer++ = OPCODE_MOVSD;
  166. }
  167. ecx -= blocks*4;
  168. }
  169. }
  170. }
  171. //-----------------------------------------------------------------------------------------
  172. // Given bitmap, bmp, finds the size of the code
  173. int mcockpit_find_inverted_bitblit_code_size( grs_bitmap * bmp, int sx, int sy, int sw, int sh, int srowsize, ubyte transparent_color )
  174. {
  175. int x,y;
  176. ubyte pixel;
  177. int draw_mode = MODE_NONE;
  178. int source_offset = 0;
  179. int dest_offset = 0;
  180. int num_to_draw, draw_start_source, draw_start_dest;
  181. int esi, edi;
  182. Code_counter = 0;
  183. esi = source_offset = 0;
  184. for ( y=sy; y<sy+sh; y++ ) {
  185. for ( x=sx; x<sx+sw; x++ ) {
  186. dest_offset = y*bmp->bm_rowsize+x;
  187. pixel = bmp->bm_data[dest_offset];
  188. if ( pixel!=transparent_color ) {
  189. switch ( draw_mode) {
  190. case MODE_DRAW:
  191. move_and_count( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  192. esi = draw_start_source + num_to_draw;
  193. edi = draw_start_dest + num_to_draw;
  194. // fall through!!!
  195. case MODE_NONE:
  196. case MODE_SKIP:
  197. break;
  198. }
  199. draw_mode = MODE_SKIP;
  200. } else {
  201. switch ( draw_mode) {
  202. case MODE_SKIP:
  203. case MODE_NONE:
  204. draw_start_source = source_offset;
  205. draw_start_dest = dest_offset;
  206. num_to_draw = 0;
  207. // fall through
  208. case MODE_DRAW:
  209. num_to_draw++;
  210. break;
  211. }
  212. draw_mode = MODE_DRAW;
  213. }
  214. source_offset++;
  215. }
  216. if ( draw_mode == MODE_DRAW ) {
  217. move_and_count( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  218. esi = draw_start_source + num_to_draw;
  219. edi = draw_start_dest + num_to_draw;
  220. }
  221. draw_mode = MODE_NONE;
  222. source_offset += (srowsize - sw);
  223. }
  224. Code_counter++; // for return
  225. //printf( "Code will be %d bytes\n", Code_counter );
  226. return Code_counter;
  227. }
  228. //-----------------------------------------------------------------------------------------
  229. // Given bitmap, bmp, create code that transfers a bitmap of size sw*sh to position
  230. // (sx,sy) on top of bmp, only overwritting transparent pixels of the bitmap.
  231. int mcockpit_create_inverted_bitblit( grs_bitmap * bmp, int sx, int sy, int sw, int sh, int srowsize, ubyte transparent_color, ubyte * code )
  232. {
  233. int x,y;
  234. ubyte pixel;
  235. int draw_mode = MODE_NONE;
  236. int source_offset = 0;
  237. int dest_offset = 0;
  238. int num_to_draw, draw_start_source, draw_start_dest;
  239. int esi, edi;
  240. Code_pointer = code;
  241. esi = source_offset = 0;
  242. for ( y=sy; y<sy+sh; y++ ) {
  243. for ( x=sx; x<sx+sw; x++ ) {
  244. dest_offset = y*bmp->bm_rowsize+x;
  245. pixel = bmp->bm_data[dest_offset];
  246. if ( pixel!=transparent_color ) {
  247. switch ( draw_mode) {
  248. case MODE_DRAW:
  249. move_and_draw( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  250. esi = draw_start_source + num_to_draw;
  251. edi = draw_start_dest + num_to_draw;
  252. // fall through!!!
  253. case MODE_NONE:
  254. case MODE_SKIP:
  255. break;
  256. }
  257. draw_mode = MODE_SKIP;
  258. } else {
  259. switch ( draw_mode) {
  260. case MODE_SKIP:
  261. case MODE_NONE:
  262. draw_start_source = source_offset;
  263. draw_start_dest = dest_offset;
  264. num_to_draw = 0;
  265. // fall through
  266. case MODE_DRAW:
  267. num_to_draw++;
  268. break;
  269. }
  270. draw_mode = MODE_DRAW;
  271. }
  272. source_offset++;
  273. }
  274. if ( draw_mode == MODE_DRAW ) {
  275. move_and_draw( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  276. esi = draw_start_source + num_to_draw;
  277. edi = draw_start_dest + num_to_draw;
  278. }
  279. draw_mode = MODE_NONE;
  280. source_offset += (srowsize - sw);
  281. }
  282. *Code_pointer++ = OPCODE_RET;
  283. //printf( "Code is %d bytes\n", Code_pointer - code );
  284. return 0;
  285. }
  286. void mcockpit_do_inverted_bitblit_asm(char *start_si, char *start_di, ubyte * code);
  287. #pragma aux mcockpit_do_inverted_bitblit_asm parm [esi] [edi] [eax] modify [ecx edi esi eax] = \
  288. "pusha" \
  289. "call eax" \
  290. "popa"
  291. void mcockpit_do_inverted_bitblit(char *start_si, char *start_di, ubyte * code)
  292. {
  293. if (code != NULL )
  294. mcockpit_do_inverted_bitblit_asm( start_si, start_di, code );
  295. }
  296. void mcockpit_find_extents( grs_bitmap * bmp, int *minx, int *miny, int *maxx, int *maxy )
  297. {
  298. ubyte c;
  299. int x, y;
  300. *minx = 0;
  301. *maxx = bmp->bm_w;
  302. *miny = 0;
  303. *maxy = bmp->bm_h;
  304. for ( y=0; y<bmp->bm_h; y++ )
  305. for ( x=0; x<bmp->bm_w; x++ ) {
  306. c = bmp->bm_data[bmp->bm_rowsize*y+x];
  307. if (c == iff_transparent_color ) {
  308. if ( x < *minx ) *minx = x;
  309. if ( y < *miny ) *miny = y;
  310. if ( x > *maxx ) *maxx = x;
  311. if ( y > *maxy ) *maxy = y;
  312. }
  313. }
  314. }
  315. */
  316.