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