From 9298f4ea8f6aa11569880829b950f8b52b46959a Mon Sep 17 00:00:00 2001 From: Extrems Date: Fri, 24 Mar 2023 17:20:23 -0400 Subject: [PATCH 1/3] Video fixes (cherry picked from commit 39b647cff1f3ac92a480663ad3e131da006976fe) video squash (cherry picked from commit 0e39e22e94b6ada9064f384a68b70eb40bcd0bd0) --- gc/ogc/video.h | 18 +++- gc/ogc/video_types.h | 2 + libogc/video.c | 220 ++++++++++++++++++++++++++++--------------- 3 files changed, 162 insertions(+), 78 deletions(-) diff --git a/gc/ogc/video.h b/gc/ogc/video.h index 601406c80..9013d95b7 100644 --- a/gc/ogc/video.h +++ b/gc/ogc/video.h @@ -90,7 +90,7 @@ void VIDEO_SetBlack(bool black); /*! * \fn u32 VIDEO_GetNextField(void) - * \brief Get the next field in DS mode. + * \brief Get the next field * * \return \ref vi_fielddef "field" */ @@ -207,6 +207,22 @@ GXRModeObj * VIDEO_GetPreferredMode(GXRModeObj *mode); */ u32 VIDEO_GetVideoScanMode(void); +/*! + * \fn u32 VIDEO_SetAdjustingValues(s16 hor,s16 ver) + * \brief Set video adjustment values + * + * \return none + */ +void VIDEO_SetAdjustingValues(s16 hor,s16 ver); + +/*! + * \fn u32 VIDEO_GetAdjustingValues(s16 hor,s16 ver) + * \brief Get video adjustment values + * + * \return none + */ +void VIDEO_GetAdjustingValues(s16 *hor,s16 *ver); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gc/ogc/video_types.h b/gc/ogc/video_types.h index ad5371f4b..276334930 100644 --- a/gc/ogc/video_types.h +++ b/gc/ogc/video_types.h @@ -54,6 +54,7 @@ distribution. #define VI_INTERLACE 0 /*!< Video mode INTERLACED. */ #define VI_NON_INTERLACE 1 /*!< Video mode NON INTERLACED */ #define VI_PROGRESSIVE 2 /*!< Video mode PROGRESSIVE. Special mode for higher quality */ +#define VI_3D 3 /*!< Video mode 3D */ /*! * @} @@ -119,6 +120,7 @@ distribution. #define VI_TVMODE_NTSC_INT VI_TVMODE(VI_NTSC, VI_INTERLACE) #define VI_TVMODE_NTSC_DS VI_TVMODE(VI_NTSC, VI_NON_INTERLACE) #define VI_TVMODE_NTSC_PROG VI_TVMODE(VI_NTSC, VI_PROGRESSIVE) +#define VI_TVMODE_NTSC_3D VI_TVMODE(VI_NTSC, VI_3D) #define VI_TVMODE_PAL_INT VI_TVMODE(VI_PAL, VI_INTERLACE) #define VI_TVMODE_PAL_DS VI_TVMODE(VI_PAL, VI_NON_INTERLACE) diff --git a/libogc/video.c b/libogc/video.c index 4ec14f74f..714ba88bb 100644 --- a/libogc/video.c +++ b/libogc/video.c @@ -1521,6 +1521,8 @@ static const struct _timing { u16 nhlines,hlw; u8 hsy,hcs,hce,hbe640; u16 hbs640; + u8 hbeCCIR656; + u16 hbsCCIR656; } video_timing[] = { { 0x06,0x00F0, @@ -1529,7 +1531,8 @@ static const struct _timing { 0x0208,0x0207,0x0208,0x0207, 0x020D,0x01AD, 0x40,0x47,0x69,0xA2, - 0x0175 + 0x0175, + 0x7A,0x019C }, { 0x06,0x00F0, @@ -1538,7 +1541,8 @@ static const struct _timing { 0x0208,0x0208,0x0208,0x0208, 0x020E,0x01AD, 0x40,0x47,0x69,0xA2, - 0x0175 + 0x0175, + 0x7A,0x019C }, { 0x05,0x0120, @@ -1547,7 +1551,8 @@ static const struct _timing { 0x026B,0x026A,0x0269,0x026C, 0x0271,0x01B0, 0x40,0x4B,0x6A,0xAC, - 0x017C + 0x017C, + 0x85,0x01A4 }, { 0x05,0x0120, @@ -1556,7 +1561,8 @@ static const struct _timing { 0x026B,0x026D,0x026B,0x026D, 0x0270,0x01B0, 0x40,0x4B,0x6A,0xAC, - 0x017C + 0x017C, + 0x85,0x01A4 }, { 0x06,0x00F0, @@ -1565,7 +1571,8 @@ static const struct _timing { 0x0206,0x0205,0x0204,0x0207, 0x020D,0x01AD, 0x40,0x4E,0x70,0xA2, - 0x0175 + 0x0175, + 0x7A,0x019C }, { 0x06,0x00F0, @@ -1574,7 +1581,8 @@ static const struct _timing { 0x0206,0x0208,0x0206,0x0208, 0x020E,0x01AD, 0x40,0x4E,0x70,0xA2, - 0x0175 + 0x0175, + 0x7A,0x019C }, { 0x0C,0x01E0, @@ -1583,7 +1591,18 @@ static const struct _timing { 0x040E,0x040E,0x040E,0x040E, 0x041A,0x01AD, 0x40,0x47,0x69,0xA2, - 0x0175 + 0x0175, + 0x7A,0x019C + }, + { + 0x0C,0x01E0, + 0x002C,0x002C,0x000A,0x000A, + 0x18,0x18,0x18,0x18, + 0x040E,0x040E,0x040E,0x040E, + 0x041A,0x01AD, + 0x40,0x47,0x69,0xA8, + 0x017B, + 0x7A,0x019C }, { 0x0A,0x0240, @@ -1592,7 +1611,8 @@ static const struct _timing { 0x04D8,0x04D8,0x04D8,0x04D8, 0x04E2,0x01B0, 0x40,0x4B,0x6A,0xAC, - 0x017C + 0x017C, + 0x85,0x01A4 } }; @@ -1600,14 +1620,14 @@ static const struct _timing { static u32 vdacFlagRegion; static u32 i2cIdentFirst = 0; static u32 i2cIdentFlag = 1; -static u32 oldTvStatus = 0x03e7; +static u32 oldTvMode = 0x03e7; static u32 oldDtvStatus = 0x03e7; static vu32* const _i2cReg = (u32*)0xCD800000; #endif static u16 regs[60]; static u16 shdw_regs[60]; -static u32 fbSet = 0; +static u32 encoderType,fbSet; static s16 displayOffsetH; static s16 displayOffsetV; static u32 currTvMode,changeMode; @@ -1625,9 +1645,6 @@ static VIPositionCallback positionCB = NULL; static vu16* const _viReg = (u16*)0xCC002000; -extern syssram* __SYS_LockSram(void); -extern u32 __SYS_UnlockSram(u32 write); - extern void __VIClearFramebuffer(void*,u32,u32); extern void udelay(int us); @@ -1718,23 +1735,21 @@ static const struct _timing* __gettiming(u32 vimode) { switch(vimode) { case VI_TVMODE_NTSC_INT: + case VI_TVMODE_EURGB60_INT: return &video_timing[0]; break; case VI_TVMODE_NTSC_DS: + case VI_TVMODE_EURGB60_DS: return &video_timing[1]; break; case VI_TVMODE_PAL_INT: + case VI_TVMODE_DEBUG_PAL_INT: return &video_timing[2]; break; case VI_TVMODE_PAL_DS: + case VI_TVMODE_DEBUG_PAL_DS: return &video_timing[3]; break; - case VI_TVMODE_EURGB60_INT: - return &video_timing[0]; - break; - case VI_TVMODE_EURGB60_DS: - return &video_timing[1]; - break; case VI_TVMODE_MPAL_INT: return &video_timing[4]; break; @@ -1742,20 +1757,20 @@ static const struct _timing* __gettiming(u32 vimode) return &video_timing[5]; break; case VI_TVMODE_NTSC_PROG: + case VI_TVMODE_MPAL_PROG: + case VI_TVMODE_EURGB60_PROG: return &video_timing[6]; break; - case VI_TVMODE_PAL_PROG: + case VI_TVMODE_NTSC_3D: return &video_timing[7]; break; - case VI_TVMODE_EURGB60_PROG: - return &video_timing[6]; - break; - case VI_TVMODE_MPAL_PROG: - return &video_timing[6]; + case VI_TVMODE_PAL_PROG: + return &video_timing[8]; break; default: - return NULL; + break; } + return NULL; } #if defined(HW_RVL) @@ -1888,7 +1903,7 @@ static inline void __calcFbbs(u32 bufAddr,u16 panPosX,u16 panPosY,u8 wordperline panPosX &= 0xfff0; bytesPerLine = (wordperline<<5)&0x1fe0; - *tfbb = bufAddr+((panPosX<<5)+(panPosY*bytesPerLine)); + *tfbb = bufAddr+((panPosX*VI_DISPLAY_PIX_SZ)+(panPosY*bytesPerLine)); *bfbb = *tfbb; if(xfbMode==VI_XFBMODE_DF) *bfbb = *tfbb+bytesPerLine; @@ -1969,14 +1984,14 @@ static inline void __setVerticalRegs(u16 dispPosY,u16 dispSizeY,u8 equ,u16 acv,u div1 = 2; div2 = 1; - if(equ>=10) { + if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==VI_3D) { div1 = 1; div2 = 2; } prb = div2*dispPosY; psb = div2*(((acv*div1)-dispSizeY)-dispPosY); - if(dispPosY%2) { + if(prb%2) { prbodd = prbEven+prb; psbodd = psbEven+psb; prbeven = prbOdd+prb; @@ -2013,7 +2028,7 @@ static inline void __setVerticalRegs(u16 dispPosY,u16 dispSizeY,u8 equ,u16 acv,u static inline void __adjustPosition(u16 acv) { - u32 fact,field; + s32 fact,field; s16 dispPosX,dispPosY; s16 dispSizeY,maxDispSizeY; @@ -2026,14 +2041,14 @@ static inline void __adjustPosition(u16 acv) fact = 1; if(HorVer.fbMode==VI_XFBMODE_SF) fact = 2; - field = HorVer.dispPosY&0x0001; dispPosY = HorVer.dispPosY+displayOffsetV; + field = dispPosY&0x0001; if(dispPosY>field) HorVer.adjustedDispPosY = dispPosY; else HorVer.adjustedDispPosY = field; dispSizeY = HorVer.dispPosY+HorVer.dispSizeY+displayOffsetV; maxDispSizeY = ((acv<<1)-field); - if(dispSizeY>maxDispSizeY) dispSizeY -= (acv<<1)-field; + if(dispSizeY>maxDispSizeY) dispSizeY -= maxDispSizeY; else dispSizeY = 0; dispPosY = HorVer.dispPosY+displayOffsetV; @@ -2059,11 +2074,7 @@ static inline void __adjustPosition(u16 acv) static inline void __importAdjustingValues(void) { #ifdef HW_DOL - syssram *sram; - - sram = __SYS_LockSram(); - displayOffsetH = sram->display_offsetH; - __SYS_UnlockSram(0); + displayOffsetH = SYS_GetDisplayOffsetH(); #else s8 offset; if ( CONF_GetDisplayOffsetH(&offset) == 0 ) { @@ -2275,8 +2286,7 @@ static void __VISetupEncoder(void) u8 dtv, tv; tv = VIDEO_GetCurrentTvMode(); - dtv = (_viReg[55]&0x01); - oldDtvStatus = dtv; + dtv = VIDEO_HaveComponentCable(); // SetRevolutionModeSimple @@ -2306,8 +2316,6 @@ static void __VISetupEncoder(void) if(tv==VI_EURGB60) __VISetFilterEURGB60(1); else __VISetFilterEURGB60(0); - oldTvStatus = tv; - } #endif @@ -2385,7 +2393,7 @@ static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py) hline = ((vpos<<1)+(hpos/currTiming->hlw)); *px = (s32)hpos; - if(HorVer.nonInter==0x0000) { + if(HorVer.nonInter==VI_INTERLACE) { if(hlinenhlines) { val = currTiming->prbOdd+(currTiming->equ*3); if(hline>=val) { @@ -2397,7 +2405,7 @@ static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py) } else *py = -1; } else { - hline -= currTiming->psbOdd; + hline -= currTiming->nhlines; val = (currTiming->prbEven+(currTiming->equ*3)); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbEven); @@ -2408,7 +2416,7 @@ static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py) } else *py = -1; } - } else if(HorVer.nonInter==0x0001) { + } else if(HorVer.nonInter==VI_NON_INTERLACE) { if(hline>=currTiming->nhlines) hline -= currTiming->nhlines; val = (currTiming->prbOdd+(currTiming->equ*3)); @@ -2420,7 +2428,7 @@ static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py) *py = -1; } else *py = -1; - } else if(HorVer.nonInter==0x0002) { + } else if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==VI_3D) { if(hlinenhlines) { val = currTiming->prbOdd+(currTiming->equ*3); if(hline>=val) { @@ -2432,7 +2440,7 @@ static void __VIDisplayPositionToXY(s32 xpos,s32 ypos,s32 *px,s32 *py) } else *py = -1; } else { - hline -= currTiming->psbOdd; + hline -= currTiming->nhlines; val = (currTiming->prbEven+(currTiming->equ*3)); if(hline>=val) { val = (currTiming->nhlines-currTiming->psbEven); @@ -2493,6 +2501,7 @@ static void __VIRetraceHandler(u32 nIrq,void *pCtx) __VIGetCurrentPosition(&xpos,&ypos); positionCB(xpos,ypos); } + return; } retraceCount++; @@ -2507,15 +2516,16 @@ static void __VIRetraceHandler(u32 nIrq,void *pCtx) } #if defined(HW_RVL) tv = VIDEO_GetCurrentTvMode(); - dtv = (_viReg[55]&0x01); - if(dtv!=oldDtvStatus || tv!=oldTvStatus) __VISetYUVSEL(dtv); + dtv = VIDEO_HaveComponentCable(); + + if(dtv!=oldDtvStatus || tv!=oldTvMode) __VISetYUVSEL(dtv); oldDtvStatus = dtv; - if(tv!=oldTvStatus) { + if(tv!=oldTvMode) { if(tv==VI_EURGB60) __VISetFilterEURGB60(1); else __VISetFilterEURGB60(0); } - oldTvStatus = tv; + oldTvMode = tv; #endif if(postRetraceCB) postRetraceCB(retraceCount); @@ -2547,6 +2557,7 @@ void VIDEO_Init(void) shdw_changed = 0; shdw_changeMode = 0; flushFlag = 0; + encoderType = 1; _viReg[38] = ((taps[1]>>6)|(taps[2]<<4)); _viReg[39] = (taps[0]|_SHIFTL(taps[1],10,6)); @@ -2566,7 +2577,7 @@ void VIDEO_Init(void) __importAdjustingValues(); - HorVer.nonInter = _SHIFTR(_viReg[1],2,1); + HorVer.nonInter = VIDEO_GetVideoScanMode(); HorVer.tv = _SHIFTR(_viReg[1],8,2); vimode = HorVer.nonInter; @@ -2624,9 +2635,9 @@ void VIDEO_Configure(GXRModeObj *rmode) const struct _timing *curtiming; #ifdef _VIDEO_DEBUG if(rmode->viHeight&0x0001) printf("VIDEO_Configure(): Odd number(%d) is specified to viHeight\n",rmode->viHeight); - if((rmode->xfbMode==VI_XFBMODE_DF || rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) + if((rmode->xfbMode==VI_XFBMODE_DF || rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_3D) && rmode->xfbHeight!=rmode->viHeight) printf("VIDEO_Configure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n",rmode->xfbHeight,rmode->viHeight); - if(rmode->xfbMode==VI_XFBMODE_SF && !(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_PROG_DS) + if(rmode->xfbMode==VI_XFBMODE_SF && !(rmode->viTVMode==VI_TVMODE_NTSC_PROG || rmode->viTVMode==VI_TVMODE_NTSC_3D) && (rmode->xfbHeight<<1)!=rmode->viHeight) printf("VIDEO_Configure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n",rmode->xfbHeight,rmode->viHeight); #endif _CPU_ISR_Disable(level); @@ -2635,7 +2646,7 @@ void VIDEO_Configure(GXRModeObj *rmode) changeMode = 1; HorVer.nonInter = nonint; } - HorVer.tv = _SHIFTR(rmode->viTVMode,2,3); + HorVer.tv = (rmode->viTVMode>>2); HorVer.dispPosX = rmode->viXOrigin; HorVer.dispPosY = rmode->viYOrigin; if(HorVer.nonInter==VI_NON_INTERLACE) HorVer.dispPosY = HorVer.dispPosY<<1; @@ -2649,11 +2660,11 @@ void VIDEO_Configure(GXRModeObj *rmode) HorVer.panPosX = 0; HorVer.panPosY = 0; - if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.dispSizeY = HorVer.panSizeY; + if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==VI_3D) HorVer.dispSizeY = HorVer.panSizeY; else if(HorVer.fbMode==VI_XFBMODE_SF) HorVer.dispSizeY = HorVer.panSizeY<<1; else HorVer.dispSizeY = HorVer.panSizeY; - if(HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) HorVer.threeD = 1; + if(HorVer.nonInter==VI_3D) HorVer.threeD = 1; else HorVer.threeD = 0; vimode = VI_TVMODE(HorVer.tv,HorVer.nonInter); @@ -2665,19 +2676,20 @@ void VIDEO_Configure(GXRModeObj *rmode) if(rmode->viXOrigin>((curtiming->hlw+40)-curtiming->hbe640)) printf("VIDEO_Configure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n",rmode->viXOrigin,((curtiming->hlw+40)-curtiming->hbe640)); if((rmode->viXOrigin+rmode->viWidth)<(680-curtiming->hbs640)) printf("VIDEO_Configure(): viXOrigin + viWidth(%d) cannot be less than %d in this TV mode\n",(rmode->viXOrigin+rmode->viWidth),(680-curtiming->hbs640)); #endif + if(!encoderType) HorVer.tv = VI_DEBUG; __setInterruptRegs(curtiming); dcr = regs[1]&~0x030c; dcr |= _SHIFTL(HorVer.threeD,3,1); - if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==(VI_NON_INTERLACE|VI_PROGRESSIVE)) dcr |= 0x0004; + if(HorVer.nonInter==VI_PROGRESSIVE || HorVer.nonInter==VI_3D) dcr |= 0x0004; else dcr |= _SHIFTL(HorVer.nonInter,2,1); - if(!(HorVer.tv==VI_EURGB60)) dcr |= _SHIFTL(HorVer.tv,8,2); + if(HorVer.tvacv); + __setScalingRegs(HorVer.panSizeX,HorVer.dispSizeX,HorVer.threeD); + __setPicConfig(HorVer.fbSizeX,HorVer.fbMode,HorVer.panPosX,HorVer.panSizeX,&HorVer.wordPerLine,&HorVer.std,&HorVer.wpl,&HorVer.xof); + + if(fbSet) __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb); + + __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.adjustedDispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black); + _CPU_ISR_Restore(level); +} + void VIDEO_WaitVSync(void) { u32 level; @@ -2805,18 +2843,15 @@ u32 VIDEO_GetNextField(void) u32 VIDEO_GetCurrentTvMode(void) { - u32 mode; u32 level; u32 tv; _CPU_ISR_Disable(level); - mode = currTvMode; - - if(mode==VI_DEBUG) tv = VI_NTSC; - else if(mode==VI_EURGB60) tv = VI_EURGB60; - else if(mode==VI_MPAL) tv = VI_MPAL; - else if(mode==VI_NTSC) tv = VI_NTSC; - else tv = VI_PAL; + if(currTvMode==VI_PAL) tv = VI_PAL; + else if(currTvMode==VI_DEBUG_PAL) tv = VI_PAL; + else if(currTvMode==VI_EURGB60) tv = VI_EURGB60; + else if(currTvMode==VI_MPAL) tv = VI_MPAL; + else tv = VI_NTSC; _CPU_ISR_Restore(level); return tv; @@ -2924,33 +2959,35 @@ u32 VIDEO_GetCurrentLine(void) VIRetraceCallback VIDEO_SetPreRetraceCallback(VIRetraceCallback callback) { - u32 level = 0; - VIRetraceCallback ret = preRetraceCB; + u32 level; + VIRetraceCallback old; + _CPU_ISR_Disable(level); + old = preRetraceCB; preRetraceCB = callback; _CPU_ISR_Restore(level); - return ret; + return old; } VIRetraceCallback VIDEO_SetPostRetraceCallback(VIRetraceCallback callback) { - u32 level = 0; - VIRetraceCallback ret = postRetraceCB; + u32 level; + VIRetraceCallback old; + _CPU_ISR_Disable(level); + old = postRetraceCB; postRetraceCB = callback; _CPU_ISR_Restore(level); - return ret; + return old; } -u32 VIDEO_GetFrameBufferSize(GXRModeObj *rmode) { +u32 VIDEO_GetFrameBufferSize(GXRModeObj *rmode) +{ u16 w, h; w = VIDEO_PadFramebufferWidth(rmode->fbWidth); h = rmode->xfbHeight; - if (rmode->aa) - h += 4; - return w * h * VI_DISPLAY_PIX_SZ; } @@ -2979,4 +3016,33 @@ u32 VIDEO_GetVideoScanMode(void) _CPU_ISR_Restore(level); return mode; +} + +void VIDEO_SetAdjustingValues(s16 hor,s16 ver) +{ + u32 level; + const struct _timing *curtiming; + + _CPU_ISR_Disable(level); + displayOffsetH = hor; + displayOffsetV = ver; + + curtiming = HorVer.timing; + __adjustPosition(curtiming->acv); + __setHorizontalRegs(curtiming,HorVer.adjustedDispPosX,HorVer.dispSizeX); + + if(fbSet) __setFbbRegs(&HorVer,&HorVer.tfbb,&HorVer.bfbb,&HorVer.rtfbb,&HorVer.rbfbb); + + __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.adjustedDispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black); + _CPU_ISR_Restore(level); +} + +void VIDEO_GetAdjustingValues(s16 *hor,s16 *ver) +{ + u32 level; + + _CPU_ISR_Disable(level); + *hor = displayOffsetH; + *ver = displayOffsetV; + _CPU_ISR_Restore(level); } \ No newline at end of file From abd45850d05cd144cb7a84c4d4f6e01d51a888d7 Mon Sep 17 00:00:00 2001 From: DacoTaco Date: Fri, 16 Jun 2023 21:09:52 +0200 Subject: [PATCH 2/3] video: merging with extrems work (cherry picked from commit a988ad61840728dc4357ca1e9ccfd0a76bb8321d) --- gc/ogc/video.h | 24 +++++++++++-- libogc/video.c | 92 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 78 insertions(+), 38 deletions(-) diff --git a/gc/ogc/video.h b/gc/ogc/video.h index 9013d95b7..85d78be04 100644 --- a/gc/ogc/video.h +++ b/gc/ogc/video.h @@ -87,6 +87,24 @@ void VIDEO_Flush(void); */ void VIDEO_SetBlack(bool black); +/*! + * \fn void VIDEO_Set3D(bool enable3d) + * \brief control the 3D bits in video + * + * \param[in] Boolean to indicate to enable 3D or not + * + * \return none + */ +void VIDEO_Set3D(bool enable3d); + +/*! + * \fn u32 VIDEO_GetRetraceCount(void) + * \brief Get current retrace count + * + * \return retracecount + */ +u32 VIDEO_GetRetraceCount(void); + /*! * \fn u32 VIDEO_GetNextField(void) @@ -116,14 +134,16 @@ u32 VIDEO_GetCurrentTvMode(void); /*! - * \fn void VIDEO_Configure(GXRModeObj *rmode) + * \fn void VIDEO_Configure(const GXRModeObj *rmode) * \brief Configure the VI with the given render mode object * * \param[in] rmode pointer to the video/render mode \ref gxrmode_obj "configuration". * * \return none */ -void VIDEO_Configure(GXRModeObj *rmode); +void VIDEO_Configure(const GXRModeObj *rmode); + +void VIDEO_ConfigurePan(u16 xOrg,u16 yOrg,u16 width,u16 height); u32 VIDEO_GetFrameBufferSize(GXRModeObj *rmode); diff --git a/libogc/video.c b/libogc/video.c index 714ba88bb..3671c4609 100644 --- a/libogc/video.c +++ b/libogc/video.c @@ -2365,7 +2365,7 @@ static inline u32 __VISetRegs(void) u64 mask; if(shdw_changeMode==1){ - if(!__getCurrentFieldEvenOdd()) return 0; + if(__getCurrentHalfLine()) return 0; } while(shdw_changed) { @@ -2628,7 +2628,7 @@ void VIDEO_Init(void) _CPU_ISR_Restore(level); } -void VIDEO_Configure(GXRModeObj *rmode) +void VIDEO_Configure(const GXRModeObj *rmode) { u16 dcr; u32 nonint,vimode,level; @@ -2826,10 +2826,27 @@ void VIDEO_SetBlack(bool black) _CPU_ISR_Disable(level); HorVer.black = black; curtiming = HorVer.timing; - __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.dispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black); + __setVerticalRegs(HorVer.adjustedDispPosY,HorVer.adjustedDispSizeY,curtiming->equ,curtiming->acv,curtiming->prbOdd,curtiming->prbEven,curtiming->psbOdd,curtiming->psbEven,HorVer.black); + _CPU_ISR_Restore(level); +} + +void VIDEO_Set3D(bool enable3d) +{ + u32 level; + + _CPU_ISR_Disable(level); + HorVer.threeD = enable3d; + regs[1] = (regs[1]&~0x0008)|(_SHIFTL(enable3d,3,1)); + changed |= VI_REGCHANGE(1); + __setScalingRegs(HorVer.panSizeX,HorVer.dispSizeX,HorVer.threeD); _CPU_ISR_Restore(level); } +u32 VIDEO_GetRetraceCount(void) +{ + return retraceCount; +} + u32 VIDEO_GetNextField(void) { u32 level,nextfield; @@ -2866,67 +2883,61 @@ GXRModeObj *rmode = NULL; u32 tvmode = CONF_GetVideo(); if (CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable()) { switch (tvmode) { - case CONF_VIDEO_NTSC: - rmode = &TVNtsc480Prog; - break; case CONF_VIDEO_PAL: - if (CONF_GetEuRGB60() > 0) - rmode = &TVEurgb60Hz480Prog; - else rmode = &TVPal576ProgScale; + rmode = CONF_GetEuRGB60() > 0 ? &TVEurgb60Hz480Prog : &TVPal576ProgScale; break; + //GCVideo-DVI might misbehave with MPAL, thinking its PAL50. + //removing this case fixes that, but then we loose the specific timings/config case CONF_VIDEO_MPAL: rmode = &TVMpal480Prog; break; default: + case CONF_VIDEO_NTSC: rmode = &TVNtsc480Prog; + break; } } else { switch (tvmode) { - case CONF_VIDEO_NTSC: - rmode = &TVNtsc480IntDf; - break; case CONF_VIDEO_PAL: - if (CONF_GetEuRGB60() > 0) - rmode = &TVEurgb60Hz480IntDf; - else rmode = &TVPal576IntDfScale; + rmode = CONF_GetEuRGB60() > 0 ? &TVEurgb60Hz480IntDf : &TVPal576IntDfScale; break; case CONF_VIDEO_MPAL: - rmode = &TVMpal480IntDf; + rmode = VIDEO_HaveComponentCable() > 0 ? &TVNtsc480IntDf : &TVMpal480IntDf; break; default: + case CONF_VIDEO_NTSC: rmode = &TVNtsc480IntDf; + break; } } #else - u32 tvmode = VIDEO_GetCurrentTvMode(); - if (VIDEO_HaveComponentCable()) { + u32 tvmode = SYS_GetVideoMode(); + if (SYS_GetProgressiveScan() && VIDEO_HaveComponentCable()) { switch (tvmode) { - case VI_NTSC: - rmode = &TVNtsc480Prog; - break; - case VI_PAL: - rmode = &TVPal576ProgScale; + case SYS_VIDEO_PAL: + rmode = SYS_GetEuRGB60() ? &TVEurgb60Hz480Prog : &TVPal576ProgScale; break; - case VI_MPAL: + //GCVideo-DVI might misbehave with MPAL, thinking its PAL50. + //removing this case fixes that, but then we loose the specific timings/config + case SYS_VIDEO_MPAL: rmode = &TVMpal480Prog; break; - case VI_EURGB60: - rmode = &TVEurgb60Hz480Prog; + default: + case SYS_VIDEO_NTSC: + rmode = &TVNtsc480Prog; break; } } else { switch (tvmode) { - case VI_NTSC: - rmode = &TVNtsc480IntDf; - break; - case VI_PAL: - rmode = &TVPal576IntDfScale; + case SYS_VIDEO_PAL: + rmode = SYS_GetEuRGB60() > 0 ? &TVEurgb60Hz480IntDf : &TVPal576IntDfScale; break; - case VI_MPAL: - rmode = &TVMpal480IntDf; + case SYS_VIDEO_MPAL: + rmode = VIDEO_HaveComponentCable() > 0 ? &TVNtsc480IntDf : &TVMpal480IntDf; break; - case VI_EURGB60: - rmode = &TVEurgb60Hz480IntDf; + default: + case SYS_VIDEO_NTSC: + rmode = &TVNtsc480IntDf; break; } } @@ -2998,7 +3009,16 @@ void VIDEO_ClearFrameBuffer(GXRModeObj *rmode,void *fb,u32 color) u32 VIDEO_HaveComponentCable(void) { - return (_viReg[55]&0x01); + u32 dtv,level; + _CPU_ISR_Disable(level); + + dtv = (_viReg[55]&0x0001); +#if defined(HW_DOL) + dtv |= (_viReg[54]&0x0001); +#endif + + _CPU_ISR_Restore(level); + return dtv; } u32 VIDEO_GetVideoScanMode(void) From 982832f1fb50a8c261a7ba217ed634ad09f17f50 Mon Sep 17 00:00:00 2001 From: DacoTaco Date: Sat, 17 Jun 2023 10:54:39 +0200 Subject: [PATCH 3/3] gx: merge changes from extrems (cherry picked from commit cebb58f4afa0e4bf5717641876ebbeb195598c56) --- gc/ogc/gx.h | 292 +++++++++++++++++++++++++------------- libogc/gx.c | 345 ++++++++++++++++++++++++++++++--------------- libogc/gx_regdef.h | 4 +- 3 files changed, 428 insertions(+), 213 deletions(-) diff --git a/gc/ogc/gx.h b/gc/ogc/gx.h index 56c6c8157..4e755557c 100644 --- a/gc/ogc/gx.h +++ b/gc/ogc/gx.h @@ -945,10 +945,11 @@ /*! \addtogroup copymode EFB copy mode - * \brief Controls whether all lines, only even lines, or only odd lines are copied from the EFB. + * \brief Controls whether all lines, no lines, only even lines, or only odd lines are copied from the EFB. * @{ */ #define GX_COPY_PROGRESSIVE 0 +#define GX_COPY_NONE 1 #define GX_COPY_INTLC_EVEN 2 #define GX_COPY_INTLC_ODD 3 /*! @} */ @@ -1174,6 +1175,7 @@ typedef union _wgpipe vu32 U32; vs32 S32; vf32 F32; + vf64 F64; } WGPipe; /*! \typedef struct _gx_color GXColor @@ -1337,11 +1339,11 @@ typedef void (*GXDrawDoneCallback)(void); */ typedef void (*GXDrawSyncCallback)(u16 token); -/*! \typedef GXTexRegion* (*GXTexRegionCallback)(GXTexObj *obj,u8 mapid) +/*! \typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj *obj,u8 mapid) * \brief function pointer typedef for the texture region callback * \param[out] token tokenvalue most recently encountered. */ -typedef GXTexRegion* (*GXTexRegionCallback)(GXTexObj *obj,u8 mapid); +typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj *obj,u8 mapid); /*! \typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 tlut_name) * \brief function pointer typedef for the TLUT region callback @@ -1459,7 +1461,7 @@ void GX_InitFifoPtrs(GXFifoObj *fifo,void *rd_ptr,void *wt_ptr); void GX_GetFifoPtrs(const GXFifoObj *fifo,void **rd_ptr,void **wt_ptr); /*! - * \fn void GX_SetCPUFifo(GXFifoObj *fifo) + * \fn void GX_SetCPUFifo(const GXFifoObj *fifo) * \brief Attaches a FIFO to the CPU. * * \note If the FIFO being attached is one already attached to the GP, the FIFO can be considered to be in immediate mode. If not, @@ -1469,10 +1471,10 @@ void GX_GetFifoPtrs(const GXFifoObj *fifo,void **rd_ptr,void **wt_ptr); * * \return none */ -void GX_SetCPUFifo(GXFifoObj *fifo); +void GX_SetCPUFifo(const GXFifoObj *fifo); /*! - * \fn void GX_SetGPFifo(GXFifoObj *fifo) + * \fn void GX_SetGPFifo(const GXFifoObj *fifo) * \brief Attaches \a fifo to the GP. * * \note If the FIFO is also attached to the CPU, the system is in immediate-mode, and the fifo acts like a true FIFO. In immediate-mode, @@ -1492,7 +1494,7 @@ void GX_SetCPUFifo(GXFifoObj *fifo); * * \return none */ -void GX_SetGPFifo(GXFifoObj *fifo); +void GX_SetGPFifo(const GXFifoObj *fifo); /*! * \fn void GX_GetCPUFifo(GXFifoObj *fifo) @@ -1780,7 +1782,7 @@ void GX_InvVtxCache(void); void GX_ClearVtxDesc(void); /*! - * \fn void GX_LoadProjectionMtx(Mtx44 mt,u8 type) + * \fn void GX_LoadProjectionMtx(const Mtx44 mt,u8 type) * \brief Sets the projection matrix. * * \note Only two types of projection matrices are supported: GX_PERSPECTIVE or GX_ORTHOGRAPHIC. @@ -1790,7 +1792,7 @@ void GX_ClearVtxDesc(void); * * \return none */ -void GX_LoadProjectionMtx(Mtx44 mt,u8 type); +void GX_LoadProjectionMtx(const Mtx44 mt,u8 type); /*! * \fn void GX_SetViewport(f32 xOrig,f32 yOrig,f32 wd,f32 ht,f32 nearZ,f32 farZ) @@ -1898,7 +1900,7 @@ void GX_SetChanAmbColor(s32 channel,GXColor color); void GX_SetChanMatColor(s32 channel,GXColor color); /*! - * \fn void GX_SetArray(u32 attr,void *ptr,u8 stride) + * \fn void GX_SetArray(u32 attr,const void *ptr,u8 stride) * \brief Sets the array base pointer and stride for a single attribute. * * \details The array base and stride are used to compute the address of indexed attribute data using the equation:

@@ -1925,7 +1927,7 @@ void GX_SetChanMatColor(s32 channel,GXColor color); * * \return none */ -void GX_SetArray(u32 attr,void *ptr,u8 stride); +void GX_SetArray(u32 attr,const void *ptr,u8 stride); /*! * \fn void GX_SetVtxAttrFmt(u8 vtxfmt,u32 vtxattr,u32 comptype,u32 compsize,u32 frac) @@ -1954,7 +1956,7 @@ void GX_SetArray(u32 attr,void *ptr,u8 stride); void GX_SetVtxAttrFmt(u8 vtxfmt,u32 vtxattr,u32 comptype,u32 compsize,u32 frac); /*! - * \fn void GX_SetVtxAttrFmtv(u8 vtxfmt,GXVtxAttrFmt *attr_list) + * \fn void GX_SetVtxAttrFmtv(u8 vtxfmt,const GXVtxAttrFmt *attr_list) * \brief Sets multiple attribute formats within a single vertex format. * * \details This is useful when you need to set all the attributes in a vertex format at once (e.g., during graphics initialization). @@ -1966,7 +1968,7 @@ void GX_SetVtxAttrFmt(u8 vtxfmt,u32 vtxattr,u32 comptype,u32 compsize,u32 frac); * * \return none */ -void GX_SetVtxAttrFmtv(u8 vtxfmt,GXVtxAttrFmt *attr_list); +void GX_SetVtxAttrFmtv(u8 vtxfmt,const GXVtxAttrFmt *attr_list); /*! * \fn void GX_SetVtxDesc(u8 attr,u8 type) @@ -1984,7 +1986,7 @@ void GX_SetVtxAttrFmtv(u8 vtxfmt,GXVtxAttrFmt *attr_list); void GX_SetVtxDesc(u8 attr,u8 type); /*! - * \fn void GX_SetVtxDescv(GXVtxDesc *attr_list) + * \fn void GX_SetVtxDescv(const GXVtxDesc *attr_list) * \brief Sets the type of multiple attributes. * * \details This function is used when more than one attribute needs to be set (e.g., during initialization of geometry). @@ -1995,7 +1997,7 @@ void GX_SetVtxDesc(u8 attr,u8 type); * * \return none */ -void GX_SetVtxDescv(GXVtxDesc *attr_list); +void GX_SetVtxDescv(const GXVtxDesc *attr_list); /*! * \fn void GX_GetVtxDescv(GXVtxDesc *attr_list) @@ -2088,7 +2090,7 @@ void GX_Begin(u8 primitve,u8 vtxfmt,u16 vtxcnt); void GX_BeginDispList(void *list,u32 size); /*! - * \fn void GX_CallDispList(void *list,u32 nbytes) + * \fn void GX_CallDispList(const void *list,u32 nbytes) * \brief Causes the GP to execute graphics commands from the display \a list instead of from the GP FIFO. * * \details When the number of bytes specified by \a nbytes have been read, the graphics processor will resume executing @@ -2106,7 +2108,7 @@ void GX_BeginDispList(void *list,u32 size); * * \return none */ -void GX_CallDispList(void *list,u32 nbytes); +void GX_CallDispList(const void *list,u32 nbytes); /*! * \fn static inline void GX_End(void) @@ -2337,7 +2339,7 @@ static inline void GX_MatrixIndex1x8(u8 index) } /*! - * \fn void GX_AdjustForOverscan(GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver) + * \fn void GX_AdjustForOverscan(const GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver) * \brief Takes a given render mode and returns a version that is reduced in size to account for overscan. * * \details The number of pixels specified by \a hor is subtracted from each side of the screen, and the number of pixels specified @@ -2355,10 +2357,10 @@ static inline void GX_MatrixIndex1x8(u8 index) * * \returns none */ -void GX_AdjustForOverscan(GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver); +void GX_AdjustForOverscan(const GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver); /*! - * \fn void GX_LoadPosMtxImm(Mtx mt,u32 pnidx) + * \fn void GX_LoadPosMtxImm(const Mtx mt,u32 pnidx) * \brief Used to load a 3x4 modelview matrix \a mt into matrix memory at location \a pnidx. * * \details This matrix can be used to transform positions in model space to view space, either by making the matrix the current one (see @@ -2378,7 +2380,7 @@ void GX_AdjustForOverscan(GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver); * * \return none */ -void GX_LoadPosMtxImm(Mtx mt,u32 pnidx); +void GX_LoadPosMtxImm(const Mtx mt,u32 pnidx); /*! * \fn void GX_LoadPosMtxIdx(u16 mtxidx,u32 pnidx) @@ -2404,7 +2406,7 @@ void GX_LoadPosMtxImm(Mtx mt,u32 pnidx); void GX_LoadPosMtxIdx(u16 mtxidx,u32 pnidx); /*! - * \fn void GX_LoadNrmMtxImm(Mtx mt,u32 pnidx) + * \fn void GX_LoadNrmMtxImm(const Mtx mt,u32 pnidx) * \brief Used to load a normal transform matrix into matrix memory at location \a pnidx from the 4x3 matrix \a mt. * * \details This matrix is used to transform normals in model space to view space, either by making it the current matrix (see GX_SetCurrentMtx()), @@ -2426,10 +2428,10 @@ void GX_LoadPosMtxIdx(u16 mtxidx,u32 pnidx); * * \return none */ -void GX_LoadNrmMtxImm(Mtx mt,u32 pnidx); +void GX_LoadNrmMtxImm(const Mtx mt,u32 pnidx); /*! - * \fn void GX_LoadNrmMtxImm3x3(Mtx33 mt,u32 pnidx) + * \fn void GX_LoadNrmMtxImm3x3(const Mtx33 mt,u32 pnidx) * \brief Used to load a normal transform matrix into matrix memory at location \a pnidx from the 3x3 matrix \a mt. * * \details This matrix is used to transform normals in model space to view space, either by making it the current matrix (see GX_SetCurrentMtx()), @@ -2449,7 +2451,7 @@ void GX_LoadNrmMtxImm(Mtx mt,u32 pnidx); * * \return none */ -void GX_LoadNrmMtxImm3x3(Mtx33 mt,u32 pnidx); +void GX_LoadNrmMtxImm3x3(const Mtx33 mt,u32 pnidx); /*! * \fn void GX_LoadNrmMtxIdx3x3(u16 mtxidx,u32 pnidx) @@ -2476,7 +2478,7 @@ void GX_LoadNrmMtxImm3x3(Mtx33 mt,u32 pnidx); void GX_LoadNrmMtxIdx3x3(u16 mtxidx,u32 pnidx); /*! - * \fn void GX_LoadTexMtxImm(Mtx mt,u32 texidx,u8 type) + * \fn void GX_LoadTexMtxImm(const Mtx mt,u32 texidx,u8 type) * \brief Loads a texture matrix \a mt into the matrix memory at location \a texidx. * * \details The matrix loaded can be either a 2x4 or 3x4 matrix as indicated by \a type. You can use the loaded matrix to @@ -2499,7 +2501,7 @@ void GX_LoadNrmMtxIdx3x3(u16 mtxidx,u32 pnidx); * * \return none */ -void GX_LoadTexMtxImm(Mtx mt,u32 texidx,u8 type); +void GX_LoadTexMtxImm(const Mtx mt,u32 texidx,u8 type); /*! * \fn void GX_LoadTexMtxIdx(u16 mtxidx,u32 texidx,u8 type) @@ -2966,6 +2968,19 @@ void GX_SetClipMode(u8 mode); */ void GX_SetScissor(u32 xOrigin,u32 yOrigin,u32 wd,u32 ht); +/*! + * \fn void GX_GetScissor(u32 *xOrigin,u32 *yOrigin,u32 *wd,u32 *ht) + * \brief This function returns the scissor box in the current screen coordinates. + * + * \param[out] xOrigin Returns the left-most coordinate of the scissor box in screen coordinates + * \param[out] yOrigin Returns the top-most coordinate of the scissor box in screen coordinates + * \param[out] wd Returns the width of the scissor box width in screen coordinates + * \param[out] ht Returns the height of the scissor box in screen coordinates + * + * \return none + */ +void GX_GetScissor(u32 *xOrigin,u32 *yOrigin,u32 *wd,u32 *ht); + /*! * \fn void GX_SetScissorBoxOffset(s32 xoffset,s32 yoffset) * \brief Repositions the scissorbox rectangle within the Embedded Frame Buffer (EFB) memory space. @@ -3287,7 +3302,7 @@ void GX_SetIndTexCoordScale(u8 indtexid,u8 scale_s,u8 scale_t); void GX_SetFog(u8 type,f32 startz,f32 endz,f32 nearz,f32 farz,GXColor col); /*! - * \fn void GX_SetFogRangeAdj(u8 enable,u16 center,GXFogAdjTbl *table) + * \fn void GX_SetFogRangeAdj(u8 enable,u16 center,const GXFogAdjTbl *table) * \brief Enables or disables horizontal fog-range adjustment. * * \details This adjustment is a factor that is multiplied by the eye-space Z used for fog computation; it is based upon the X position of the pixels being @@ -3305,7 +3320,7 @@ void GX_SetFog(u8 type,f32 startz,f32 endz,f32 nearz,f32 farz,GXColor col); * * \return none */ -void GX_SetFogRangeAdj(u8 enable,u16 center,GXFogAdjTbl *table); +void GX_SetFogRangeAdj(u8 enable,u16 center,const GXFogAdjTbl *table); /*! * \fn GX_SetFogColor(GXColor color) @@ -3318,7 +3333,7 @@ void GX_SetFogRangeAdj(u8 enable,u16 center,GXFogAdjTbl *table); void GX_SetFogColor(GXColor color); /*! - * \fn void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,f32 projmtx[4][4]) + * \fn void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,const f32 projmtx[4][4]) * \brief Generates the standard range adjustment table and puts the results into \a table. * * \details This table can be used by GX_SetFogRangeAdj() to adjust the eye-space Z used for fog based upon the X position of the pixels being rendered. @@ -3332,10 +3347,10 @@ void GX_SetFogColor(GXColor color); * \param[in] width width of the viewport * \param[in] projmtx projection matrix used to render into the viewport */ -void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,f32 projmtx[4][4]); +void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,const f32 projmtx[4][4]); /*! - * \fn void GX_SetIndTexMatrix(u8 indtexmtx,f32 offset_mtx[2][3],s8 scale_exp) + * \fn void GX_SetIndTexMatrix(u8 indtexmtx,const f32 offset_mtx[2][3],s8 scale_exp) * \brief Sets one of the three static indirect matrices and the associated scale factor. * * \details The indirect matrix and scale is used to process the results of an indirect lookup in order to produce offsets to use during a regular lookup. @@ -3352,7 +3367,7 @@ void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,f32 projmtx[4][4]); * * \return none */ -void GX_SetIndTexMatrix(u8 indtexmtx,f32 offset_mtx[2][3],s8 scale_exp); +void GX_SetIndTexMatrix(u8 indtexmtx,const f32 offset_mtx[2][3],s8 scale_exp); /*! * \fn void GX_SetTevIndBumpST(u8 tevstage,u8 indstage,u8 mtx_sel) @@ -3393,6 +3408,24 @@ void GX_SetTevIndBumpST(u8 tevstage,u8 indstage,u8 mtx_sel); */ void GX_SetTevIndBumpXYZ(u8 tevstage,u8 indstage,u8 mtx_sel); +/*! + * \fn void GX_SetTevIndWarp(u8 tevstage,u8 indstage,u8 signed_offset,u8 replace_mode,u8 mtx_sel) + * \brief Allows an indirect map to warp or distort the texture coordinates used with a regular TEV stage lookup. + * + * \details The indirect map should have 8-bit offsets, which may be signed or unsigned. "Signed" actually means "biased," and thus if \a signed_offset is GX_TRUE, + * 128 is subtracted from the values looked up from the indirect map. The indirect results can either modify or completely replace the regular texture coordinates. + * One may use the indirect matrix and scale to modify the indirect offsets. + * + * \param[in] tevstage \ref tevstage that is being affected + * \param[in] indstage \ref indtexstage results to use with this TEV stage + * \param[in] signed_offset whether the 8-bit offsets should be signed/biased (GX_TRUE) or unsigned (GX_FALSE) + * \param[in] replace_mode whether the offsets should replace (GX_TRUE) or be added to (GX_FALSE) the regular texture coordinates + * \param[in] mtx_sel which \ref indtexmtx to multiply the offsets with + * + * \return none + */ +void GX_SetTevIndWarp(u8 tevstage,u8 indstage,u8 signed_offset,u8 replace_mode,u8 mtx_sel); + /*! * \fn void GX_SetTevIndTile(u8 tevstage,u8 indtexid,u16 tilesize_x,u16 tilesize_y,u16 tilespacing_x,u16 tilespacing_y,u8 indtexfmt,u8 indtexmtx,u8 bias_sel,u8 alpha_sel) * \brief Used to implement tiled texturing using indirect textures. @@ -3418,20 +3451,6 @@ void GX_SetTevIndBumpXYZ(u8 tevstage,u8 indstage,u8 mtx_sel); */ void GX_SetTevIndTile(u8 tevstage,u8 indtexid,u16 tilesize_x,u16 tilesize_y,u16 tilespacing_x,u16 tilespacing_y,u8 indtexfmt,u8 indtexmtx,u8 bias_sel,u8 alpha_sel); -/*! - * \fn void GX_SetTevIndWarp(u8 tevstage, u8 indtexid, u8 bias_flag, u8 replace_tex, u8 mtxid) - * \brief Used to warp a normal texture lookup using an indirect texture map with 8-bit offsets. - * - * \param[in] tevstage \ref tevstage that is being affected - * \param[in] indtexid \ref indtexstage results to use with this TEV stage - * \param[in] bias_flag biases the indirect texture map offsets by -128 if the value is GX_TRUE - * \param[in] replace_tex GX_TRUE makes the indirect texture map offsets replace the input texture coordinates rather than offset them as with GX_FALSE - * \param[in] mtxid which \ref indtexmtx to use for warping the texture - * \return none - */ - -void GX_SetTevIndWarp(u8 tevstage, u8 indtexid, u8 bias_flag, u8 replace_tex, u8 mtxid); - /*! * \fn void GX_SetTevIndRepeat(u8 tevstage) * \brief Set a given TEV stage to use the same texture coordinates as were computed in the previous stage. @@ -3574,6 +3593,17 @@ void GX_SetFieldMask(u8 even_mask,u8 odd_mask); */ void GX_SetFieldMode(u8 field_mode,u8 half_aspect_ratio); +/*! + * \fn u16 GX_GetNumXfbLines(u16 efbHeight,f32 yscale) + * \brief Calculates the number of lines copied to the XFB, based on given EFB height and Y scale. + * + * \param[in] efbHeight Height of embedded framebuffer. Range from 2 to 528. Should be a multiple of 2. + * \param[in] yscale Vertical scale value. Range from 1.0 to 256.0. + * + * \return Number of lines that will be copied. + */ +u16 GX_GetNumXfbLines(u16 efbHeight,f32 yscale); + /*! * \fn f32 GX_GetYScaleFactor(u16 efbHeight,u16 xfbHeight) * \brief Calculates an appropriate Y scale factor value for GX_SetDispCopyYScale() based on the height of the EFB and @@ -3647,7 +3677,7 @@ void GX_SetCopyClamp(u8 clamp); void GX_SetDispCopyGamma(u8 gamma); /*! - * \fn void GX_SetCopyFilter(u8 aa,u8 sample_pattern[12][2],u8 vf,u8 vfilter[7]) + * \fn void GX_SetCopyFilter(u8 aa,const u8 sample_pattern[12][2],u8 vf,const u8 vfilter[7]) * \brief Sets the subpixel sample patterns and vertical filter coefficients used to filter subpixels into pixels. * * \details This function normally uses the \a aa, \a sample_pattern and \a vfilter provided by the render mode struct:

@@ -3665,7 +3695,7 @@ void GX_SetDispCopyGamma(u8 gamma); * * \return none */ -void GX_SetCopyFilter(u8 aa,u8 sample_pattern[12][2],u8 vf,u8 vfilter[7]); +void GX_SetCopyFilter(u8 aa,const u8 sample_pattern[12][2],u8 vf,const u8 vfilter[7]); /*! * \fn void GX_SetDispCopyFrame2Field(u8 mode) @@ -4000,55 +4030,55 @@ void GX_PeekZ(u16 x,u16 y,u32 *z); void GX_PokeZMode(u8 comp_enable,u8 func,u8 update_enable); /*! - * \fn u32 GX_GetTexObjFmt(const GXTexObj *obj) - * \brief Returns the texture format described by texture object \a obj. + * \fn void* GX_GetTexObjData(const GXTexObj *obj) + * \brief Used to get a pointer to texture data from the \ref GXTexObj structure. * - * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture format. + * \note The returned pointer is a physical address. * * \param[in] obj ptr to a texture object * - * \return texture format of the given texture object + * \return Physical pointer to texture data. */ -u32 GX_GetTexObjFmt(const GXTexObj *obj); +void* GX_GetTexObjData(const GXTexObj *obj); /*! - * \fn u32 GX_GetTexObjMipMap(const GXTexObj *obj) - * \brief Returns the texture mipmap enable described by texture object \a obj. + * \fn u16 GX_GetTexObjWidth(const GXTexObj *obj) + * \brief Returns the texture width described by texture object \a obj. * - * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture mipmap enable. + * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture width. * * \param[in] obj ptr to a texture object * - * \return mipmap enable flag + * \return texture width */ -u32 GX_GetTexObjMipMap(const GXTexObj *obj); +u16 GX_GetTexObjWidth(const GXTexObj *obj); /*! - * \fn void* GX_GetTexObjUserData(const GXTexObj *obj) - * \brief Used to get a pointer to user data from the \ref GXTexObj structure. + * \fn u16 GX_GetTexObjHeight(const GXTexObj *obj) + * \brief Returns the texture height described by texture object \a obj. * - * \details You can use this function to retrieve private data structures from the texture object. This pointer is set using GX_InitTexObjUserData(). + * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture height. * - * \param[in] obj ptr to object to read data from + * \param[in] obj ptr to a texture object * - * \return Pointer to user data. + * \return texture height */ -void* GX_GetTexObjUserData(const GXTexObj *obj); +u16 GX_GetTexObjHeight(const GXTexObj *obj); /*! - * \fn void* GX_GetTexObjData(const GXTexObj *obj) - * \brief Used to get a pointer to texture data from the \ref GXTexObj structure. + * \fn u8 GX_GetTexObjFmt(const GXTexObj *obj) + * \brief Returns the texture format described by texture object \a obj. * - * \note The returned pointer is a physical address. + * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture format. * * \param[in] obj ptr to a texture object * - * \return Physical pointer to texture data. + * \return texture format of the given texture object */ -void* GX_GetTexObjData(const GXTexObj *obj); +u8 GX_GetTexObjFmt(const GXTexObj *obj); /*! - * \fn u8 GX_GetTexObjWrapS(const GXTexObj* obj) + * \fn u8 GX_GetTexObjWrapS(const GXTexObj *obj) * \brief Returns the texture wrap s mode described by texture object \a obj. * * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture wrap s mode. @@ -4057,10 +4087,10 @@ void* GX_GetTexObjData(const GXTexObj *obj); * * \return wrap s mode */ -u8 GX_GetTexObjWrapS(const GXTexObj* obj); +u8 GX_GetTexObjWrapS(const GXTexObj *obj); /*! - * \fn u8 GX_GetTexObjWrapT(const GXTexObj* obj) + * \fn u8 GX_GetTexObjWrapT(const GXTexObj *obj) * \brief Returns the texture wrap t mode described by texture object \a obj. * * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture wrap t mode. @@ -4069,46 +4099,108 @@ u8 GX_GetTexObjWrapS(const GXTexObj* obj); * * \return wrap t mode */ -u8 GX_GetTexObjWrapT(const GXTexObj* obj); +u8 GX_GetTexObjWrapT(const GXTexObj *obj); /*! - * \fn u16 GX_GetTexObjHeight(const GXTexObj* obj) - * \brief Returns the texture height described by texture object \a obj. + * \fn u8 GX_GetTexObjMipMap(const GXTexObj *obj) + * \brief Returns the texture mipmap enable described by texture object \a obj. * - * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture height. + * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture mipmap enable. * * \param[in] obj ptr to a texture object * - * \return texture height + * \return mipmap enable flag */ -u16 GX_GetTexObjHeight(const GXTexObj* obj); +u8 GX_GetTexObjMipMap(const GXTexObj *obj); /*! - * \fn u16 GX_GetTexObjWidth(const GXTexObj* obj) - * \brief Returns the texture width described by texture object \a obj. + * \fn void* GX_GetTexObjUserData(const GXTexObj *obj) + * \brief Used to get a pointer to user data from the \ref GXTexObj structure. * - * \note Use GX_InitTexObj() or GX_InitTexObjCI() to initialize the texture width. + * \details You can use this function to retrieve private data structures from the texture object. This pointer is set using GX_InitTexObjUserData(). + * + * \param[in] obj ptr to object to read data from + * + * \return Pointer to user data. + */ +void* GX_GetTexObjUserData(const GXTexObj *obj); + +/*! + * \fn u32 GX_GetTexObjTlut(const GXTexObj *obj) + * \brief Returns the TLUT name associated with texture object \a obj. + * + * \note Use GX_InitTexObjCI() to initialize a texture object with the desired TLUT name. + * + * \note Use GX_InitTexObjTlut() to modify the TLUT associated with an existing texture object. * * \param[in] obj ptr to a texture object * - * \return texture width + * \return TLUT name associated with this texture object */ -u16 GX_GetTexObjWidth(const GXTexObj* obj); +u32 GX_GetTexObjTlut(const GXTexObj *obj); /*! - * \fn void GX_GetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, u8* format, u8* wrap_s, u8* wrap_t, u8* mipmap); + * \fn void GX_GetTexObjAll(const GXTexObj *obj,void **img_ptr,u16 *wd,u16 *ht,u8 *fmt,u8 *wrap_s,u8 *wrap_t,u8 *mipmap); * \brief Returns the parameters described by a texture object. Texture objects are used to describe all the parameters associated with a texture, including size, format, wrap modes, filter modes, etc. Texture objects are initialized using either GX_InitTexObj() or, for color index format textures, GX_InitTexObjCI(). * * \param[in] obj ptr to a texture object - * \param[out] image_ptr Returns a physical pointer to the image data for a texture. - * \param[out] width Returns the width of the texture or LOD 0 for mipmaps - * \param[out] height Returns the height of the texture or LOD 0 for mipmaps - * \param[out] format Returns the texel format + * \param[out] img_ptr Returns a physical pointer to the image data for a texture. + * \param[out] wd Returns the width of the texture or LOD 0 for mipmaps + * \param[out] ht Returns the height of the texture or LOD 0 for mipmaps + * \param[out] fmt Returns the texel format + * \param[out] wrap_s Returns the mode which describes how texture coordinates will be wrapped in the S direction + * \param[out] wrap_t Returns the mode which describes how texture coordinates will be wrapped in the T direction * \param[out] mipmap Returns the mipmap enable flag. * * \return none */ -void GX_GetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, u8* format, u8* wrap_s, u8* wrap_t, u8* mipmap); +void GX_GetTexObjAll(const GXTexObj *obj,void **img_ptr,u16 *wd,u16 *ht,u8 *fmt,u8 *wrap_s,u8 *wrap_t,u8 *mipmap); + +/*! + * \fn void GX_GetTexObjLODAll(const GXTexObj *obj,u8 *minfilt,u8 *magfilt,f32 *minlod,f32 *maxlod,f32 *lodbias,u8 *biasclamp,u8 *edgelod,u8 *maxaniso) + * \brief Returns the LOD-related parameters described by a texture object. Texture objects are used to describe all the parameters associated with a texture, including size, format, wrap modes, filter modes, etc. Texture objects are initialized using either GX_InitTexObj() or, for color index format textures, GXInitTexObjCI(). The LOD-related parameters are set using GX_InitTexObjLOD(). + * + * \param[in] obj ptr to a texture object + * \param[out] minfilt Returns the minification filter from the texture object + * \param[out] magfilt Returns the magnification filter + * \param[out] minlod Returns the minimum LOD bound + * \param[out] maxlod Returns the maximum LOD bound + * \param[out] lodbias Returns the LOD bias control + * \param[out] biasclamp Returns the LOD bias clamping parameter + * \param[out] edgelod Returns whether or not edge LOD has been enabled + * \param[out] maxaniso Returns the anisotropic filtering setting + * + * \return none + */ +void GX_GetTexObjLODAll(const GXTexObj *obj,u8 *minfilt,u8 *magfilt,f32 *minlod,f32 *maxlod,f32 *lodbias,u8 *biasclamp,u8 *edgelod,u8 *maxaniso); + +u8 GX_GetTexObjMinFilt(const GXTexObj *obj); +u8 GX_GetTexObjMagFilt(const GXTexObj *obj); +f32 GX_GetTexObjMinLOD(const GXTexObj *obj); +f32 GX_GetTexObjMaxLOD(const GXTexObj *obj); +f32 GX_GetTexObjLODBias(const GXTexObj *obj); +u8 GX_GetTexObjBiasClamp(const GXTexObj *obj); +u8 GX_GetTexObjEdgeLOD(const GXTexObj *obj); +u8 GX_GetTexObjMaxAniso(const GXTexObj *obj); + +void* GX_GetTlutObjData(const GXTlutObj *obj); +u8 GX_GetTlutObjFmt(const GXTlutObj *obj); +u16 GX_GetTlutObjNumEntries(const GXTlutObj *obj); + +/*! + * \fn void GX_GetTlutObjAll(const GXTlutObj *obj,void **lut,u8 *fmt,u16 *entries) + * \brief Returns all the parameters describing a Texture Look-Up Table (TLUT) object. + * + * \details The TLUT object describes the location of the TLUT in main memory, its format and the number of entries. + * + * \param[in] obj ptr to a TLUT object + * \param[out] lut Returns a physical pointer to the look-up table data + * \param[out] fmt Returns the format of the entries in the TLUT + * \param[out] entries Returns the number of entries in the TLUT + * + * \return none + */ +void GX_GetTlutObjAll(const GXTlutObj *obj,void **lut,u8 *fmt,u16 *entries); /*! * \fn u32 GX_GetTexBufferSize(u16 wd,u16 ht,u32 fmt,u8 mipmap,u8 maxlod) @@ -4143,7 +4235,7 @@ u32 GX_GetTexBufferSize(u16 wd,u16 ht,u32 fmt,u8 mipmap,u8 maxlod); void GX_InvalidateTexAll(void); /*! - * \fn void GX_InvalidateTexRegion(GXTexRegion *region) + * \fn void GX_InvalidateTexRegion(const GXTexRegion *region) * \brief Invalidates the texture cache in Texture Memory (TMEM) described by \a region. * * \details This function should be called when the CPU is used to modify a texture in main memory, or a new texture is loaded into main memory that @@ -4159,7 +4251,7 @@ void GX_InvalidateTexAll(void); * * \return none */ -void GX_InvalidateTexRegion(GXTexRegion *region); +void GX_InvalidateTexRegion(const GXTexRegion *region); /*! * \fn void GX_InitTexCacheRegion(GXTexRegion *region,u8 is32bmipmap,u32 tmem_even,u8 size_even,u32 tmem_odd,u8 size_odd) @@ -4409,7 +4501,7 @@ void GX_InitTexObjMaxAniso(GXTexObj *obj,u8 maxaniso); void GX_InitTexObjUserData(GXTexObj *obj,void *userdata); /*! - * \fn void GX_LoadTexObj(GXTexObj *obj,u8 mapid) + * \fn void GX_LoadTexObj(const GXTexObj *obj,u8 mapid) * \brief Loads the state describing a texture into one of eight hardware register sets. * * \details Before this happens, the texture object \a obj should be initialized using GX_InitTexObj() or GX_InitTexObjCI(). The \a id parameter refers to @@ -4425,10 +4517,10 @@ void GX_InitTexObjUserData(GXTexObj *obj,void *userdata); * * \return none */ -void GX_LoadTexObj(GXTexObj *obj,u8 mapid); +void GX_LoadTexObj(const GXTexObj *obj,u8 mapid); /*! - * \fn void GX_LoadTlut(GXTlutObj *obj,u32 tlut_name) + * \fn void GX_LoadTlut(const GXTlutObj *obj,u32 tlut_name) * \brief Copies a Texture Look-Up Table (TLUT) from main memory to Texture Memory (TMEM). * * \details The \a tlut_name parameter is the name of a pre-allocated area of TMEM. The callback function set by GX_SetTlutRegionCallback() converts @@ -4445,10 +4537,10 @@ void GX_LoadTexObj(GXTexObj *obj,u8 mapid); * * \return none */ -void GX_LoadTlut(GXTlutObj *obj,u32 tlut_name); +void GX_LoadTlut(const GXTlutObj *obj,u32 tlut_name); /*! - * \fn void GX_LoadTexObjPreloaded(GXTexObj *obj,GXTexRegion *region,u8 mapid) + * \fn void GX_LoadTexObjPreloaded(const GXTexObj *obj,const GXTexRegion *region,u8 mapid) * \brief Loads the state describing a preloaded texture into one of eight hardware register sets. * * \details Before this happens, the texture object \a obj should be initialized using GX_InitTexObj() or GX_InitTexObjCI(). The \a mapid parameter refers to @@ -4468,10 +4560,10 @@ void GX_LoadTlut(GXTlutObj *obj,u32 tlut_name); * * \return none */ -void GX_LoadTexObjPreloaded(GXTexObj *obj,GXTexRegion *region,u8 mapid); +void GX_LoadTexObjPreloaded(const GXTexObj *obj,const GXTexRegion *region,u8 mapid); /*! - * \fn void GX_PreloadEntireTexture(GXTexObj *obj,GXTexRegion *region) + * \fn void GX_PreloadEntireTexture(const GXTexObj *obj,const GXTexRegion *region) * \brief Loads a given texture from DRAM into the texture memory. * * \details Accesses to this texture will bypass the texture cache tag look-up and instead read the texels directly from texture memory. The @@ -4486,7 +4578,7 @@ void GX_LoadTexObjPreloaded(GXTexObj *obj,GXTexRegion *region,u8 mapid); * * \return none */ -void GX_PreloadEntireTexture(GXTexObj *obj,GXTexRegion *region); +void GX_PreloadEntireTexture(const GXTexObj *obj,const GXTexRegion *region); /*! * \fn void GX_InitTlutObj(GXTlutObj *obj,void *lut,u8 fmt,u16 entries) diff --git a/libogc/gx.c b/libogc/gx.c index 86c79ce25..9a343ec03 100644 --- a/libogc/gx.c +++ b/libogc/gx.c @@ -4,6 +4,7 @@ #include #include "asm.h" #include "processor.h" +#include "gcutil.h" #include "irq.h" #include "lwp.h" #include "system.h" @@ -128,8 +129,8 @@ static const u32 _gxtexregionaddrtable[48] = #endif -extern u8 __gxregs[]; -static struct __gx_regdef *__gx = (struct __gx_regdef*)__gxregs; +static u8 __gxregs[STRUCT_REGDEF_SIZE] ATTRIBUTE_ALIGN(32); +static struct __gx_regdef* const __gx = (struct __gx_regdef*)__gxregs; static u8 _gx_saved_data[STRUCT_REGDEF_SIZE] ATTRIBUTE_ALIGN(32); static s32 __gx_onreset(s32 final); @@ -314,8 +315,13 @@ static void __GX_SaveFifo(void) if(_gxcpufifoready) { val = _piReg[0x05]; +#if defined(HW_DOL) + cpufifo->wt_ptr = (u32)MEM_PHYSICAL_TO_K0((val&0x03FFFFE0)); + cpufifo->fifo_wrap = ((val&0x04000000)==0x04000000); +#else cpufifo->wt_ptr = (u32)MEM_PHYSICAL_TO_K0((val&0x1FFFFFE0)); cpufifo->fifo_wrap = ((val&0x20000000)==0x20000000); +#endif } if(_gxgpfifoready) { @@ -327,6 +333,7 @@ static void __GX_SaveFifo(void) cpufifo->rd_ptr = gpfifo->rd_ptr; cpufifo->rdwt_dst = gpfifo->rdwt_dst; gpfifo->wt_ptr = cpufifo->wt_ptr; + gpfifo->fifo_wrap = cpufifo->fifo_wrap; } else if(_gxcpufifoready) { rdwt_dst = (cpufifo->wt_ptr - cpufifo->rd_ptr); if(rdwt_dst<0) cpufifo->rdwt_dst = (cpufifo->rdwt_dst + cpufifo->size); @@ -547,7 +554,7 @@ static void __GX_SetTmemConfig(u8 nr) } #if defined(HW_RVL) -static GXTexRegion* __GXDefTexRegionCallback(GXTexObj *obj,u8 mapid) +static GXTexRegion* __GXDefTexRegionCallback(const GXTexObj *obj,u8 mapid) { u32 fmt,mipmap; GXTexRegion *ret = NULL; @@ -566,7 +573,7 @@ static GXTexRegion* __GXDefTexRegionCallback(GXTexObj *obj,u8 mapid) return ret; } #else -static GXTexRegion* __GXDefTexRegionCallback(GXTexObj *obj,u8 mapid) +static GXTexRegion* __GXDefTexRegionCallback(const GXTexObj *obj,u8 mapid) { u32 fmt; u32 idx; @@ -796,20 +803,20 @@ static void __GX_SendFlushPrim(void) cnt = tmp2/8; while(cnt) { wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - cnt--; + wgPipe->U32 = 0; + wgPipe->U32 = 0; + wgPipe->U32 = 0; + wgPipe->U32 = 0; + wgPipe->U32 = 0; + wgPipe->U32 = 0; + wgPipe->U32 = 0; + cnt--; } tmp2 &= 0x0007; if(tmp2) { while(tmp2) { wgPipe->U32 = 0; - tmp2--; + tmp2--; } } } @@ -1288,10 +1295,10 @@ void GX_GetFifoPtrs(const GXFifoObj *fifo,void **rd_ptr,void **wt_ptr) *wt_ptr = (void*)ptr->wt_ptr; } -void GX_SetCPUFifo(GXFifoObj *fifo) +void GX_SetCPUFifo(const GXFifoObj *fifo) { u32 level; - struct __gxfifo *ptr = (struct __gxfifo*)fifo; + const struct __gxfifo *ptr = (const struct __gxfifo*)fifo; struct __gxfifo *cpufifo = (struct __gxfifo*)&_cpufifo; _CPU_ISR_Disable(level); @@ -1371,10 +1378,10 @@ void GX_GetCPUFifo(GXFifoObj *fifo) ptr->gpfifo_ready = cpufifo->gpfifo_ready; } -void GX_SetGPFifo(GXFifoObj *fifo) +void GX_SetGPFifo(const GXFifoObj *fifo) { u32 level; - struct __gxfifo *ptr = (struct __gxfifo*)fifo; + const struct __gxfifo *ptr = (const struct __gxfifo*)fifo; struct __gxfifo *gpfifo = (struct __gxfifo*)&_gpfifo; _CPU_ISR_Disable(level); @@ -1524,7 +1531,6 @@ lwp_t GX_SetCurrentGXThread(void) volatile void* GX_RedirectWriteGatherPipe(void *ptr) { u32 level; - struct __gxfifo *cpufifo = (struct __gxfifo*)&_cpufifo; _CPU_ISR_Disable(level); GX_Flush(); @@ -1535,41 +1541,35 @@ volatile void* GX_RedirectWriteGatherPipe(void *ptr) __GX_FifoLink(GX_FALSE); __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE); } - cpufifo->wt_ptr = (u32)MEM_PHYSICAL_TO_K0(_piReg[5]&~0x04000000); + __GX_SaveFifo(); _piReg[3] = 0; _piReg[4] = 0x04000000; - _piReg[5] = (((u32)ptr&0x3FFFFFE0)&~0x04000000); - _sync(); + _piReg[5] = ((u32)ptr&0x1FFFFFE0); + ppcsync(); _CPU_ISR_Restore(level); - return (volatile void*)0x0C008000; + return (volatile void*)0xCC008000; } void GX_RestoreWriteGatherPipe(void) { - u32 level; + u32 i,level; struct __gxfifo *cpufifo = (struct __gxfifo*)&_cpufifo; _CPU_ISR_Disable(level); - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - wgPipe->U32 = 0; - + for(i=0;i<31;i++) { + wgPipe->U8 = 0; + } ppcsync(); while(!IsWriteGatherBufferEmpty()); mtwpar(0x0C008000); _piReg[3] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo->buf_start); _piReg[4] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo->buf_end); - _piReg[5] = (((u32)cpufifo->wt_ptr&0x3FFFFFE0)&~0x04000000); + _piReg[5] = (cpufifo->wt_ptr&0x1FFFFFE0); if(_cpgplinked) { __GX_WriteFifoIntReset(GX_TRUE,GX_TRUE); __GX_WriteFifoIntEnable(GX_ENABLE,GX_DISABLE); @@ -1791,7 +1791,7 @@ void GX_SetViewport(f32 xOrig,f32 yOrig,f32 wd,f32 ht,f32 nearZ,f32 farZ) GX_SetViewportJitter(xOrig,yOrig,wd,ht,nearZ,farZ,1); } -void GX_LoadProjectionMtx(Mtx44 mt,u8 type) +void GX_LoadProjectionMtx(const Mtx44 mt,u8 type) { f32 tmp[7]; @@ -1860,6 +1860,7 @@ static void __GetImageTileCount(u32 fmt,u16 wd,u16 ht,u32 *xtiles,u32 *ytiles,u3 case GX_TF_RGB565: case GX_TF_RGB5A3: case GX_TF_RGBA8: + case GX_CTF_YUVA8: xshift = 2; yshift = 2; break; @@ -1881,7 +1882,7 @@ static void __GetImageTileCount(u32 fmt,u16 wd,u16 ht,u32 *xtiles,u32 *ytiles,u3 *ytiles = tile; *zplanes = 1; - if(fmt==GX_TF_RGBA8 || fmt==GX_TF_Z24X8) *zplanes = 2; + if(fmt==GX_TF_RGBA8 || fmt==GX_TF_Z24X8 || fmt==GX_CTF_YUVA8) *zplanes = 2; } void GX_SetCopyClear(GXColor color,u32 zvalue) @@ -1909,7 +1910,7 @@ void GX_SetDispCopyGamma(u8 gamma) __gx->dispCopyCntrl = (__gx->dispCopyCntrl&~0x180)|(_SHIFTL(gamma,7,2)); } -void GX_SetCopyFilter(u8 aa,u8 sample_pattern[12][2],u8 vf,u8 vfilter[7]) +void GX_SetCopyFilter(u8 aa,const u8 sample_pattern[12][2],u8 vf,const u8 vfilter[7]) { u32 reg01=0,reg02=0,reg03=0,reg04=0,reg53=0,reg54=0; @@ -1985,7 +1986,7 @@ u32 GX_SetDispCopyYScale(f32 yscale) GX_LOAD_BP_REG(0x4e000000|yScale); __gx->dispCopyCntrl = (__gx->dispCopyCntrl&~0x400)|(_SHIFTL(((256-yScale)>0),10,1)); - ht = _SHIFTR(__gx->dispCopyWH,12,10)+1; + ht = _SHIFTR(__gx->dispCopyWH,10,10)+1; return __GX_GetNumXfbLines(ht,yScale); } @@ -2173,7 +2174,7 @@ u32 GX_EndDispList(void) return GX_GetFifoCount(&_gx_dl_fifoobj); } -void GX_CallDispList(void *list,u32 nbytes) +void GX_CallDispList(const void *list,u32 nbytes) { if(__gx->dirtyState) __GX_SetDirtyState(); @@ -2276,7 +2277,7 @@ void GX_SetChanMatColor(s32 channel,GXColor color) __gx->dirtyState |= (0x0400<dirtyState |= 0x0008; } -void GX_SetVtxDescv(GXVtxDesc *attr_list) +void GX_SetVtxDescv(const GXVtxDesc *attr_list) { u32 i; @@ -2622,7 +2623,7 @@ void GX_SetVtxAttrFmt(u8 vtxfmt,u32 vtxattr,u32 comptype,u32 compsize,u32 frac) __gx->dirtyState |= 0x0010; } -void GX_SetVtxAttrFmtv(u8 vtxfmt,GXVtxAttrFmt *attr_list) +void GX_SetVtxAttrFmtv(u8 vtxfmt,const GXVtxAttrFmt *attr_list) { u32 i; @@ -2783,7 +2784,7 @@ void GX_SetZTexture(u8 op,u8 fmt,u32 bias) GX_LOAD_BP_REG(0xF5000000|(val&0x00FFFFFF)); } -static inline void WriteMtxPS4x3(register Mtx mt,register void *wgpipe) +static inline void WriteMtxPS4x3(register const Mtx mt,register void *wgpipe) { register f32 tmp0,tmp1,tmp2,tmp3,tmp4,tmp5; __asm__ __volatile__ ( @@ -2805,7 +2806,7 @@ static inline void WriteMtxPS4x3(register Mtx mt,register void *wgpipe) ); } -static inline void WriteMtxPS3x3from4x3(register Mtx mt,register void *wgpipe) +static inline void WriteMtxPS3x3from4x3(register const Mtx mt,register void *wgpipe) { register f32 tmp0,tmp1,tmp2,tmp3,tmp4,tmp5; __asm__ __volatile__ @@ -2827,7 +2828,7 @@ static inline void WriteMtxPS3x3from4x3(register Mtx mt,register void *wgpipe) ); } -static inline void WriteMtxPS3x3(register Mtx33 mt,register void *wgpipe) +static inline void WriteMtxPS3x3(register const Mtx33 mt,register void *wgpipe) { register f32 tmp0,tmp1,tmp2,tmp3,tmp4; __asm__ __volatile__ @@ -2847,7 +2848,7 @@ static inline void WriteMtxPS3x3(register Mtx33 mt,register void *wgpipe) ); } -static inline void WriteMtxPS4x2(register Mtx mt,register void *wgpipe) +static inline void WriteMtxPS4x2(register const Mtx mt,register void *wgpipe) { register f32 tmp0,tmp1,tmp2,tmp3; __asm__ __volatile__ @@ -2865,7 +2866,7 @@ static inline void WriteMtxPS4x2(register Mtx mt,register void *wgpipe) ); } -void GX_LoadPosMtxImm(Mtx mt,u32 pnidx) +void GX_LoadPosMtxImm(const Mtx mt,u32 pnidx) { GX_LOAD_XF_REGS((0x0000|(_SHIFTL(pnidx,2,8))),12); WriteMtxPS4x3(mt,(void*)wgPipe); @@ -2877,13 +2878,13 @@ void GX_LoadPosMtxIdx(u16 mtxidx,u32 pnidx) wgPipe->U32 = ((_SHIFTL(mtxidx,16,16))|0xb000|(_SHIFTL(pnidx,2,8))); } -void GX_LoadNrmMtxImm(Mtx mt,u32 pnidx) +void GX_LoadNrmMtxImm(const Mtx mt,u32 pnidx) { GX_LOAD_XF_REGS((0x0400|(pnidx*3)),9); WriteMtxPS3x3from4x3(mt,(void*)wgPipe); } -void GX_LoadNrmMtxImm3x3(Mtx33 mt,u32 pnidx) +void GX_LoadNrmMtxImm3x3(const Mtx33 mt,u32 pnidx) { GX_LOAD_XF_REGS((0x0400|(pnidx*3)),9); WriteMtxPS3x3(mt,(void*)wgPipe); @@ -2895,7 +2896,7 @@ void GX_LoadNrmMtxIdx3x3(u16 mtxidx,u32 pnidx) wgPipe->U32 = ((_SHIFTL(mtxidx,16,16))|0x8000|(0x0400|(pnidx*3))); } -void GX_LoadTexMtxImm(Mtx mt,u32 texidx,u8 type) +void GX_LoadTexMtxImm(const Mtx mt,u32 texidx,u8 type) { u32 addr = 0; u32 rows = (type==GX_MTX2x4)?2:3; @@ -2993,99 +2994,181 @@ static void __GetTexTileShift(u32 fmt,u32 *xshift,u32 *yshift) } #endif -u32 GX_GetTexObjFmt(const GXTexObj *obj) +void GX_GetTexObjAll(const GXTexObj *obj,void **img_ptr,u16 *wd,u16 *ht,u8 *fmt,u8 *wrap_s,u8 *wrap_t,u8 *mipmap) { - return ((const struct __gx_texobj*)obj)->tex_fmt; + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + *img_ptr = (void*)_SHIFTL(ptr->tex_maddr,5,24); + *wd = (ptr->tex_size&0x3ff)+1; + *ht = _SHIFTR(ptr->tex_size,10,10)+1; + *fmt = ptr->tex_fmt; + *wrap_s = ptr->tex_filt&0x03; + *wrap_t = _SHIFTR(ptr->tex_filt,2,2); + *mipmap = ptr->tex_flag&0x01; } -u32 GX_GetTexObjMipMap(const GXTexObj *obj) +void* GX_GetTexObjData(const GXTexObj *obj) { - return (((const struct __gx_texobj*)obj)->tex_flag&0x01); + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return (void*)_SHIFTL(ptr->tex_maddr,5,24); } -void* GX_GetTexObjData(const GXTexObj *obj) + +u16 GX_GetTexObjWidth(const GXTexObj *obj) { - return (void*)(_SHIFTL(((const struct __gx_texobj*)obj)->tex_maddr & 0x00ffffff,5,24)); + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return (ptr->tex_size&0x3ff)+1; +} + +u16 GX_GetTexObjHeight(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return _SHIFTR(ptr->tex_size,10,10)+1; +} + +u8 GX_GetTexObjFmt(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return ptr->tex_fmt; } u8 GX_GetTexObjWrapS(const GXTexObj *obj) { - return ((const struct __gx_texobj*)obj)->tex_filt & 0x03; + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return ptr->tex_filt&0x03; } u8 GX_GetTexObjWrapT(const GXTexObj *obj) { - return _SHIFTR(((const struct __gx_texobj*)obj)->tex_filt & 0x0c, 2, 2); + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return _SHIFTR(ptr->tex_filt,2,2); } -u16 GX_GetTexObjHeight(const GXTexObj *obj) +u8 GX_GetTexObjMipMap(const GXTexObj *obj) { - return _SHIFTR(((const struct __gx_texobj*)obj)->tex_size & 0xffc00, 10, 10) + 1; + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return ptr->tex_flag&0x01; } -u16 GX_GetTexObjWidth(const GXTexObj *obj) +void GX_GetTexObjLODAll(const GXTexObj *obj,u8 *minfilt,u8 *magfilt,f32 *minlod,f32 *maxlod,f32 *lodbias,u8 *biasclamp,u8 *edgelod,u8 *maxaniso) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + static const u8 HW2GXFiltConv[] = {0x00,0x02,0x04,0x00,0x01,0x03,0x05,0x00}; + + *minfilt = HW2GXFiltConv[_SHIFTR(ptr->tex_filt,5,3)]; + *magfilt = _SHIFTR(ptr->tex_filt,4,1); + *minlod = (ptr->tex_lod&0xff)/16.0f; + *maxlod = _SHIFTR(ptr->tex_lod,8,8)/16.0f; + *lodbias = (s8)_SHIFTR(ptr->tex_filt,9,8)/32.0f; + *biasclamp = _SHIFTR(ptr->tex_filt,21,1); + *edgelod = !_SHIFTR(ptr->tex_filt,8,1); + *maxaniso = _SHIFTR(ptr->tex_filt,19,2); +} + +u8 GX_GetTexObjMinFilt(const GXTexObj *obj) { - return (((const struct __gx_texobj*)obj)->tex_size & 0x3ff) + 1; + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + static const u8 HW2GXFiltConv[] = {0x00,0x02,0x04,0x00,0x01,0x03,0x05,0x00}; + + return HW2GXFiltConv[_SHIFTR(ptr->tex_filt,5,3)]; +} + +u8 GX_GetTexObjMagFilt(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return _SHIFTR(ptr->tex_filt,4,1); +} + +f32 GX_GetTexObjMinLOD(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return (ptr->tex_lod&0xff)/16.0f; } +f32 GX_GetTexObjMaxLOD(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return _SHIFTR(ptr->tex_lod,8,8)/16.0f; +} -void GX_GetTexObjAll(const GXTexObj *obj, void** image_ptr, u16* width, u16* height, - u8* format, u8* wrap_s, u8* wrap_t, u8* mipmap) +f32 GX_GetTexObjLODBias(const GXTexObj *obj) { const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; - *image_ptr = (void*)(_SHIFTL(ptr->tex_maddr & 0x00ffffff,5,24)); - *width = (ptr->tex_size & 0x3ff) + 1; - *height = _SHIFTR(ptr->tex_size & 0xffc00, 10, 10) + 1; - *format = ptr->tex_fmt; - *wrap_s = ptr->tex_filt & 0x03; - *wrap_t = _SHIFTR(ptr->tex_filt & 0x0c, 2, 2); - *mipmap = ptr->tex_flag & 0x01; + return (s8)_SHIFTR(ptr->tex_filt,9,8)/32.0f; } + +u8 GX_GetTexObjBiasClamp(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return _SHIFTR(ptr->tex_filt,21,1); +} + +u8 GX_GetTexObjEdgeLOD(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return !_SHIFTR(ptr->tex_filt,8,1); +} + +u8 GX_GetTexObjMaxAniso(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return _SHIFTR(ptr->tex_filt,19,2); +} + +u32 GX_GetTexObjTlut(const GXTexObj *obj) +{ + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + return ptr->tex_tlut; +} + u32 GX_GetTexBufferSize(u16 wd,u16 ht,u32 fmt,u8 mipmap,u8 maxlod) { u32 xshift,yshift,xtiles,ytiles,bitsize,size; switch(fmt) { case GX_TF_I4: + case GX_TF_CI4: case GX_TF_CMPR: case GX_CTF_R4: - case GX_CTF_RA4: case GX_CTF_Z4: xshift = 3; yshift = 3; break; - case GX_TF_Z8: case GX_TF_I8: case GX_TF_IA4: + case GX_TF_CI8: + case GX_TF_Z8: + case GX_CTF_RA4: case GX_CTF_A8: case GX_CTF_R8: case GX_CTF_G8: case GX_CTF_B8: - case GX_CTF_RG8: - case GX_CTF_GB8: case GX_CTF_Z8M: case GX_CTF_Z8L: xshift = 3; yshift = 2; break; case GX_TF_IA8: - case GX_TF_Z16: - case GX_TF_Z24X8: case GX_TF_RGB565: case GX_TF_RGB5A3: case GX_TF_RGBA8: - case GX_CTF_Z16L: + case GX_TF_CI14: + case GX_TF_Z16: + case GX_TF_Z24X8: case GX_CTF_RA8: + case GX_CTF_YUVA8: + case GX_CTF_RG8: + case GX_CTF_GB8: + case GX_CTF_Z16L: xshift = 2; yshift = 2; break; default: - xshift = 2; - yshift = 2; + xshift = 0; + yshift = 0; break; } bitsize = 32; - if(fmt==GX_TF_RGBA8 || fmt==GX_TF_Z24X8) bitsize = 64; + if(fmt==GX_TF_RGBA8 || fmt==GX_TF_Z24X8 || fmt==GX_CTF_YUVA8) bitsize = 64; size = 0; if(mipmap) { @@ -3243,12 +3326,12 @@ void GX_InitTexObj(GXTexObj *obj,void *img_ptr,u16 wd,u16 ht,u8 fmt,u8 wrap_s,u8 case GX_TF_IA8: case GX_TF_RGB565: case GX_TF_RGB5A3: - case GX_TF_RGBA8: + case GX_TF_CI14: xshift = 2; yshift = 2; ptr->tex_tile_type = 2; break; - case GX_TF_CI14: + case GX_TF_RGBA8: xshift = 2; yshift = 2; ptr->tex_tile_type = 3; @@ -3285,7 +3368,6 @@ void GX_InitTexObjLOD(GXTexObj *obj,u8 minfilt,u8 magfilt,f32 minlod,f32 maxlod, { struct __gx_texobj *ptr = (struct __gx_texobj*)obj; static const u8 GX2HWFiltConv[] = {0x00,0x04,0x01,0x05,0x02,0x06,0x00,0x00}; - //static const u8 HW2GXFiltConv[] = {0x00,0x02,0x04,0x00,0x01,0x03,0x05,0x00}; if(lodbias<-4.0f) lodbias = -4.0f; else if(lodbias==4.0f) lodbias = 3.99f; @@ -3407,7 +3489,33 @@ void GX_InitTlutObj(GXTlutObj *obj,void *lut,u8 fmt,u16 entries) ptr->tlut_nentries = entries; } -void GX_LoadTexObj(GXTexObj *obj,u8 mapid) +void GX_GetTlutObjAll(const GXTlutObj *obj,void **lut,u8 *fmt,u16 *entries) +{ + const struct __gx_tlutobj *ptr = (const struct __gx_tlutobj*)obj; + *lut = (void*)_SHIFTL(ptr->tlut_maddr,5,24); + *fmt = _SHIFTR(ptr->tlut_fmt,10,2); + *entries = ptr->tlut_nentries; +} + +void* GX_GetTlutObjData(const GXTlutObj *obj) +{ + const struct __gx_tlutobj *ptr = (const struct __gx_tlutobj*)obj; + return (void*)_SHIFTL(ptr->tlut_maddr,5,24); +} + +u8 GX_GetTlutObjFmt(const GXTlutObj *obj) +{ + const struct __gx_tlutobj *ptr = (const struct __gx_tlutobj*)obj; + return _SHIFTR(ptr->tlut_fmt,10,2); +} + +u16 GX_GetTlutObjNumEntries(const GXTlutObj *obj) +{ + const struct __gx_tlutobj *ptr = (const struct __gx_tlutobj*)obj; + return ptr->tlut_nentries; +} + +void GX_LoadTexObj(const GXTexObj *obj,u8 mapid) { GXTexRegion *region = NULL; @@ -3417,7 +3525,7 @@ void GX_LoadTexObj(GXTexObj *obj,u8 mapid) GX_LoadTexObjPreloaded(obj,region,mapid); } -void GX_LoadTexObjPreloaded(GXTexObj *obj,GXTexRegion *region,u8 mapid) +void GX_LoadTexObjPreloaded(const GXTexObj *obj,const GXTexRegion *region,u8 mapid) { u8 type; struct __gx_tlutregion *tlut = NULL; @@ -3455,7 +3563,7 @@ void GX_LoadTexObjPreloaded(GXTexObj *obj,GXTexRegion *region,u8 mapid) __gx->dirtyState |= 0x0001; } -void GX_PreloadEntireTexture(GXTexObj *obj,GXTexRegion *region) +void GX_PreloadEntireTexture(const GXTexObj *obj,const GXTexRegion *region) { u32 i,fmt; s32 wd,ht; @@ -3464,8 +3572,8 @@ void GX_PreloadEntireTexture(GXTexObj *obj,GXTexRegion *region) u32 regB = 0; u32 regC = 0; u32 regD = 0; - struct __gx_texobj *ptr = (struct __gx_texobj*)obj; - struct __gx_texregion *reg = (struct __gx_texregion*)region; + const struct __gx_texobj *ptr = (const struct __gx_texobj*)obj; + const struct __gx_texregion *reg = (const struct __gx_texregion*)region; regA = (regA&~0xff000000)|(_SHIFTL(0x60,24,8)); regA = (regA&~0x00ffffff)|(ptr->tex_maddr&~0xff000000); @@ -3532,20 +3640,21 @@ void GX_PreloadEntireTexture(GXTexObj *obj,GXTexRegion *region) h = wd>>(i+1); switch(ptr->tex_fmt) { case GX_TF_I4: - case GX_TF_IA4: case GX_TF_CI4: case GX_TF_CMPR: xshift = 3; yshift = 3; break; case GX_TF_I8: + case GX_TF_IA4: case GX_TF_CI8: xshift = 3; yshift = 2; break; case GX_TF_IA8: - case GX_TF_RGB5A3: case GX_TF_RGB565: + case GX_TF_RGB5A3: + case GX_TF_RGBA8: case GX_TF_CI14: xshift = 2; yshift = 2; @@ -3587,12 +3696,12 @@ void GX_InvalidateTexAll(void) __GX_FlushTextureState(); } -void GX_InvalidateTexRegion(GXTexRegion *region) +void GX_InvalidateTexRegion(const GXTexRegion *region) { u8 ismipmap; s32 cw_e,ch_e,cw_o,ch_o; u32 size,tmp,regvalA = 0,regvalB = 0; - struct __gx_texregion *ptr = (struct __gx_texregion*)region; + const struct __gx_texregion *ptr = (const struct __gx_texregion*)region; cw_e = (_SHIFTR(ptr->tmem_even,15,3))-1; ch_e = (_SHIFTR(ptr->tmem_even,18,3))-1; @@ -3622,10 +3731,10 @@ void GX_InvalidateTexRegion(GXTexRegion *region) __GX_FlushTextureState(); } -void GX_LoadTlut(GXTlutObj *obj,u32 tlut_name) +void GX_LoadTlut(const GXTlutObj *obj,u32 tlut_name) { struct __gx_tlutregion *region = NULL; - struct __gx_tlutobj *ptr = (struct __gx_tlutobj*)obj; + const struct __gx_tlutobj *ptr = (const struct __gx_tlutobj*)obj; if(tlut_regionCB) region = (struct __gx_tlutregion*)tlut_regionCB(tlut_name); @@ -3928,7 +4037,7 @@ void GX_EnableTexOffsets(u8 coord,u8 line_enable,u8 point_enable) void GX_SetClipMode(u8 mode) { - GX_LOAD_XF_REG(0x1005,(mode&1)); + GX_LOAD_XF_REG(0x1005,(mode&0x7)); } void GX_SetScissor(u32 xOrigin,u32 yOrigin,u32 wd,u32 ht) @@ -3948,6 +4057,19 @@ void GX_SetScissor(u32 xOrigin,u32 yOrigin,u32 wd,u32 ht) GX_LOAD_BP_REG(__gx->sciBRcorner); } +void GX_GetScissor(u32 *xOrigin,u32 *yOrigin,u32 *wd,u32 *ht) +{ + u32 xo = _SHIFTR(__gx->sciTLcorner,12,11); + u32 yo = _SHIFTL(__gx->sciTLcorner,0,11); + u32 nwd = _SHIFTR(__gx->sciBRcorner,12,11); + u32 nht = _SHIFTL(__gx->sciBRcorner,0,11); + + *xOrigin = xo-0x156; + *yOrigin = yo-0x156; + *wd = (nwd+1)-xo; + *ht = (nht+1)-yo; +} + void GX_SetScissorBoxOffset(s32 xoffset,s32 yoffset) { s32 xoff = _SHIFTR((xoffset+0x156),1,24); @@ -4081,7 +4203,7 @@ void GX_SetNumIndStages(u8 nstages) __gx->dirtyState |= 0x0006; } -void GX_SetIndTexMatrix(u8 indtexmtx,f32 offset_mtx[2][3],s8 scale_exp) +void GX_SetIndTexMatrix(u8 indtexmtx,const f32 offset_mtx[2][3],s8 scale_exp) { u32 ma,mb; u32 val,s,idx; @@ -4176,16 +4298,9 @@ void GX_SetIndTexCoordScale(u8 indtexid,u8 scale_s,u8 scale_t) void GX_SetTevIndWarp(u8 tevstage, u8 indtexid, u8 bias_flag, u8 replace_tex, u8 mtxid) { - u8 wrap = GX_ITW_OFF; - u8 bias = GX_ITB_NONE; - if(replace_tex) - { - wrap = GX_ITW_0; - } - if(bias_flag) - { - bias = GX_ITB_STU; - } + u8 bias = (bias_flag)?GX_ITB_STU:GX_ITB_NONE; + u8 wrap = (replace_tex)?GX_ITW_0:GX_ITW_OFF; + GX_SetTevIndirect(tevstage, indtexid, GX_ITF_8, bias, mtxid, wrap, wrap, GX_FALSE, GX_FALSE, GX_ITBA_OFF); } @@ -4297,7 +4412,7 @@ void GX_SetFog(u8 type,f32 startz,f32 endz,f32 nearz,f32 farz,GXColor col) GX_LOAD_BP_REG(val); } -void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,f32 projmtx[4][4]) +void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,const f32 projmtx[4][4]) { u32 i,val7; f32 val0,val1,val2,val4,val5,val6; @@ -4324,7 +4439,7 @@ void GX_InitFogAdjTable(GXFogAdjTbl *table,u16 width,f32 projmtx[4][4]) } } -void GX_SetFogRangeAdj(u8 enable,u16 center,GXFogAdjTbl *table) +void GX_SetFogRangeAdj(u8 enable,u16 center,const GXFogAdjTbl *table) { u32 val; @@ -5126,23 +5241,31 @@ void GX_ReadGPMetric(u32 *cnt0,u32 *cnt1) // cnt1 fails.... } -void GX_AdjustForOverscan(GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver) +void GX_AdjustForOverscan(const GXRModeObj *rmin,GXRModeObj *rmout,u16 hor,u16 ver) { if(rmin!=rmout) memcpy(rmout,rmin,sizeof(GXRModeObj)); rmout->fbWidth = rmin->fbWidth-(hor<<1); rmout->efbHeight = rmin->efbHeight-((rmin->efbHeight*(ver<<1))/rmin->xfbHeight); - if(rmin->xfbMode==VI_XFBMODE_SF && !(rmin->viTVMode&VI_PROGRESSIVE)) rmout->xfbHeight = rmin->xfbHeight-ver; + if(rmin->xfbMode==VI_XFBMODE_SF && (rmin->viTVMode&0x3)==VI_INTERLACE) rmout->xfbHeight = rmin->xfbHeight-ver; else rmout->xfbHeight = rmin->xfbHeight-(ver<<1); rmout->viWidth = rmin->viWidth-(hor<<1); - if(rmin->viTVMode&VI_PROGRESSIVE) rmout->viHeight = rmin->viHeight-(ver<<2); + if((rmin->viTVMode&0x3)==VI_NON_INTERLACE) rmout->viHeight = rmin->viHeight-(ver<<2); else rmout->viHeight = rmin->viHeight-(ver<<1); rmout->viXOrigin += hor; rmout->viYOrigin += ver; } +u16 GX_GetNumXfbLines(u16 efbHeight,f32 yscale) +{ + u32 yScale; + + yScale = ((u32)(256.0f/yscale))&0x1ff; + return __GX_GetNumXfbLines(efbHeight,yScale); +} + f32 GX_GetYScaleFactor(u16 efbHeight,u16 xfbHeight) { u32 yScale,xfblines,cnt; diff --git a/libogc/gx_regdef.h b/libogc/gx_regdef.h index 5978d7780..82a0dd985 100644 --- a/libogc/gx_regdef.h +++ b/libogc/gx_regdef.h @@ -67,7 +67,7 @@ struct __gx_regdef u8 gxFifoUnlinked; u8 texCopyZTex; u8 _pad; -}; +} __attribute__((packed)); struct __gxfifo { vu32 buf_start; @@ -82,7 +82,7 @@ struct __gxfifo { vu8 cpufifo_ready; vu8 gpfifo_ready; u8 _pad[93]; -}; +} __attribute__((packed)); struct __gx_litobj {