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