frontend: export fps stats to plugins
[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 #ifdef __arm__
88 #include "gpu_arm.h"
89
90 void gpuDrawS16(void)
91 {
92         s32 x0, y0;
93         s32 u0, v0;
94         s32 xmin, xmax;
95         s32 ymin, ymax;
96         u32 h = 16;
97
98         x0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[2]) + DrawingOffset[0];
99         y0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[3]) + DrawingOffset[1];
100
101         xmin = DrawingArea[0];  xmax = DrawingArea[2];
102         ymin = DrawingArea[1];  ymax = DrawingArea[3];
103         u0 = PacketBuffer.U1[8];
104         v0 = PacketBuffer.U1[9];
105
106         if (x0 > xmax - 16 || x0 < xmin ||
107             ((u0 | v0) & 15) || !(TextureWindow[2] & TextureWindow[3] & 8)) {
108                 // send corner cases to general handler
109                 PacketBuffer.U4[3] = 0x00100010;
110                 gpuDrawS(gpuSpriteSpanFn<0x20>);
111                 return;
112         }
113
114         if (y0 >= ymax || y0 <= ymin - 16)
115                 return;
116         if (y0 < ymin) {
117                 h -= ymin - y0;
118                 v0 += ymin - y0;
119                 y0 = ymin;
120         }
121         else if (ymax - y0 < 16)
122                 h = ymax - y0;
123
124         draw_spr16_full(&GPU_FrameBuffer[FRAME_OFFSET(x0, y0)], &TBA[FRAME_OFFSET(u0/4, v0)], CBA, h);
125 }
126 #endif // __arm__
127
128 ///////////////////////////////////////////////////////////////////////////////
129 void gpuDrawT(const PT gpuTileSpanDriver)
130 {
131         s32 x0, y0;
132         s32 x1, y1;
133
134         x1 = x0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[2]) + DrawingOffset[0];
135         y1 = y0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[3]) + DrawingOffset[1];
136         x1+= PacketBuffer.S2[4];
137         y1+= PacketBuffer.S2[5];
138
139         {
140                 s32 xmin, xmax;
141                 s32 ymin, ymax;
142                 xmin = DrawingArea[0];  xmax = DrawingArea[2];
143                 ymin = DrawingArea[1];  ymax = DrawingArea[3];
144
145                 {
146                         int rx0 = Max2(xmin,Min2(x0,x1));
147                         int ry0 = Max2(ymin,Min2(y0,y1));
148                         int rx1 = Min2(xmax,Max2(x0,x1));
149                         int ry1 = Min2(ymax,Max2(y0,y1));
150                         if(rx0>=rx1 || ry0>=ry1) return;
151                 }
152
153                 if (y0 < ymin) y0 = ymin;
154                 if (y1 > ymax) y1 = ymax;
155                 if (y1 <= y0) return;
156
157                 if (x0 < xmin) x0 = xmin;
158                 if (x1 > xmax) x1 = xmax;
159                 x1 -= x0;
160                 if (x1 <= 0) return;
161         }
162         
163         {
164                 u16 *Pixel = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, y0)];
165                 const u16 Data = GPU_RGB16(PacketBuffer.U4[0]);
166                 const int li=linesInterlace;
167
168                 for (; y0<y1; ++y0)
169                 {
170                         if( 0 == (y0&li) ) gpuTileSpanDriver(Pixel,x1,Data);
171                         Pixel += FRAME_WIDTH;
172                 }
173         }
174 }