Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2725 lines (2363 sloc)
81.6 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. | |
| * | |
| * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and | |
| * Jerremy Koot (jkoot@snes9x.com) | |
| * | |
| * Super FX C emulator code | |
| * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and | |
| * Gary Henderson. | |
| * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. | |
| * | |
| * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. | |
| * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. | |
| * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). | |
| * | |
| * DOS port code contains the works of other authors. See headers in | |
| * individual files. | |
| * | |
| * Snes9x homepage: http://www.snes9x.com | |
| * | |
| * Permission to use, copy, modify and distribute Snes9x in both binary and | |
| * source form, for non-commercial purposes, is hereby granted without fee, | |
| * providing that this license information and copyright notice appear with | |
| * all copies and any derived work. | |
| * | |
| * This software is provided 'as-is', without any express or implied | |
| * warranty. In no event shall the authors be held liable for any damages | |
| * arising from the use of this software. | |
| * | |
| * Snes9x is freeware for PERSONAL USE only. Commercial users should | |
| * seek permission of the copyright holders first. Commercial use includes | |
| * charging money for Snes9x or software derived from Snes9x. | |
| * | |
| * The copyright holders request that bug fixes and improvements to the code | |
| * should be forwarded to them so everyone can benefit from the modifications | |
| * in future versions. | |
| * | |
| * Super NES and Super Nintendo Entertainment System are trademarks of | |
| * Nintendo Co., Limited and its subsidiary companies. | |
| */ | |
| #include "snes9x.h" | |
| #include "memmap.h" | |
| #include "ppu.h" | |
| #include "cpuexec.h" | |
| #include "display.h" | |
| #include "gfx.h" | |
| #include "apu.h" | |
| #include "cheats.h" | |
| #include "tile_psp.h" | |
| #define M7 19 | |
| #define M8 19 | |
| void ComputeClipWindows (); | |
| extern int os9x_BG0,os9x_BG1,os9x_BG2,os9x_BG3,os9x_OBJ,os9x_easy,os9x_fastsprite; | |
| extern int os9x_render; | |
| extern int add_sub_mode; | |
| extern int last_palette; | |
| extern int current_bitshift; | |
| extern int render_timestamp; | |
| //extern u16 __attribute__((aligned(16))) clut256[256*3]; | |
| extern u16* clut256; | |
| extern u16* clut; | |
| extern u32 fixedcol16; | |
| extern u32 fixedcol; | |
| extern int rendering_beware_fix16; | |
| // for OBJ & BGS | |
| extern struct Vertex *vertices[3]; | |
| extern struct Vertex *vertices_ptr[3]; | |
| extern struct Vertex *vertices_end[3]; | |
| // for Blending | |
| extern struct Vertex *_vertices; | |
| extern struct Vertex *_vertices_ptr; | |
| extern struct VertexCol *_verticesCol; | |
| extern struct VertexCol *_verticesCol_ptr; | |
| extern struct VertexCol *_verticesCol_end; | |
| //s32 realZ1,realZ2; | |
| extern void S9xSetupOBJ(void); | |
| extern uint8 BitShifts[8][4]; | |
| extern uint8 TileShifts[8][4]; | |
| extern uint8 PaletteShifts[8][4]; | |
| extern uint8 PaletteMasks[8][4]; | |
| extern uint8 Depths[8][4]; | |
| extern uint8 BGSizes [2]; | |
| extern NormalTileRendererPSP DrawTilePtr; | |
| extern ClippedTileRendererPSP DrawClippedTilePtr; | |
| extern NormalTileRendererPSP DrawHiResTilePtr; | |
| extern ClippedTileRendererPSP DrawHiResClippedTilePtr; | |
| extern LargePixelRendererPSP DrawLargePixelPtr; | |
| extern struct SBG BG; | |
| extern struct SLineData LineData[240]; | |
| extern struct SLineMatrixData LineMatrixData [240]; | |
| extern uint8 Mode7Depths [2]; | |
| ClipDataFix* pCurrentClipFix; | |
| #define ON_MAIN(N) \ | |
| (GPUPack.GFX.r212c & (1 << (N)) && \ | |
| !(PPUPack.PPU.BG_Forced & (1 << (N)))) | |
| #define SUB_OR_ADD(N) \ | |
| (GPUPack.GFX.r2131 & (1 << (N))) | |
| #define ON_SUB(N) \ | |
| ((GPUPack.GFX.r2130 & 0x30) != 0x30 && \ | |
| (GPUPack.GFX.r2130 & 2) && \ | |
| (GPUPack.GFX.r212d & (1 << N)) && \ | |
| !(PPUPack.PPU.BG_Forced & (1 << (N)))) | |
| #define ANYTHING_ON_SUB \ | |
| ((GPUPack.GFX.r2130 & 0x30) != 0x30 && \ | |
| (GPUPack.GFX.r2130 & 2) && \ | |
| (GPUPack.GFX.r212d & 0x1f)) | |
| #define ADD_OR_SUB_ON_ANYTHING \ | |
| (GPUPack.GFX.r2131 & 0x3f) | |
| #define BLACK BUILD_PIXEL(0,0,0) | |
| void pspDrawTile16 (uint32 Tile, s32 x,s32 y, uint32 StartLine, | |
| uint32 LineCount,short realZ2); | |
| void pspDrawClippedTile16 (uint32 Tile, s32 x,s32 y, | |
| uint32 StartPixel, uint32 Width, | |
| uint32 StartLine, uint32 LineCount,short realZ2); | |
| void pspDrawHiResTile16 (uint32 Tile, s32 x,s32 y, uint32 StartLine, | |
| uint32 LineCount,short realZ2); | |
| void pspDrawHiResClippedTile16 (uint32 Tile, s32 x,s32 y, | |
| uint32 StartPixel, uint32 Width, | |
| uint32 StartLine, uint32 LineCount,short realZ2); | |
| void pspDrawLargePixel16 (uint32 Tile, s32 x,s32 y, | |
| uint32 StartPixel, uint32 Pixels, | |
| uint32 StartLine, uint32 LineCount,short realZ2); | |
| inline void pspSelectAddSubMode() { | |
| if (GPUPack.GFX.r2131 & 0x80) { | |
| if (GPUPack.GFX.r2131 & 0x40) { | |
| if (GPUPack.GFX.r2130 & 2) { | |
| add_sub_mode=1; | |
| //debug_log("tile sub 1_2"); | |
| } else { | |
| add_sub_mode=2; | |
| // Fixed colour substraction | |
| //debug_log("Fixed colour substraction"); | |
| } | |
| } else { | |
| add_sub_mode=3; | |
| //debug_log("tile sub"); | |
| } | |
| } else { | |
| if (GPUPack.GFX.r2131 & 0x40) { | |
| if (GPUPack.GFX.r2130 & 2) { | |
| add_sub_mode=4; | |
| //debug_log("tile add1_2"); | |
| } else { | |
| add_sub_mode=5; | |
| // Fixed colour addition | |
| //debug_log("Fixed colour addition"); | |
| } | |
| } else { | |
| add_sub_mode=6; | |
| //debug_log("tile add"); | |
| } | |
| } | |
| } | |
| #define pspDrawTile16_order pspDrawTile16 | |
| #define pspDrawClippedTile16_order pspDrawClippedTile16 | |
| void initRenderingFix(){ | |
| sceGuStart(GU_DIRECT,list); | |
| //rendering options | |
| sceGuEnable(GU_DEPTH_TEST); | |
| sceGuDepthFunc(GU_GREATER); | |
| sceGuEnable(GU_ALPHA_TEST); | |
| sceGuAlphaFunc(GU_EQUAL,0,0x1); | |
| sceGuEnable(GU_TEXTURE_2D); | |
| sceGuTexFilter(GU_NEAREST,GU_NEAREST); | |
| sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); | |
| sceGuClutMode(GU_PSM_5551,0,255,0); | |
| last_palette=0; //start in non directcolour mode, coz first things to be rendered are s | |
| clut = (u16*)NO_CPU_CACHE(&clut256[0]); | |
| memcpy(clut,&IPPU.ScreenColors[0],256*2); | |
| if (rendering_beware_fix16) | |
| for (int i=0;i<256;i++) { | |
| if (clut[i]==fixedcol16) clut[i]^=1<<10; //swap blue 1st bit | |
| } | |
| clut[0]|=0x8000; | |
| sceGuClutLoad(256/16,clut); | |
| } | |
| void pspDrawOBJS (bool8 OnMain, uint8 D, uint8 drawmode); | |
| void endRenderingFix(){ | |
| sceGuFinish(); | |
| sceGuSync(0,0); | |
| } | |
| void waitRenderingFix() { | |
| /*sceGuFinish(); | |
| sceGuSync(0,0); | |
| sceGuStart(GU_DIRECT,list); | |
| */ | |
| } | |
| void pspDrawFASTOBJSFix (bool8 OnMain, uint8 D, uint8 drawmode) | |
| { | |
| //uint32 O; | |
| s32 Xs,Ys; | |
| uint32 BaseTile, Tile; | |
| GPUPack.BG.BitShift = 4; | |
| GPUPack.BG.TileShift = 5; | |
| GPUPack.BG.TileAddress = PPUPack.PPU.OBJNameBase; | |
| GPUPack.BG.StartPalette = 128; | |
| GPUPack.BG.PaletteShift = 4; | |
| GPUPack.BG.PaletteMask = 7; | |
| current_bitshift=TILE_4BIT; | |
| GPUPack.BG.Buffer = tile_texture[TILE_4BIT];//IPPU.TileCache8 [TILE_4BIT]; | |
| GPUPack.BG.Buffered = IPPU.TileCached [TILE_4BIT]; | |
| GPUPack.BG.NameSelect = PPUPack.PPU.OBJNameSelect; | |
| GPUPack.BG.DirectColourMode = false; | |
| /********************************************************/ | |
| /****************PSP STUFF*******************************/ | |
| /********************************************************/ | |
| int num_vert=0;//8192;//0; | |
| int I=0; | |
| for (int S = GPUPack.GFX.OBJList [I++]; S >= 0; S = GPUPack.GFX.OBJList [I++]) { | |
| int VPos = GPUPack.GFX.VPositions [S]; | |
| int Size = GPUPack.GFX.Sizes[S]; | |
| if (VPos + Size <= (int) GPUPack.GFX.StartY || VPos > (int) GPUPack.GFX.EndY) continue; | |
| num_vert+=(Size/8)*(Size/8); | |
| } | |
| if (!(vertices[current_bitshift]=(struct Vertex*)sceGuGetMemory(num_vert*2* sizeof(struct Vertex)))){ | |
| debug_log("not enough vertices!"); | |
| return; | |
| } | |
| vertices_ptr[current_bitshift]=vertices[current_bitshift]; | |
| vertices_end[current_bitshift]=vertices_ptr[current_bitshift]+num_vert*2; | |
| /********************************************************/ | |
| /********************************************************/ | |
| GPUPack.GFX.Z1 = (D + 2); | |
| //realZ1=(int)(GPUPack.GFX.Z1); | |
| I=0; | |
| for (int S = GPUPack.GFX.OBJList [I++]; S >= 0; S = GPUPack.GFX.OBJList [I++]) { | |
| int VPos = GPUPack.GFX.VPositions [S]; | |
| int Size = GPUPack.GFX.Sizes[S]; | |
| int TileInc = 1; | |
| int Offset; | |
| if (VPos + Size <= (int) GPUPack.GFX.StartY || VPos > (int) GPUPack.GFX.EndY) | |
| continue; | |
| //drawing sub/added sprites => palette has to be 4-7 | |
| if (OnMain){ | |
| if ((drawmode==1) && (PPUPack.PPU.OBJ [S].Palette < 4) ) continue; | |
| //drawing not sub/added sprites => palette has to be 4-7 or no add/sub in effect for OBJ | |
| if ((drawmode==2) && (PPUPack.PPU.OBJ [S].Palette >= 4) && SUB_OR_ADD(4)) continue; | |
| } | |
| BaseTile = PPUPack.PPU.OBJ[S].Name | (PPUPack.PPU.OBJ[S].Palette << 10); | |
| if (PPUPack.PPU.OBJ[S].HFlip) { | |
| BaseTile += ((Size >> 3) - 1) | H_FLIP; | |
| TileInc = -1; | |
| } | |
| if (PPUPack.PPU.OBJ[S].VFlip) BaseTile |= V_FLIP; | |
| int clipcount = GPUPack.GFX.pCurrentClip->Count [4]; | |
| if (!clipcount) clipcount = 1; | |
| GPUPack.GFX.Z2 = ((PPUPack.PPU.OBJ[S].Priority + 1) * 4 + D); | |
| short realZ2=(short)(GPUPack.GFX.Z2);//+I-1; | |
| for (int clip = 0; clip < clipcount; clip++){ | |
| int Left; | |
| int Right; | |
| if (!GPUPack.GFX.pCurrentClip->Count [4]){ | |
| Left = 0; | |
| Right = 256; | |
| }else{ | |
| Left = GPUPack.GFX.pCurrentClip->Left [clip][4]; | |
| Right = GPUPack.GFX.pCurrentClip->Right [clip][4]; | |
| } | |
| if (Right <= Left || PPUPack.PPU.OBJ[S].HPos + Size <= Left || PPUPack.PPU.OBJ[S].HPos >= Right) continue; | |
| for (int Y = 0; Y < Size; Y += 8) { | |
| if (VPos + Y + 7 >= (int) GPUPack.GFX.StartY && VPos + Y <= (int) GPUPack.GFX.EndY){ | |
| int StartLine; | |
| int TileLine; | |
| int LineCount; | |
| int Last; | |
| if ((StartLine = VPos + Y) < (int) GPUPack.GFX.StartY) { | |
| StartLine = GPUPack.GFX.StartY - StartLine; | |
| LineCount = 8 - StartLine; | |
| }else{ | |
| StartLine = 0; | |
| LineCount = 8; | |
| } | |
| if ((Last = VPos + Y + 7 - GPUPack.GFX.EndY) > 0) | |
| if ((LineCount -= Last) <= 0) break; | |
| TileLine = StartLine;// << 3; | |
| Ys = (VPos + Y + StartLine); | |
| if (!PPUPack.PPU.OBJ[S].VFlip) Tile = BaseTile + (Y << 1); | |
| else Tile = BaseTile + ((Size - Y - 8) << 1); | |
| int Middle = Size >> 3; | |
| if (PPUPack.PPU.OBJ[S].HPos < Left) { | |
| Tile += ((Left - PPUPack.PPU.OBJ[S].HPos) >> 3) * TileInc; | |
| Middle -= (Left - PPUPack.PPU.OBJ[S].HPos) >> 3; | |
| Xs = Left ; | |
| if ((Offset = (Left - PPUPack.PPU.OBJ[S].HPos) & 7)) { | |
| Xs -= Offset ; | |
| int W = 8 - Offset; | |
| int Width = Right - Left; | |
| if (W > Width) W = Width; | |
| pspDrawClippedTile16 (Tile, Xs,Ys, Offset, W,TileLine, LineCount,realZ2); | |
| if (W >= Width) continue; | |
| Tile += TileInc; | |
| Middle--; | |
| Xs += 8 ; | |
| } | |
| } else Xs = PPUPack.PPU.OBJ[S].HPos ; | |
| if (PPUPack.PPU.OBJ[S].HPos + Size >= Right) { | |
| Middle -= ((PPUPack.PPU.OBJ[S].HPos + Size + 7) - Right) >> 3; | |
| Offset = (Right - (PPUPack.PPU.OBJ[S].HPos + Size)) & 7; | |
| }else Offset = 0; | |
| for (int X = 0; X < Middle; X++, Xs += 8 , Tile += TileInc){ | |
| pspDrawTile16 (Tile, Xs,Ys, TileLine, LineCount,realZ2); | |
| } | |
| if (Offset){ | |
| pspDrawClippedTile16 (Tile, Xs,Ys, 0, Offset,TileLine, LineCount,realZ2); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (vertices_ptr[current_bitshift]-vertices[current_bitshift]) { | |
| sceGuTexImage(0,512,512,512,tile_texture[current_bitshift]); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,(vertices_ptr[current_bitshift]-vertices[current_bitshift]),0,vertices[current_bitshift]); | |
| } | |
| } | |
| void pspDrawOBJSFix (bool8 OnMain, uint8 D, uint8 drawmode) { | |
| //uint32 O; | |
| s32 Xs,Ys; | |
| int speZ; | |
| uint32 BaseTile, Tile; | |
| GPUPack.BG.BitShift = 4; | |
| current_bitshift=TILE_4BIT; | |
| GPUPack.BG.TileShift = 5; | |
| GPUPack.BG.TileAddress = PPUPack.PPU.OBJNameBase; | |
| GPUPack.BG.StartPalette = 128; | |
| GPUPack.BG.PaletteShift = 4; | |
| GPUPack.BG.PaletteMask = 7; | |
| GPUPack.BG.Buffer = tile_texture[TILE_4BIT];//IPPU.TileCache8 [TILE_4BIT]; | |
| GPUPack.BG.Buffered = IPPU.TileCached [TILE_4BIT]; | |
| GPUPack.BG.NameSelect = PPUPack.PPU.OBJNameSelect; | |
| GPUPack.BG.DirectColourMode = false; | |
| /********************************************************/ | |
| /****************PSP STUFF*******************************/ | |
| /********************************************************/ | |
| int num_vert=0;//8192;//0; | |
| int I=0; | |
| for (int S = GPUPack.GFX.OBJList [I++]; S >= 0; S = GPUPack.GFX.OBJList [I++]) { | |
| int VPos = GPUPack.GFX.VPositions [S]; | |
| int Size = GPUPack.GFX.Sizes[S]; | |
| if (VPos + Size <= (int) GPUPack.GFX.StartY || VPos > (int) GPUPack.GFX.EndY) | |
| continue; | |
| //drawing sub/added sprites => palette has to be 4-7 | |
| num_vert+=(Size/8)*(Size/8); | |
| } | |
| num_vert += 33*pCurrentClipFix->GroupCount [4]; | |
| if (!(vertices[current_bitshift]=(struct Vertex*)sceGuGetMemory(num_vert*2* sizeof(struct Vertex)))){ | |
| debug_log("not enough vertices!"); | |
| return; | |
| } | |
| vertices_ptr[current_bitshift]=vertices[current_bitshift]; | |
| vertices_end[current_bitshift]=vertices_ptr[current_bitshift]+num_vert*2; | |
| /********************************************************/ | |
| /********************************************************/ | |
| GPUPack.GFX.Z1 = (D + 2); | |
| //realZ1=(int)(GPUPack.GFX.Z1); | |
| I=0; | |
| for (int S = GPUPack.GFX.OBJList [I++]; S >= 0; S = GPUPack.GFX.OBJList [I++]) { | |
| int VPos = GPUPack.GFX.VPositions [S]; | |
| int Size = GPUPack.GFX.Sizes[S]; | |
| int TileInc = 1; | |
| int Offset; | |
| for (uint32 g = 0; g < pCurrentClipFix->GroupCount [4]; g++) | |
| { | |
| if (VPos + Size <= (int) pCurrentClipFix->Start[4][g] || VPos > (int) pCurrentClipFix->End[4][g]) | |
| continue; | |
| //drawing sub/added sprites => palette has to be 4-7 | |
| speZ=0; | |
| if (OnMain) | |
| { | |
| if ((drawmode==1) && (PPUPack.PPU.OBJ [S].Palette < 4) ) speZ=1; | |
| //drawing not sub/added sprites => palette has to be 4-7 or no add/sub in effect for OBJ | |
| else if ((drawmode==2) && (PPUPack.PPU.OBJ [S].Palette >= 4) && SUB_OR_ADD(4)) speZ=1; | |
| } | |
| BaseTile = PPUPack.PPU.OBJ[S].Name | (PPUPack.PPU.OBJ[S].Palette << 10); | |
| if (PPUPack.PPU.OBJ[S].HFlip) | |
| { | |
| BaseTile += ((Size >> 3) - 1) | H_FLIP; | |
| TileInc = -1; | |
| } | |
| if (PPUPack.PPU.OBJ[S].VFlip) BaseTile |= V_FLIP; | |
| int clipcount = pCurrentClipFix->Count [4][g]; | |
| if (!clipcount) clipcount = 1; | |
| GPUPack.GFX.Z2 = ((PPUPack.PPU.OBJ[S].Priority + 1) * 4 + D); | |
| short realZ2; | |
| if (!speZ) realZ2=(short)(GPUPack.GFX.Z2);//+I-1; | |
| else realZ2=0; | |
| for (int clip = 0; clip < clipcount; clip++) | |
| { | |
| int Left; | |
| int Right; | |
| if(pCurrentClipFix->Count [4][g]==0) | |
| { | |
| Left = 0; | |
| Right = 256; | |
| }else | |
| { | |
| Left = pCurrentClipFix->Left [clip][4][g]; | |
| Right = pCurrentClipFix->Right [clip][4][g]; | |
| } | |
| if (Right <= Left || PPUPack.PPU.OBJ[S].HPos + Size <= Left || PPUPack.PPU.OBJ[S].HPos >= Right) continue; | |
| for (int Y = 0; Y < Size; Y += 8) | |
| { | |
| if (VPos + Y + 7 >= (int) pCurrentClipFix->Start[4][g] && VPos + Y <= (int) pCurrentClipFix->End[4][g]) | |
| { | |
| int StartLine; | |
| int TileLine; | |
| int LineCount; | |
| int Last; | |
| if ((StartLine = VPos + Y) < (int) pCurrentClipFix->Start[4][g]) | |
| { | |
| StartLine = pCurrentClipFix->Start[4][g] - StartLine; | |
| LineCount = 8 - StartLine; | |
| } else | |
| { | |
| StartLine = 0; | |
| LineCount = 8; | |
| } | |
| if ((Last = VPos + Y + 7 - pCurrentClipFix->End[4][g]) > 0) | |
| if ((LineCount -= Last) <= 0) break; | |
| TileLine = StartLine;// << 3; | |
| Ys = (VPos + Y + StartLine); | |
| if (!PPUPack.PPU.OBJ[S].VFlip) Tile = BaseTile + (Y << 1); | |
| else Tile = BaseTile + ((Size - Y - 8) << 1); | |
| int Middle = Size >> 3; | |
| if (PPUPack.PPU.OBJ[S].HPos < Left) | |
| { | |
| Tile += ((Left - PPUPack.PPU.OBJ[S].HPos) >> 3) * TileInc; | |
| Middle -= (Left - PPUPack.PPU.OBJ[S].HPos) >> 3; | |
| Xs = Left ; | |
| if ((Offset = (Left - PPUPack.PPU.OBJ[S].HPos) & 7)) | |
| { | |
| Xs -= Offset ; | |
| int W = 8 - Offset; | |
| int Width = Right - Left; | |
| if (W > Width) W = Width; | |
| pspDrawClippedTile16 (Tile, Xs,Ys, Offset, W,TileLine, LineCount,realZ2); | |
| if (W >= Width) continue; | |
| Tile += TileInc; | |
| Middle--; | |
| Xs += 8 ; | |
| } | |
| } | |
| else Xs = PPUPack.PPU.OBJ[S].HPos ; | |
| if (PPUPack.PPU.OBJ[S].HPos + Size >= Right) | |
| { | |
| Middle -= ((PPUPack.PPU.OBJ[S].HPos + Size + 7) - Right) >> 3; | |
| Offset = (Right - (PPUPack.PPU.OBJ[S].HPos + Size)) & 7; | |
| } | |
| else Offset = 0; | |
| for (int X = 0; X < Middle; X++, Xs += 8 , Tile += TileInc) | |
| { | |
| pspDrawTile16 (Tile, Xs,Ys, TileLine, LineCount,realZ2); | |
| } | |
| if (Offset) | |
| { | |
| pspDrawClippedTile16 (Tile, Xs,Ys, 0, Offset,TileLine, LineCount,realZ2); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /*{ | |
| int i=0; | |
| char str[32]; | |
| tile_cache_t *p=tile_cache_first_free[TILE_4BIT]; | |
| while (p) {i++;p=p->next;} | |
| sprintf(str,"cached %d free %d/%d",tile_cached[TILE_4BIT],i,i+tile_cached[TILE_4BIT]); | |
| info(32,12,str); | |
| }*/ | |
| if (vertices_ptr[current_bitshift]-vertices[current_bitshift]) | |
| { | |
| sceGuEnable(GU_STENCIL_TEST);//stencil | |
| sceGuClearStencil(0); | |
| sceGuClear(GU_STENCIL_BUFFER_BIT); | |
| sceGuStencilOp( GU_KEEP, GU_INCR, GU_INCR); | |
| sceGuStencilFunc(GU_EQUAL,0,0xFFFFFFFF); | |
| sceGuTexImage(0,512,512,512,tile_texture[current_bitshift]); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,(vertices_ptr[current_bitshift]-vertices[current_bitshift]),0,vertices[current_bitshift]); | |
| } | |
| sceGuDisable(GU_STENCIL_TEST);//stencil | |
| } | |
| void pspDrawBackgroundMosaicFix (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) { | |
| uint32 Tile; | |
| uint16 *SC0; | |
| uint16 *SC1; | |
| uint16 *SC2; | |
| uint16 *SC3; | |
| uint8 depths [2] = {Z1, Z2}; | |
| if (last_palette!=GPUPack.BG.DirectColourMode){ | |
| //DirectColourMode has changed, so we have to reload palette | |
| waitRenderingFix(); | |
| last_palette=GPUPack.BG.DirectColourMode; | |
| clut = (u16*)NO_CPU_CACHE(&clut256[0]); | |
| memcpy(clut,GPUPack.GFX.ScreenColors,256*2); | |
| if (rendering_beware_fix16) | |
| for (int i=0;i<256;i++) { | |
| if (clut[i]==fixedcol16) clut[i]^=1<<10; //swap blue 1st bit | |
| } | |
| clut[0]|=0x8000; | |
| sceGuClutLoad(256/16,clut); | |
| } | |
| //bg is 32x30 tile but needs more in case of clipping or scroll changing every line | |
| int num_vert=((GPUPack.GFX.EndY-GPUPack.GFX.StartY+1)+2+pCurrentClipFix->GroupCount [bg])*(256/8+6); | |
| if (!(_verticesCol=(struct VertexCol*)sceGuGetMemory(num_vert*2* sizeof(struct VertexCol)))){ | |
| debug_log("not enough vertices!"); | |
| return; | |
| } | |
| _verticesCol_ptr=_verticesCol; | |
| _verticesCol_end=_verticesCol_ptr+num_vert*2; | |
| /***********************************************************/ | |
| /***********************************************************/ | |
| if (BGMode == 0) GPUPack.BG.StartPalette = bg << 5; | |
| else GPUPack.BG.StartPalette = 0; | |
| SC0 = (uint16 *) &VRAM[PPUPack.PPU.BG[bg].SCBase << 1]; | |
| if (PPUPack.PPU.BG[bg].SCSize & 1) SC1 = SC0 + 1024; | |
| else SC1 = SC0; | |
| if((SC1-(unsigned short*)VRAM)>0x10000) SC1-=0x10000; | |
| if (PPUPack.PPU.BG[bg].SCSize & 2) SC2 = SC1 + 1024; | |
| else SC2 = SC0; | |
| if((SC2-(unsigned short*)VRAM)>0x10000) SC2-=0x10000; | |
| if (PPUPack.PPU.BG[bg].SCSize & 1) SC3 = SC2 + 1024; | |
| else SC3 = SC2; | |
| if((SC3-(unsigned short*)VRAM)>0x10000) SC3-=0x10000; | |
| uint32 Lines; | |
| uint32 OffsetMask; | |
| uint32 OffsetShift; | |
| if (GPUPack.BG.TileSize == 16) { | |
| OffsetMask = 0x3ff; | |
| OffsetShift = 4; | |
| } else { | |
| OffsetMask = 0x1ff; | |
| OffsetShift = 3; | |
| } | |
| uint32 Y = GPUPack.GFX.StartY; | |
| for (uint32 g = 0; g < pCurrentClipFix->GroupCount [bg]; g++) | |
| { | |
| Y=pCurrentClipFix->Start [bg][g]; | |
| for (; Y <= GPUPack.GFX.EndY && Y <= pCurrentClipFix->End [bg][g]; Y += Lines) | |
| { | |
| uint32 VOffset = LineData [Y].BG[bg].VOffset; | |
| uint32 HOffset = LineData [Y].BG[bg].HOffset; | |
| uint32 MosaicOffset = Y % PPUPack.PPU.Mosaic; | |
| for (Lines = 1; Lines < PPUPack.PPU.Mosaic - MosaicOffset; Lines++) | |
| if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || (HOffset != LineData [Y + Lines].BG[bg].HOffset)) break; | |
| uint32 MosaicLine = VOffset + Y - MosaicOffset; | |
| if (Y + Lines > GPUPack.GFX.EndY) Lines = GPUPack.GFX.EndY + 1 - Y; | |
| uint32 VirtAlign = (MosaicLine & 7);// << 3; | |
| uint16 *b1; | |
| uint16 *b2; | |
| uint32 ScreenLine = MosaicLine >> OffsetShift; | |
| uint32 Rem16 = MosaicLine & 15; | |
| if (ScreenLine & 0x20) b1 = SC2, b2 = SC3; | |
| else b1 = SC0, b2 = SC1; | |
| b1 += (ScreenLine & 0x1f) << 5; | |
| b2 += (ScreenLine & 0x1f) << 5; | |
| uint16 *t; | |
| uint32 Left = 0; | |
| uint32 Right = 256; | |
| uint32 ClipCount = pCurrentClipFix->Count [bg][g]; | |
| uint32 HPos = HOffset; | |
| uint32 PixWidth = PPUPack.PPU.Mosaic; | |
| if (!ClipCount) ClipCount = 1; | |
| for (uint32 clip = 0; clip < ClipCount; clip++) | |
| { | |
| if (pCurrentClipFix->Count [bg][g]) | |
| { | |
| Left = pCurrentClipFix->Left [clip][bg][g]; | |
| Right = pCurrentClipFix->Right [clip][bg][g]; | |
| uint32 r = Left % PPUPack.PPU.Mosaic; | |
| HPos = HOffset + Left; | |
| PixWidth = PPUPack.PPU.Mosaic - r; | |
| } | |
| //uint32 s = Y * GPUPack.GFX.PPL + Left * GPUPack.GFX.PixSize; | |
| s32 Xt=Left; | |
| s32 Yt=Y; | |
| for (uint32 x = Left; x < Right; x += PixWidth, /*s += PixWidth * GPUPack.GFX.PixSize*/Xt+=PixWidth,HPos += PixWidth, PixWidth = PPUPack.PPU.Mosaic) | |
| { | |
| uint32 Quot = (HPos & OffsetMask) >> 3; | |
| if (x + PixWidth >= Right) PixWidth = Right - x; | |
| if (GPUPack.BG.TileSize == 8) { | |
| if (Quot > 31) t = b2 + (Quot & 0x1f); | |
| else t = b1 + Quot; | |
| } else { | |
| if (Quot > 63) t = b2 + ((Quot >> 1) & 0x1f); | |
| else t = b1 + (Quot >> 1); | |
| } | |
| Tile = READ_2BYTES (t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| // pspDraw tile... | |
| if (GPUPack.BG.TileSize != 8) | |
| { | |
| if (Tile & H_FLIP) | |
| { | |
| // Horizontal flip, but what about vertical flip ? | |
| if (Tile & V_FLIP) | |
| { | |
| // Both horzontal & vertical flip | |
| if (Rem16 < 8) { | |
| pspDrawLargePixel16 (Tile + 17 - (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } else { | |
| pspDrawLargePixel16 (Tile + 1 - (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } | |
| } else { | |
| // Horizontal flip only | |
| if (Rem16 > 7) { | |
| pspDrawLargePixel16 (Tile + 17 - (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } else { | |
| pspDrawLargePixel16 (Tile + 1 - (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| } else | |
| { | |
| // No horizontal flip, but is there a vertical flip ? | |
| if (Tile & V_FLIP) | |
| { | |
| // Vertical flip only | |
| if (Rem16 < 8) { | |
| pspDrawLargePixel16 (Tile + 16 + (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } else { | |
| pspDrawLargePixel16 (Tile + (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // Normal unflipped | |
| if (Rem16 > 7) { | |
| pspDrawLargePixel16 (Tile + 16 + (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } else { | |
| pspDrawLargePixel16 (Tile + (Quot & 1), Xt,Yt,HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| } | |
| } else pspDrawLargePixel16 (Tile, Xt,Yt, HPos & 7, PixWidth,VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| } | |
| } | |
| //render | |
| if (_verticesCol_ptr-_verticesCol) { | |
| sceGuTexImage(0,512,512,512,tile_texture[current_bitshift]); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT/*GU_COLOR_5551*/|GU_VERTEX_16BIT|GU_TRANSFORM_2D,(_verticesCol_ptr-_verticesCol),0,_verticesCol); | |
| } | |
| } | |
| void pspDrawBackgroundMode5Fix (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) { | |
| GPUPack.GFX.Pitch = GPUPack.GFX.RealPitch; | |
| GPUPack.GFX.PPL = GPUPack.GFX.PPLx2 >> 1; | |
| uint8 depths [2] = {Z1, Z2}; | |
| uint32 Tile; | |
| uint16 *SC0; | |
| uint16 *SC1; | |
| uint16 *SC2; | |
| uint16 *SC3; | |
| uint32 Width; | |
| if (last_palette!=GPUPack.BG.DirectColourMode){ | |
| //DirectColourMode has changed, so we have to reload palette | |
| waitRenderingFix(); | |
| last_palette=GPUPack.BG.DirectColourMode; | |
| clut = (u16*)NO_CPU_CACHE(&clut256[0]); | |
| memcpy(clut,GPUPack.GFX.ScreenColors,256*2); | |
| if (rendering_beware_fix16) | |
| for (int i=0;i<256;i++) { | |
| if (clut[i]==fixedcol16) clut[i]^=1<<10; //swap blue 1st bit | |
| } | |
| clut[0]|=0x8000; | |
| sceGuClutLoad(256/16,clut); | |
| } | |
| //bg is 32x30 tile but needs more in case of clipping or scroll changing every line | |
| int num_vert=((GPUPack.GFX.EndY-GPUPack.GFX.StartY+1)+2+pCurrentClipFix->GroupCount [bg])*(256/8+6); | |
| if (!(vertices[current_bitshift]=(struct Vertex*)sceGuGetMemory(num_vert*2* sizeof(struct Vertex)))){ | |
| debug_log("not enough vertices!"); | |
| return; | |
| } | |
| vertices_ptr[current_bitshift]=vertices[current_bitshift]; | |
| vertices_end[current_bitshift]=vertices_ptr[current_bitshift]+num_vert*2; | |
| /********************************************************/ | |
| /********************************************************/ | |
| GPUPack.BG.StartPalette = 0; | |
| SC0 = (uint16 *) &VRAM[PPUPack.PPU.BG[bg].SCBase << 1]; | |
| if ((PPUPack.PPU.BG[bg].SCSize & 1)) SC1 = SC0 + 1024; | |
| else SC1 = SC0; | |
| if((SC1-(unsigned short*)VRAM)>0x10000) SC1=(uint16*)&VRAM[(((uint8*)SC1)-VRAM)%0x10000]; | |
| if ((PPUPack.PPU.BG[bg].SCSize & 2)) SC2 = SC1 + 1024; | |
| else SC2 = SC0; | |
| if((SC2-(unsigned short*)VRAM)>0x10000) SC2=(uint16*)&VRAM[(((uint8*)SC2)-VRAM)%0x10000]; | |
| if ((PPUPack.PPU.BG[bg].SCSize & 1)) SC3 = SC2 + 1024; | |
| else SC3 = SC2; | |
| if((SC3-(unsigned short*)VRAM)>0x10000) SC3=(uint16*)&VRAM[(((uint8*)SC3)-VRAM)%0x10000]; | |
| int Lines; | |
| uint32 endy = GPUPack.GFX.EndY; | |
| uint32 Y = GPUPack.GFX.StartY; | |
| for (uint32 g = 0; g < pCurrentClipFix->GroupCount [bg]; g++) | |
| { | |
| Y=pCurrentClipFix->Start [bg][g]; | |
| for (; Y <= GPUPack.GFX.EndY && Y <= pCurrentClipFix->End [bg][g]; Y += Lines) | |
| { | |
| int y = Y; | |
| uint32 VOffset = LineData [y].BG[bg].VOffset; | |
| uint32 HOffset = LineData [y].BG[bg].HOffset; | |
| int VirtAlign = (Y + VOffset) & 7; | |
| for (Lines = 1; Lines < 8 - VirtAlign; Lines++) | |
| if ((VOffset != LineData [y + Lines].BG[bg].VOffset) || (HOffset != LineData [y + Lines].BG[bg].HOffset)) break; | |
| HOffset <<= 1; | |
| if (Y + Lines > endy) Lines = endy + 1 - Y; | |
| // VirtAlign <<= 3; | |
| int ScreenLine = (VOffset + Y) >> (GPUPack.BG.TileSize == 16 ? 4 : 3); | |
| int t1; | |
| int t2; | |
| if (((VOffset + Y) & 15) > 7) { | |
| t1 = 16; | |
| t2 = 0; | |
| } else { | |
| t1 = 0; | |
| t2 = 16; | |
| } | |
| uint16 *b1; | |
| uint16 *b2; | |
| if (ScreenLine & 0x20) b1 = SC2, b2 = SC3; | |
| else b1 = SC0, b2 = SC1; | |
| b1 += (ScreenLine & 0x1f) << 5; | |
| b2 += (ScreenLine & 0x1f) << 5; | |
| int clipcount = pCurrentClipFix->Count [bg][g]; | |
| if (!clipcount) clipcount = 1; | |
| for (int clip = 0; clip < clipcount; clip++) | |
| { | |
| int Left; | |
| int Right; | |
| if (pCurrentClipFix->Count [bg][g]==0) | |
| { | |
| Left = 0; | |
| Right = 512; | |
| } else | |
| { | |
| Left = pCurrentClipFix->Left [clip][bg][g]* 2; | |
| Right = pCurrentClipFix->Right [clip][bg][g] * 2; | |
| if (Right <= Left) continue; | |
| } | |
| //uint32 s = (Left>>1) * GPUPack.GFX.PixSize + Y * 256;//GPUPack.GFX.PPL; | |
| s32 Xt=Left>>1; | |
| s32 Yt=Y; | |
| uint32 HPos = (HOffset + Left * 1) & 0x3ff; | |
| uint32 Quot = HPos >> 3; | |
| uint32 Count = 0; | |
| uint16 *t; | |
| if (Quot > 63) t = b2 + ((Quot >> 1) & 0x1f); | |
| else t = b1 + (Quot >> 1); | |
| Width = Right - Left; | |
| // Left hand edge clipped tile | |
| if (HPos & 7) | |
| { | |
| int Offset = (HPos & 7); | |
| Count = 8 - Offset; | |
| if (Count > Width) Count = Width; | |
| //s -= Offset>>1; | |
| Xt-=Offset>>1; | |
| Tile = READ_2BYTES (t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (GPUPack.BG.TileSize == 8) | |
| { | |
| if (!(Tile & H_FLIP)) | |
| { | |
| // Normal, unflipped | |
| pspDrawHiResClippedTile16 (Tile + (Quot & 1), Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip | |
| pspDrawHiResClippedTile16 (Tile + 1 - (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| if (!(Tile & (V_FLIP | H_FLIP))) | |
| { | |
| // Normal, unflipped | |
| pspDrawHiResClippedTile16 (Tile + t1 + (Quot & 1), Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } else if (Tile & H_FLIP) | |
| { | |
| if (Tile & V_FLIP) | |
| { | |
| // H & V flip | |
| pspDrawHiResClippedTile16 (Tile + t2 + 1 - (Quot & 1), Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip only | |
| pspDrawHiResClippedTile16 (Tile + t1 + 1 - (Quot & 1), Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // V flip only | |
| pspDrawHiResClippedTile16 (Tile + t2 + (Quot & 1), Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| t += Quot & 1; | |
| if (Quot == 63) t = b2; | |
| else if (Quot == 127) t = b1; | |
| Quot++; | |
| //s += 4; | |
| Xt+=4; | |
| } | |
| // Middle, unclipped tiles | |
| Count = Width - Count; | |
| int Middle = Count >> 3; | |
| Count &= 7; | |
| for (int C = Middle; C > 0; Xt+=4/*s += 4*/, Quot++, C--) | |
| { | |
| Tile = READ_2BYTES(t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (GPUPack.BG.TileSize == 8) | |
| { | |
| if (!(Tile & H_FLIP)) | |
| { | |
| // Normal, unflipped | |
| pspDrawHiResTile16 (Tile + (Quot & 1),Xt,Yt, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip | |
| pspDrawHiResTile16 (Tile + 1 - (Quot & 1), Xt,Yt, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| if (!(Tile & (V_FLIP | H_FLIP))) | |
| { | |
| // Normal, unflipped | |
| pspDrawHiResTile16 (Tile + t1 + (Quot & 1),Xt,Yt, VirtAlign, Lines,realZ2); | |
| } else if (Tile & H_FLIP) | |
| { | |
| if (Tile & V_FLIP) | |
| { | |
| // H & V flip | |
| pspDrawHiResTile16 (Tile + t2 + 1 - (Quot & 1), Xt,Yt, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip only | |
| pspDrawHiResTile16 (Tile + t1 + 1 - (Quot & 1), Xt,Yt, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // V flip only | |
| pspDrawHiResTile16 (Tile + t2 + (Quot & 1), Xt,Yt, VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| t += Quot & 1; | |
| if (Quot == 63) t = b2; | |
| else if (Quot == 127) t = b1; | |
| } | |
| // Right-hand edge clipped tiles | |
| if (Count) | |
| { | |
| Tile = READ_2BYTES(t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (GPUPack.BG.TileSize == 8) | |
| { | |
| if (!(Tile & H_FLIP)) | |
| { | |
| // Normal, unflipped | |
| pspDrawHiResClippedTile16 (Tile + (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip | |
| pspDrawHiResClippedTile16 (Tile + 1 - (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| if (!(Tile & (V_FLIP | H_FLIP))) | |
| { | |
| // Normal, unflipped | |
| pspDrawHiResClippedTile16 (Tile + t1 + (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } else if (Tile & H_FLIP) | |
| { | |
| if (Tile & V_FLIP) | |
| { | |
| // H & V flip | |
| pspDrawHiResClippedTile16 (Tile + t2 + 1 - (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip only | |
| pspDrawHiResClippedTile16 (Tile + t1 + 1 - (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // V flip only | |
| pspDrawHiResClippedTile16 (Tile + t2 + (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| GPUPack.GFX.Pitch = GPUPack.GFX.RealPitch; | |
| GPUPack.GFX.PPL = GPUPack.GFX.PPLx2 >> 1; | |
| //render | |
| if (vertices_ptr[current_bitshift]-vertices[current_bitshift]) { | |
| sceGuTexImage(0,512,512,512,tile_texture[current_bitshift]); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,(vertices_ptr[current_bitshift]-vertices[current_bitshift]),0,vertices[current_bitshift]); | |
| } | |
| } | |
| //#define DEBUG_DRAWBACKGROUND | |
| #if 0 | |
| #else | |
| void pspDrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2); | |
| void pspDrawBackgroundOffsetFix (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2); | |
| void pspDrawBackgroundFix (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) { | |
| GPUPack.BG.TileSize = BGSizes [PPUPack.PPU.BG[bg].BGSize]; | |
| GPUPack.BG.BitShift = BitShifts[BGMode][bg]; | |
| GPUPack.BG.TileShift = TileShifts[BGMode][bg]; | |
| GPUPack.BG.TileAddress = PPUPack.PPU.BG[bg].NameBase << 1; | |
| GPUPack.BG.NameSelect = 0; | |
| current_bitshift=Depths [BGMode][bg]; | |
| GPUPack.BG.Buffer = tile_texture[current_bitshift];//IPPU.TileCache8 [Depths [BGMode][bg]]; | |
| GPUPack.BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]]; | |
| GPUPack.BG.PaletteShift = PaletteShifts[BGMode][bg]; | |
| GPUPack.BG.PaletteMask = PaletteMasks[BGMode][bg]; | |
| GPUPack.BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 && (GPUPack.GFX.r2130 & 1); | |
| if (GPUPack.BG.DirectColourMode) { | |
| if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); | |
| GPUPack.GFX.ScreenColors = DirectColourMaps[0]; | |
| } | |
| else GPUPack.GFX.ScreenColors = &IPPU.ScreenColors[0]; | |
| /********************************************************/ | |
| /********************************************************/ | |
| /********************************************************/ | |
| /********************************************************/ | |
| if (PPUPack.PPU.BGMosaic [bg] && PPUPack.PPU.Mosaic > 1){ | |
| #ifdef DEBUG_DRAWBACKGROUND | |
| {char str[32]; | |
| sprintf(str,"BGMode : %d mosaic",BGMode); | |
| pgPrintBG(0,10,0xffff,str); | |
| } | |
| #endif | |
| pspDrawBackgroundMosaicFix (BGMode, bg, Z1, Z2); | |
| //debug_log("mosaic mode not supported"); | |
| return; | |
| } | |
| switch (BGMode) { | |
| case 2: if (Settings.WrestlemaniaArcade) break; | |
| case 4: // Used by Puzzle Bobble | |
| // Not used in psp hardware mode, since it's not really fit | |
| //void pspDrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2); | |
| pspDrawBackgroundOffsetFix (BGMode, bg, Z1, Z2); | |
| return; | |
| case 5: | |
| case 6: // XXX: is also offset per tile. | |
| #ifdef DEBUG_DRAWBACKGROUND | |
| {char str[32]; | |
| sprintf(str,"BGMode : %d mode5",BGMode); | |
| pgPrintBG(0,10,0xffff,str); | |
| } | |
| #endif | |
| pspDrawBackgroundMode5Fix (BGMode, bg, Z1, Z2); | |
| return; | |
| } | |
| #ifdef DEBUG_DRAWBACKGROUND | |
| {char str[32]; | |
| sprintf(str,"BGMode : %d",BGMode); | |
| pgPrintBG(0,10,0xffff,str); | |
| } | |
| #endif | |
| uint32 Tile; | |
| uint16 *SC0; | |
| uint16 *SC1; | |
| uint16 *SC2; | |
| uint16 *SC3; | |
| uint32 Width; | |
| uint8 depths [2] = {Z1, Z2}; | |
| if (last_palette!=GPUPack.BG.DirectColourMode){ | |
| //DirectColourMode has changed, so we have to reload palette | |
| waitRenderingFix(); | |
| last_palette=GPUPack.BG.DirectColourMode; | |
| clut = (u16*)NO_CPU_CACHE(&clut256[0]); | |
| memcpy(clut,GPUPack.GFX.ScreenColors,256*2); | |
| if (rendering_beware_fix16) | |
| for (int i=0;i<256;i++) { | |
| if (clut[i]==fixedcol16) clut[i]^=1<<10; //swap blue 1st bit | |
| } | |
| clut[0]|=0x8000; | |
| sceGuClutLoad(256/16,clut); | |
| } | |
| //bg is 32x30 tile but needs more in case of clipping or scroll changing every line | |
| //int num_vert=((GPUPack.GFX.EndY-GPUPack.GFX.StartY+1)+2)*(256/8+6); | |
| int num_vert=((GPUPack.GFX.EndY-GPUPack.GFX.StartY+1)+2+pCurrentClipFix->GroupCount [bg])*(256/8+6); | |
| if (!(vertices[current_bitshift]=(struct Vertex*)sceGuGetMemory(num_vert*2* sizeof(struct Vertex)))){ | |
| debug_log("not enough vertices!"); | |
| return; | |
| } | |
| vertices_ptr[current_bitshift]=vertices[current_bitshift]; | |
| vertices_end[current_bitshift]=vertices_ptr[current_bitshift]+num_vert*2; | |
| if (BGMode == 0) GPUPack.BG.StartPalette = bg << 5; | |
| else GPUPack.BG.StartPalette = 0; | |
| SC0 = (uint16 *) &VRAM[PPUPack.PPU.BG[bg].SCBase << 1]; | |
| if (PPUPack.PPU.BG[bg].SCSize & 1) SC1 = SC0 + 1024; | |
| else SC1 = SC0; | |
| if(SC1>=(unsigned short*)(VRAM+0x10000)) SC1=(uint16*)&VRAM[((uint8*)SC1-&VRAM[0])%0x10000]; | |
| if (PPUPack.PPU.BG[bg].SCSize & 2) SC2 = SC1 + 1024; | |
| else SC2 = SC0; | |
| if (PPUPack.PPU.BG[bg].SCSize & 1) SC3 = SC2 + 1024; | |
| else SC3 = SC2; | |
| if((SC3-(unsigned short*)VRAM)>0x10000) SC3-=0x10000; | |
| int Lines; | |
| int OffsetMask; | |
| int OffsetShift; | |
| bool BGTileSizeis8=GPUPack.BG.TileSize == 8; | |
| if (GPUPack.BG.TileSize == 16){ | |
| OffsetMask = 0x3ff; | |
| OffsetShift = 4; | |
| }else{ | |
| OffsetMask = 0x1ff; | |
| OffsetShift = 3; | |
| } | |
| uint32 Y = GPUPack.GFX.StartY; | |
| for (uint32 g = 0; g < pCurrentClipFix->GroupCount [bg]; g++) | |
| { | |
| Y=pCurrentClipFix->Start [bg][g]; | |
| for (; Y <= GPUPack.GFX.EndY && Y <= pCurrentClipFix->End [bg][g]; Y += Lines) | |
| { | |
| uint32 VOffset = LineData [Y].BG[bg].VOffset; | |
| uint32 HOffset = LineData [Y].BG[bg].HOffset; | |
| int VirtAlign = (Y + VOffset) & 7; | |
| for (Lines = 1; Lines < 8 - VirtAlign; Lines++) | |
| if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || (HOffset != LineData [Y + Lines].BG[bg].HOffset)) break; | |
| if (Y + Lines > pCurrentClipFix->End [bg][g]) Lines = pCurrentClipFix->End [bg][g] + 1 - Y; | |
| uint32 ScreenLine = (VOffset + Y) >> OffsetShift; | |
| uint32 t1; | |
| uint32 t2; | |
| if (((VOffset + Y) & 15) > 7) | |
| { | |
| t1 = 16; | |
| t2 = 0; | |
| }else | |
| { | |
| t1 = 0; | |
| t2 = 16; | |
| } | |
| uint16 *b1; | |
| uint16 *b2; | |
| if (ScreenLine & 0x20) b1 = SC2, b2 = SC3; | |
| else b1 = SC0, b2 = SC1; | |
| b1 += (ScreenLine & 0x1f) << 5; | |
| b2 += (ScreenLine & 0x1f) << 5; | |
| uint32 clipcount = pCurrentClipFix->Count [bg][g]; | |
| if (!clipcount) clipcount = 1; | |
| //int clip = 0; | |
| //for (int clip = 0; clip < clipcount; clip++) | |
| for (uint32 clip = 0; clip < clipcount; clip++) | |
| { | |
| uint32 Left; | |
| uint32 Right; | |
| if (pCurrentClipFix->Count [bg][g]==0) | |
| { | |
| Left = 0; | |
| Right = 256; | |
| } else | |
| { | |
| Left = pCurrentClipFix->Left [clip][bg][g]; | |
| Right = pCurrentClipFix->Right [clip][bg][g]; | |
| if (Right <= Left) continue; | |
| } | |
| //uint32 sGP32 = Left + Y*256; | |
| s32 Xt=Left; | |
| s32 Yt=Y; | |
| uint32 HPos = (HOffset + Left) & OffsetMask; | |
| uint32 Quot = HPos >> 3; | |
| uint32 Count = 0; | |
| uint16 *t; | |
| if (BGTileSizeis8) { | |
| if (Quot > 31) t = b2 + (Quot & 0x1f); | |
| else t = b1 + Quot; | |
| } else { | |
| if (Quot > 63) t = b2 + ((Quot >> 1) & 0x1f); | |
| else t = b1 + (Quot >> 1); | |
| } | |
| Width = Right - Left; | |
| // Left hand edge clipped tile | |
| if (HPos & 7) | |
| { | |
| uint32 Offset = (HPos & 7); | |
| Count = 8 - Offset; | |
| if (Count > Width) Count = Width; | |
| Xt-=Offset;//sGP32 -= Offset ; | |
| Tile = READ_2BYTES(t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (BGTileSizeis8) pspDrawClippedTile16_order (Tile, Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| else | |
| { | |
| if (!(Tile & (V_FLIP | H_FLIP))) | |
| { | |
| // Normal, unflipped | |
| pspDrawClippedTile16_order(Tile + t1 + (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } else if (Tile & H_FLIP) | |
| { | |
| if (Tile & V_FLIP) | |
| { | |
| // H & V flip | |
| pspDrawClippedTile16_order (Tile + t2 + 1 - (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip only | |
| pspDrawClippedTile16_order (Tile + t1 + 1 - (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // V flip only | |
| pspDrawClippedTile16_order (Tile + t2 + (Quot & 1), Xt,Yt,Offset, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| if (GPUPack.BG.TileSize == 8) | |
| { | |
| t++; | |
| if (Quot == 31) t = b2; | |
| else if (Quot == 63) t = b1; | |
| } else { | |
| t += Quot & 1; | |
| if (Quot == 63)t = b2; | |
| else if (Quot == 127) | |
| t = b1; | |
| } | |
| Quot++; | |
| //sGP32 += 8 ; | |
| Xt+=8; | |
| } | |
| // Middle, unclipped tiles | |
| Count = Width - Count; | |
| int Middle = Count >> 3;//count/8 | |
| Count &= 7; | |
| for (int C = Middle; C > 0;/*sGP32 += 8*/Xt+=8 , Quot++, C--) { | |
| Tile = READ_2BYTES(t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (!BGTileSizeis8) | |
| { | |
| if (Tile & H_FLIP) | |
| { | |
| // Horizontal flip, but what about vertical flip ? | |
| if (Tile & V_FLIP) | |
| { | |
| // Both horzontal & vertical flip | |
| pspDrawTile16_order (Tile + t2 + 1 - (Quot & 1), Xt,Yt,VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // Horizontal flip only | |
| pspDrawTile16_order (Tile + t1 + 1 - (Quot & 1), Xt,Yt,VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // No horizontal flip, but is there a vertical flip ? | |
| if (Tile & V_FLIP) | |
| { | |
| // Vertical flip only | |
| pspDrawTile16_order (Tile + t2 + (Quot & 1), Xt,Yt,VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // Normal unflipped | |
| pspDrawTile16_order (Tile + t1 + (Quot & 1), Xt,Yt,VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| } | |
| else | |
| { | |
| pspDrawTile16_order (Tile, Xt,Yt, VirtAlign, Lines,realZ2); | |
| } | |
| if (BGTileSizeis8) | |
| { | |
| t++; | |
| if (Quot == 31) t = b2; | |
| else if (Quot == 63) | |
| t = b1; | |
| } else | |
| { | |
| t += Quot & 1; | |
| if (Quot == 63) t = b2; | |
| else if (Quot == 127) | |
| t = b1; | |
| } | |
| } | |
| // Right-hand edge clipped tiles | |
| if (Count) | |
| { | |
| Tile = READ_2BYTES(t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| //realZ1=(int)GPUPack.GFX.Z1;realZ2=(int)GPUPack.GFX.Z2; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (BGTileSizeis8) pspDrawClippedTile16_order (Tile, Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| else | |
| { | |
| if (!(Tile & (V_FLIP | H_FLIP))) | |
| { | |
| // Normal, unflipped | |
| pspDrawClippedTile16_order (Tile + t1 + (Quot & 1), Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| }else if (Tile & H_FLIP) | |
| { | |
| if (Tile & V_FLIP) | |
| { | |
| // H & V flip | |
| pspDrawClippedTile16_order (Tile + t2 + 1 - (Quot & 1),Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } else | |
| { | |
| // H flip only | |
| pspDrawClippedTile16_order (Tile + t1 + 1 - (Quot & 1),Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } else | |
| { | |
| // V flip only | |
| pspDrawClippedTile16_order (Tile + t2 + (Quot & 1),Xt,Yt, 0, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| //render | |
| if (vertices_ptr[current_bitshift]-vertices[current_bitshift]) { | |
| sceGuTexImage(0,512,512,512,tile_texture[current_bitshift]); | |
| //if(pCurrentClipFix->GroupCount [bg]==0) | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,(vertices_ptr[current_bitshift]-vertices[current_bitshift]),0,vertices[current_bitshift]); | |
| } | |
| } | |
| #endif | |
| //drawmode is : 0 => everything (for sub & main when no transp) | |
| // 1 => only what's added/subbed (for main) | |
| // 2 => only what's not added/subbed (for main) | |
| void pspRenderScreenFix (uint8 *Screen, bool8 sub, uint8 D, uint8 drawmode) | |
| { | |
| #define TO_DRAW(a) \ | |
| ( (drawmode==0) || \ | |
| ((drawmode==1)&&SUB_OR_ADD(a)) ||\ | |
| ((drawmode==2)&&(!SUB_OR_ADD(a))) \ | |
| ) | |
| #define TO_DRAW_OBJ(a) \ | |
| ( (drawmode==0) || \ | |
| ((drawmode==1)&&SUB_OR_ADD(a)) ||\ | |
| (drawmode==2) \ | |
| ) | |
| bool8 BG0; | |
| bool8 BG1; | |
| bool8 BG2; | |
| bool8 BG3; | |
| bool8 OB; | |
| GPUPack.GFX.S = Screen; | |
| if (!sub) { | |
| GPUPack.GFX.pCurrentClip = &IPPU.Clip [0]; | |
| pCurrentClipFix = &IPPU.ClipFix [0]; | |
| BG0 = ON_MAIN (0); | |
| BG1 = ON_MAIN (1); | |
| BG2 = ON_MAIN (2); | |
| BG3 = ON_MAIN (3); | |
| OB = ON_MAIN (4); | |
| } else { | |
| GPUPack.GFX.pCurrentClip = &IPPU.Clip [1]; | |
| pCurrentClipFix = &IPPU.ClipFix [1]; | |
| BG0 = ON_SUB (0); | |
| BG1 = ON_SUB (1); | |
| BG2 = ON_SUB (2); | |
| BG3 = ON_SUB (3); | |
| OB = ON_SUB (4); | |
| } | |
| if (PPUPack.PPU.BGMode <= 1) { | |
| if (OB&&os9x_OBJ) { | |
| if (TO_DRAW_OBJ(4)) { | |
| /*if (os9x_fastsprite) pspDrawFASTOBJSFix (!sub, D,drawmode); | |
| else*/ if(pCurrentClipFix->GroupCount [4]>0) | |
| pspDrawOBJSFix (!sub, D,drawmode); | |
| else | |
| pspDrawOBJS (!sub, D,drawmode); | |
| } | |
| } | |
| if (BG0&&os9x_BG0) { | |
| if (TO_DRAW(0)) { | |
| /* if(IPPU.PaletteLineCount>0) | |
| pspDrawBackgroundFixPalette (PPUPack.PPU.BGMode, 0, D + 10, D + 14); | |
| else*/ if(pCurrentClipFix->GroupCount [0]>0) | |
| pspDrawBackgroundFix (PPUPack.PPU.BGMode, 0, D + 10, D + 14); | |
| else | |
| pspDrawBackground (PPUPack.PPU.BGMode, 0, D + 10, D + 14); | |
| } | |
| } | |
| if (BG1&&os9x_BG1) { | |
| if (TO_DRAW(1)) { | |
| /* if(IPPU.PaletteLineCount>0) | |
| pspDrawBackgroundFixPalette (PPUPack.PPU.BGMode, 1, D + 9, D + 13); | |
| else*/ if(pCurrentClipFix->GroupCount [1]>0) | |
| pspDrawBackgroundFix (PPUPack.PPU.BGMode, 1, D + 9, D + 13); | |
| else | |
| pspDrawBackground (PPUPack.PPU.BGMode, 1, D + 9, D + 13); | |
| } | |
| } | |
| if (BG2&&os9x_BG2) { | |
| if (TO_DRAW(2)) { | |
| /* if(IPPU.PaletteLineCount>0) | |
| pspDrawBackgroundFixPalette (PPUPack.PPU.BGMode, 2, D + 3, (ROM_GLOBAL [0x2105] & 8) == 0 ? D + 6 : D + 17); | |
| else*/ if(pCurrentClipFix->GroupCount [2]>0) | |
| pspDrawBackgroundFix (PPUPack.PPU.BGMode, 2, D + 3, (ROM_GLOBAL [0x2105] & 8) == 0 ? D + 6 : D + 17); | |
| else | |
| pspDrawBackground (PPUPack.PPU.BGMode, 2, D + 3, (ROM_GLOBAL [0x2105] & 8) == 0 ? D + 6 : D + 17); | |
| } | |
| } | |
| if (BG3 && PPUPack.PPU.BGMode == 0 && os9x_BG3) { | |
| if (TO_DRAW(3)) { | |
| /* if(IPPU.PaletteLineCount>0) | |
| pspDrawBackgroundFixPalette (PPUPack.PPU.BGMode, 3, D + 2, D + 5); | |
| else*/ if(pCurrentClipFix->GroupCount [3]>0) | |
| pspDrawBackgroundFix (PPUPack.PPU.BGMode, 3, D + 2, D + 5); | |
| else | |
| pspDrawBackground (PPUPack.PPU.BGMode, 3, D + 2, D + 5); | |
| } | |
| } | |
| } else if (PPUPack.PPU.BGMode != 7) { | |
| if (OB&&os9x_OBJ) { | |
| /*if (os9x_fastsprite) pspDrawFASTOBJSFix (!sub, D,drawmode); | |
| else*/ if(pCurrentClipFix->GroupCount [4]>0) | |
| pspDrawOBJSFix (!sub, D,drawmode); | |
| else | |
| pspDrawOBJS (!sub, D,drawmode); | |
| } | |
| if (BG0&&os9x_BG0) { | |
| if (TO_DRAW(0)) { | |
| if(pCurrentClipFix->GroupCount [0]>0) | |
| pspDrawBackgroundFix (PPUPack.PPU.BGMode, 0, D + 5, D + 13); | |
| else | |
| pspDrawBackground (PPUPack.PPU.BGMode, 0, D + 5, D + 13); | |
| } | |
| } | |
| if (PPUPack.PPU.BGMode != 6 && BG1 &&os9x_BG1) { | |
| if (TO_DRAW(1)) { | |
| if(pCurrentClipFix->GroupCount [1]>0) | |
| pspDrawBackgroundFix (PPUPack.PPU.BGMode, 1, D + 2, D + 9); | |
| else | |
| pspDrawBackground (PPUPack.PPU.BGMode, 1, D + 2, D + 9); | |
| } | |
| } | |
| } else { | |
| return; | |
| /*if (OB &&os9x_OBJ) | |
| { | |
| //pspDrawOBJSFix (!sub, D); | |
| } | |
| if (BG0 || ((ROM_GLOBAL [0x2133] & 0x40) && BG1) &&os9x_BG0) | |
| { | |
| int bg; | |
| if (ROM_GLOBAL [0x2133] & 0x40) | |
| { | |
| GPUPack.GFX.Mode7Mask = 0x7f; | |
| GPUPack.GFX.Mode7PriorityMask = 0x80; | |
| Mode7Depths [0] = 5 + D; | |
| Mode7Depths [1] = 9 + D; | |
| bg = 1; | |
| } | |
| else | |
| { | |
| GPUPack.GFX.Mode7Mask = 0xff; | |
| GPUPack.GFX.Mode7PriorityMask = 0; | |
| Mode7Depths [0] = 5 + D; | |
| Mode7Depths [1] = 5 + D; | |
| bg = 0; | |
| } | |
| if (sub || !SUB_OR_ADD(0)) | |
| { | |
| pspDrawBGMode7Background16 (Screen, bg); | |
| } | |
| else | |
| { | |
| if (GPUPack.GFX.r2131 & 0x80) | |
| { | |
| if (GPUPack.GFX.r2131 & 0x40) | |
| { | |
| pspDrawBGMode7Background16Sub1_2 (Screen, bg); | |
| } | |
| else | |
| { | |
| pspDrawBGMode7Background16Sub (Screen, bg); | |
| } | |
| } | |
| else | |
| { | |
| if (GPUPack.GFX.r2131 & 0x40) | |
| { | |
| pspDrawBGMode7Background16Add1_2 (Screen, bg); | |
| } | |
| else | |
| { | |
| pspDrawBGMode7Background16Add (Screen, bg); | |
| } | |
| } | |
| } | |
| }*/ | |
| } | |
| #undef TO_DRAW | |
| } | |
| extern int debug_counts[]; | |
| void pspS9xUpdateScreenFix (){ | |
| int i; | |
| render_timestamp++; | |
| /*GPUPack.GFX.S = GPUPack.GFX.Screen; | |
| GPUPack.GFX.r2131 = ROM_GLOBAL [0x2131]; | |
| GPUPack.GFX.r212c = ROM_GLOBAL [0x212c]; | |
| GPUPack.GFX.r212d = ROM_GLOBAL [0x212d]; | |
| GPUPack.GFX.r2130 = ROM_GLOBAL [0x2130]; | |
| GPUPack.GFX.Pseudo = (ROM_GLOBAL [0x2133] & 8) != 0 && | |
| (GPUPack.GFX.r212c & 15) != (GPUPack.GFX.r212d & 15) && | |
| (GPUPack.GFX.r2131 & 0x3f) == 0; | |
| if (IPPU.OBJChanged) | |
| S9xSetupOBJ (); | |
| if (PPUPack.PPU.RecomputeClipWindows) | |
| { | |
| ComputeClipWindows (); | |
| PPUPack.PPU.RecomputeClipWindows = FALSE; | |
| } | |
| */ | |
| SET_DEBUG_COUNT(30,IPPU.ClipFixMaxCount); | |
| GPUPack.GFX.StartY = IPPU.PreviousLine; | |
| if ((GPUPack.GFX.EndY = IPPU.CurrentLine - 1) >= PPUPack.PPU.ScreenHeight) | |
| GPUPack.GFX.EndY = PPUPack.PPU.ScreenHeight - 1; | |
| uint32 starty = GPUPack.GFX.StartY; | |
| uint32 endy = GPUPack.GFX.EndY; | |
| if (tile_cache_reset) tile_reset_cache(); | |
| else tile_resetask=0; | |
| if (GPUPack.GFX.Pseudo) { | |
| GPUPack.GFX.r2131 = 0x5f; | |
| GPUPack.GFX.r212d = (ROM_GLOBAL [0x212c] ^ ROM_GLOBAL [0x212d]) & 15; | |
| GPUPack.GFX.r212c &= ~GPUPack.GFX.r212d; | |
| GPUPack.GFX.r2130 |= 2; | |
| } | |
| //extern ClipDataFix debug_ClipDataFix; | |
| //extern int debug_start; | |
| //extern int debug_end; | |
| //extern int os9x_renderingpass; | |
| //if(os9x_renderingpass==1) | |
| //{ | |
| // debug_start=starty | 1000; | |
| // debug_end=endy; | |
| // memcpy(&debug_ClipDataFix,&IPPU.ClipFix [1],sizeof(ClipDataFix)); | |
| //} | |
| if (!os9x_easy&&!PPUPack.PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && (GPUPack.GFX.r2130 & 0x30) != 0x30 && | |
| (!((GPUPack.GFX.r2130 & 0x30) == 0x10 && IPPU.ClipFix[1].GroupCount[5] == 0) || !((GPUPack.GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0))){ | |
| fixedcol=((int)(IPPU.XB [PPUPack.PPU.FixedColourRed])<<3)|((int)(IPPU.XB [PPUPack.PPU.FixedColourGreen])<<11)|((int)(IPPU.XB [PPUPack.PPU.FixedColourBlue])<<19); | |
| fixedcol16=((int)(IPPU.XB [PPUPack.PPU.FixedColourRed])<<0)|((int)(IPPU.XB [PPUPack.PPU.FixedColourGreen])<<5)|((int)(IPPU.XB [PPUPack.PPU.FixedColourBlue])<<10); | |
| INC_DEBUG_COUNT(TRANCE_COUNT); | |
| info(32,0,"transp"); | |
| //get current add_sub_mode | |
| pspSelectAddSubMode (); | |
| int _2passblending,_fixaddsub; | |
| if ((add_sub_mode==1)||(add_sub_mode==4)) _2passblending=1; | |
| else _2passblending=0; | |
| if ((add_sub_mode==2)||(add_sub_mode==5)) _fixaddsub=1; | |
| else _fixaddsub=0; | |
| if (_2passblending||_fixaddsub) rendering_beware_fix16=1; | |
| //start a new rendering pass | |
| initRenderingFix(); | |
| //set subscreen as drawing buffer | |
| sceGuDrawBufferList(GU_PSM_5551,(void*)(512*272*2*2+256*240*2+0*256*256*2),256); | |
| sceGuTexMode(GU_PSM_T8,0,0,0); //8bit texture | |
| //clear the ZBuffer | |
| sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| sceGuClearDepth(0); | |
| sceGuClear(GU_DEPTH_BUFFER_BIT); | |
| //subscreen colour window handling | |
| if ( IPPU.ClipFix [1].GroupCount [5]) { | |
| SET_DEBUG_COUNT(SUBSCREEN_COLOUR_WINDOW,1); | |
| // Colour window enabled on subscreen | |
| // first we clear it with 0 | |
| // if 2 pass blending is need, 0 will be used to detect fixed colour | |
| // so the "normal black", 0, is replaced by 1 (dark blue) | |
| if (rendering_beware_fix16) { | |
| if (fixedcol==0) sceGuClearColor(1<<19); | |
| else sceGuClearColor(0); | |
| } else sceGuClearColor(0); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| //extern ClipDataFix debug_ClipDataFix; | |
| //if(IPPU.ClipFix [1].GroupCount [5]>10)memcpy(&debug_ClipDataFix,&IPPU.ClipFix [1],sizeof(ClipDataFix)); | |
| if(IPPU.FixColorCount) | |
| { | |
| //clipping && Fix color change | |
| SET_DEBUG_COUNT(FIXCOLORCOUNT_ON_COLOUR_WINDOW,IPPU.FixColorCount); | |
| for (uint32 g = 0; g < IPPU.ClipFix [1].GroupCount [5]; g++) { | |
| int startcl; | |
| int endcl; | |
| startcl = IPPU.ClipFix [1].Start [5][g]; | |
| endcl = IPPU.ClipFix [1].End [5][g]+1; | |
| int i=0; | |
| int startc=startcl; | |
| int endc=startcl; | |
| for(;i<IPPU.FixColorCount-1;i++) | |
| { | |
| if(IPPU.FixColorLines[i+1]<startcl) | |
| continue; | |
| if(IPPU.FixColorLines[i+1]>endcl) | |
| break; | |
| endc= IPPU.FixColorLines[i+1]; | |
| sceGuScissor(0,startc,256,endc); | |
| sceGuClearColor(IPPU.FixColorLog [i]); | |
| for (uint32 c = 0; c < IPPU.ClipFix [1].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [1].Right [c][5][g] > IPPU.ClipFix [1].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [1].Left [c][5][g],startc,(IPPU.ClipFix [1].Right [c][5][g])+1,endc); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| startc=endc; | |
| } | |
| if(endc<endcl) | |
| { | |
| sceGuClearColor(IPPU.FixColorLog [i]); | |
| for (uint32 c = 0; c < IPPU.ClipFix [1].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [1].Right [c][5][g] > IPPU.ClipFix [1].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [1].Left [c][5][g],endc,(IPPU.ClipFix [1].Right [c][5][g])+1,endcl); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| else | |
| { | |
| // then with FixedColour where it will be rendered | |
| sceGuClearColor(fixedcol); | |
| for (uint32 g = 0; g < IPPU.ClipFix [1].GroupCount [5]; g++) { | |
| for (uint32 c = 0; c < IPPU.ClipFix [1].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [1].Right [c][5][g] > IPPU.ClipFix [1].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [1].Left [c][5][g],IPPU.ClipFix [1].Start [5][g],(IPPU.ClipFix [1].Right [c][5][g])+1,IPPU.ClipFix [1].End [5][g]+1); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| } | |
| sceGuScissor(0,starty,256,endy+1); | |
| } else { | |
| // No colour window enabled on subscreen | |
| info(32,1,"no color win sub"); | |
| // we clear it with FixedColour | |
| //if(IPPU.FixColorCount>100) | |
| //{ | |
| //extern int debug_FixColorCount; | |
| //extern uint8 debug_FixColorLines[256]; | |
| //extern uint16 debug_FixColorLog[256]; | |
| //memcpy(debug_FixColorLines,IPPU.FixColorLines,256); | |
| //memcpy(debug_FixColorLog,IPPU.FixColorLog,256*2); | |
| //debug_FixColorCount=IPPU.FixColorCount; | |
| //} | |
| if(IPPU.FixColorCount) | |
| { | |
| SET_DEBUG_COUNT(FIXCOLORCOUNT_ON_NO_COLOUR_WINDOW,IPPU.FixColorCount); | |
| uint32 startc=starty; | |
| uint32 endc=starty; | |
| int i=0; | |
| for(;i<IPPU.FixColorCount-1;i++) | |
| { | |
| endc= IPPU.FixColorLines[i+1]; | |
| sceGuScissor(0,startc,256,endc); | |
| sceGuClearColor(IPPU.FixColorLog[i]); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| startc=endc; | |
| } | |
| if(endc-1<endy) | |
| { | |
| sceGuScissor(0,endc,256,endy+1); | |
| sceGuClearColor(IPPU.FixColorLog[i]); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| sceGuScissor(0,starty,256,endy+1); | |
| } | |
| else | |
| { | |
| sceGuClearColor(fixedcol); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| if (ANYTHING_ON_SUB) { | |
| info(32,2,"rendering subscreen "); | |
| pspRenderScreenFix (GPUPack.GFX.SubScreen, true, SUB_SCREEN_DEPTH,0); | |
| } else { | |
| info(32,2,"nothing on subscreen"); | |
| } | |
| //now main screen | |
| sceGuDrawBufferList(GU_PSM_5551,(void*)(512*272*2*2+256*240*2+1*256*256*2),256); | |
| //handle main screen colour window | |
| if (IPPU.ClipFix [0].GroupCount[5]) | |
| { | |
| SET_DEBUG_COUNT(MAINSCREEN_COLOUR_WINDOW,1); | |
| // Colour window enabled on mainscreen | |
| int col=(((IPPU.ScreenColors [0])&31)<<3)|(((IPPU.ScreenColors [0]>>5)&31)<<11)|(((IPPU.ScreenColors [0]>>10)&31)<<19); | |
| // first we clear it with 0 everywhere | |
| if (rendering_beware_fix16) | |
| { | |
| if (fixedcol==0) sceGuClearColor(1<<19); | |
| else sceGuClearColor(0); | |
| } else sceGuClearColor(0); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| // and back color inside rendered area | |
| if (rendering_beware_fix16) { | |
| if (fixedcol==IPPU.ScreenColors [0]) col^=1<<19; | |
| //if (fixedcol16==IPPU.ScreenColors [0]) col^=1<<19; | |
| } | |
| if(IPPU.MainColorCount) | |
| { | |
| //clipping && color change | |
| SET_DEBUG_COUNT(MAINCOLORCOUNT_CLIP,IPPU.MainColorCount); | |
| sceGuClearColor(col); | |
| for (uint32 g = 0; g < IPPU.ClipFix [0].GroupCount [5]; g++) { | |
| int startcl; | |
| int endcl; | |
| startcl = IPPU.ClipFix [0].Start [5][g]; | |
| endcl = IPPU.ClipFix [0].End [5][g]+1; | |
| int i=0; | |
| int startc=startcl; | |
| int endc=startcl; | |
| for(;i<IPPU.MainColorCount-1;i++) | |
| { | |
| if(IPPU.MainColorLines[i+1]<startcl) | |
| continue; | |
| if(IPPU.MainColorLines[i+1]>endcl) | |
| break; | |
| endc= IPPU.MainColorLines[i+1]; | |
| sceGuScissor(0,startc,256,endc); | |
| col=(((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19); | |
| if (rendering_beware_fix16) { | |
| if (fixedcol==IPPU.ScreenColors [0]) col^=1<<19; | |
| //if (IPPU.MainColorLog [i]==IPPU.ScreenColors [0]) col^=1<<19; | |
| } | |
| sceGuClearColor(col); | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],startc,(IPPU.ClipFix [0].Right [c][5][g])+1,endc); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| startc=endc; | |
| } | |
| if(endc<endcl) | |
| { | |
| col=(((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19); | |
| if (rendering_beware_fix16) { | |
| if (fixedcol==IPPU.ScreenColors [0]) col^=1<<19; | |
| } | |
| sceGuClearColor(col); | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],endc,(IPPU.ClipFix [0].Right [c][5][g])+1,endcl); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| else | |
| { | |
| //clipping | |
| sceGuClearColor(col); | |
| for (uint32 g = 0; g < IPPU.ClipFix [0].GroupCount [5]; g++) { | |
| int startcl; | |
| int endcl; | |
| startcl = IPPU.ClipFix [0].Start [5][g]; | |
| endcl = IPPU.ClipFix [0].End [5][g]+1; | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],startcl,(IPPU.ClipFix [0].Right [c][5][g])+1,endcl); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| } | |
| sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| // perhaps we should only do that when subscreen & mainscreen colour window aren't overlapping | |
| // then we copy subscreen where there are pixels | |
| if (ANYTHING_ON_SUB){ | |
| sceGuTexMode(GU_PSM_5551,0,0,0); //16bit texture | |
| sceGuDisable(GU_ALPHA_TEST); | |
| sceGuDepthFunc(GU_LESS); | |
| sceGuDepthMask(GU_TRUE); | |
| sceGuTexImage(0,256,256,256,(u8*)(0x44000000+512*272*2*2+256*240*2+0*256*256*2)); | |
| _vertices = (struct Vertex*)sceGuGetMemory(4*2 * sizeof(struct Vertex)); | |
| if (_vertices) | |
| { | |
| _vertices_ptr=_vertices; | |
| for (i=0;i<256;i+=64){ | |
| _vertices_ptr->u = i; _vertices_ptr->v = starty; | |
| _vertices_ptr->x = i; _vertices_ptr->y = starty;_vertices_ptr->z = 0; | |
| _vertices_ptr++; | |
| _vertices_ptr->u = i+64; _vertices_ptr->v = endy+1; | |
| _vertices_ptr->x = i+64; _vertices_ptr->y = endy+1;_vertices_ptr->z = 0; | |
| _vertices_ptr++; | |
| } | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2*4,0,_vertices); | |
| } | |
| sceGuEnable(GU_ALPHA_TEST); | |
| sceGuDepthFunc(GU_GREATER); | |
| sceGuDepthMask(GU_FALSE); | |
| sceGuTexMode(GU_PSM_T8,0,0,0); //8bit texture | |
| } | |
| // we set ZBuffer to 0 | |
| // so further blending won't update others pixels (outside colour window) | |
| sceGuClearDepth(0); | |
| sceGuClear(GU_DEPTH_BUFFER_BIT); | |
| // and 1 to updatable area | |
| sceGuClearDepth(1); | |
| for (uint32 g = 0; g < IPPU.ClipFix [0].GroupCount [5]; g++) { | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],IPPU.ClipFix [0].Start [5][g],(IPPU.ClipFix [0].Right [c][5][g])+1,IPPU.ClipFix [0].End [5][g]+1); | |
| sceGuClear(GU_DEPTH_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| // and back to whole rendering area | |
| sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| } else {//"no color win main" | |
| // Colour window disabled on mainscreen | |
| // we clear it with ScreenColors[0] | |
| //extern int debug_MainColorCount; | |
| //extern uint8 debug_MainColorLines[256]; | |
| //extern uint16 debug_MainColorLog[256]; | |
| if(IPPU.MainColorCount) | |
| { | |
| SET_DEBUG_COUNT(MAINCOLORCOUNT_NO_CLIP,IPPU.MainColorCount); | |
| uint32 startc=starty; | |
| uint32 endc=starty;//endy+1;//IPPU.MainColorLines[1]; | |
| int i=0; | |
| //if(os9x_renderingpass==4) | |
| //{ | |
| // memcpy(debug_MainColorLines,IPPU.MainColorLines,256); | |
| // memcpy(debug_MainColorLog,IPPU.MainColorLog,256*2); | |
| // debug_MainColorCount=IPPU.MainColorCount; | |
| //} | |
| sceGuClearDepth(1);//MAIN_SCREEN_DEPTH);//0??? seiken3 dialog | |
| for(;i<IPPU.MainColorCount-1;i++) | |
| { | |
| endc= IPPU.MainColorLines[i+1]; | |
| sceGuScissor(0,startc,256,endc); | |
| sceGuClearColor((((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19)); | |
| sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| startc=endc; | |
| } | |
| if(endc-1<endy) | |
| { | |
| sceGuScissor(0,endc,256,endy+1); | |
| sceGuClearColor((((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19)); | |
| sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| } | |
| sceGuScissor(0,starty,256,endy+1); | |
| } | |
| else | |
| { | |
| sceGuClearColor((((IPPU.ScreenColors [0])&31)<<3)|(((IPPU.ScreenColors [0]>>5)&31)<<11)|(((IPPU.ScreenColors [0]>>10)&31)<<19)); | |
| //clear Z buffer, TODO : check if Zbuffer clear is needed each time (ADD_OR_SUB(5) only since no colour window ?) | |
| sceGuClearDepth(1);//MAIN_SCREEN_DEPTH);//0??? seiken3 dialog | |
| sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| } | |
| } | |
| // now first pass main screen (with BG/OBJ to be combined with subscreen/fixed colour | |
| //invalidate last palette | |
| pspRenderScreenFix (GPUPack.GFX.Screen, false, SUB_SCREEN_DEPTH,1); | |
| // now draw on final buffer | |
| // if rendering mode == 0, then draw directly on final screen | |
| sceGuDrawBufferList(GU_PSM_5551,(void*)(512*272*2*2+256*240*2+2*256*256*2),256); | |
| // first, simple copy of first pass main screen | |
| sceGuTexMode(GU_PSM_5551,0,0,0); //16bit texture | |
| sceGuTexImage(0,256,256,256,(u16*)(0x44000000+512*272*2*2+256*240*2+1*256*256*2)); | |
| sceGuDisable(GU_DEPTH_TEST); | |
| sceGuDisable(GU_ALPHA_TEST); | |
| int zmin; | |
| if ((!IPPU.Clip [0].Count[5])&&SUB_OR_ADD(5)){ | |
| //no colour window on mainscreen | |
| //and sub_or_add back colour as well | |
| //so no need to filter subscreen, the whole will be blended | |
| //sceGuDepthFunc(GU_ALWAYS); | |
| zmin=0; | |
| } else { | |
| // colour window on mainscreen or not sub_or_add back colour | |
| // we have to filter rendering using ZBuffer | |
| // but no update has to be done in ZBuffer in order to not corrupt the second pass of | |
| // main screen rendering | |
| if (SUB_OR_ADD(5)) zmin=0; //depth of back is 1 | |
| else zmin=1; | |
| } | |
| _vertices = (struct Vertex*)sceGuGetMemory(4*2 * sizeof(struct Vertex)); | |
| if (_vertices) | |
| { | |
| _vertices_ptr=_vertices; | |
| for (i=0;i<256;i+=64){ | |
| _vertices_ptr->u = i; _vertices_ptr->v = starty; | |
| _vertices_ptr->x = i; _vertices_ptr->y = starty;_vertices_ptr->z = zmin; | |
| _vertices_ptr++; | |
| _vertices_ptr->u = (i+64); _vertices_ptr->v = endy+1; | |
| _vertices_ptr->x = (i+64); _vertices_ptr->y = endy+1;_vertices_ptr->z = zmin; | |
| _vertices_ptr++; | |
| } | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2*4,0,_vertices); | |
| } | |
| //load subscreen texture | |
| sceGuTexImage(0,256,256,256,(u16*)(0x44000000+512*272*2*2+256*240*2+0*256*256*2)); | |
| sceGuEnable(GU_DEPTH_TEST); | |
| sceGuDepthMask(GU_TRUE); | |
| // now we'll add subscreen/fixedcolour | |
| if ((!IPPU.ClipFix [0].Count[5])&&SUB_OR_ADD(5)) | |
| { | |
| //no colour window on mainscreen | |
| //and sub_or_add back colour as well | |
| //so no need to filter subscreen, the whole will be blended | |
| //sceGuDepthFunc(GU_ALWAYS); | |
| sceGuDisable(GU_DEPTH_TEST); | |
| } else | |
| { | |
| // colour window on mainscreen or not sub_or_add back colour | |
| // we have to filter rendering using ZBuffer | |
| // but no update has to be done in ZBuffer in order to not corrupt the second pass of | |
| // main screen rendering | |
| sceGuDepthFunc(GU_LESS); | |
| } | |
| // setup blend mode | |
| if (_2passblending) { | |
| //char st[32];sprintf(st,"%08X",fixedcol);info(32,20,st); | |
| sceGuEnable(GU_BLEND); | |
| if (add_sub_mode==1) sceGuBlendFunc(2,GU_FIX,GU_FIX,0xffffff,0xffffff); | |
| else sceGuBlendFunc(0,GU_FIX,GU_FIX,0xffffff,0xffffff); | |
| sceGuEnable(GU_COLOR_TEST); //color test | |
| sceGuColorFunc(GU_EQUAL,fixedcol,(0x1F<<3)|(0x1F<<11)|(0x1F<<19)); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2*4,0,_vertices); | |
| sceGuColorFunc(GU_NOTEQUAL,fixedcol,(0x1F<<3)|(0x1F<<11)|(0x1F<<19)); | |
| } else sceGuEnable(GU_BLEND); | |
| //detect blending type | |
| switch (add_sub_mode){ | |
| case 0:info(32,4,"oops!!");break; | |
| case 1://sub1_2 | |
| info(32,4,"sub1_2"); | |
| sceGuBlendFunc(2,GU_FIX,GU_FIX,0x7f7f7f,0x7f7f7f); break; | |
| case 2://fix sub | |
| info(32,4,"subfix"); | |
| sceGuBlendFunc(2,GU_FIX,GU_FIX,0x7f7f7f,0x7f7f7f); break; | |
| case 3://sub | |
| info(32,4,"sub***"); | |
| sceGuBlendFunc(2,GU_FIX,GU_FIX,0xffffff,0xffffff); break; | |
| case 4://add1_2 | |
| info(32,4,"add1_2"); | |
| sceGuBlendFunc(0,GU_FIX,GU_FIX,0x7f7f7f,0x7f7f7f); break; | |
| case 5://fix add | |
| info(32,4,"addfix"); | |
| sceGuBlendFunc(0,GU_FIX,GU_FIX,0x7f7f7f,0x7f7f7f); break; | |
| case 6://add | |
| info(32,4,"add***"); | |
| sceGuBlendFunc(0,GU_FIX,GU_FIX,0xffffff,0xffffff); break; | |
| } | |
| if (_fixaddsub) { | |
| sceGuEnable(GU_COLOR_TEST); //color test | |
| sceGuColorFunc(GU_NOTEQUAL,0,0xFFFFFF); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2*4,0,_vertices); | |
| } else { | |
| if (IPPU.ClipFix [1].GroupCount [5]) { | |
| //col win sub, so not apply blending everywhere | |
| uint32 end = 0; | |
| uint32 start; | |
| for (uint32 g = 0; g < IPPU.ClipFix [1].GroupCount [5]; g++) { | |
| if(IPPU.ClipFix [1].Start [5][g] == end-1) | |
| start=end; | |
| else | |
| start=IPPU.ClipFix [1].Start [5][g]; | |
| end = IPPU.ClipFix [1].End [5][g]+1; | |
| for (uint32 c = 0; c < IPPU.ClipFix [1].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [1].Right [c][5][g] > IPPU.ClipFix [1].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [1].Left [c][5][g],start,(IPPU.ClipFix [1].Right [c][5][g])+1,end); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2*4,0,_vertices); | |
| } | |
| } | |
| } | |
| sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| } else { | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2*4,0,_vertices); | |
| } | |
| } | |
| #if 0 | |
| waitRenderingFix(); | |
| #endif | |
| sceGuDisable(GU_BLEND); | |
| if (_fixaddsub||_2passblending) { | |
| sceGuDisable(GU_COLOR_TEST); | |
| } | |
| sceGuTexMode(GU_PSM_T8,0,0,0); //8bit texture | |
| sceGuEnable(GU_ALPHA_TEST); | |
| sceGuEnable(GU_DEPTH_TEST); | |
| sceGuDepthFunc(GU_GREATER); | |
| sceGuDepthMask(GU_FALSE); | |
| // and now second pass for mainscreen (OBJs/BGs not combined with subscreen) | |
| //invalidate last palette | |
| rendering_beware_fix16=0; | |
| pspRenderScreenFix (GPUPack.GFX.Screen, false,SUB_SCREEN_DEPTH,2); | |
| endRenderingFix(); | |
| } else { | |
| INC_DEBUG_COUNT(NO_TRANCE_COUNT); | |
| info(32,0,"notransp"); | |
| /* if(os9x_renderingpass==1) | |
| { | |
| debug_start=starty | 2000; | |
| debug_end=endy; | |
| memcpy(&debug_ClipDataFix,&IPPU.ClipFix [0],sizeof(ClipDataFix)); | |
| }*/ | |
| // 16bit and transparency but currently no transparency effects in | |
| // operation. | |
| if (!PPUPack.PPU.ForcedBlanking) { | |
| rendering_beware_fix16=0; | |
| initRenderingFix(); | |
| sceGuDrawBufferList(GU_PSM_5551,(void*)(0x40000000+512*272*2*2+256*240*2+2*256*256*2),256); | |
| sceGuTexMode(GU_PSM_T8,0,0,0); //8bit texture | |
| //setup back colors | |
| int col=(((IPPU.ScreenColors [0])&31)<<3)|(((IPPU.ScreenColors [0]>>5)&31)<<11)|(((IPPU.ScreenColors [0]>>10)&31)<<19); | |
| //sceGuClearColor((((IPPU.ScreenColors [0]>>0)&31)<<3)|(((IPPU.ScreenColors [0]>>5)&31)<<11)|(((IPPU.ScreenColors [0]>>10)&31)<<19)); | |
| /*if (IPPU.Clip [0].Count [5]) { | |
| sceGuClearColor(col); | |
| for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++) { | |
| if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]){ | |
| sceGuScissor(IPPU.Clip [0].Left [c][5],starty,(IPPU.Clip [0].Right [c][5])+1,endy+1); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| sceGuScissor(0,starty,256,endy+1); | |
| sceGuClearDepth(0); | |
| sceGuClear(GU_DEPTH_BUFFER_BIT);*/ | |
| if (IPPU.ClipFix [0].GroupCount [5]) { | |
| if(IPPU.MainColorCount) | |
| { | |
| //clipping && color change | |
| SET_DEBUG_COUNT(MAINCOLORCOUNT_CLIP,IPPU.MainColorCount); | |
| sceGuClearColor(col); | |
| for (uint32 g = 0; g < IPPU.ClipFix [0].GroupCount [5]; g++) { | |
| int startcl; | |
| int endcl; | |
| startcl = IPPU.ClipFix [0].Start [5][g]; | |
| endcl = IPPU.ClipFix [0].End [5][g]+1; | |
| int i=0; | |
| int startc=startcl; | |
| int endc=startcl; | |
| for(;i<IPPU.MainColorCount-1;i++) | |
| { | |
| if(IPPU.MainColorLines[i+1]<startcl) | |
| continue; | |
| if(IPPU.MainColorLines[i+1]>endcl) | |
| break; | |
| endc= IPPU.MainColorLines[i+1]; | |
| sceGuScissor(0,startc,256,endc); | |
| col=(((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19); | |
| if (rendering_beware_fix16) { | |
| if (fixedcol==IPPU.ScreenColors [0]) col^=1<<19; | |
| //if (IPPU.MainColorLog [i]==IPPU.ScreenColors [0]) col^=1<<19; | |
| } | |
| sceGuClearColor(col); | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],startc,(IPPU.ClipFix [0].Right [c][5][g])+1,endc); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| startc=endc; | |
| } | |
| if(endc<endcl) | |
| { | |
| col=(((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19); | |
| if (rendering_beware_fix16) { | |
| if (fixedcol==IPPU.ScreenColors [0]) col^=1<<19; | |
| } | |
| sceGuClearColor(col); | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],endc,(IPPU.ClipFix [0].Right [c][5][g])+1,endcl); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| else | |
| { | |
| //clipping | |
| sceGuClearColor(col); | |
| for (uint32 g = 0; g < IPPU.ClipFix [0].GroupCount [5]; g++) { | |
| int startcl; | |
| int endcl; | |
| startcl = IPPU.ClipFix [0].Start [5][g]; | |
| endcl = IPPU.ClipFix [0].End [5][g]+1; | |
| for (uint32 c = 0; c < IPPU.ClipFix [0].Count [5][g]; c++) { | |
| if (IPPU.ClipFix [0].Right [c][5][g] > IPPU.ClipFix [0].Left [c][5][g]){ | |
| //current rendering area | |
| sceGuScissor(IPPU.ClipFix [0].Left [c][5][g],startcl,(IPPU.ClipFix [0].Right [c][5][g])+1,endcl); | |
| sceGuClear(GU_COLOR_BUFFER_BIT); | |
| } | |
| } | |
| } | |
| } | |
| sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| sceGuClearDepth(0); | |
| sceGuClear(GU_DEPTH_BUFFER_BIT); | |
| } else { | |
| //sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| //sceGuClearDepth(0); | |
| //sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| if(IPPU.MainColorCount) | |
| { | |
| SET_DEBUG_COUNT(MAINCOLORCOUNT_NO_CLIP,IPPU.MainColorCount); | |
| int startc=starty; | |
| uint32 endc=starty;//endy+1;//IPPU.MainColorLines[1]; | |
| int i=0; | |
| for(;i<IPPU.MainColorCount-1;i++) | |
| { | |
| endc= IPPU.MainColorLines[i+1]; | |
| sceGuScissor(0,startc,256,endc); | |
| sceGuClearColor((((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19)); | |
| sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| startc=endc; | |
| } | |
| if(endc<endy+1) | |
| { | |
| sceGuScissor(0,endc,256,endy+1); | |
| sceGuClearColor((((IPPU.MainColorLog [i])&31)<<3)|(((IPPU.MainColorLog [i]>>5)&31)<<11)|(((IPPU.MainColorLog [i]>>10)&31)<<19)); | |
| sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| } | |
| sceGuScissor(0,starty,256,endy+1); | |
| sceGuClearDepth(0);//MAIN_SCREEN_DEPTH);//0??? seiken3 dialog | |
| } | |
| else | |
| { | |
| sceGuScissor(0,starty,256,endy/*-starty*/+1); | |
| sceGuClearColor(col); | |
| //clear Z buffer, TODO : check if Zbuffer clear is needed each time (ADD_OR_SUB(5) only since no colour window ?) | |
| sceGuClearDepth(0);//MAIN_SCREEN_DEPTH);//0??? seiken3 dialog | |
| sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); | |
| } | |
| } | |
| if (os9x_easy) { | |
| pspRenderScreenFix (GPUPack.GFX.Screen, true, SUB_SCREEN_DEPTH,0); | |
| pspRenderScreenFix (GPUPack.GFX.Screen, false, MAIN_SCREEN_DEPTH,0); | |
| } else { | |
| pspRenderScreenFix (GPUPack.GFX.Screen, false, SUB_SCREEN_DEPTH,0); | |
| } | |
| endRenderingFix(); | |
| } | |
| } | |
| IPPU.PreviousLine = IPPU.CurrentLine; | |
| } | |
| void pspDrawBackgroundOffsetFix (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) | |
| { | |
| CHECK_SOUND(); | |
| uint32 Tile; | |
| uint16 *SC0; | |
| uint16 *SC1; | |
| uint16 *SC2; | |
| uint16 *SC3; | |
| uint16 *BPS0; | |
| uint16 *BPS1; | |
| uint16 *BPS2; | |
| uint16 *BPS3; | |
| uint32 Width; | |
| if (last_palette!=GPUPack.BG.DirectColourMode){ | |
| //DirectColourMode has changed, so we have to reload palette | |
| last_palette=GPUPack.BG.DirectColourMode; | |
| clut = (u16*)NO_CPU_CACHE(&clut256[0]); | |
| memcpy(clut,GPUPack.GFX.ScreenColors,256*2); | |
| if (rendering_beware_fix16) | |
| for (int i=0;i<256;i++) { | |
| if (clut[i]==fixedcol16) clut[i]^=1<<10; //swap blue 1st bit | |
| } | |
| clut[0]|=0x8000; | |
| sceGuClutLoad(256/16,clut); | |
| } | |
| //bg is 32x30 tile but needs more in case of clipping or scroll changing every line | |
| int num_vert=((GPUPack.GFX.EndY-GPUPack.GFX.StartY+1)+2+pCurrentClipFix->GroupCount [bg])*(256/8+6); | |
| if (!(vertices[current_bitshift]=(struct Vertex*)sceGuGetMemory(num_vert*2* sizeof(struct Vertex)))){ | |
| debug_log("not enough vertices!"); | |
| return; | |
| } | |
| vertices_ptr[current_bitshift]=vertices[current_bitshift]; | |
| vertices_end[current_bitshift]=vertices_ptr[current_bitshift]+num_vert*2; | |
| /********************************************************/ | |
| /********************************************************/ | |
| int VOffsetOffset = BGMode == 4 ? 0 : 32; | |
| uint8 depths [2] = {Z1, Z2}; | |
| GPUPack.BG.StartPalette = 0; | |
| BPS0 = (uint16 *) &VRAM[PPUPack.PPU.BG[2].SCBase << 1]; | |
| if (PPUPack.PPU.BG[2].SCSize & 1) | |
| BPS1 = BPS0 + 1024; | |
| else | |
| BPS1 = BPS0; | |
| if (PPUPack.PPU.BG[2].SCSize & 2) | |
| BPS2 = BPS1 + 1024; | |
| else | |
| BPS2 = BPS0; | |
| if (PPUPack.PPU.BG[2].SCSize & 1) | |
| BPS3 = BPS2 + 1024; | |
| else | |
| BPS3 = BPS2; | |
| SC0 = (uint16 *) &VRAM[PPUPack.PPU.BG[bg].SCBase << 1]; | |
| if (PPUPack.PPU.BG[bg].SCSize & 1) | |
| SC1 = SC0 + 1024; | |
| else | |
| SC1 = SC0; | |
| if((SC1-(unsigned short*)VRAM)>0x10000) | |
| SC1-=0x10000; | |
| if (PPUPack.PPU.BG[bg].SCSize & 2) | |
| SC2 = SC1 + 1024; | |
| else | |
| SC2 = SC0; | |
| if((SC2-(unsigned short*)VRAM)>0x10000) | |
| SC2-=0x10000; | |
| if (PPUPack.PPU.BG[bg].SCSize & 1) | |
| SC3 = SC2 + 1024; | |
| else | |
| SC3 = SC2; | |
| if((SC3-(unsigned short*)VRAM)>0x10000) | |
| SC3-=0x10000; | |
| /*static const */int Lines = 1; | |
| int OffsetMask; | |
| int OffsetShift; | |
| int OffsetEnableMask = 1 << (bg + 13); | |
| if (GPUPack.BG.TileSize == 16) | |
| { | |
| OffsetMask = 0x3ff; | |
| OffsetShift = 4; | |
| } | |
| else | |
| { | |
| OffsetMask = 0x1ff; | |
| OffsetShift = 3; | |
| } | |
| uint32 Y = GPUPack.GFX.StartY; | |
| for (uint32 g = 0; g < pCurrentClipFix->GroupCount [bg]; g++) | |
| { | |
| Y=pCurrentClipFix->Start [bg][g]; | |
| for (; Y <= GPUPack.GFX.EndY && Y <= pCurrentClipFix->End [bg][g]; Y += Lines) | |
| { | |
| uint32 VOff = LineData [Y].BG[2].VOffset - 1; | |
| // uint32 VOff = LineData [Y].BG[2].VOffset; | |
| uint32 HOff = LineData [Y].BG[2].HOffset; | |
| int VirtAlign; | |
| int ScreenLine = VOff >> 3; | |
| int t1; | |
| int t2; | |
| uint16 *s0; | |
| uint16 *s1; | |
| uint16 *s2; | |
| if (ScreenLine & 0x20) | |
| s1 = BPS2, s2 = BPS3; | |
| else | |
| s1 = BPS0, s2 = BPS1; | |
| s1 += (ScreenLine & 0x1f) << 5; | |
| s2 += (ScreenLine & 0x1f) << 5; | |
| if(BGMode != 4) | |
| { | |
| if((ScreenLine & 0x1f) == 0x1f) | |
| { | |
| if(ScreenLine & 0x20) | |
| VOffsetOffset = BPS0 - BPS2 - 0x1f*32; | |
| else | |
| VOffsetOffset = BPS2 - BPS0 - 0x1f*32; | |
| } | |
| else | |
| { | |
| VOffsetOffset = 32; | |
| } | |
| } | |
| int clipcount = GPUPack.GFX.pCurrentClip->Count [bg]; | |
| if (!clipcount) | |
| clipcount = 1; | |
| for (int clip = 0; clip < clipcount; clip++) | |
| { | |
| uint32 Left; | |
| uint32 Right; | |
| if (!GPUPack.GFX.pCurrentClip->Count [bg]) | |
| { | |
| Left = 0; | |
| Right = 256; | |
| } | |
| else | |
| { | |
| Left = GPUPack.GFX.pCurrentClip->Left [clip][bg]; | |
| Right = GPUPack.GFX.pCurrentClip->Right [clip][bg]; | |
| if (Right <= Left) | |
| continue; | |
| } | |
| uint32 VOffset; | |
| uint32 HOffset; | |
| //added: | |
| uint32 LineHOffset=LineData [Y].BG[bg].HOffset; | |
| uint32 Offset; | |
| uint32 HPos; | |
| uint32 Quot; | |
| uint32 Count; | |
| uint16 *t; | |
| uint32 Quot2; | |
| uint32 VCellOffset; | |
| uint32 HCellOffset; | |
| uint16 *b1; | |
| uint16 *b2; | |
| uint32 TotalCount = 0; | |
| uint32 MaxCount = 8; | |
| int Xt = Left;// * 1 + Y * GPUPack.GFX.PPL; | |
| int Yt =Y; | |
| bool8 left_hand_edge = (Left == 0); | |
| Width = Right - Left; | |
| if (Left & 7) | |
| MaxCount = 8 - (Left & 7); | |
| while (Left < Right) | |
| { | |
| if (left_hand_edge) | |
| { | |
| // The SNES offset-per-tile background mode has a | |
| // hardware limitation that the offsets cannot be set | |
| // for the tile at the left-hand edge of the screen. | |
| VOffset = LineData [Y].BG[bg].VOffset; | |
| //MKendora; use temp var to reduce memory accesses | |
| //HOffset = LineData [Y].BG[bg].HOffset; | |
| HOffset = LineHOffset; | |
| //End MK | |
| left_hand_edge = FALSE; | |
| } | |
| else | |
| { | |
| // All subsequent offset tile data is shifted left by one, | |
| // hence the - 1 below. | |
| Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3; | |
| if (Quot2 > 31) | |
| s0 = s2 + (Quot2 & 0x1f); | |
| else | |
| s0 = s1 + Quot2; | |
| HCellOffset = READ_2BYTES (s0); | |
| if (BGMode == 4) | |
| { | |
| VOffset = LineData [Y].BG[bg].VOffset; | |
| //MKendora another mem access hack | |
| //HOffset = LineData [Y].BG[bg].HOffset; | |
| HOffset=LineHOffset; | |
| //end MK | |
| if ((HCellOffset & OffsetEnableMask)) | |
| { | |
| if (HCellOffset & 0x8000) | |
| VOffset = HCellOffset + 1; | |
| else | |
| HOffset = HCellOffset; | |
| } | |
| } | |
| else | |
| { | |
| VCellOffset = READ_2BYTES (s0 + VOffsetOffset); | |
| if ((VCellOffset & OffsetEnableMask)) | |
| VOffset = VCellOffset + 1; | |
| else | |
| VOffset = LineData [Y].BG[bg].VOffset; | |
| //MKendora Strike Gunner fix | |
| if ((HCellOffset & OffsetEnableMask)) | |
| { | |
| //HOffset= HCellOffset; | |
| HOffset = (HCellOffset & ~7)|(LineHOffset&7); | |
| //HOffset |= LineData [Y].BG[bg].HOffset&7; | |
| } | |
| else | |
| HOffset=LineHOffset; | |
| //HOffset = LineData [Y].BG[bg].HOffset - | |
| //Settings.StrikeGunnerOffsetHack; | |
| //HOffset &= (~7); | |
| //end MK | |
| } | |
| } | |
| VirtAlign = ((Y + VOffset) & 7)/* << 3*/; | |
| ScreenLine = (VOffset + Y) >> OffsetShift; | |
| //for (Lines = 1; Lines < 8 - VirtAlign; Lines++) | |
| // if ((LineData [Y].BG[bg].VOffset != LineData [Y + Lines].BG[bg].VOffset) || (LineData [Y].BG[bg].HOffset != LineData [Y + Lines].BG[bg].HOffset)) break; | |
| //if (Y + Lines > GPUPack.GFX.EndY) Lines = GPUPack.GFX.EndY + 1 - Y; | |
| if (((VOffset + Y) & 15) > 7) | |
| { | |
| t1 = 16; | |
| t2 = 0; | |
| } | |
| else | |
| { | |
| t1 = 0; | |
| t2 = 16; | |
| } | |
| if (ScreenLine & 0x20) | |
| b1 = SC2, b2 = SC3; | |
| else | |
| b1 = SC0, b2 = SC1; | |
| b1 += (ScreenLine & 0x1f) << 5; | |
| b2 += (ScreenLine & 0x1f) << 5; | |
| HPos = (HOffset + Left) & OffsetMask; | |
| Quot = HPos >> 3; | |
| if (GPUPack.BG.TileSize == 8) | |
| { | |
| if (Quot > 31) | |
| t = b2 + (Quot & 0x1f); | |
| else | |
| t = b1 + Quot; | |
| } | |
| else | |
| { | |
| if (Quot > 63) | |
| t = b2 + ((Quot >> 1) & 0x1f); | |
| else | |
| t = b1 + (Quot >> 1); | |
| } | |
| if (MaxCount + TotalCount > Width) | |
| MaxCount = Width - TotalCount; | |
| Offset = HPos & 7; | |
| //Count =1; | |
| Count = 8 - Offset; | |
| if (Count > MaxCount) | |
| Count = MaxCount; | |
| Xt -= Offset; | |
| Tile = READ_2BYTES(t); | |
| GPUPack.GFX.Z1 = GPUPack.GFX.Z2 = depths [(Tile & 0x2000) >> 13]; | |
| short realZ2=(short)GPUPack.GFX.Z2; | |
| if (GPUPack.BG.TileSize == 8) | |
| pspDrawClippedTile16_order (Tile, Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| //(*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines); | |
| else | |
| { | |
| if (!(Tile & (V_FLIP | H_FLIP))) | |
| { | |
| // Normal, unflipped | |
| pspDrawClippedTile16_order(Tile + t1 + (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| //(*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, Offset, Count, VirtAlign, Lines); | |
| } else if (Tile & H_FLIP) | |
| { | |
| if (Tile & V_FLIP) | |
| { | |
| // H & V flip | |
| pspDrawClippedTile16_order (Tile + t2 + 1 - (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| //(*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), s, Offset, Count, VirtAlign, Lines); | |
| } else | |
| { | |
| // H flip only | |
| pspDrawClippedTile16_order (Tile + t1 + 1 - (Quot & 1),Xt,Yt, Offset, Count, VirtAlign, Lines,realZ2); | |
| //(*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), s, Offset, Count, VirtAlign, Lines); | |
| } | |
| } else | |
| { | |
| // V flip only | |
| pspDrawClippedTile16_order (Tile + t2 + (Quot & 1), Xt,Yt,Offset, Count, VirtAlign, Lines,realZ2); | |
| } | |
| } | |
| Left += Count; | |
| TotalCount += Count; | |
| Xt += (Offset + Count) * 1; | |
| //Xt+=8; | |
| MaxCount = 8; | |
| } | |
| } | |
| } | |
| } | |
| //render | |
| if (vertices_ptr[current_bitshift]-vertices[current_bitshift]) { | |
| sceGuTexImage(0,512,512,512,tile_texture[current_bitshift]); | |
| sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,(vertices_ptr[current_bitshift]-vertices[current_bitshift]),0,vertices[current_bitshift]); | |
| } | |
| } |