home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / JAGUAR / JAG_SRC / SOURCE / OBJECT.C < prev    next >
C/C++ Source or Header  |  2001-08-18  |  20KB  |  482 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Jagulator: Atari Jaguar Console Emulation Project (object.c)
  3. // -----------------------------------------------------------------------------
  4. // Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is" 
  5. // without any expressed or implied warranty. I have no Trademarks, Legal or 
  6. // otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All 
  7. // other Copyrights and Trademarks are acknowledged. This project is in no way 
  8. // linked to Atari/Hasbro or other associated Atari companies.                
  9.  
  10. #include "core.h"
  11.  
  12. ////////////////////////////////////////////////////////////////////////////////
  13. // Macros
  14.  
  15. //#define DBGOP                          // Include Object Processor Debug Code
  16.  
  17. ////////////////////////////////////////////////////////////////////////////////
  18. // Globals
  19.  
  20.    static GLuint fi[0x2EC00];          // Frame Image (512 x 374)
  21.    static dword tolp;                  // Traversing Object List Pointer
  22.    static char *iolp;                  // Internal Object Pointer
  23.    static dword hi, lo;                // Object Phrase Hi and Lo Words
  24.    static dword olir;                  // Object List in Cartridge Rom Flag
  25.  
  26.    extern GLuint clut[];               // RGBA Translation of CrY CLUT Table
  27.  
  28. ////////////////////////////////////////////////////////////////////////////////
  29. // Process a Standard Bitmap or Scaled Bitmap Object
  30.  
  31.    void object_bitmap( dword scale )
  32.    {
  33.       word   xpos;                     // X Position of First Pixel
  34.       word   ypos;                     // Y Position (in Half Lines)
  35.       word   height;                   // Number of Data Lines in Object
  36.       word   depth;                    // Bits Per Pixel
  37.       word   pitch;                    // Skipping
  38.       word   dwidth;                   // Data Width in Phrases
  39.       word   iwidth;                   // Image Width in Phrases
  40.       word   index;                    // Pallette Address Element
  41.       word   flags;                    // Reflect, RMW, Trans, Release
  42.       word   fpix;                     // First Pixel to be Displayed
  43.       dword  link;                     // Address of Next Object
  44.       dword  data;                     // Address of Pixel Data
  45.       dword  temp;                     // Temporary Bit Data
  46.       word   hscale;                   // Horizontal Scaling
  47.       word   vscale;                   // Vertical Scaling
  48.       word   remainder;                // Scaling Remainder
  49.       dword  trans;                    // Transparency Flag
  50.       static int bpp[6] = { 1, 2, 4, 8, 16, 24 };
  51.       word   wpil;                     // 16 Bit Words Per Image Line
  52.       word   wpdl;                     // 16 Bit Words Per Data Line
  53.       word   ddil;                     // 16 Bit Words Difference Above
  54.       dword  index_d;                  // Index * 2 (To Reduce Calc Time)
  55.  
  56.       // Process First Bitmap Object Phrase. First Phrase Obtained from
  57.       // Object Processor List Execution Routine object_exec()
  58.       ypos    = (lo & O_YPOS  ) >> 3;
  59.       height  = (lo & O_HEIGHT) >> 14;
  60.       temp    = (lo & O_LINK1 ) >> 24;
  61.       temp   |= (hi & O_LINK2 ) << 8;
  62.       link    = (temp << 3) | (tolp & 0xFFE00007);
  63.       data    = (hi & O_DATA  ) >> 8;
  64.  
  65.       // Obtain Second Bitmap Phrase
  66.       hi  = *(word *)(iolp +  8) << 16;
  67.       hi |= *(word *)(iolp + 10);
  68.       lo  = *(word *)(iolp + 12) << 16;
  69.       lo |= *(word *)(iolp + 14);
  70.  
  71.       // Process Second Bitmap Object Phrase
  72.       xpos    = (lo & O_XPOS   );
  73.       depth   = (lo & O_DEPTH  ) >> 12;
  74.       pitch   = (lo & O_PITCH  ) >> 15;
  75.       dwidth  = (lo & O_DWIDTH ) >> 18;
  76.       iwidth  = (lo & O_IWIDTH1) >> 28;
  77.       iwidth |= (hi & O_IWIDTH2) << 4;
  78.       index   = (hi & O_INDEX  ) >> 6;
  79.       flags   = (hi & O_FLAGS  );
  80.       fpix    = (hi & O_1STPIX ) >> 17;
  81.  
  82.       index_d = (2 * index);
  83.  
  84.       // Obtain and Process Third Bitmap Object Phrase if Scaled Object
  85.       if( scale )
  86.       {
  87.          hi  = *(word *)(iolp + 16) << 16;
  88.          hi |= *(word *)(iolp + 18);
  89.          lo  = *(word *)(iolp + 20) << 16;
  90.          lo |= *(word *)(iolp + 22);
  91.  
  92.          hscale    = (lo & O_HSCALE);
  93.          vscale    = (lo & O_VSCALE) >> 8;
  94.          remainder = (lo & O_REMAIN) >> 16;
  95.       }
  96.  
  97.       #ifdef DBGOP
  98.       if( scale )
  99.          print( BLUE"Object List: Scaled Bitmap Object (OLP = 0x%08X)\n",tolp );
  100.       else
  101.          print( BLUE"Object List: Bitmap Object (OLP = 0x%08X)\n", tolp );
  102.       print( "YPOS     : 0x%04X (%04i/2 = %04i)     HEIGHT : 0x%04X (%04i)\n",
  103.              ypos, ypos, ypos/2, height, height );
  104.       print( "LINK     : 0x%08X                 DATA   : 0x%08X\n",link, data );
  105.       print( "XPOS     : 0x%04X (%04i)              DEPTH  : 0x%04X\n", 
  106.              xpos, xpos, depth );
  107.       print( "PITCH    : 0x%04X   DWIDTH : 0x%04X   IWIDTH : 0x%04X   INDEX   "
  108.              ": 0x%04X\n", pitch, dwidth, iwidth, index );
  109.       print( "REFLECT  : 0x%01X      RMW    : 0x%01X      TRANS  : 0x%01X      "
  110.              "RELEASE : 0x%01X\n", flags & 0x01, (flags & 0x02) >> 1, 
  111.              (flags & 0x04) >> 2, (flags & 0x08) >> 3 );
  112.       print( "FIRSTPIX : 0x%04X   ", fpix );
  113.       if( scale )
  114.          print( "HSCALE : 0x%04X   VSCALE : 0x%04X   REMAIN  : 0x%04X\n", 
  115.                 hscale, vscale, remainder );
  116.       print( "Image = %i x %i\n", (dwidth * 64) / bpp[depth], height );
  117.       #endif
  118.  
  119.       // Activate Transparency if Required
  120.       if( (flags & O_TRANS) )    
  121.       {
  122.          clut[0]       &= 0x00FFFFFF;
  123.          clut[index_d] &= 0x00FFFFFF;
  124.          trans = 1;
  125.       }
  126.       else        
  127.       {
  128.          clut[0]       |= 0xFF000000;
  129.          clut[index_d] |= 0xFF000000;
  130.          trans = 0;
  131.       }
  132.  
  133.       // Write Image Data to Frame Image
  134.       {
  135.          int x;                        // Frame Image Index
  136.          int i, j;                     // Loop Iterators
  137.          dword dw, addr;               // Data Word and Address
  138.  
  139.          wpil = (iwidth * 8) / 2;      // Number of Words Per Visible Data Line
  140.          wpdl = (dwidth * 8) / 2;      // Number of Words Per Actual Data Line
  141.          ddil = (wpdl - wpil) * 2;     // Difference Between Image & Data Lines
  142.  
  143.          addr = data;                  // Get Jaguar Data Address
  144.  
  145.          switch( depth )
  146.          {
  147.             // --- 1BPP [CLUT] -------------------------------------------------
  148.             case 0:               
  149.                x = 0;                  // Initialise Frame Image Index
  150.                // Lines
  151.                for( i = height; i > 0; i-- )
  152.                {
  153.                   // Pixels
  154.                   for( j = 0; j < wpil; j ++ )
  155.                   {
  156.                      // Read 16 Bit Word from Jaguar Memory
  157.                      dw = mem_readword( addr );
  158.                      // Update Frame Image using the CLUT
  159.                      fi[x++] = clut[(index_d + ((dw & 0x8000) >> 15))];
  160.                      fi[x++] = clut[(index_d + ((dw & 0x4000) >> 14))];
  161.                      fi[x++] = clut[(index_d + ((dw & 0x2000) >> 13))];
  162.                      fi[x++] = clut[(index_d + ((dw & 0x1000) >> 12))];
  163.                      fi[x++] = clut[(index_d + ((dw & 0x0800) >> 11))];
  164.                      fi[x++] = clut[(index_d + ((dw & 0x0400) >> 10))];
  165.                      fi[x++] = clut[(index_d + ((dw & 0x0200) >> 9 ))];
  166.                      fi[x++] = clut[(index_d + ((dw & 0x0100) >> 8 ))];
  167.                      fi[x++] = clut[(index_d + ((dw & 0x0080) >> 7 ))];
  168.                      fi[x++] = clut[(index_d + ((dw & 0x0040) >> 6 ))];
  169.                      fi[x++] = clut[(index_d + ((dw & 0x0020) >> 5 ))];
  170.                      fi[x++] = clut[(index_d + ((dw & 0x0010) >> 4 ))];
  171.                      fi[x++] = clut[(index_d + ((dw & 0x0008) >> 3 ))];
  172.                      fi[x++] = clut[(index_d + ((dw & 0x0004) >> 2 ))];
  173.                      fi[x++] = clut[(index_d + ((dw & 0x0002) >> 1 ))];
  174.                      fi[x++] = clut[(index_d + ((dw & 0x0001)      ))];
  175.                      // Increment Jaguar Memory Address
  176.                      addr += 2;
  177.                   }
  178.                   // Increment Jaguar Memory Address Dependant on Differences
  179.                   // Between The Data Width and Image Width
  180.                   addr += ddil;
  181.                }
  182.                break;
  183.  
  184.             // --- 2BPP [CLUT] -------------------------------------------------
  185.             case 1:                
  186.                x = 0;                  // Initialise Frame Image Index
  187.                // Lines
  188.                for( i = height; i > 0; i-- )
  189.                {
  190.                   // Pixels
  191.                   for( j = 0; j < wpil; j ++ )
  192.                   {
  193.                      // Read 16 Bit Word from Jaguar Memory
  194.                      dw = mem_readword( addr );
  195.                      // Update Frame Image using the CLUT
  196.                      fi[x++] = clut[(index_d + ((dw & 0xC000) >> 14))];
  197.                      fi[x++] = clut[(index_d + ((dw & 0x3000) >> 12))];
  198.                      fi[x++] = clut[(index_d + ((dw & 0x0C00) >> 10))];
  199.                      fi[x++] = clut[(index_d + ((dw & 0x0300) >> 8 ))];
  200.                      fi[x++] = clut[(index_d + ((dw & 0x00C0) >> 6 ))];
  201.                      fi[x++] = clut[(index_d + ((dw & 0x0030) >> 4 ))];
  202.                      fi[x++] = clut[(index_d + ((dw & 0x000C) >> 2 ))];
  203.                      fi[x++] = clut[(index_d + ((dw & 0x0003)      ))];
  204.                      // Increment Jaguar Memory Address
  205.                      addr += 2;
  206.                   }
  207.                   // Increment Jaguar Memory Address Dependant on Differences
  208.                   // Between The Data Width and Image Width
  209.                   addr += ddil;
  210.                }
  211.                break;
  212.  
  213.             // --- 4BPP [CLUT] -------------------------------------------------
  214.             case 2:               
  215.                x = 0;                  // Initialise Frame Image Index
  216.                // Lines
  217.                for( i = height; i > 0; i-- )
  218.                {
  219.                   // Pixels
  220.                   for( j = 0; j < wpil; j ++ )
  221.                   {
  222.                      // Read 16 Bit Word from Jaguar Memory
  223.                      dw = mem_readword( addr );
  224.                      // Update Frame Image using the CLUT
  225.                      fi[x++] = clut[(index_d + ((dw & 0xF000) >> 12))];
  226.                      fi[x++] = clut[(index_d + ((dw & 0x0F00) >> 8 ))];
  227.                      fi[x++] = clut[(index_d + ((dw & 0x00F0) >> 4 ))];
  228.                      fi[x++] = clut[(index_d + ((dw & 0x000F)      ))];
  229.                      // Increment Jaguar Memory Address
  230.                      addr += 2;
  231.                   }
  232.                   // Increment Jaguar Memory Address Dependant on Differences
  233.                   // Between The Data Width and Image Width
  234.                   addr += ddil;
  235.                }
  236.                break;
  237.  
  238.             // --- 8BPP [CLUT] -------------------------------------------------
  239.             case 3:
  240.                x = 0;                  // Initialise Frame Image Index
  241.                // Lines
  242.                for( i = height; i > 0; i-- )
  243.                {
  244.                   // Pixels
  245.                   for( j = 0; j < wpil; j ++ )
  246.                   {
  247.                      // Read 16 Bit Word from Jaguar Memory
  248.                      dw = mem_readword( addr );
  249.                      // Update Frame Image using the CLUT
  250.                      fi[x++] = clut[((dw & 0xFF00) >> 8)];
  251.                      fi[x++] = clut[((dw & 0x00FF)     )];
  252.                      // Increment Jaguar Memory Address
  253.                      addr += 2;
  254.                   }
  255.                   // Increment Jaguar Memory Address Dependant on Differences
  256.                   // Between The Data Width and Image Width
  257.                   addr += ddil;
  258.                }
  259.                break;
  260.  
  261.             // --- 16BPP -------------------------------------------------------
  262.             case 4:                 // 16 Bpp - 65536 Colors 
  263.                x = 0;                  // Initialise Frame Image Index
  264.                switch( gst.cmode )
  265.                {
  266.                   case 0:              // CRY16
  267.                      // Lines
  268.                      for( i = height; i > 0; i-- )
  269.                      {
  270.                         // Pixels
  271.                         for( j = 0; j < wpil; j ++ )
  272.                         {
  273.                            // Read 16 Bit Word from Jaguar Memory
  274.                            dw = mem_readword( addr );
  275.                            // Update Frame Image
  276.                            fi[x++] = cry16_rgb32( dw, trans );
  277.                            // Increment Jaguar Memory Address
  278.                            addr += 2;
  279.                         }
  280.                         // Increment Jaguar Memory Address Dependant on 
  281.                         // Differences Between The Data Width and Image Width
  282.                         addr += ddil;
  283.                      }
  284.                      break;
  285.                   case 3:              // RGB16
  286.                      // Lines
  287.                      for( i = height; i > 0; i-- )
  288.                      {
  289.                         // Pixels
  290.                         for( j = 0; j < wpil; j ++ )
  291.                         {
  292.                            // Read 16 Bit Word from Jaguar Memory
  293.                            dw = mem_readword( addr );
  294.                            // Update Frame Image
  295.                            fi[x++] = rgb16_rgb32( dw, trans );
  296.                            // Increment Jaguar Memory Address
  297.                            addr += 2;
  298.                         }
  299.                         // Increment Jaguar Memory Address Dependant on 
  300.                         // Differences Between The Data Width and Image Width
  301.                         addr += ddil;
  302.                      }
  303.                      break;
  304.                   default:
  305.                      #ifdef DBGOP
  306.                      error( "OP-BMP: Unsupported 16-Bit Color Mode [%i]", 
  307.                             gst.cmode );
  308.                      #endif
  309.                      break;
  310.                }
  311.                break;
  312.  
  313.             // --- 24BPP -------------------------------------------------------
  314.             case 5:  
  315.                #ifdef DBGOP
  316.                error( "OP-BMP: Unsupported Color Depth [%i]", depth );
  317.                #endif
  318.                break;
  319.          }
  320.       }
  321.  
  322.       // Set Pixel X, Y Position
  323.       glRasterPos2i( xpos, (ypos / 2) );
  324.  
  325.       // Draw with Correct Orientation and Scaling if Required
  326.       if( scale )
  327.       {
  328.          glPixelZoom(  (GLfloat)((1.0 / 32.0) * hscale), 
  329.                      -((GLfloat)((1.0 / 32.0) * vscale)) );
  330.       }
  331.       else
  332.       {
  333.          glPixelZoom( 1.0, -1.0 );
  334.       }
  335.  
  336.       // Send Image to Back Buffer
  337.       glDrawPixels( ((iwidth * 64) / bpp[depth]), height, 
  338.                     GL_RGBA, GL_UNSIGNED_BYTE, &fi );
  339.  
  340.       #ifdef DBGOP
  341.       glBegin( GL_QUADS );
  342.       glVertex2i( xpos, (ypos / 2) );
  343.       glVertex2i( xpos + ((iwidth * 64) / bpp[depth]), (ypos / 2) );
  344.       glVertex2i( xpos + ((iwidth * 64) / bpp[depth]), (ypos / 2) + height );
  345.       glVertex2i( xpos, (ypos / 2) + height );
  346.       glEnd();
  347.       #endif
  348.  
  349.       // Obtain Link Address to Next Object
  350.       tolp = link;
  351.    }
  352.  
  353. ////////////////////////////////////////////////////////////////////////////////
  354. // Process a Branch Object
  355.  
  356.    void object_branch( void )
  357.    {
  358.       static dword link;
  359.  
  360.       link = ((lo & 0xFF000000) >> 21) | ((hi & 0x000007FF) << 11);
  361.  
  362.       #ifdef DBGOP
  363.       print( BLUE"Object List - Branch Object (OLP = 0x%08X)\n", tolp );
  364.       print( "YPOS = 0x%04X  LINK = 0x%06X\n",(lo & 0x3FF8) >> 3, link );
  365.       #endif
  366.       switch( ((lo & 0x0001C000) >> 14) )
  367.       {
  368.          case O_BREQ: 
  369.             #ifdef DBGOP
  370.             print( "Branch to Link if YPOS==VC or YPOS==7FF\n" ); 
  371.             #endif
  372.             tolp = link;
  373.             break;
  374.          case O_BRGT: 
  375.             #ifdef DBGOP
  376.             print( "Branch to Link if YPOS > VC\n" ); 
  377.             #endif
  378.             tolp += 8;
  379.             break;
  380.          case O_BRLT: 
  381.             #ifdef DBGOP
  382.             print( "Branch to Link if YPOS < VC\n" ); 
  383.             #endif
  384.             tolp += 8;
  385.             break;
  386.          case O_BROP: 
  387.             #ifdef DBGOP
  388.             print( YEL"Branch to Link if Object Processor Flag Set\n" ); 
  389.             #endif
  390.             gst.olista = FALSE;
  391.             break;
  392.          case O_BRHALF: 
  393.             #ifdef DBGOP
  394.             print( YEL"Branch to Link if on Second Half of Display Line\n" ); 
  395.             #endif
  396.             gst.olista = FALSE;
  397.             break;
  398.       }
  399.    }
  400.  
  401. ////////////////////////////////////////////////////////////////////////////////
  402. // Process a Stop Object
  403.  
  404.    void object_stop( void )
  405.    {
  406.       #ifdef DBGOP
  407.       print( BLUE"Object List - Stop Object (OLP = 0x%08X)\n", tolp );
  408.       if( (hi & 0xFFFFFFFF) && (lo & 0xFFFFFFF8) )
  409.           error( "Unhandled STOP Object Data" );
  410.       #endif
  411.       gst.olista = FALSE;
  412.    }
  413.  
  414. ////////////////////////////////////////////////////////////////////////////////
  415. // Object Processor Execution
  416.  
  417.    void object_exec( void )
  418.    {
  419.       if( !gst.vmode ) return;         // Don't Continue if Video Mode Not Set
  420.       
  421.       #ifdef DBGOP
  422.       print( CYAN"Object Processor Starting...\n" );
  423.       #endif
  424.  
  425.       gst.objActive = TRUE;            // Object Processing is Starting
  426.  
  427.       obj_framestart();
  428.  
  429.       #ifdef DBGOP
  430.       // Wireframe Mode
  431.       glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  432.       #endif
  433.  
  434.       // Setup Transparency Dependant on Alpha Channel (0=Transparent, 1=Opaque)
  435.       glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  436.       glEnable( GL_BLEND );
  437.  
  438.       tolp = gst.olp;                  // Set Traversing Object List Pointer
  439.       if( tolp >= 0x800000 ) olir = 1;
  440.       else                   olir = 0;
  441.       gst.olista = TRUE;               // Set Object List Active Flag
  442.  
  443.       while( gst.olista )              // Process Object List
  444.       {
  445.          // Set Memory Pointer Dependant on Object List Location
  446.          if( olir ) iolp = (st.game + (tolp - 0x800000));
  447.          else       iolp = (st.ram + tolp);
  448.  
  449.          // Get Object List Phrase
  450.          hi  = *(word *)(iolp    ) << 16;
  451.          hi |= *(word *)(iolp + 2);
  452.          lo  = *(word *)(iolp + 4) << 16;
  453.          lo |= *(word *)(iolp + 6);
  454.  
  455.          switch( lo & O_MASK_TYPE )
  456.          {
  457.             case BITOBJ:    object_bitmap( 0 ); break;
  458.             case SCBITOBJ:  object_bitmap( 1 ); break;
  459.             case STOPOBJ:   object_stop();      break;
  460.             case BRANCHOBJ: object_branch();    break;
  461.             case GPUOBJ:
  462.             default:
  463.                #ifdef DBG
  464.                print( YEL"OP - Unknown Object Type\n" );
  465.                #endif
  466.                gst.olista = FALSE;
  467.                break;
  468.          }
  469.       }
  470.  
  471.       obj_frameend();
  472.  
  473.       gst.objActive = FALSE;           // Object Processing is Terminating
  474.       
  475.       #ifdef DBGOP
  476.       print( BROWN"Displayed Frame %i\n", gst.frame++ );
  477.       print( RED"Object Processor Stopping...\n" );
  478.       #endif
  479.    }
  480.  
  481.  
  482.