home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / Mode5.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  10.0 KB  |  406 lines

  1. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
  2. // Copyright (C) 1999-2003 Forgotten
  3. // Copyright (C) 2004 Forgotten and the VBA development team
  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, or(at your option)
  8. // 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, write to the Free Software Foundation,
  17. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19. #include "GBA.h"
  20. #include "Globals.h"
  21. #include "Gfx.h"
  22.  
  23. void mode5RenderLine()
  24. {
  25.   if(DISPCNT & 0x0080) {
  26.     for(int x = 0; x < 240; x++) {
  27.       lineMix[x] = 0x7fff;
  28.     }
  29.     gfxLastVCOUNT = VCOUNT;    
  30.     return;
  31.   }
  32.  
  33.   u16 *palette = (u16 *)paletteRAM;
  34.  
  35.   if(layerEnable & 0x0400) {
  36.     int changed = gfxBG2Changed;
  37.  
  38.     if(gfxLastVCOUNT > VCOUNT)
  39.       changed = 3;
  40.     
  41.     gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
  42.                              BG2Y_L, BG2Y_H, BG2PA, BG2PB,
  43.                              BG2PC, BG2PD,
  44.                              gfxBG2X, gfxBG2Y, changed,
  45.                              line2);
  46.   }
  47.  
  48.   gfxDrawSprites(lineOBJ);
  49.  
  50.   u32 background = (READ16LE(&palette[0]) | 0x30000000);
  51.   
  52.   for(int x = 0; x < 240; x++) {
  53.     u32 color = background;
  54.     u8 top = 0x20;
  55.  
  56.     if(line2[x] < color) {
  57.       color = line2[x];
  58.       top = 0x04;
  59.     }
  60.  
  61.     if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
  62.       color = lineOBJ[x];
  63.       top = 0x10;
  64.     }
  65.  
  66.     if((top & 0x10) && (color & 0x00010000)) {
  67.       // semi-transparent OBJ
  68.       u32 back = background;
  69.       u8 top2 = 0x20;
  70.       
  71.       if(line2[x] < back) {
  72.         back = line2[x];
  73.         top2 = 0x04;
  74.       }
  75.       
  76.       if(top2 & (BLDMOD>>8))
  77.         color = gfxAlphaBlend(color, back,
  78.                               coeff[COLEV & 0x1F],
  79.                               coeff[(COLEV >> 8) & 0x1F]);
  80.       else {
  81.         switch((BLDMOD >> 6) & 3) {
  82.         case 2:
  83.           if(BLDMOD & top)
  84.             color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
  85.           break;
  86.         case 3:
  87.           if(BLDMOD & top)
  88.             color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
  89.           break;
  90.         }         
  91.       }      
  92.     }    
  93.       
  94.     lineMix[x] = color;
  95.   }
  96.   gfxBG2Changed = 0;
  97.   gfxLastVCOUNT = VCOUNT;  
  98. }
  99.  
  100. void mode5RenderLineNoWindow()
  101. {
  102.   if(DISPCNT & 0x0080) {
  103.     for(int x = 0; x < 240; x++) {
  104.       lineMix[x] = 0x7fff;
  105.     }
  106.     gfxLastVCOUNT = VCOUNT;    
  107.     return;
  108.   }
  109.  
  110.   u16 *palette = (u16 *)paletteRAM;
  111.  
  112.   if(layerEnable & 0x0400) {
  113.     int changed = gfxBG2Changed;
  114.  
  115.     if(gfxLastVCOUNT > VCOUNT)
  116.       changed = 3;
  117.     
  118.     gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
  119.                              BG2Y_L, BG2Y_H, BG2PA, BG2PB,
  120.                              BG2PC, BG2PD,
  121.                              gfxBG2X, gfxBG2Y, changed,
  122.                              line2);
  123.   }
  124.  
  125.   gfxDrawSprites(lineOBJ);
  126.  
  127.   u32 background = ( READ16LE(&palette[0]) | 0x30000000);
  128.   
  129.   for(int x = 0; x < 240; x++) {
  130.     u32 color = background;
  131.     u8 top = 0x20;
  132.  
  133.     if(line2[x] < color) {
  134.       color = line2[x];
  135.       top = 0x04;
  136.     }
  137.  
  138.     if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
  139.       color = lineOBJ[x];
  140.       top = 0x10;
  141.     }
  142.  
  143.     if(!(color & 0x00010000)) {
  144.       switch((BLDMOD >> 6) & 3) {
  145.       case 0:
  146.         break;
  147.       case 1:
  148.         {
  149.           if(top & BLDMOD) {
  150.             u32 back = background;
  151.             u8 top2 = 0x20;
  152.             
  153.             if(line2[x] < back) {
  154.               if(top != 0x04) {
  155.                 back = line2[x];
  156.                 top2 = 0x04;
  157.               }
  158.             }
  159.             
  160.             if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
  161.               if(top != 0x10) {
  162.                 back = lineOBJ[x];
  163.                 top2 = 0x10;
  164.               }
  165.             }
  166.             
  167.             if(top2 & (BLDMOD>>8))
  168.               color = gfxAlphaBlend(color, back,
  169.                                     coeff[COLEV & 0x1F],
  170.                                     coeff[(COLEV >> 8) & 0x1F]);
  171.             
  172.           }
  173.         }
  174.         break;
  175.       case 2:
  176.         if(BLDMOD & top)
  177.           color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
  178.         break;
  179.       case 3:
  180.         if(BLDMOD & top)
  181.           color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
  182.         break;
  183.       }
  184.     } else {
  185.       // semi-transparent OBJ
  186.       u32 back = background;
  187.       u8 top2 = 0x20;
  188.       
  189.       if(line2[x] < back) {
  190.         back = line2[x];
  191.         top2 = 0x04;
  192.       }
  193.       
  194.       if(top2 & (BLDMOD>>8))
  195.         color = gfxAlphaBlend(color, back,
  196.                               coeff[COLEV & 0x1F],
  197.                               coeff[(COLEV >> 8) & 0x1F]);
  198.       else {
  199.         switch((BLDMOD >> 6) & 3) {
  200.         case 2:
  201.           if(BLDMOD & top)
  202.             color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
  203.           break;
  204.         case 3:
  205.           if(BLDMOD & top)
  206.             color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
  207.           break;
  208.         }         
  209.       }      
  210.     }    
  211.       
  212.     lineMix[x] = color;
  213.   }
  214.   gfxBG2Changed = 0;
  215.   gfxLastVCOUNT = VCOUNT;  
  216. }
  217.  
  218. void mode5RenderLineAll()
  219. {
  220.   if(DISPCNT & 0x0080) {
  221.     for(int x = 0; x < 240; x++) {
  222.       lineMix[x] = 0x7fff;
  223.     }
  224.     gfxLastVCOUNT = VCOUNT;    
  225.     return;
  226.   }
  227.  
  228.   u16 *palette = (u16 *)paletteRAM;
  229.  
  230.   if(layerEnable & 0x0400) {
  231.     int changed = gfxBG2Changed;
  232.  
  233.     if(gfxLastVCOUNT > VCOUNT)
  234.       changed = 3;
  235.     
  236.     gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
  237.                              BG2Y_L, BG2Y_H, BG2PA, BG2PB,
  238.                              BG2PC, BG2PD,
  239.                              gfxBG2X, gfxBG2Y, changed,
  240.                              line2);
  241.   }
  242.  
  243.   gfxDrawSprites(lineOBJ);
  244.   gfxDrawOBJWin(lineOBJWin);
  245.  
  246.   bool inWindow0 = false;
  247.   bool inWindow1 = false;
  248.  
  249.   if(layerEnable & 0x2000) {
  250.     u8 v0 = WIN0V >> 8;
  251.     u8 v1 = WIN0V & 255;
  252.     inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
  253.     if(v1 >= v0)
  254.       inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
  255.     else
  256.       inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
  257.   }
  258.   if(layerEnable & 0x4000) {
  259.     u8 v0 = WIN1V >> 8;
  260.     u8 v1 = WIN1V & 255;
  261.     inWindow1 = ((v0 == v1) && (v0 >= 0xe8));    
  262.     if(v1 >= v0)
  263.       inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
  264.     else
  265.       inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
  266.   }
  267.   
  268.   u8 inWin0Mask = WININ & 0xFF;
  269.   u8 inWin1Mask = WININ >> 8;
  270.   u8 outMask = WINOUT & 0xFF;
  271.  
  272.   u32 background = (READ16LE(&palette[0]) | 0x30000000);
  273.   
  274.   for(int x = 0; x < 240; x++) {
  275.     u32 color = background;
  276.     u8 top = 0x20;
  277.     u8 mask = outMask;
  278.  
  279.     if(!(lineOBJWin[x] & 0x80000000)) {
  280.       mask = WINOUT >> 8;
  281.     }
  282.  
  283.     if(inWindow1) {
  284.       if(gfxInWin1[x])
  285.         mask = inWin1Mask;
  286.     }
  287.  
  288.     if(inWindow0) {
  289.       if(gfxInWin0[x]) {
  290.         mask = inWin0Mask;
  291.       }
  292.     }
  293.  
  294.     if((mask & 4) && (line2[x] < color)) {
  295.       color = line2[x];
  296.       top = 0x04;
  297.     }
  298.  
  299.     if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
  300.       color = lineOBJ[x];
  301.       top = 0x10;
  302.     }
  303.  
  304.     if(mask & 32) {
  305.       if(!(color & 0x00010000)) {
  306.         switch((BLDMOD >> 6) & 3) {
  307.         case 0:
  308.           break;
  309.         case 1:
  310.           {
  311.             if(top & BLDMOD) {
  312.               u32 back = background;
  313.               u8 top2 = 0x20;
  314.               
  315.               if((mask & 4) && line2[x] < back) {
  316.                 if(top != 0x04) {
  317.                   back = line2[x];
  318.                   top2 = 0x04;
  319.                 }
  320.               }
  321.               
  322.               if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
  323.                 if(top != 0x10) {
  324.                   back = lineOBJ[x];
  325.                   top2 = 0x10;
  326.                 }
  327.               }
  328.               
  329.               if(top2 & (BLDMOD>>8))
  330.                 color = gfxAlphaBlend(color, back,
  331.                                       coeff[COLEV & 0x1F],
  332.                                       coeff[(COLEV >> 8) & 0x1F]);
  333.               
  334.             }
  335.           }
  336.           break;
  337.         case 2:
  338.           if(BLDMOD & top)
  339.             color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
  340.           break;
  341.         case 3:
  342.           if(BLDMOD & top)
  343.             color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
  344.           break;
  345.         }
  346.       } else {
  347.         // semi-transparent OBJ
  348.         u32 back = background;
  349.         u8 top2 = 0x20;
  350.         
  351.         if((mask & 4) && line2[x] < back) {
  352.           back = line2[x];
  353.           top2 = 0x04;
  354.         }
  355.         
  356.         if(top2 & (BLDMOD>>8))
  357.           color = gfxAlphaBlend(color, back,
  358.                                 coeff[COLEV & 0x1F],
  359.                                 coeff[(COLEV >> 8) & 0x1F]);
  360.         else {
  361.           switch((BLDMOD >> 6) & 3) {
  362.           case 2:
  363.             if(BLDMOD & top)
  364.               color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
  365.             break;
  366.           case 3:
  367.             if(BLDMOD & top)
  368.               color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
  369.             break;
  370.           }       
  371.         }
  372.       }
  373.     } else if(color & 0x00010000) {
  374.       // semi-transparent OBJ
  375.       u32 back = background;
  376.       u8 top2 = 0x20;
  377.       
  378.       if((mask & 4) && line2[x] < back) {
  379.         back = line2[x];
  380.         top2 = 0x04;
  381.       }
  382.       
  383.       if(top2 & (BLDMOD>>8))
  384.         color = gfxAlphaBlend(color, back,
  385.                               coeff[COLEV & 0x1F],
  386.                               coeff[(COLEV >> 8) & 0x1F]);
  387.       else {
  388.         switch((BLDMOD >> 6) & 3) {
  389.         case 2:
  390.           if(BLDMOD & top)
  391.             color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
  392.           break;
  393.         case 3:
  394.           if(BLDMOD & top)
  395.             color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
  396.           break;
  397.         }         
  398.       }
  399.     }
  400.       
  401.     lineMix[x] = color;
  402.   }
  403.   gfxBG2Changed = 0;
  404.   gfxLastVCOUNT = VCOUNT;  
  405. }
  406.