📄 halgxm.cpp
字号:
DWORD DwordsRemain;
DWORD i;
// Fill blt buffer 1 with ColorKey.
if (pDriverData->dwBpp == 8)
{
memset((BYTE *)(pDriverData->RegLinear+pDriverData->BB1Base),
(BYTE)ColorKey, pDriverData->MaxBufferPixels);
}
else if (pDriverData->dwBpp == 16)
{
// Can't do memset here since it only takes a byte.
ColorKey |= ColorKey << 16;
DwordsRemain = pDriverData->MaxBufferPixels >> 1;
for (i = 0; i < DwordsRemain; i++)
{
MEM_WRITE_32(pDriverData->RegLinear, pDriverData->BB1Base + (i << 2), ColorKey);
//RETAILMSG(1,(TEXT("Blt32: BB1Base = %08X \n"), pDriverData->BB1Base ));
//RETAILMSG(1,(TEXT("Blt32: DwordsRemain = %08X \n"), DwordsRemain ));
}
}
#ifdef DURANGO
PixelsRemain=0;
RETAILMSG(1,(TEXT("Durango ScrToScrxBlt\r\n")));
gfx_set_solid_pattern(0);
gfx_set_raster_operation((unsigned char) 0xcc);
gfx_screen_to_screen_xblt((unsigned short) (SrcX), (unsigned short)(SrcY),
(unsigned short)(DstX), (unsigned short)(DstY),
(unsigned short)Width, (unsigned short)Height,ColorKey);
#else
// Check for Y reverse direction.
if (SrcY < DstY)
{
SrcY += Height - 1;
DstY += Height - 1;
BlitMode |= BM_REVERSE_Y;
}
// Check to see if enough room in blt buffer for each scan line.
if (Width <= pDriverData->MaxBufferPixels)
{
// SET BUSY FLAG
// This is used to prevent save to disk from happening during GP setup.
MEM_WRITE_8(pDriverData->RegLinear, SPAD_BUSY_FLAG, 1);
// This is special code to perform transparent blt's of any size in
// just two passes. The first pass does the first line of the blt with
// the colorkey coming from BB1. The second pass does the rest of the blt
// with the colorkey coming from an internal GX register. This is done
// by turning off reads of BB1 as dest data on the second pass.
// Load GX command registers.
WAIT_PENDING(pDriverData->RegLinear);
MEM_WRITE_32(pDriverData->RegLinear, GP_SRC_XCOOR, (SrcY << 16) | SrcX);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, (DstY << 16) | DstX);
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, (1 << 16) | Width);
MEM_WRITE_16(pDriverData->RegLinear, GP_PAT_COLOR_0, 0xFFFF);
MEM_WRITE_16(pDriverData->RegLinear, GP_RASTER_MODE, 0x10C6);
// Do the blt.
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BlitMode);
// Load GX command registers.
WAIT_PENDING(pDriverData->RegLinear);
if (BlitMode & BM_REVERSE_Y)
{
MEM_WRITE_32(pDriverData->RegLinear, GP_SRC_XCOOR, ((SrcY - 1) << 16) | SrcX);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, ((DstY - 1) << 16) | DstX);
}
else
{
MEM_WRITE_32(pDriverData->RegLinear, GP_SRC_XCOOR, ((SrcY + 1) << 16) | SrcX);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, ((DstY + 1) << 16) | DstX);
}
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, ((Height - 1) << 16) | Width);
MEM_WRITE_16(pDriverData->RegLinear, GP_PAT_COLOR_0, 0xFFFF);
MEM_WRITE_16(pDriverData->RegLinear, GP_RASTER_MODE, 0x10C6);
// Do the blt.
BlitMode &= ~BM_READ_DST_BB1;
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BlitMode);
}
else
{
// There's not enough room in the blt buffer so do
// the blt one line at a time.
// Check for X reverse direction.
if (SrcX < DstX)
{
SrcX += Width;
DstX += Width;
ReverseX = TRUE;
}
// SET BUSY FLAG
// This is used to prevent save to disk from happening during GP setup.
MEM_WRITE_8(pDriverData->RegLinear, SPAD_BUSY_FLAG, 1);
// Blt MaxBufferPixels at a time.
PixelsRemain = Width;
do {
Width = PixelsRemain;
if ( Width > (DWORD)pDriverData->MaxBufferPixels)
{
Width = pDriverData->MaxBufferPixels;
}
PixelsRemain -= Width;
// Adjust for X reverse direction.
if (ReverseX)
{
SrcX -= Width;
DstX -= Width;
}
// Load GX command registers.
WAIT_PENDING(pDriverData->RegLinear);
MEM_WRITE_32(pDriverData->RegLinear, GP_SRC_XCOOR, (SrcY << 16) | SrcX);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, (DstY << 16) | DstX);
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, (1 << 16) | Width);
MEM_WRITE_16(pDriverData->RegLinear, GP_PAT_COLOR_0, 0xFFFF);
MEM_WRITE_16(pDriverData->RegLinear, GP_RASTER_MODE, 0x10C6);
// Do the blt.
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BlitMode);
// Load GX command registers.
WAIT_PENDING(pDriverData->RegLinear);
if (BlitMode & BM_REVERSE_Y)
{
MEM_WRITE_32(pDriverData->RegLinear, GP_SRC_XCOOR, ((SrcY - 1) << 16) | SrcX);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, ((DstY - 1) << 16) | DstX);
}
else
{
MEM_WRITE_32(pDriverData->RegLinear, GP_SRC_XCOOR, ((SrcY + 1) << 16) | SrcX);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, ((DstY + 1) << 16) | DstX);
}
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, ((Height - 1) << 16) | Width);
MEM_WRITE_16(pDriverData->RegLinear, GP_PAT_COLOR_0, 0xFFFF);
MEM_WRITE_16(pDriverData->RegLinear, GP_RASTER_MODE, 0x10C6);
// Do the blt.
BlitMode &= ~BM_READ_DST_BB1;
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BlitMode);
// Adjust for NOT X reverse direction.
if (!ReverseX)
{
SrcX += Width;
DstX += Width;
}
} while (PixelsRemain > 0);
}
MEM_WRITE_8(pDriverData->RegLinear, SPAD_BUSY_FLAG, 0);
#endif
return(TRUE);
}
/****
NAME: FillBlt
RETURN VALUE
TRUE if successful, else FALSE.
****/
BOOL FillBlt(DWORD DstX, DWORD DstY, DWORD Width, DWORD Height, DWORD Color)
{
// DEBUGENTER( FillBlt );
#ifdef DURANGO
RETAILMSG(1,(TEXT("Durango FillBlt \r\n")));
gfx_set_solid_pattern(Color);
gfx_set_raster_operation((unsigned char) GX_PATCOPY);
gfx_pattern_fill((unsigned short)DstX, (unsigned short)DstY,
(unsigned short)Width, (unsigned short)Height);
#else
DWORD RightDstX;
DWORD RightWidth;
DWORD LeftWidth;
// Repeat color out to 16 bits.
if (pDriverData->dwBpp == 8)
{
Color |= Color << 8;
}
// SET BUSY FLAG
// This is used to prevent save to disk from happening during GP setup.
MEM_WRITE_8(pDriverData->RegLinear, SPAD_BUSY_FLAG, 1);
// Special GXm hack, if width is greater than 16 then must break fill
// into 2 and start right half on a 16 byte boundry.
if(Width > 16)
{
RightDstX = (DstX & 0xFFFFFFF0) + 0x10;
LeftWidth = RightDstX - DstX;
RightWidth = Width - LeftWidth;
// Left fill
WAIT_PENDING(pDriverData->RegLinear);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, (DstY << 16) | DstX);
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, (Height << 16) | LeftWidth);
MEM_WRITE_16(pDriverData->RegLinear, GP_PAT_COLOR_0, Color);
MEM_WRITE_16(pDriverData->RegLinear, GP_RASTER_MODE, GX_PATCOPY);
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BM_WRITE_FB);
// Right fill
WAIT_PENDING(pDriverData->RegLinear);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, (DstY << 16) | RightDstX);
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, (Height << 16) | RightWidth);
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BM_WRITE_FB);
}
else
{
WAIT_PENDING(pDriverData->RegLinear);
MEM_WRITE_32(pDriverData->RegLinear, GP_DST_XCOOR, (DstY << 16) | DstX);
MEM_WRITE_32(pDriverData->RegLinear, GP_WIDTH, (Height << 16) | Width);
MEM_WRITE_16(pDriverData->RegLinear, GP_PAT_COLOR_0, Color);
MEM_WRITE_16(pDriverData->RegLinear, GP_RASTER_MODE, GX_PATCOPY);
MEM_WRITE_16(pDriverData->RegLinear, GP_BLIT_MODE, BM_WRITE_FB);
}
MEM_WRITE_8(pDriverData->RegLinear, SPAD_BUSY_FLAG, 0);
#endif //Durango
return(TRUE);
}
/****
NAME: SetVideoPalette
DESCRIPTION
Loads the video palette in COGNAC (Gamma RAM)
RedGamma is the red channel gamma power factor
GreenGamma is the green channel gamma power factor
BlueGamma is the blue channel gamma power factor
RETURN VALUE
TRUE if successful, else FALSE.
****/
BOOL SetVideoPalette(BYTE *RedGamma, BYTE *GreenGamma, BYTE *BlueGamma)
{
// DEBUGENTER( SetVideoPalette );
int i;
double ImageRed, ImageGreen, ImageBlue, ImageIn;
double InvRG, InvGG, InvBG;
int Red, Green, Blue;
int RedShift, GreenShift, BlueShift;
double RedSlope, GreenSlope, BlueSlope;
double RedG, GreenG, BlueG;
// Gamma Correction
RedG = (double)(COLOR_RANGE - RedGamma[MODE_GAMMA]) / (double)COLOR_RANGE;
RedG *= 2.0;
if(RedG > 1.0) RedG = 1.0 + (RedG - 1.0) * 3.0;
GreenG = (double)(COLOR_RANGE - GreenGamma[MODE_GAMMA]) / (double)COLOR_RANGE;
GreenG *= 2.0;
if(GreenG > 1.0) GreenG = 1.0 + (GreenG - 1.0) * 3.0;
BlueG = (double)(COLOR_RANGE - BlueGamma[MODE_GAMMA]) / (double)COLOR_RANGE;
BlueG *= 2.0;
if(BlueG > 1.0) BlueG = 1.0 + (BlueG - 1.0) * 3.0;
InvRG = 1.0 / (double)RedG;
InvGG = 1.0 / (double)GreenG;
InvBG = 1.0 / (double)BlueG;
// Brightness Correction
RedShift = (COLOR_RANGE - RedGamma[MODE_BRIGHT]); // Scale to 0-255
GreenShift = (COLOR_RANGE - GreenGamma[MODE_BRIGHT]);
BlueShift = (COLOR_RANGE - BlueGamma[MODE_BRIGHT]);
RedShift -= COLOR_MID;
GreenShift -= COLOR_MID;
BlueShift -= COLOR_MID;
// Contrast Correction
RedSlope = (double)(COLOR_RANGE - RedGamma[MODE_CONTRAST]) / (double)COLOR_RANGE;
RedSlope *= 2.0;
if(RedSlope > 1.0) RedSlope = 1.0 + (RedSlope - 1.0) * 5.0;
GreenSlope = (double)(COLOR_RANGE - GreenGamma[MODE_CONTRAST]) / (double)COLOR_RANGE;
GreenSlope *= 2.0;
if(GreenSlope > 1.0) GreenSlope = 1.0 + (GreenSlope - 1.0) * 5.0;
BlueSlope = (double)(COLOR_RANGE - BlueGamma[MODE_CONTRAST]) / (double)COLOR_RANGE;
BlueSlope *= 2.0;
if(BlueSlope > 1.0) BlueSlope = 1.0 + (BlueSlope - 1.0) * 5.0;
// Wait till the beginning of VBlank
while(InVBlank());
while(!InVBlank());
MEM_WRITE_32(pDriverData->RegLinear, VC_PAL_HOST_ADDR, 0x0);
for(i = 0; i < 256; i++)
{
ImageIn = (double)i / 255.0;
ImageRed = pow(ImageIn,InvRG);
ImageGreen = pow(ImageIn,InvGG);
ImageBlue = pow(ImageIn,InvBG);
Red = (int)(ImageRed * 255.0);
Green = (int)(ImageGreen * 255.0);
Blue = (int)(ImageBlue * 255.0);
Red = (int)(Red * RedSlope);
Green = (int)(Green * GreenSlope);
Blue = (int)(Blue * BlueSlope);
Red += RedShift;
Green += GreenShift;
Blue += BlueShift;
if(Red < 0) Red = 0; if(Red > 255) Red = 255;
if(Green < 0) Green = 0; if(Green > 255) Green = 255;
if(Blue < 0) Blue = 0; if(Blue > 255) Blue = 255;
MEM_WRITE_32(pDriverData->RegLinear, VC_PAL_READ_DATA,
((DWORD)Blue | ((DWORD)Green << 8) | ((DWORD)Red << 16)));
}
return(TRUE);
}
/****
NAME: SetVideoOutput
DESCRIPTION
Turns video output on and off in GXi
RETURN VALUE
TRUE if successful, else FALSE.
****/
BOOL SetVideoOutput(BOOL State)
{
// DEBUGENTER( SetVideoOutput );
DWORD RegData;
DWORD RegLinear = pDriverData->RegLinear;
DWORD CfgData = 0x10000000;
// If GXm 4.4 or above then set early ready video bit
//if(pDriverData->ProcessorID >= 0x44)
//{
// CfgData |= 0x20000000;
// // Divide video clock for higher speed CPU's
// if(pDriverData->CPUSpeed > 266)
// {
// {
if(pDriverData->DeviceID == DHRUVA)
CfgData |= 0x00000000;
else
CfgData |= 0x00000004;
// }
//}
// Wait till the beginning of VBlank
while(!InVBlank());
while(InVBlank());
while(!InVBlank());
if(State == TRUE) // Enable video output in GXi
{
MEM_WRITE_32(pDriverData->RegLinear, DC_UNLOCK, 0x4758);
RegData = MEM_READ_32(pDriverData->RegLinear, DC_GENERAL_CFG);
_asm {
// Special HACK for GXm to turn on VIDE
mov ecx, 2
mov eax, RegLinear
VIDE_TurnOn:
// Read/Write DC_CFG and make sure VIDE is OFF
mov esi, eax
add esi, 8304h
mov edx, DWORD PTR [esi]
and edx, NOT 10000000h
mov DWORD PTR [esi], edx
// Setup for VIDE ON, early ready
or edx, CfgData
mov esi, eax
mov edi, eax
add esi, 10000h
add edi, 8304h
// Do any PCI read cycle and
// write DC_CFG and turn ON VIDE,
// these instructions must be back to back and
// in the L1 cache. Hence the two times thru
// this code.
mov ebx, DWORD PTR [esi]
mov DWORD PTR [edi], edx
dec ecx
jnz VIDE_TurnOn
}
// MEM_WRITE_32(pDriverData->RegLinear, DC_GENERAL_CFG, RegData | 0x10000000);
}
else // Disable video output in GXi
{
MEM_WRITE_32(pDriverData->RegLinear, DC_UNLOCK, 0x4758);
RegData = MEM_READ_32(pDriverData->RegLinear, DC_GENERAL_CFG);
MEM_WRITE_32(pDriverData->RegLinear, DC_GENERAL_CFG, RegData & ~0x10000000);
}
MEM_WRITE_32(pDriverData->RegLinear, DC_UNLOCK, 0x0);
RegData = MEM_READ_32(pDriverData->RegLinear, VC_DISP_CFG_BUS);
RegData &= ~VC_DCFG_VGCK; // Set color keying to graphics compare
RegData |= VC_DCFG_GVPB; // Set graphics data to bypass palette
MEM_WRITE_32(pDriverData->RegLinear, VC_DISP_CFG_BUS, RegData);
return(TRUE);
}
/****
NAME: SetVideoBufferSize
DESCRIPTION
Sets the video buffer size in COGNAC
RETURN VALUE
TRUE if successful, else FALSE.
****/
BOOL SetVideoBufferSize(DWORD SizeBytes)
{
// DEBUGENTER( SetVideoBufferSize );
DWORD RegData;
DWORD VPStatus;
// Unlock
MEM_WRITE_32(pDriverData->RegLinear, DC_UNLOCK, 0x4758);
// Calc and write out video buffer size in 64B granularity
RegData = MEM_READ_32(pDriverData->RegLinear, DC_BUF_SIZE);
RegData &= ~DC_VID_BUF_SZ_MASK;
VPStatus = MEM_READ_32(pDriverData->VIPLinear, 0x00000008);
//jp
VPStatus &= 0x00000001;
if(VPStatus == 1) {
SizeBytes = SizeBytes * 2;
}
MEM_WRITE_32(pDriverData->RegLinear, DC_BUF_SIZE, RegData |
((SizeBytes >> 6) << DC_VID_BUF_SZ_POS));
// Lock
MEM_WRITE_32(pDriverData->RegLinear, DC_UNLOCK, 0x0);
return(TRUE);
}
/****
NAME: SetVideoDisplay
DESCRIPTION
Turns video output on and off in COGNAC
RETURN VALUE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -