gpu_unai: avoid useless blits
[pcsx_rearmed.git] / plugins / gpu_unai / gpu_raster_sprite.h
1 /***************************************************************************
2 *   Copyright (C) 2010 PCSX4ALL Team                                      *
3 *   Copyright (C) 2010 Unai                                               *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 *   This program is distributed in the hope that it will be useful,       *
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13 *   GNU General Public License for more details.                          *
14 *                                                                         *
15 *   You should have received a copy of the GNU General Public License     *
16 *   along with this program; if not, write to the                         *
17 *   Free Software Foundation, Inc.,                                       *
18 *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
19 ***************************************************************************/
20
21 ///////////////////////////////////////////////////////////////////////////////
22 //  GPU internal sprite drawing functions
23
24 ///////////////////////////////////////////////////////////////////////////////
25 void gpuDrawS(const PS gpuSpriteSpanDriver)
26 {
27         s32 x0, x1;
28         s32 y0, y1;
29         s32 u0;
30         s32 v0;
31
32         x1 = x0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[2]) + DrawingOffset[0];
33         y1 = y0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[3]) + DrawingOffset[1];
34         x1+= PacketBuffer.S2[6];
35         y1+= PacketBuffer.S2[7];
36
37         {
38                 s32 xmin, xmax;
39                 s32 ymin, ymax;
40                 xmin = DrawingArea[0];  xmax = DrawingArea[2];
41                 ymin = DrawingArea[1];  ymax = DrawingArea[3];
42
43                 {
44                         int rx0 = Max2(xmin,Min2(x0,x1));
45                         int ry0 = Max2(ymin,Min2(y0,y1));
46                         int rx1 = Min2(xmax,Max2(x0,x1));
47                         int ry1 = Min2(ymax,Max2(y0,y1));
48                         if( rx0>=rx1 || ry0>=ry1) return;
49                 }
50
51                 u0 = PacketBuffer.U1[8];
52                 v0 = PacketBuffer.U1[9];
53
54                 r4 = s32(PacketBuffer.U1[0]);
55                 g4 = s32(PacketBuffer.U1[1]);
56                 b4 = s32(PacketBuffer.U1[2]);
57
58                 {
59                         s32 temp;
60                         temp = ymin - y0;
61                         if (temp > 0) { y0 = ymin; v0 += temp; }
62                         if (y1 > ymax) y1 = ymax;
63                         if (y1 <= y0) return;
64                         
65                         temp = xmin - x0;
66                         if (temp > 0) { x0 = xmin; u0 += temp; }
67                         if (x1 > xmax) x1 = xmax;
68                         x1 -= x0;
69                         if (x1 <= 0) return;
70                 }
71         }
72
73         {
74                 u16 *Pixel = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, y0)];
75                 const int li=linesInterlace;
76                 const u32 masku=TextureWindow[2];
77                 const u32 maskv=TextureWindow[3];
78
79                 for (;y0<y1;++y0) {
80                         if( 0 == (y0&li) ) gpuSpriteSpanDriver(Pixel,x1,FRAME_OFFSET(u0,v0),masku);
81                         Pixel += FRAME_WIDTH;
82                         v0 = (v0+1)&maskv;
83                 }
84         }
85 }
86
87 ///////////////////////////////////////////////////////////////////////////////
88 void gpuDrawT(const PT gpuTileSpanDriver)
89 {
90         s32 x0, y0;
91         s32 x1, y1;
92
93         x1 = x0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[2]) + DrawingOffset[0];
94         y1 = y0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[3]) + DrawingOffset[1];
95         x1+= PacketBuffer.S2[4];
96         y1+= PacketBuffer.S2[5];
97
98         {
99                 s32 xmin, xmax;
100                 s32 ymin, ymax;
101                 xmin = DrawingArea[0];  xmax = DrawingArea[2];
102                 ymin = DrawingArea[1];  ymax = DrawingArea[3];
103
104                 {
105                         int rx0 = Max2(xmin,Min2(x0,x1));
106                         int ry0 = Max2(ymin,Min2(y0,y1));
107                         int rx1 = Min2(xmax,Max2(x0,x1));
108                         int ry1 = Min2(ymax,Max2(y0,y1));
109                         if(rx0>=rx1 || ry0>=ry1) return;
110                 }
111
112                 if (y0 < ymin) y0 = ymin;
113                 if (y1 > ymax) y1 = ymax;
114                 if (y1 <= y0) return;
115
116                 if (x0 < xmin) x0 = xmin;
117                 if (x1 > xmax) x1 = xmax;
118                 x1 -= x0;
119                 if (x1 <= 0) return;
120         }
121         
122         {
123                 u16 *Pixel = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, y0)];
124                 const u16 Data = GPU_RGB16(PacketBuffer.U4[0]);
125                 const int li=linesInterlace;
126
127                 for (; y0<y1; ++y0)
128                 {
129                         if( 0 == (y0&li) ) gpuTileSpanDriver(Pixel,x1,Data);
130                         Pixel += FRAME_WIDTH;
131                 }
132         }
133 }