⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbagpu.cpp

📁 一个任天堂掌上游戏机NDS的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************** DSemu - The Next Generation                                             ** GBA scanline GPU: Plugin Implementation [gbagpu.cpp]                    ** Copyright Imran Nazar, 2005; released under the BSD public licence.     ***************************************************************************/#include <string>#include "defs.h"#include "events.h"#include "gbagpu.h"#include "config.h"#include "font5x7.h"#include "log.h"#include "err.h"//---Static private class members------------------------------------------// Every plugin has an INFO structure attached, with info about the plugin.PLUGININFO gbaGPU::pInfo={    PLUGIN_TYPE_GPU,    0x00010001,    "GBA graphics processor",    "DSemu-ng"};u8  *gbaGPU::VRAMb, *gbaGPU::OAMb;u16 *gbaGPU::VRAMh, *gbaGPU::PALh, *gbaGPU::OAMh;u32 *gbaGPU::VRAMw, *gbaGPU::PALw, *gbaGPU::OAMw;gbaGPU::IOREG gbaGPU::reg[0x30];// IO access flags: 1=Readable, 2=Writableint gbaGPU::rflags[0x30]={    3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,    3,3,3,3,3,3,3,0,3,3,3,0,0,0,0,0,};#define REG(x) reg[REG_ ## x].datau32 gbaGPU::BGX[2], gbaGPU::BGY[2];u8 gbaGPU::mospy[4];int gbaGPU::curline;std::string gbaGPU::pluginName;GUIPlugin *gbaGPU::GUI;int gbaGPU::palwinID;u32 *gbaGPU::palbuffer;u8 *gbaGPU::dispbuffer;int gbaGPU::ForceBG[4];// Convert a GBA 15-bit colour to 32-bit#define COLSHIFT(out, in) \{ \    *((out)+0) = ((in)<<3)&255; \    *((out)+1) = ((in)>>2)&255; \    *((out)+2) = ((in)>>7)&255; \    *((out)+3) = 0; \}// Table of function pointers to mode-specific renderersgbaGPU::modefptr gbaGPU::lineM[8]={    lineM0, lineM1, lineM2, lineM3,    lineM4, lineM5, lineMNULL, lineMNULL};//---Implementation--------------------------------------------------------// ACK: gladius (tile and rotated BG, and sprite renderers)void gbaGPU::scanTile(u8 *buf, int bg){    u16 bgcnt, scrnBase, charBase, hofs, vofs, x, y, tileIdx, tileY;    u16 tmpTileIdx, width=0, height=0, a, bgx, bgy, tileChar; u8 b=0, palnum;    u8 mosx, mospx, mosy;    bgcnt=reg[REG_BG0CNT+bg].data;    switch((bgcnt>>14)&3)    {        case 0: width=256; height=256; break;        case 1: width=512; height=256; break;        case 2: width=256; height=512; break;        case 3: width=512; height=512; break;    }    scrnBase=((bgcnt>>8)&0x1F)*0x400;    charBase=((bgcnt>>2)&0x3)*0x4000;    hofs=reg[REG_BG0HOFS+bg*2].data;    vofs=reg[REG_BG0VOFS+bg*2].data;/*    vramptr=VRAM+(VRAMmap[(lcd)*128]<<13);    vram8ptr=VRAM8+(VRAMmap[(lcd)*128]<<14);*/    if(bgcnt&0x0040)    {        mosx=(REG(MOSAIC)&0x000F);        mosy=((REG(MOSAIC)&0x00F0)>>4);        mospx=mosx; if(!curline) mospy[bg]=mosy;        mospy[bg]++; if(mospy[bg]<=mosy) vofs-=mospy[bg];        else mospy[bg]=0;    } else { mospx=0; mosx=0; }    if(bgcnt&0x0080)    {        bgy=((curline+vofs)&(height-1))/8;        tileIdx=scrnBase+(((bgy&31)*32));        switch((bgcnt>>14)&3)        {            case 2: if(bgy>=32) tileIdx += 32*32; break;            case 3: if(bgy>=32) tileIdx += 32*32*2; break;        }        tileY=((curline+vofs)&7)*8;        for(a=0;a<240;a++)        {            bgx=((a+hofs)&(width-1))/8;            tmpTileIdx=tileIdx+((bgx&31));            if(bgx>=32) tmpTileIdx += 32*32;            tileChar=VRAMh[tmpTileIdx];            x=(a+hofs)&7; y=tileY;            if(tileChar&0x0400) x=7-x;            if(tileChar&0x0800) y=56-y;            if(mospx>=mosx) b=VRAMb[charBase+((tileChar&0x03FF)*64)+x+y];            mospx++; if(mospx>mosx) mospx=0;            if(b) COLSHIFT(buf+a*4,PALh[b]);        }    } else {        bgy=((curline+vofs)&(height-1))/8;        tileIdx=scrnBase+(((bgy&31)*32));        switch((bgcnt>>14)&3)        {            case 2: if(bgy>=32) tileIdx += 32*32; break;            case 3: if(bgy>=32) tileIdx += 32*32*2; break;        }        tileY=((curline+vofs)&7)*4;        for(a=0;a<240;a++)        {            bgx=((a+hofs)&(width-1))/8;            tmpTileIdx=tileIdx+((bgx&31));            if(bgx>=32) tmpTileIdx += 32*32;            tileChar=VRAMh[tmpTileIdx];            x=(a+hofs)&7; y=tileY;            if(tileChar&0x0400) x=7-x;            if(tileChar&0x0800) y=28-y;            if(mospx>=mosx)            {                b=VRAMb[charBase+((tileChar&0x03FF)*32)+(x/2)+y];                if(x&1) b>>=4; b&=15;            }            palnum=((tileChar>>12)&15)*16;            mospx++; if(mospx>mosx) mospx=0;            if(b) COLSHIFT(buf+a*4,PALh[b+palnum]);        }    }}void gbaGPU::scanRot(u8 *buf, int bg){    u16 bgcnt, scrnBase, charBase;    u32 x,y; int ax,ay; s16 dx,dy; int trans; u8 mosx, mospx, mosy;    u16 tmpTileIdx, width=0, height=0, a, tileChar; u8 b=0;        bgcnt=REG(BG0CNT+bg); bg-=2;    trans=(bgcnt&0x2000)==0;    switch((bgcnt>>14)&3)    {        case 0: width=128; height=128; break;        case 1: width=256; height=256; break;        case 2: width=512; height=512; break;        case 3: width=1024; height=1024; break;    }    scrnBase=((bgcnt>>8)&0x1F)*0x800;    charBase=((bgcnt>>2)&0x3)*0x4000;    x=BGX[bg]; y=BGY[bg];    dx=REG(BG2PA+(bg*8)); dy=REG(BG2PC+(bg*8));    if(bgcnt&0x0040)    {        mosx=(REG(MOSAIC)&0x000F);        mosy=((REG(MOSAIC)&0x00F0)>>4);        mospx=mosx; if(!curline) mospy[bg]=mosy;        mospy[bg]++; if(mospy[bg]<=mosy) y-=mospy[bg]*256;        else mospy[bg]=0;    } else { mospx=0; mosx=0; }    for(a=0;a<240;a++)    {        ax=x>>8; ay=y>>8;        if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !trans)        {            tmpTileIdx=scrnBase+(((ay&(height-1))/8)*(width/8)+((ax&(width-1))/8));            tileChar=VRAMb[tmpTileIdx];            if(mospx>=mosx) b=VRAMb[charBase+tileChar*64+((ay&7)*8)+(ax&7)];            mospx+=(dx>>8); if(mospx>mosx) mospx=0;            if(b) COLSHIFT(buf+a*4,PALh[b]);        }        x+=dx; y+=dy;    }}void gbaGPU::sprites(u8 *buf, int pri){    u16 dispcnt=REG(DISPCNT), oamNum, attr0,attr1,attr2;    int x, y, i, width=-1, height=-1, rwidth, rheight, scale=1;    int spritey, baseSprite, baseInc, curIdx, palIdx; u8 b;    s16 dx,dmx,rx,dy,dmy,ry; int tx,ty,cx,cy,pitch,rotScaleParam;    if(!(dispcnt&0x1000)) return;    pri<<=10;    oamNum=128; do    {	width=0; height=0;        oamNum--;        attr2=OAMh[oamNum*4+2];        if((attr2&0x0C00)!=pri) continue;        attr0=OAMh[oamNum*4+0];        attr1=OAMh[oamNum*4+1];        x=attr1&0x01FF; y=attr0&0x00FF;                switch ((attr0 >> 14) & 3)                {                    case 0:                        // Square                        switch ((attr1 >> 14) & 3)                        {                            case 0: width = 8; height = 8; break;                            case 1: width = 16; height = 16; break;                            case 2: width = 32; height = 32; break;                            case 3: width = 64; height = 64; break;                        }                        break;                    case 1:                        // Horizontal Rectangle                        switch ((attr1 >> 14) & 3)                        {                            case 0: width = 16; height = 8; break;                            case 1: width = 32; height = 8; break;                            case 2: width = 32; height = 16; break;                            case 3: width = 64; height = 32; break;                        }                        break;                    case 2:                        // Vertical Rectangle                        switch ((attr1 >> 14) & 3)                        {                            case 0: width = 8; height = 16; break;                            case 1: width = 8; height = 32; break;                            case 2: width = 16; height = 32; break;                            case 3: width = 32; height = 64; break;                        }                        break;                }                rwidth=width; rheight=height;                if (attr0&0x0100)                    // Rot-scale on                    if (attr0&0x0200) { rwidth*=2; rheight*=2; }                else                    // Invalid sprite                    if (attr0&0x0200) width = -1;                if (width == -1)                    // Invalid sprite                    continue;                // Y clipping                if (y > ((y + rheight) & 0xff))                    if (curline >= ((y + rheight) & 0xff) && !(y < curline)) continue;                else                    if (curline < y || curline >= ((y + rheight) & 0xff)) continue;                if (attr0&0x2000) scale = 2;                spritey = curline - y;                if (spritey < 0) spritey += 256;                if (!(attr0&0x0100))                {                    if (attr1&0x2000) spritey = (height - 1) - spritey;                    if (dispcnt&0x0040)                        // 1 dimensional                        baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;                    else                        // 2 dimensional                        baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);                    baseInc = scale;                    if (attr1&0x1000)                    {                        baseSprite += ((width / 8) * scale) - scale;                        baseInc = -baseInc;                    }                    if (attr0&0x2000)                    {                        // 256 colors			//if(baseSprite && spritey>=0 && spritey<height)                        //printf("GPU: Line #%d: Sprite #%d: %dx%d at %d,%d, non-rotating, 8-bit\n",curline,oamNum,width,height,x,y);                        for (i = x; i < x + width; i++)                        {                            if ((i & 0x1ff) < 240 && spritey >= 0 && spritey < height)                            {                                tx = (i - x) & 7;                                if (attr1&0x1000) tx = 7 - tx;                                curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;                                b = VRAMb[0x10000 + curIdx];                                if (b) COLSHIFT(buf+(i&0x1ff)*4,PALh[b+256]);                            }                            if (((i - x) & 7) == 7) baseSprite += baseInc;                        }                    }                    else                    {                        // 16 colors			//if(baseSprite && spritey>=0 && spritey<height)                        //printf("GPU: Line #%d: Sprite #%d: %dx%d at %d,%d, non-rotating, 4-bit\n",curline,oamNum,width,height,x,y);                        palIdx = ((attr2 >> 8) & 0xF0);                        for (i = x; i < x + width; i++)                        {                            if ((i & 0x1ff) < 240 && spritey >= 0 && spritey < height)                            {                                tx = (i - x) & 7;                                if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;                                curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);                                b = VRAMb[0x10000 + curIdx];                                if (tx & 1) b>>=4; b&=15;                                if(b) COLSHIFT(buf+(i&0x1ff)*4, PALh[palIdx+b+256]);                            }                            if (((i - x) & 7) == 7) baseSprite += baseInc;                        }                    }                }                else                {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -