diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-04-16 06:22:51 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-04-16 06:22:51 +0000 |
| commit | 8139fbf8204882663446bcb06f68789353597820 (patch) | |
| tree | 6ea1f39932b33faee84d603e956470e37f135804 /plugins/dfOpenGL/primitive_drawing.c | |
| download | pcsxr-8139fbf8204882663446bcb06f68789353597820.tar.gz | |
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@23061 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/dfOpenGL/primitive_drawing.c')
| -rw-r--r-- | plugins/dfOpenGL/primitive_drawing.c | 1710 |
1 files changed, 1710 insertions, 0 deletions
diff --git a/plugins/dfOpenGL/primitive_drawing.c b/plugins/dfOpenGL/primitive_drawing.c new file mode 100644 index 00000000..8d2104bd --- /dev/null +++ b/plugins/dfOpenGL/primitive_drawing.c @@ -0,0 +1,1710 @@ +#include <stdlib.h> +#include <string.h> +#include "gpu_i.h" + +typedef unsigned char byte; + +byte texshade[256]; +uint32_t torgba[65536]; +uint32_t image[65536]; +char curText=0; +TextureState_t texinfo; +struct texturecache texture[64]; +GLuint nullid; + +struct TransparencySettings{ + int mode; + int src; + int dst; + byte alpha; + bool change; +}; + +struct TransparencySettings TransRate[4]={ + {GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,128,TRUE}, + {GL_FUNC_ADD, GL_ONE, GL_ONE_MINUS_SRC_ALPHA,0,TRUE}, + {GL_FUNC_ADD, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, 0,TRUE}, + {GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE,64,TRUE} +}; +bool transparent=FALSE; +byte gAlpha; + +void cmdSTP(unsigned char * baseAddr) +{ + uint32_t gdata = ((uint32_t*)baseAddr)[0]; + + GPUstatusRet&=~0x1800; // Clear the necessary bits + GPUstatusRet|=((gdata & 0x03) << 11); // Set the necessary bits + + psxDraw.setmask = gdata & 1; + psxDraw.testmask = (gdata & 2) >> 1; + + gllog(77," CMD: STP: %x",gdata&0xffffff); +} + + +inline void UpdateTextureInfo ( uint32_t gdata ) +{ + texinfo.x = ( gdata << 6 ) & 0x3c0; // texture addr + texinfo.y = ( gdata << 4 ) & 0x100; + + //if ( gdata&200 ) iDither=iUseDither; else iDither=0; + + texinfo.colormode = ( gdata >> 7 ) & 0x3; // tex mode (4bit,8bit,15direct) + if ( texinfo.colormode==3 ) + texinfo.colormode=2; // seen in Wild9 :( + + texinfo.abr = ( gdata >> 5 ) & 0x3; // blend mode + + texinfo.mirror = gdata&0x3000 >> 12; //??? + + GPUstatusRet&=~0x07ff; // Clear the necessary bits + GPUstatusRet|= ( gdata & 0x07ff ); // set the necessary bits +} + +void cmdTexturePage(unsigned char * baseAddr) +{ + uint32_t gdata = ((uint32_t*)baseAddr)[0]; + + int32_t tempABR = (gdata >> 5) & 0x3; + if(texinfo.abr != tempABR){ + texinfo.abr = tempABR; + //glBlendEquation(TransRate[texinfo.abr].mode); + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + gAlpha=TransRate[texinfo.abr].alpha; + transparent=TRUE; + } + UpdateTextureInfo(gdata); + + + /*switch(texinfo.abr){ + case 0: + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=128; + break; + case 1: + glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=0; + break; + case 2: + glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR); + gAlpha=0; + break; + case 3: + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + gAlpha=64; + break; + }*/ + //textREST = (gdata&0x00ffffff)>>9; + //gllog(77," CMD: TPage: %d,%d TP=%d ABR=%d REST=%x\n",textAddrX,textAddrY,textTP,texinfo.abr,(gdata&0x00ffffff)>>9); + return; +} + +void cmdTextureWindow(unsigned char *baseAddr) +{ + //hopefully true psx texture window emulation, oddities & all + //taken from peops soft gpu + + uint32_t gdata = ((uint32_t*)baseAddr)[0]; + //gllog(77,"CDM: TWin: %x *NI*", gdata&0xffffff); + + GPUInfoVals[INFO_TW]=gdata&0xFFFFF; + + uint32_t YAlign,XAlign; + + if(gdata & 0x020) + psxDraw.texwinY2 = 8; // xxxx1 + else if (gdata & 0x040) + psxDraw.texwinY2 = 16; // xxx10 + else if (gdata & 0x080) + psxDraw.texwinY2 = 32; // xx100 + else if (gdata & 0x100) + psxDraw.texwinY2 = 64; // x1000 + else if (gdata & 0x200) + psxDraw.texwinY2 = 128; // 10000 + else + psxDraw.texwinY2 = 256; // 00000 + + // Texture window size is determined by the least bit set of the relevant 5 bits + + if (gdata & 0x001) + psxDraw.texwinX2 = 8; // xxxx1 + else if (gdata & 0x002) + psxDraw.texwinX2 = 16; // xxx10 + else if (gdata & 0x004) + psxDraw.texwinX2 = 32; // xx100 + else if (gdata & 0x008) + psxDraw.texwinX2 = 64; // x1000 + else if (gdata & 0x010) + psxDraw.texwinX2 = 128; // 10000 + else + psxDraw.texwinX2 = 256; // 00000 + + // Re-calculate the bit field, because we can't trust what is passed in the data + + + YAlign = (uint32_t)(32 - (psxDraw.texwinY2 >> 3)); + XAlign = (uint32_t)(32 - (psxDraw.texwinX2 >> 3)); + + // Absolute position of the start of the texture window + + psxDraw.texwinY1 = (short)(((gdata >> 15) & YAlign) << 3); + psxDraw.texwinX1 = (short)(((gdata >> 10) & XAlign) << 3); + + if((psxDraw.texwinX1 == 0 && // tw turned off + psxDraw.texwinY1 == 0 && + psxDraw.texwinX2 == 0 && + psxDraw.texwinY2 == 0) || + (psxDraw.texwinX2 == 256 && + psxDraw.texwinY2 == 256)) + { + psxDraw.texwinenabled = 0; // -> just do it + } + else // otherwise + { + psxDraw.texwinenabled = 1; // -> tw turned on + } +} + +void cmdDrawAreaStart(unsigned char * baseAddr) +{ + uint32_t gdata = ((uint32_t*)baseAddr)[0]; + GPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF; + + psxDraw.clipX1 = gdata & 0x3ff; + psxDraw.clipY1 = (gdata>>10)&0x1ff; + + GLdouble equation[4]={0.0,0.0,0.0,0.0}; + equation[0]=1.0; + equation[3]=(GLdouble)-(psxDraw.clipX1); + glClipPlane(GL_CLIP_PLANE0,equation); + + equation[0]=0.0; + equation[1]=1.0; + equation[3]=(GLdouble)-(psxDraw.clipY1); + glClipPlane(GL_CLIP_PLANE1,equation); + + //gllog(77," CMD: DrawArea Start %d,%d %x",drawX,drawY,gdata); +} + +void cmdDrawAreaEnd(unsigned char * baseAddr) +{ + uint32_t gdata = ((uint32_t*)baseAddr)[0]; + GPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF; + + psxDraw.clipX2 = gdata & 0x3ff; + psxDraw.clipY2 = (gdata>>10)&0x1ff; + + GLdouble equation[4]={0.0,0.0,0.0,0.0}; + equation[0]=-1.0; + equation[3]=(GLdouble)(psxDraw.clipX2); + glClipPlane(GL_CLIP_PLANE2,equation); + + equation[0]=0.0; + equation[1]=-1.0; + equation[3]=(GLdouble)(psxDraw.clipY2); + glClipPlane(GL_CLIP_PLANE3,equation); + + + //gllog(77," CMD: DrawArea End %d,%d",drawW,drawH); +} + +void cmdDrawOffset(unsigned char * baseAddr) +{ + uint32_t gdata = ((uint32_t*)baseAddr)[0]; + GPUInfoVals[INFO_DRAWOFF]=gdata&0x7FFFFF; + + psxDraw.offsetX = (short)(gdata & 0x7ff); + psxDraw.offsetY = (short)((gdata>>11)&0x7ff); + + psxDraw.offsetX=(short)(((int)psxDraw.offsetX<<21)>>21); + psxDraw.offsetY=(short)(((int)psxDraw.offsetY<<21)>>21); + + //gllog(77," CMD: Draw Offset %d,%d",ofsX,ofsY,gdata); +} + +void primLoadImage(unsigned char * baseAddr) +{ + short *sgpuData = ((short *) baseAddr); + //uint32_t *gpuData = ((uint32_t *) baseAddr); + + short x = (sgpuData[2]<<21)>>21; + short y = (sgpuData[3]<<21)>>21; + short w = (sgpuData[4]<<21)>>21; + short h = (sgpuData[5]<<21)>>21; + + if (w == -1024) w = 1024; + if (h == -512) h = 512; + + if (x < 0 || y < 0 || w<0 || h<0 || x+w > 1024 || y+h > 512) + { + return; + } + + vramWrite.curx = vramWrite.x = x; + vramWrite.cury = vramWrite.y = y; + vramWrite.w = w; + vramWrite.h = h; + vramWrite.extratarget = (uint32_t*)malloc(vramWrite.w*vramWrite.h*4); + vramWrite.enabled = 1; + + imageTransfer = 1; + + int i; + + for(i=0;i<gpuConfig.nMaxTextures;i++){ + if(((texture[i].textAddrX+255)>=x) + &&((texture[i].textAddrY+255)>=y) + &&(texture[i].textAddrX<=(x+w)) + &&(texture[i].textAddrY<=(y+h))){ + texture[i].Update=TRUE; + } + } + + //gllog(1," CMD: MEM->VRAM %d,%d %d,%d\n",imageX0,imageY0,imageX1,imageY1); +} + +void primStoreImage(unsigned char * baseAddr) +{ + uint32_t *gpuData = ((uint32_t *) baseAddr); + + imageX0 = (short)(gpuData[1] & 0x3ff); + imageY0 = (short)(gpuData[1]>>16) & 0x1ff; + imageX1 = (short)(gpuData[2] & 0xffff); + imageY1 = (short)((gpuData[2]>>16) & 0xffff); + + //gllog(1," CMD: VRAM->MEM %d,%d %d,%d\n",imageX0,imageY0,imageX1,imageY1); + imTX=imageX0; imTY=imageY0; + imTXc=imageX1; imTYc=imageY1; + imSize=imageY1*imageX1/2; + + imageTransfer = 2; + GPUstatusRet|=0x08000000; +} + +void primMoveImage(unsigned char * baseAddr) +{ + // 0x80 image move (VRAM->VRAM) + uint32_t *gpuData = ((uint32_t *) baseAddr); + + unsigned short imageX0,imageY0,imageX1,imageY1,imageSX,imageSY,i,j; + + imageX0 = (short)(gpuData[1] & 0x3ff); + imageY0 = (short)(gpuData[1]>>16) & 0x1ff; + + imageX1 = (short)(gpuData[2] & 0x3ff); + imageY1 = (short)((gpuData[2]>>16) & 0x1ff); + + imageSY = (short)((gpuData[3]>>16) & 0xffff); + imageSX = (short)(gpuData[3] & 0xffff); + + for(i=0;i<gpuConfig.nMaxTextures;i++){ + if(((texture[i].textAddrX+255)>=imageX1) + &&((texture[i].textAddrY+255)>=imageY1) + &&(texture[i].textAddrX<=(imageX1+imageSX)) + &&(texture[i].textAddrY<=(imageY1+imageSY))){ + texture[i].Update=TRUE; + } + } + + //gllog(1," CMD: VRAM->VRAM %d,%d -> %d,%d (%d,%d)\n",imageX0,imageY0,imageX1,imageY1,imageSX,imageSY); + + if((imageY0+imageSY)>512) imageSY=512-imageY0; + if((imageY1+imageSY)>512) imageSY=512-imageY1; + if((imageX0+imageSX)>1024) imageSX=1024-imageX0; + if((imageX1+imageSX)>1024) imageSX=1024-imageX1; + for(j=0;j<imageSY;j++) + for(i=0;i<imageSX;i++) + psxVuw[((imageY1+j)<<10)+imageX1+i]=psxVuw[((imageY0+j)<<10)+imageX0+i]; +} + + + + +void primTileS(unsigned char * baseAddr) +{ + //gllog(2,"Tile S *NI*");// : %04x,%04x - %04x,%04x",baseAddrW[addr+2],baseAddrW[addr+3],baseAddrW[addr+4],baseAddrW[addr+5]); + //gllog(2,"Tile S *NI* : %04x,%04x - %04x,%04x",baseAddrW[addr+2],baseAddrW[addr+3],baseAddrW[addr+4],baseAddrW[addr+5]); + + //uint32_t *gpuData = (uint32_t *)baseAddr; + unsigned short *gpuPoint = (unsigned short*) baseAddr; + + short x = (gpuPoint[2]<<21)>>21; + short y = (gpuPoint[3]<<21)>>21; + short w = (gpuPoint[4]<<21)>>21; + short h = (gpuPoint[5]<<21)>>21; + + x += psxDraw.offsetX; + y += psxDraw.offsetY; + + if(baseAddr[3]&2){ //if blending on + //if(TransRate[texinfo.abr].change && !transparent){ + //glBlendEquation(TransRate[texinfo.abr].mode); + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + gAlpha=TransRate[texinfo.abr].alpha; + transparent=TRUE; + //} + //if(baseAddr[3]&1){ + // glColor4ub(255,255,255,gAlpha); + //}else{ + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + //} + }else{ + //if(TransRate[texinfo.abr].change && transparent){ + //glBlendEquation(TransRate[0].mode); + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + //} + //if(baseAddr[3]&1){ + // glColor3ub(255,255,255); + //}else{ + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + //} + } + + glBegin(GL_POLYGON); + glVertex2s(x,y); + glVertex2s(x+w,y); + glVertex2s(x+w,y+h); + glVertex2s(x,y+h); + glEnd(); + + + return; +} + +void primBlkFill(unsigned char * baseAddr) +{ + short * gpuPoint = (short*) baseAddr; + //uint32_t *gpuData = ((uint32_t *) baseAddr); + + //gllog(2,"BlkFill : %04x,%04x - %04x,%04x",gpuPoint[2],gpuPoint[3],gpuPoint[4],gpuPoint[5]); + + short x = (gpuPoint[2]<<21)>>21; + short y = (gpuPoint[3]<<21)>>21; + short w = (gpuPoint[4]<<21)>>21; + short h = (gpuPoint[5]<<21)>>21; + +/* + this function is something like clear_with_given_color + and according to baseAddr + struct packet + { + unsigned char R,G,B,code; + unsigned short X,Y,W,H; + } + this function is not clipped bby drawing area, accesses whole VRAM +*/ + + glDisable(GL_CLIP_PLANE0); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE2); + glDisable(GL_CLIP_PLANE3); + + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + glBegin(GL_POLYGON); + glVertex2s(x,y); + glVertex2s(x+w,y); + glVertex2s(x+w,y+h); + glVertex2s(x,y+h); + glEnd(); + + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); +} + + + +void setupTexture(int32_t clutP){ + int i; + int32_t sprCY,sprCX,tbw; + short color,tC; + int ctext; + union uPointers psxVOffset,psxVOffset2; + + if( (texinfo.colormode&2) == 2 ) + clutP=nullclutP; + + ctext=curText; + for(i=0;i<gpuConfig.nMaxTextures;i++){ + if(texture[i].textAddrX==texinfo.x && texture[i].textAddrY==texinfo.y && clutP==texture[i].clutP) + { + if(texture[i].Update==TRUE || texinfo.colormode!=texture[i].textTP) + { + ctext=i; + break; + } + glBindTexture(GL_TEXTURE_2D,texture[i].id); + return; + } + } + + texture[ctext].textAddrX=texinfo.x; + texture[ctext].textAddrY=texinfo.y; + texture[ctext].textTP=texinfo.colormode; + texture[ctext].clutP=clutP; + texture[ctext].Update=FALSE; + glBindTexture(GL_TEXTURE_2D,texture[ctext].id); + if(ctext==curText){ + curText++; + if(curText>=gpuConfig.nMaxTextures)curText=0; + } + + + tbw=256; + psxVOffset.w=psxVuw+(texinfo.y<<10)+texinfo.x; + + uint32_t *pimage = image; + + switch(texinfo.colormode) + { + //4bit clut + case 0: + for (sprCY=0;sprCY<256;sprCY++){ + psxVOffset2.b=psxVOffset.b; + for (sprCX=0;sprCX<256;sprCX+=2){ + tC = (*psxVOffset2.b)&0x0f; + *pimage = torgba[psxVuw[clutP+tC]]; + pimage++; + + tC = (*psxVOffset2.b>>4)&0x0f; + *pimage = torgba[psxVuw[clutP+tC]]; + pimage++; + + psxVOffset2.b++; + } + psxVOffset.w+=1024; + } + break; + + //8bit clut + case 1: + if(texinfo.x==960)tbw=128; + for (sprCY=0;sprCY<256;sprCY++){ + psxVOffset2.b=psxVOffset.b; + for (sprCX=0;sprCX<tbw;sprCX++){ + tC = *psxVOffset2.b; + image[(sprCY<<8)+sprCX] = torgba[psxVuw[clutP+tC]]; + psxVOffset2.b++; + } + psxVOffset.w+=1024; + } + break; + + //15bit direct + case 2: + if(texinfo.x==960)tbw=64; + else if(texinfo.x==896)tbw=128; + else if(texinfo.x==832)tbw=192; + + for (sprCY=0;sprCY<256;sprCY++){ + psxVOffset2.w=psxVOffset.w; + for (sprCX=0;sprCX<tbw;sprCX++){ + color = *psxVOffset2.w; + image[(sprCY<<8)+sprCX] = torgba[color]; + psxVOffset2.w++; + } + psxVOffset.w+=1024; + } + break; + } + glTexSubImage2D(GL_TEXTURE_2D,0,0,0,256,256,GL_RGBA,GL_UNSIGNED_BYTE,image); +} + + +void setSpriteBlendMode(int32_t command){ + unsigned char *baseAddr = (unsigned char *)&command; + + //color info is 0-127, or bit 0x80 to indicate full color + //note: above applies to texture (and sprite) color shading info only? + unsigned char r,g,b; + r = texshade[baseAddr[0]]; + g = texshade[baseAddr[1]]; + b = texshade[baseAddr[2]]; + + if(baseAddr[3]&2){ //if blending on + //if(TransRate[texinfo.abr].change && !transparent){ + //glBlendEquation(TransRate[texinfo.abr].mode); + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + //} + if(baseAddr[3]&1){ //should always be 0 for sprite? Apparantly not... + glColor4ub(255,255,255,gAlpha); + }else{ + glColor4ub(r,g,b,gAlpha); + } + }else{ + //if(TransRate[texinfo.abr].change && transparent){ + //glBlendEquation(TransRate[0].mode); + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + //} + if(baseAddr[3]&1){ + glColor3ub(255,255,255); + }else{ + glColor3ub(r,g,b); + } + } +} + +void primSprt8(unsigned char * baseAddr) +{ +/* + fixed size (8x8) sprite +*/ + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint = (short*) baseAddr; + int32_t clutP; + short tx,ty; + short x,y; + + //gllog(2,"Sprt8x8 : %d,%d %02x",gpuPoint[2],gpuPoint[3],baseAddr[3]); + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + tx = (short)(gpuData[2] & 0x000000ff); + ty = (short)((gpuData[2]>>8) & 0x000000ff); + + x = (gpuPoint[2]<<21)>>21; + y = (gpuPoint[3]<<21)>>21; + + x += psxDraw.offsetX; + y += psxDraw.offsetY; + + setupTexture(clutP); + setSpriteBlendMode(*gpuData); + + /*switch(baseAddr[3]&3){ + case 0: + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + break; + case 1: + glColor3ub(255,255,255); + break; + case 2: + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + break; + case 3: + glColor4ub(255,255,255,gAlpha); + break; + }*/ + + glBegin(GL_POLYGON); + glTexCoord2s(tx,ty); + glVertex2s(x,y); + glTexCoord2s(tx+7,ty); + glVertex2s(x+8,y); + glTexCoord2s(tx+7,ty+7); + glVertex2s(x+8,y+8); + glTexCoord2s(tx,ty+7); + glVertex2s(x,y+8); + glEnd(); + + //draw opaque areas of texture + if(baseAddr[3]&2){ + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_EQUAL, 1); + glColor3ub(255,255,255); + glDisable(GL_BLEND); + glBegin(GL_POLYGON); + glTexCoord2s(tx,ty); + glVertex2s(x,y); + glTexCoord2s(tx+7,ty); + glVertex2s(x+8,y); + glTexCoord2s(tx+7,ty+7); + glVertex2s(x+8,y+8); + glTexCoord2s(tx,ty+7); + glVertex2s(x,y+8); + glEnd(); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + glBindTexture(GL_TEXTURE_2D,nullid); +} + +void primSprt16(unsigned char * baseAddr) +{ +/* + fixed size (16x16) sprite +*/ + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint = (short*) baseAddr; + int32_t clutP; + short tx,ty; + short x,y; + + //gllog(2,"Sprt16x16 : %d,%d %02x",gpuPoint[2],gpuPoint[3],baseAddr[3]); + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + tx = (short)(gpuData[2] & 0x000000ff); + ty = (short)((gpuData[2]>>8) & 0x000000ff); + + x = (gpuPoint[2]<<21)>>21; + y = (gpuPoint[3]<<21)>>21; + + x += psxDraw.offsetX; + y += psxDraw.offsetY; + + setupTexture(clutP); + setSpriteBlendMode(*gpuData); + + glBegin(GL_POLYGON); + glTexCoord2s(tx,ty); + glVertex2s(x,y); + glTexCoord2s(tx+15,ty); + glVertex2s(x+16,y); + glTexCoord2s(tx+15,ty+15); + glVertex2s(x+16,y+16); + glTexCoord2s(tx,ty+15); + glVertex2s(x,y+16); + glEnd(); + + //draw opaque areas of texture + if(baseAddr[3]&2){ + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_EQUAL, 1); + glColor3ub(255,255,255); + glDisable(GL_BLEND); + glBegin(GL_POLYGON); + glTexCoord2s(tx,ty); + glVertex2s(x,y); + glTexCoord2s(tx+15,ty); + glVertex2s(x+16,y); + glTexCoord2s(tx+15,ty+15); + glVertex2s(x+16,y+16); + glTexCoord2s(tx,ty+15); + glVertex2s(x,y+16); + glEnd(); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + + glBindTexture(GL_TEXTURE_2D,nullid); +} + +void primSprtS(unsigned char * baseAddr) +{ +/* + free size (up to 256x256) sprite +*/ + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint = (short*) baseAddr; + int32_t clutP; + short tx,ty,sprtW,sprtH; + short tx1,tx2,ty1,ty2; + short x,y; + + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + + tx = (short)(gpuData[2] & 0x000000ff); + ty = (short)((gpuData[2]>>8) & 0x000000ff); + sprtW = (short)(gpuData[3] & 0x3ff); + sprtH = (short)((gpuData[3]>>16) & 0x1ff); + + x = (gpuPoint[2]<<21)>>21; + y = (gpuPoint[3]<<21)>>21; + + x += psxDraw.offsetX; + y += psxDraw.offsetY; + + //gllog(2,"Sprt : %04x,%04x - %04x,%04x code=%02x pal=%05x",gpuPoint[2],gpuPoint[3],gpuPoint[6],gpuPoint[7],baseAddr[3],clutP); + /*if(textAddrX==320&&textAddrY==0){ + gllog(2,"Sprt : %d,%d - %d,%d pal=%05x",gpuPoint[2],gpuPoint[3],gpuPoint[6],gpuPoint[7],gpuData[2]>>12); + }*/ + + //scaled instead of repeated for now... + #define min(a,b) ((a) < (b) ? (a) : (b)) + + short minw = min(psxDraw.texwinX2, sprtW); + short minh = min(psxDraw.texwinY2, sprtH); + + tx1 = tx + psxDraw.texwinX1; + tx2 = tx1 + minw - 1; + ty1 = ty + psxDraw.texwinY1; + ty2 = ty1 + minh - 1; +/* + short tswap; + + #define swap(a,b) tswap = (a); (a)=(b); (b) = tswap + + switch (texinfo.mirror) + { + case 1: + swap(tx1, tx2); + break; + case 2: + swap(ty1, ty2); + break; + case 3: + swap(tx1,tx2); + swap(ty1,ty2); + break; + } +*/ + + setupTexture(clutP); + setSpriteBlendMode(*gpuData); + + glBegin(GL_POLYGON); + glTexCoord2s(tx1, ty1); + glVertex2s(x,y); + glTexCoord2s(tx2, ty1); + glVertex2s(x+sprtW,y); + glTexCoord2s(tx2, ty2); + glVertex2s(x+sprtW,y+sprtH); + glTexCoord2s(tx1, ty2); + glVertex2s(x,y+sprtH); + glEnd(); + + //draw opaque areas of texture + if(baseAddr[3]&2){ + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_EQUAL, 1); + glDisable(GL_BLEND); + glColor3ub(255,255,255); + glBegin(GL_POLYGON); + glTexCoord2s(tx1, ty1); + glVertex2s(x,y); + glTexCoord2s(tx2, ty1); + glVertex2s(x+sprtW,y); + glTexCoord2s(tx2, ty2); + glVertex2s(x+sprtW,y+sprtH); + glTexCoord2s(tx1, ty2); + glVertex2s(x,y+sprtH); + glEnd(); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + glBindTexture(GL_TEXTURE_2D,nullid); +} + + +void primLineF2(unsigned char *baseAddr) +{ +/* + Flat Line 2 vertices +*/ + short *gpuPoint=((short *) baseAddr); + short x1,y1,x2,y2; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[4]<<21)>>21; + y2 = (gpuPoint[5]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + }else{ + if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + } + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + } + /*if(baseAddr[3]&2){ + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + }else{ + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + }*/ + glBegin(GL_LINES); + glVertex2s(x1,y1); + glVertex2s(x2,y2); + glEnd(); +} + +void primLineG2(unsigned char *baseAddr) +{ +/* + Goraud Line 2 vertices +*/ + short *gpuPoint=((short *) baseAddr); + short x1,y1,x2,y2; + unsigned char alpha; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[6]<<21)>>21; + y2 = (gpuPoint[7]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + alpha=gAlpha; + }else{ + if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + } + alpha=255; + } + /*if(baseAddr[3]&2){ + alpha=gAlpha; + }else{ + alpha=255; + }*/ + glBegin(GL_LINES); + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],alpha); + glVertex2s(x1,y1); + glColor4ub(baseAddr[8],baseAddr[9],baseAddr[10],alpha); + glVertex2s(x2,y2); + glEnd(); +} + +void primPolyF3(unsigned char *baseAddr) +{ +/* + Flat Shaded Polygon 3 vertices +*/ + short *gpuPoint=((short *) baseAddr); + short x1,x2,x3,y1,y2,y3; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[4]<<21)>>21; + y2 = (gpuPoint[5]<<21)>>21; + x3 = (gpuPoint[6]<<21)>>21; + y3 = (gpuPoint[7]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + + //gllog(77,"!GPU! P3 F %d,%d %d,%d %d,%d\n",lx0,ly0,lx1,ly1,lx2,ly2); + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + gAlpha = TransRate[texinfo.abr].alpha; + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + }else{ + if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + } + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + } + glBegin(GL_POLYGON); + glVertex2s(x1,y1); + glVertex2s(x2,y2); + glVertex2s(x3,y3); + glEnd(); +} + +void primPolyF4(unsigned char *baseAddr) +{ +/* + Flat Shaded Polygon 4 vertices +*/ + short *gpuPoint=((short *) baseAddr); + short x1,x2,x3,x4,y1,y2,y3,y4; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[4]<<21)>>21; + y2 = (gpuPoint[5]<<21)>>21; + x3 = (gpuPoint[6]<<21)>>21; + y3 = (gpuPoint[7]<<21)>>21; + x4 = (gpuPoint[8]<<21)>>21; + y4 = (gpuPoint[9]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + x4 += psxDraw.offsetX; + y4 += psxDraw.offsetY; + + //gllog(77,"!GPU! P4 F %d,%d %d,%d %d,%d %d,%d %6x\n",lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3,gpuData[0]); + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + gAlpha = TransRate[texinfo.abr].alpha; + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + }else{ + if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + } + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + } + glBegin(GL_POLYGON); + glVertex2s(x1,y1); + glVertex2s(x2,y2); + glVertex2s(x4,y4); + glVertex2s(x3,y3); + glEnd(); +} + +void primPolyG3(unsigned char *baseAddr) +{ +/* + Goraud Shaded Polygon 3 vertices +*/ + short *gpuPoint=((short *) baseAddr); + unsigned char alpha; + short x1,x2,x3,y1,y2,y3; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[6]<<21)>>21; + y2 = (gpuPoint[7]<<21)>>21; + x3 = (gpuPoint[10]<<21)>>21; + y3 = (gpuPoint[11]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + + //gllog(77,"!GPU! P3 G %d,%d %d,%d %d,%d\n",lx0,ly0,lx1,ly1,lx2,ly2); + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + alpha = TransRate[texinfo.abr].alpha; + }else{ + if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + } + alpha=255; + } + glBegin(GL_POLYGON); + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],alpha); + glVertex2s(x1,y1); + glColor4ub(baseAddr[8],baseAddr[9],baseAddr[10],alpha); + glVertex2s(x2,y2); + glColor4ub(baseAddr[16],baseAddr[17],baseAddr[18],alpha); + glVertex2s(x3,y3); + glEnd(); +} + +void primPolyG4(unsigned char * baseAddr) +{ +/* + Goraud Shaded Polygon 4 vertices +*/ + short *gpuPoint=((short *) baseAddr); + short x1,x2,x3,x4,y1,y2,y3,y4; + unsigned char alpha; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[6]<<21)>>21; + y2 = (gpuPoint[7]<<21)>>21; + x3 = (gpuPoint[10]<<21)>>21; + y3 = (gpuPoint[11]<<21)>>21; + x4 = (gpuPoint[14]<<21)>>21; + y4 = (gpuPoint[15]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + x4 += psxDraw.offsetX; + y4 += psxDraw.offsetY; + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + alpha = TransRate[texinfo.abr].alpha; + }else{ + if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + } + alpha=255; + } + glBegin(GL_POLYGON); + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],alpha); + glVertex2s(x1,y1); + glColor4ub(baseAddr[8],baseAddr[9],baseAddr[10],alpha); + glVertex2s(x2,y2); + glColor4ub(baseAddr[24],baseAddr[25],baseAddr[26],alpha); + glVertex2s(x4,y4); + glColor4ub(baseAddr[16],baseAddr[17],baseAddr[18],alpha); + glVertex2s(x3,y3); + glEnd(); +} + +void primPolyFT3(unsigned char * baseAddr) +{ +/* + Flat Shaded Textured Polygon 3 vertices +*/ + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint=((short *) baseAddr); + int32_t clutP; + short x1,x2,x3,y1,y2,y3; + short tx0,ty0,tx1,ty1,tx2,ty2; + unsigned short gpuDataX; + + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[6]<<21)>>21; + y2 = (gpuPoint[7]<<21)>>21; + x3 = (gpuPoint[10]<<21)>>21; + y3 = (gpuPoint[11]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + + tx0 = (short)(gpuData[2] & 0xff); + ty0 = (short)((gpuData[2]>>8) & 0xff); + tx1 = (short)(gpuData[4] & 0xff); + ty1 = (short)((gpuData[4]>>8) & 0xff); + tx2 = (short)(gpuData[6] & 0xff); + ty2 = (short)((gpuData[6]>>8) & 0xff); + //gllog(77,"!GPU! P3 F %d,%d %d,%d %d,%d\n",lx0,ly0,lx1,ly1,lx2,ly2); + gpuDataX=(unsigned short)(gpuData[4]>>16); + + int32_t tempABR = (gpuDataX >>5) & 0x3; + if(texinfo.abr!=tempABR){ + texinfo.abr = tempABR; + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + gAlpha=TransRate[texinfo.abr].alpha; + transparent=TRUE; + } + UpdateTextureInfo(gpuDataX); + + /*switch(texinfo.abr){ + case 0: + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=128; + break; + case 1: + glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=0; + break; + case 2: + glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR); + gAlpha=0; + break; + case 3: + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + gAlpha=64; + break; + }*/ + //gllog(77," CMD: P3TF: %d,%d TP=%d",textAddrX,textAddrY,textTP); + //gllog(77," CMD: P3TF: %d,%d %02x",lx0,ly0,baseAddr[3]); + + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + setupTexture(clutP); + //setPolyTexBlendMode(*gpuData); + + baseAddr[0] = texshade[baseAddr[0]]; + baseAddr[1] = texshade[baseAddr[1]]; + baseAddr[2] = texshade[baseAddr[2]]; + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + if(baseAddr[3]&1){ + glColor4ub(255,255,255,gAlpha); + //glColor4ub(255,255,255,255); + }else{ + glColor4ub(baseAddr[0],baseAddr[1],baseAddr[2],gAlpha); + } + }else{ + //if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + //} + if(baseAddr[3]&1){ + glColor3ub(255,255,255); + }else{ + glColor3ub(baseAddr[0],baseAddr[1],baseAddr[2]); + } + } + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + short xtest = (x1-x2)*(tx0-tx1); + if (xtest == 0) + xtest = (x1-x3)*(tx0-tx2); + if (xtest < 0) + glTranslatef(1.0f, 0, 0); + + short ytest = (y1-y2)*(ty0-ty1); + if (ytest == 0) + ytest = (y1-y3)*(ty0-ty2); + if (ytest < 0) + glTranslatef(0, 1.0f, 0); + + glBegin(GL_POLYGON); + glTexCoord2s(tx0,ty0); + glVertex2s(x1,y1); + glTexCoord2s(tx1,ty1); + glVertex2s(x2,y2); + glTexCoord2s(tx2,ty2); + glVertex2s(x3,y3); + glEnd(); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D,nullid); +} + + +void primPolyFT4(unsigned char * baseAddr) +{ +/* + Flat Shaded Textured Polygon 4 vertices +*/ + + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint=((short *) baseAddr); + int32_t clutP; + short x1,x2,x3,x4,y1,y2,y3,y4; + short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3; + unsigned short gpuDataX; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[6]<<21)>>21; + y2 = (gpuPoint[7]<<21)>>21; + x3 = (gpuPoint[10]<<21)>>21; + y3 = (gpuPoint[11]<<21)>>21; + x4 = (gpuPoint[14]<<21)>>21; + y4 = (gpuPoint[15]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + x4 += psxDraw.offsetX; + y4 += psxDraw.offsetY; + + tx0 = (short)(gpuData[2] & 0xff); + ty0 = (short)((gpuData[2]>>8) & 0xff); + tx1 = (short)(gpuData[4] & 0xff); + ty1 = (short)((gpuData[4]>>8) & 0xff); + tx2 = (short)(gpuData[6] & 0xff); + ty2 = (short)((gpuData[6]>>8) & 0xff); + tx3 = (short)(gpuData[8] & 0xff); + ty3 = (short)((gpuData[8]>>8) & 0xff); + //gllog(77,"!GPU! P4 F %d,%d %d,%d %d,%d %d,%d %6x\n",tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3,gpuData[0]); + + gpuDataX=(unsigned short)(gpuData[4]>>16); + + int32_t tempABR = (gpuDataX >> 5) & 0x3; + if(texinfo.abr!=tempABR){ + texinfo.abr = tempABR; + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + gAlpha=TransRate[texinfo.abr].alpha; + transparent=TRUE; + } + UpdateTextureInfo(gpuDataX); + + /*switch(texinfo.abr){ + case 0: + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=128; + break; + case 1: + glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=0; + break; + case 2: + glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR); + gAlpha=0; + break; + case 3: + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + gAlpha=64; + break; + }*/ + //gllog(77," CMD: P4TF: %d,%d TP=%d",textAddrX,textAddrY,textTP); + //gllog(77," CMD: P4TG: %d,%d,%d,%d",baseAddr[3],baseAddr[15],baseAddr[39],baseAddr[27]); + //gllog(77," CMD: P4TF: %d,%d %02x",lx0,ly0,baseAddr[3]); + + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + setupTexture(clutP); + + if(baseAddr[3]&2){ + if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + } + if(baseAddr[3]&1){ + glColor4ub(255,255,255,gAlpha); + //glColor4ub(255,255,255,255); + }else{ + glColor4ub(texshade[baseAddr[0]],texshade[baseAddr[1]],texshade[baseAddr[2]],gAlpha); + } + }else{ + //if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + //} + if(baseAddr[3]&1){ + glColor3ub(255,255,255); + }else{ + glColor3ub(texshade[baseAddr[0]],texshade[baseAddr[1]],texshade[baseAddr[2]]); + } + } + + //verify order, otherwise it will pick wrong texture pixel if backwards + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + short xtest = (x1-x2)^(tx0-tx1); + if (xtest == 0) + xtest = (x1-x3)^(tx0-tx2); + if (xtest < 0) + glTranslatef(1.0f, 0, 0); + + short ytest = (y1-y2)^(ty0-ty1); + if (ytest == 0) + ytest = (y1-y3)^(ty0-ty2); + if (ytest < 0) + glTranslatef(0, 1.0f, 0); + + glBegin(GL_POLYGON); + glTexCoord2s(tx0,ty0); + glVertex2s(x1,y1); + glTexCoord2s(tx1,ty1); + glVertex2s(x2,y2); + glTexCoord2s(tx3,ty3); + glVertex2s(x4,y4); + glTexCoord2s(tx2,ty2); + glVertex2s(x3,y3); + glEnd(); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D,nullid); +} + +void primPolyGT3(unsigned char *baseAddr) +{ +/* + Goraud Shaded Textured Polygon 3 vertices +*/ + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint=((short *) baseAddr); + int32_t clutP; + short x1,x2,x3,y1,y2,y3; + short tx0,ty0,tx1,ty1,tx2,ty2; + unsigned short gpuDataX; + unsigned char alpha; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[8]<<21)>>21; + y2 = (gpuPoint[9]<<21)>>21; + x3 = (gpuPoint[14]<<21)>>21; + y3 = (gpuPoint[15]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + + + tx0 = (short)(gpuData[2] & 0xff); + ty0 = (short)((gpuData[2]>>8) & 0xff); + tx1 = (short)(gpuData[5] & 0xff); + ty1 = (short)((gpuData[5]>>8) & 0xff); + tx2 = (short)(gpuData[8] & 0xff); + ty2 = (short)((gpuData[8]>>8) & 0xff); + //gllog(77,"!GPU! P3TG %d,%d %d,%d %d,%d\n",lx0,ly0,lx1,ly1,lx2,ly2); + + gpuDataX=(unsigned short)(gpuData[5]>>16); + int32_t tempABR = (gpuDataX >> 5) & 0x3; + if(texinfo.abr!=tempABR){ + texinfo.abr = tempABR; + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + gAlpha=TransRate[texinfo.abr].alpha; + transparent=TRUE; + } + UpdateTextureInfo(gpuDataX); + + /*switch(texinfo.abr){ + case 0: + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=128; + break; + case 1: + glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=0; + break; + case 2: + glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR); + gAlpha=0; + break; + case 3: + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + gAlpha=64; + break; + }*/ + + //gllog(77," CMD: P3TG: %d,%d TP=%d",textAddrX,textAddrY,textTP); + //gllog(77," CMD: P3TG: %d,%d %02x",lx0,ly0,baseAddr[3]); + + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + setupTexture(clutP); + if(baseAddr[3]&2){ + //if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + //} + alpha=gAlpha; + }else{ + //if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + //} + alpha=255; + } + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + short xtest = (x1-x2)*(tx0-tx1); + if (xtest == 0) + xtest = (x1-x3)*(tx0-tx2); + if (xtest < 0) + glTranslatef(1.0f, 0, 0); + + short ytest = (y1-y2)*(ty0-ty1); + if (ytest == 0) + ytest = (y1-y3)*(ty0-ty2); + if (ytest < 0) + glTranslatef(0, 1.0f, 0); + + glBegin(GL_POLYGON); + glColor4ub(texshade[baseAddr[0]],texshade[baseAddr[1]],texshade[baseAddr[2]],alpha); + glTexCoord2s(tx0,ty0); + glVertex2s(x1,y1); + glColor4ub(texshade[baseAddr[12]],texshade[baseAddr[13]],texshade[baseAddr[14]],alpha); + glTexCoord2s(tx1,ty1); + glVertex2s(x2,y2); + glColor4ub(texshade[baseAddr[24]],texshade[baseAddr[25]],texshade[baseAddr[26]],alpha); + glTexCoord2s(tx2,ty2); + glVertex2s(x3,y3); + glEnd(); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D,nullid); +} + +void primPolyGT4(unsigned char *baseAddr) +{ +/* + Goraud Shaded Textured Polygon 4 vertices +*/ + uint32_t *gpuData = (uint32_t *)baseAddr; + short *gpuPoint=((short *) baseAddr); + int32_t clutP; + short x1,y1,x2,y2,x3,y3,x4,y4; + short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3; + unsigned short gpuDataX; + unsigned char alpha; + + x1 = (gpuPoint[2]<<21)>>21; + y1 = (gpuPoint[3]<<21)>>21; + x2 = (gpuPoint[8]<<21)>>21; + y2 = (gpuPoint[9]<<21)>>21; + x3 = (gpuPoint[14]<<21)>>21; + y3 = (gpuPoint[15]<<21)>>21; + x4 = (gpuPoint[20]<<21)>>21; + y4 = (gpuPoint[21]<<21)>>21; + + x1 += psxDraw.offsetX; + y1 += psxDraw.offsetY; + x2 += psxDraw.offsetX; + y2 += psxDraw.offsetY; + x3 += psxDraw.offsetX; + y3 += psxDraw.offsetY; + x4 += psxDraw.offsetX; + y4 += psxDraw.offsetY; + + tx0 = (short)(gpuData[2] & 0xff); + ty0 = (short)((gpuData[2]>>8) & 0xff); + tx1 = (short)(gpuData[5] & 0xff); + ty1 = (short)((gpuData[5]>>8) & 0xff); + tx2 = (short)(gpuData[8] & 0xff); + ty2 = (short)((gpuData[8]>>8) & 0xff); + tx3 = (short)(gpuData[11] & 0xff); + ty3 = (short)((gpuData[11]>>8) & 0xff); + + gpuDataX=(unsigned short)(gpuData[5]>>16); + int32_t tempABR = (gpuDataX >> 5) & 0x3; + if(texinfo.abr!=tempABR){ + texinfo.abr = tempABR; + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + gAlpha=TransRate[texinfo.abr].alpha; + transparent=TRUE; + } + UpdateTextureInfo(gpuDataX); + + /*switch(texinfo.abr){ + case 0: + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=128; + break; + case 1: + glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); + gAlpha=0; + break; + case 2: + glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR); + gAlpha=0; + break; + case 3: + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + gAlpha=64; + break; + }*/ + + //gllog(77," CMD: P4TG: %d,%d TP=%d",textAddrX,textAddrY,textTP); + //gllog(77," CMD: P4TG: %d,%d %02x",lx0,ly0,baseAddr[3]); + + clutP = (gpuData[2]>>12) & 0x7fff0;//0xffff0; + setupTexture(clutP); + if(baseAddr[3]&2){ + //if(TransRate[texinfo.abr].change&&!transparent){ + glBlendFunc(TransRate[texinfo.abr].src,TransRate[texinfo.abr].dst); + transparent=TRUE; + //} + alpha=gAlpha; + }else{ + //if(TransRate[texinfo.abr].change&&transparent){ + glBlendFunc(TransRate[0].src,TransRate[0].dst); + transparent=FALSE; + //} + alpha=255; + } + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + short xtest = (x1-x2)*(tx0-tx1); + if (xtest == 0) + xtest = (x1-x3)*(tx0-tx2); + if (xtest < 0) + glTranslatef(1.0f, 0, 0); + + short ytest = (y1-y2)*(ty0-ty1); + if (ytest == 0) + ytest = (y1-y3)*(ty0-ty2); + if (ytest < 0) + glTranslatef(0, 1.0f, 0); + + glBegin(GL_POLYGON); + glColor4ub(texshade[baseAddr[0]],texshade[baseAddr[1]],texshade[baseAddr[2]],alpha); + glTexCoord2s(tx0,ty0); + glVertex2s(x1,y1); + glColor4ub(texshade[baseAddr[12]],texshade[baseAddr[13]],texshade[baseAddr[14]],alpha); + glTexCoord2s(tx1,ty1); + glVertex2s(x2,y2); + glColor4ub(texshade[baseAddr[36]],texshade[baseAddr[37]],texshade[baseAddr[38]],alpha); + glTexCoord2s(tx3,ty3); + glVertex2s(x4,y4); + glColor4ub(texshade[baseAddr[24]],texshade[baseAddr[25]],texshade[baseAddr[26]],alpha); + glTexCoord2s(tx2,ty2); + glVertex2s(x3,y3); + glEnd(); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D,nullid); +} + + +void primNI(unsigned char *bA) +{ + // primitive not implemented + if (bA[3]) gllog(255,"PRIM: *NI* %02x",bA[3]); +} + + +unsigned char primTableC[256] = +{ + // 00 + 0,0,3,0,0,0,0,0, + // 08 + 0,0,0,0,0,0,0,0, + // 10 + 0,0,0,0,0,0,0,0, + // 18 + 0,0,0,0,0,0,0,0, + // 20 + 4,4,4,4,7,7,7,7, + // 28 + 5,5,5,5,9,9,9,9, + // 30 + 6,6,6,6,9,9,9,9, + // 38 + 8,8,8,8,12,12,12,12, + // 40 + 3,3,3,3,0,0,0,0, // LineF2 + // 48 + 5,5,5,5,6,6,6,6, // LineF3 LineF4 + // 50 + 4,4,4,4,0,0,0,0, // LineG2 + // 58 + 7,7,7,7,9,9,9,9, // LineG3 LineG4 + // 60 + 3,3,3,3,4,4,4,4, // Tile Sprt + // 68 + 2,2,2,2,0,0,0,0, // Tile1 + // 70 + 2,2,2,2,3,3,3,3, // Tile8 Sprt8 + // 78 + 2,2,2,2,3,3,3,3, // Tile16 Sprt16 + // 80 + 4,0,0,0,0,0,0,0, + // 88 + 0,0,0,0,0,0,0,0, + // 90 + 0,0,0,0,0,0,0,0, + // 98 + 0,0,0,0,0,0,0,0, + // a0 + 3,0,0,0,0,0,0,0, + // a8 + 0,0,0,0,0,0,0,0, + // b0 + 0,0,0,0,0,0,0,0, + // b8 + 0,0,0,0,0,0,0,0, + // c0 + 3,0,0,0,0,0,0,0, + // c8 + 0,0,0,0,0,0,0,0, + // d0 + 0,0,0,0,0,0,0,0, + // d8 + 0,0,0,0,0,0,0,0, + // e0 + 0,1,1,1,1,1,1,0, + // e8 + 0,0,0,0,0,0,0,0, + // f0 + 0,0,0,0,0,0,0,0, + // f8 + 0,0,0,0,0,0,0,0 + +}; + +void (*primTableJ[256])(unsigned char *) = +{ + // 00 + primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI, + // 08 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 10 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 18 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 20 + primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3, + // 28 + primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4, + // 30 + primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3, + // 38 + primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4, + // 40 + primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI, + // 48 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 50 + primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI, + // 58 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 60 + primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS, + // 68 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 70 + primNI,primNI,primNI,primNI,primSprt8,primSprt8,primSprt8,primSprt8, + // 78 + primNI,primNI,primNI,primNI,primSprt16,primSprt16,primSprt16,primSprt16, + // 80 + primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 88 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 90 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // 98 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // a0 + primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // a8 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // b0 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // b8 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // c0 + primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // c8 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // d0 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // d8 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // e0 + primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI, + // e8 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // f0 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, + // f8 + primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI +}; + |
