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