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