home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / mcockpit.c < prev    next >
Text File  |  1998-06-08  |  9KB  |  357 lines

  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.  
  53.  
  54. #pragma off (unreferenced)
  55. static char rcsid[] = "$Id: mcockpit.c 2.0 1995/02/27 11:30:20 john Exp $";
  56. #pragma on (unreferenced)
  57.  
  58. /*
  59. #include <conio.h>
  60. #include <dos.h>
  61. #include <stdio.h>
  62. #include <stdlib.h>
  63.  
  64. #include "types.h"
  65. #include "gr.h"
  66. #include "iff.h"
  67. #include "mem.h"
  68. #include "screens.h"
  69. #include "mcockpit.h"
  70.  
  71. #define MODE_NONE        0
  72. #define MODE_SKIP        1
  73. #define MODE_DRAW        2
  74.  
  75. #define OPCODE_ADD             0x81            
  76. #define OPCODE_ESI            0xC6            // Followed by a dword    (add esi, ????)
  77. #define OPCODE_EDI             0xC7            // Followed by a dword  (add edi, ????)
  78. #define OPCODE_MOV_ECX        0xB9            // Followed by a dword  (mov ecx,????)
  79. #define OPCODE_MOVSB           0xA4            // movsb
  80. #define OPCODE_16BIT         0x66            // movsw
  81. #define OPCODE_MOVSD         0xA5            // movsd
  82. #define OPCODE_REP            0xF3            // rep
  83. #define OPCODE_RET            0xC3            // ret
  84.  
  85. ubyte *Code_pointer = NULL;
  86. int Code_counter = 0;
  87.  
  88. void move_and_count( int dsource, int ddest, int ecx )
  89. {
  90.     int blocks;
  91.     if ( ecx <= 0 )    
  92.         return;
  93.  
  94.     if ( dsource > 0 )
  95.         Code_counter+=6;        // ADD ESI, dsource
  96.  
  97.     if ( ddest > 0 )
  98.         Code_counter+=6;        // ADD EDI, ddest
  99.  
  100.     while ( ecx > 0 )    {
  101.         switch(ecx)    {
  102.         case 1: Code_counter++; ecx = 0; break;    // MOVSB
  103.         case 2: Code_counter+=2; ecx = 0; break;    // MOVSW
  104.         case 3: Code_counter+=3; ecx = 0; break;    // MOVSW, MOVSB
  105.         case 4: Code_counter++; ecx = 0; break;     // MOVSD
  106.         default:
  107.             blocks = ecx / 4;
  108.             if ( blocks == 1 )
  109.                 Code_counter++;    // MOVSD
  110.             else 
  111.                 Code_counter+=7;
  112.             ecx -= blocks*4;
  113.         }
  114.     }
  115. }
  116.  
  117.  
  118. void move_and_draw( int dsource, int ddest, int ecx )
  119. {
  120.     int blocks;
  121.     int * iptr;
  122.  
  123.     if ( ecx <= 0 )
  124.         return;
  125.  
  126.     if ( dsource > 0 )    {
  127.         // ADD ESI, dsource
  128.         *Code_pointer++ = OPCODE_ADD;
  129.         *Code_pointer++ = OPCODE_ESI;
  130.         iptr = (int *)Code_pointer;
  131.         *iptr++ = dsource;
  132.         Code_pointer = (ubyte *)iptr;                        
  133.     }
  134.     if ( ddest > 0 )    {
  135.         // ADD EDI, ddest
  136.         *Code_pointer++ = OPCODE_ADD;
  137.         *Code_pointer++ = OPCODE_EDI;
  138.         iptr = (int *)Code_pointer;
  139.         *iptr++ = ddest;
  140.         Code_pointer = (ubyte *)iptr;                        
  141.     }
  142.  
  143.     while ( ecx > 0 )    {
  144.         switch( ecx )    {
  145.         case 1:
  146.             // MOVSB
  147.             *Code_pointer++ = OPCODE_MOVSB;
  148.             ecx = 0;
  149.             break;
  150.         case 2:
  151.             // MOVSW
  152.             *Code_pointer++ = OPCODE_16BIT;
  153.             *Code_pointer++ = OPCODE_MOVSD;
  154.             ecx = 0;
  155.             break;
  156.         case 3:
  157.             // MOVSW, MOVSB
  158.             *Code_pointer++ = OPCODE_16BIT;
  159.             *Code_pointer++ = OPCODE_MOVSD;
  160.             *Code_pointer++ = OPCODE_MOVSB;
  161.             ecx = 0;
  162.             break;
  163.         case 4:
  164.             // MOVSD
  165.             *Code_pointer++ = OPCODE_MOVSD;
  166.             ecx = 0;
  167.             break;
  168.         default:
  169.             blocks = ecx / 4;
  170.  
  171.             if ( blocks == 1 )    {    
  172.                 // MOVSD
  173.                 *Code_pointer++ = OPCODE_MOVSD;
  174.             } else {
  175.                 // MOV ECX, blocks
  176.                 *Code_pointer++ = OPCODE_MOV_ECX;
  177.                 iptr = (int *)Code_pointer;
  178.                 *iptr++ = blocks;
  179.                 Code_pointer = (ubyte *)iptr;                        
  180.                 // REP MOVSD
  181.                 *Code_pointer++ = OPCODE_REP;
  182.                 *Code_pointer++ = OPCODE_MOVSD;
  183.             }
  184.             ecx -= blocks*4;
  185.         }
  186.     }
  187. }
  188.  
  189. //-----------------------------------------------------------------------------------------
  190. // Given bitmap, bmp, finds the size of the code 
  191.  
  192. int mcockpit_find_inverted_bitblit_code_size( grs_bitmap * bmp, int sx, int sy, int sw, int sh, int srowsize, ubyte transparent_color )
  193. {
  194.     int x,y;
  195.     ubyte pixel;
  196.     int draw_mode = MODE_NONE;
  197.     int source_offset = 0;
  198.     int dest_offset = 0;
  199.     int num_to_draw, draw_start_source, draw_start_dest;
  200.     int esi, edi;
  201.  
  202.     Code_counter = 0;
  203.  
  204.     esi = source_offset = 0;
  205.  
  206.     for ( y=sy; y<sy+sh; y++ )    {
  207.         for ( x=sx; x<sx+sw; x++ )    {
  208.             dest_offset = y*bmp->bm_rowsize+x;
  209.             pixel = bmp->bm_data[dest_offset];
  210.             if ( pixel!=transparent_color )    {
  211.                 switch ( draw_mode)    {
  212.                 case MODE_DRAW:
  213.                     move_and_count( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  214.                     esi = draw_start_source + num_to_draw;
  215.                     edi = draw_start_dest + num_to_draw;
  216.                     // fall through!!!
  217.                 case MODE_NONE:
  218.                 case MODE_SKIP:
  219.                     break;
  220.                 }
  221.                 draw_mode = MODE_SKIP;
  222.             } else {
  223.                 switch ( draw_mode)    {
  224.                 case MODE_SKIP:
  225.                 case MODE_NONE:
  226.                     draw_start_source = source_offset;
  227.                     draw_start_dest = dest_offset;
  228.                     num_to_draw = 0;
  229.                     // fall through
  230.                 case MODE_DRAW:
  231.                     num_to_draw++;
  232.                     break;
  233.                 }
  234.                 draw_mode = MODE_DRAW;
  235.             }
  236.             source_offset++;
  237.         }
  238.         if ( draw_mode == MODE_DRAW )    {
  239.             move_and_count( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  240.             esi = draw_start_source + num_to_draw;
  241.             edi = draw_start_dest + num_to_draw;
  242.         }
  243.         draw_mode = MODE_NONE;
  244.         source_offset += (srowsize - sw);
  245.     }
  246.     Code_counter++;        // for return
  247.  
  248.     //printf( "Code will be %d bytes\n", Code_counter );
  249.  
  250.     return Code_counter;
  251. }
  252.  
  253.  
  254. //-----------------------------------------------------------------------------------------
  255. // Given bitmap, bmp, create code that transfers a bitmap of size sw*sh to position
  256. // (sx,sy) on top of bmp, only overwritting transparent pixels of the bitmap.
  257.  
  258. int mcockpit_create_inverted_bitblit( grs_bitmap * bmp, int sx, int sy, int sw, int sh, int srowsize, ubyte transparent_color, ubyte * code )
  259. {
  260.     int x,y;
  261.     ubyte pixel;
  262.     int draw_mode = MODE_NONE;
  263.     int source_offset = 0;
  264.     int dest_offset = 0;
  265.     int num_to_draw, draw_start_source, draw_start_dest;
  266.     int esi, edi;
  267.  
  268.     Code_pointer = code;
  269.  
  270.     esi = source_offset = 0;
  271.  
  272.     for ( y=sy; y<sy+sh; y++ )    {
  273.         for ( x=sx; x<sx+sw; x++ )    {
  274.             dest_offset = y*bmp->bm_rowsize+x;
  275.             pixel = bmp->bm_data[dest_offset];
  276.             if ( pixel!=transparent_color )    {
  277.                 switch ( draw_mode)    {
  278.                 case MODE_DRAW:
  279.                     move_and_draw( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  280.                     esi = draw_start_source + num_to_draw;
  281.                     edi = draw_start_dest + num_to_draw;
  282.                     // fall through!!!
  283.                 case MODE_NONE:
  284.                 case MODE_SKIP:
  285.                     break;
  286.                 }
  287.                 draw_mode = MODE_SKIP;
  288.             } else {
  289.                 switch ( draw_mode)    {
  290.                 case MODE_SKIP:
  291.                 case MODE_NONE:
  292.                     draw_start_source = source_offset;
  293.                     draw_start_dest = dest_offset;
  294.                     num_to_draw = 0;
  295.                     // fall through
  296.                 case MODE_DRAW:
  297.                     num_to_draw++;
  298.                     break;
  299.                 }
  300.                 draw_mode = MODE_DRAW;
  301.             }
  302.             source_offset++;
  303.         }
  304.         if ( draw_mode == MODE_DRAW )    {
  305.             move_and_draw( draw_start_source-esi, draw_start_dest-edi, num_to_draw );
  306.             esi = draw_start_source + num_to_draw;
  307.             edi = draw_start_dest + num_to_draw;
  308.         }
  309.         draw_mode = MODE_NONE;
  310.         source_offset += (srowsize - sw);
  311.     }
  312.     *Code_pointer++ = OPCODE_RET;
  313.  
  314.     //printf( "Code is %d bytes\n", Code_pointer - code );
  315.  
  316.     return 0;
  317. }
  318.  
  319.  
  320. void mcockpit_do_inverted_bitblit_asm(char *start_si, char *start_di, ubyte * code);
  321. #pragma aux mcockpit_do_inverted_bitblit_asm parm [esi] [edi] [eax] modify [ecx edi esi eax] = \
  322.     "pusha"    \
  323.     "call    eax"    \
  324.     "popa"
  325.  
  326. void mcockpit_do_inverted_bitblit(char *start_si, char *start_di, ubyte * code)
  327. {
  328.     if (code != NULL )
  329.         mcockpit_do_inverted_bitblit_asm( start_si, start_di, code );
  330. }
  331.  
  332.  
  333. void mcockpit_find_extents( grs_bitmap * bmp, int *minx, int *miny, int *maxx, int *maxy )
  334. {
  335.     ubyte c;
  336.     int x, y;
  337.  
  338.     *minx = 0;
  339.     *maxx = bmp->bm_w;
  340.     *miny = 0;
  341.     *maxy = bmp->bm_h;
  342.  
  343.     for ( y=0; y<bmp->bm_h; y++ )
  344.         for ( x=0; x<bmp->bm_w; x++ )    {
  345.             c = bmp->bm_data[bmp->bm_rowsize*y+x];
  346.             if (c == iff_transparent_color )    {
  347.                 if ( x < *minx ) *minx = x;
  348.                 if ( y < *miny ) *miny = y;
  349.                 if ( x > *maxx ) *maxx = x;
  350.                 if ( y > *maxy ) *maxy = y;
  351.             }
  352.         }
  353. }
  354.  
  355. */
  356. 
  357.