86aad47b |
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 line drawing functions |
23 | |
24 | #define GPU_DIGITS 16 |
25 | #define GPU_DIGITSC (GPU_DIGITS+3) |
26 | |
27 | INLINE long GPU_DIV(long rs, long rt) |
28 | { |
29 | return rt ? (rs / rt) : (0); |
30 | } |
31 | |
32 | /////////////////////////////////////////////////////////////////////////////// |
33 | void gpuDrawLF(const PD gpuPixelDriver) |
34 | { |
35 | s32 temp; |
36 | s32 xmin, xmax; |
37 | s32 ymin, ymax; |
38 | s32 x0, x1, dx; |
39 | s32 y0, y1, dy; |
40 | |
41 | x0 = PacketBuffer.S2[2] + DrawingOffset[0]; GPU_TESTRANGE(x0); |
42 | y0 = PacketBuffer.S2[3] + DrawingOffset[1]; GPU_TESTRANGE(y0); |
43 | x1 = PacketBuffer.S2[4] + DrawingOffset[0]; GPU_TESTRANGE(x1); |
44 | y1 = PacketBuffer.S2[5] + DrawingOffset[1]; GPU_TESTRANGE(y1); |
45 | |
46 | xmin = DrawingArea[0]; xmax = DrawingArea[2]; |
47 | ymin = DrawingArea[1]; ymax = DrawingArea[3]; |
48 | const u16 pixeldata = GPU_RGB16(PacketBuffer.U4[0]); |
49 | |
50 | dy = (y1 - y0); |
51 | if (dy < 0) dy = -dy; |
52 | dx = (x1 - x0); |
53 | if (dx < 0) dx = -dx; |
54 | if (dx > dy) { |
55 | if (x0 > x1) { |
56 | GPU_SWAP(x0, x1, temp); |
57 | GPU_SWAP(y0, y1, temp); |
58 | } |
59 | y1 = GPU_DIV((y1 - y0) << GPU_DIGITS, dx); |
60 | y0 <<= GPU_DIGITS; |
61 | temp = xmin - x0; |
62 | if (temp > 0) { |
63 | x0 = xmin; |
64 | y0 += (y1 * temp); |
65 | } |
66 | if (x1 > xmax) x1 = xmax; |
67 | x1 -= x0; |
68 | if (x1 < 0) x1 = 0; |
69 | |
70 | const int li=linesInterlace; |
71 | for (; x1; x1--) { |
72 | temp = y0 >> GPU_DIGITS; |
73 | if( 0 == (temp&li) ) { |
74 | if ((u32) (temp - ymin) < (u32) (ymax - ymin)) { |
75 | gpuPixelDriver(&((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, temp)],pixeldata); |
76 | } |
77 | } |
78 | x0++; |
79 | y0 += y1; |
80 | } |
81 | } else if (dy) { |
82 | if (y0 > y1) { |
83 | GPU_SWAP(x0, x1, temp); |
84 | GPU_SWAP(y0, y1, temp); |
85 | } |
86 | x1 = GPU_DIV((x1 - x0) << GPU_DIGITS, dy); |
87 | x0 <<= GPU_DIGITS; |
88 | temp = ymin - y0; |
89 | if (temp > 0) { |
90 | y0 = ymin; |
91 | x0 += (x1 * temp); |
92 | } |
93 | if (y1 > ymax) y1 = ymax; |
94 | y1 -= y0; |
95 | if (y1 < 0) y1 = 0; |
96 | |
97 | const int li=linesInterlace; |
98 | for (; y1; y1--) { |
99 | if( 0 == (y0&li) ) { |
100 | temp = x0 >> GPU_DIGITS; |
101 | if ((u32) (temp - xmin) < (u32) (xmax - xmin)) { |
102 | gpuPixelDriver(&((u16*)GPU_FrameBuffer)[FRAME_OFFSET(temp, y0)],pixeldata); |
103 | } |
104 | } |
105 | y0++; |
106 | x0 += x1; |
107 | } |
108 | |
109 | } else { |
110 | if( 0 == (y0&linesInterlace) ) { |
111 | if ((u32) (x0 - xmin) < (u32) (xmax - xmin)) { |
112 | if ((u32) (y0 - ymin) < (u32) (ymax - ymin)) { |
113 | gpuPixelDriver(&((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, y0)],pixeldata); |
114 | } |
115 | } |
116 | } |
117 | } |
118 | } |
119 | |
120 | /*---------------------------------------------------------------------- |
121 | GF |
122 | ----------------------------------------------------------------------*/ |
123 | |
124 | /////////////////////////////////////////////////////////////////////////////// |
125 | void gpuDrawLG(const PD gpuPixelDriver) |
126 | { |
127 | s32 temp; |
128 | s32 xmin, xmax; |
129 | s32 ymin, ymax; |
130 | s32 x0, x1, dx; |
131 | s32 y0, y1, dy; |
132 | s32 r0, r1; |
133 | s32 g0, g1; |
134 | s32 b0, b1; |
135 | |
136 | x0 = PacketBuffer.S2[2] + DrawingOffset[0]; GPU_TESTRANGE(x0); |
137 | y0 = PacketBuffer.S2[3] + DrawingOffset[1]; GPU_TESTRANGE(y0); |
138 | x1 = PacketBuffer.S2[6] + DrawingOffset[0]; GPU_TESTRANGE(x1); |
139 | y1 = PacketBuffer.S2[7] + DrawingOffset[1]; GPU_TESTRANGE(y1); |
140 | |
141 | r0 = PacketBuffer.U1[0]; g0 = PacketBuffer.U1[1]; b0 = PacketBuffer.U1[2]; |
142 | r1 = PacketBuffer.U1[8]; g1 = PacketBuffer.U1[9]; b1 = PacketBuffer.U1[10]; |
143 | |
144 | xmin = DrawingArea[0]; xmax = DrawingArea[2]; |
145 | ymin = DrawingArea[1]; ymax = DrawingArea[3]; |
146 | |
147 | dy = (y1 - y0); |
148 | if (dy < 0) |
149 | dy = -dy; |
150 | dx = (x1 - x0); |
151 | if (dx < 0) |
152 | dx = -dx; |
153 | if (dx > dy) { |
154 | if (x0 > x1) { |
155 | GPU_SWAP(x0, x1, temp); |
156 | GPU_SWAP(y0, y1, temp); |
157 | GPU_SWAP(r0, r1, temp); |
158 | GPU_SWAP(g0, g1, temp); |
159 | GPU_SWAP(b0, b1, temp); |
160 | } |
161 | y1 = GPU_DIV((y1 - y0) << GPU_DIGITS, dx); |
162 | r1 = GPU_DIV((r1 - r0) << GPU_DIGITS, dx); |
163 | g1 = GPU_DIV((g1 - g0) << GPU_DIGITS, dx); |
164 | b1 = GPU_DIV((b1 - b0) << GPU_DIGITS, dx); |
165 | y0 <<= GPU_DIGITS; |
166 | r0 <<= GPU_DIGITS; |
167 | g0 <<= GPU_DIGITS; |
168 | b0 <<= GPU_DIGITS; |
169 | temp = xmin - x0; |
170 | if (temp > 0) { |
171 | x0 = xmin; |
172 | y0 += (y1 * temp); |
173 | r0 += (r1 * temp); |
174 | g0 += (g1 * temp); |
175 | b0 += (b1 * temp); |
176 | } |
177 | if (x1 > xmax) x1 = xmax; |
178 | x1 -= x0; |
179 | if (x1 < 0) x1 = 0; |
180 | |
181 | const int li=linesInterlace; |
182 | for (; x1; x1--) { |
183 | temp = y0 >> GPU_DIGITS; |
184 | if( 0 == (temp&li) ) { |
185 | if ((u32) (temp - ymin) < (u32) (ymax - ymin)) { |
186 | gpuPixelDriver ( |
187 | &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, temp)], |
188 | (((b0>>GPU_DIGITSC)&0x1F)<<10) | (((g0>>GPU_DIGITSC)&0x1F)<< 5) | ((r0>>GPU_DIGITSC)&0x1F) |
189 | ); |
190 | } |
191 | } |
192 | x0++; |
193 | y0 += y1; |
194 | r0 += r1; |
195 | g0 += g1; |
196 | b0 += b1; |
197 | } |
198 | } else if (dy) { |
199 | if (y0 > y1) { |
200 | GPU_SWAP(x0, x1, temp); |
201 | GPU_SWAP(y0, y1, temp); |
202 | GPU_SWAP(r0, r1, temp); |
203 | GPU_SWAP(g0, g1, temp); |
204 | GPU_SWAP(b0, b1, temp); |
205 | } |
206 | x1 = GPU_DIV((x1 - x0) << GPU_DIGITS, dy); |
207 | r1 = GPU_DIV((r1 - r0) << GPU_DIGITS, dy); |
208 | g1 = GPU_DIV((g1 - g0) << GPU_DIGITS, dy); |
209 | b1 = GPU_DIV((b1 - b0) << GPU_DIGITS, dy); |
210 | x0 <<= GPU_DIGITS; |
211 | r0 <<= GPU_DIGITS; |
212 | g0 <<= GPU_DIGITS; |
213 | b0 <<= GPU_DIGITS; |
214 | temp = ymin - y0; |
215 | if (temp > 0) { |
216 | y0 = ymin; |
217 | x0 += (x1 * temp); |
218 | r0 += (r1 * temp); |
219 | g0 += (g1 * temp); |
220 | b0 += (b1 * temp); |
221 | } |
222 | if (y1 > ymax) y1 = ymax; |
223 | y1 -= y0; |
224 | if (y1 < 0) y1 = 0; |
225 | |
226 | const int li=linesInterlace; |
227 | for (; y1; y1--) { |
228 | if( 0 == (y0&li) ) { |
229 | temp = x0 >> GPU_DIGITS; |
230 | if ((u32) (temp - xmin) < (u32) (xmax - xmin)) { |
231 | gpuPixelDriver ( |
232 | &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(temp, y0)], |
233 | (((b0>>GPU_DIGITSC)&0x1F)<<10) | (((g0>>GPU_DIGITSC)&0x1F)<< 5) | ((r0>>GPU_DIGITSC)&0x1F) |
234 | ); |
235 | } |
236 | } |
237 | y0++; |
238 | x0 += x1; |
239 | r0 += r1; |
240 | g0 += g1; |
241 | b0 += b1; |
242 | } |
243 | } else { |
244 | if( 0 == (y0&linesInterlace) ) { |
245 | if ((u32) (x0 - xmin) < (u32) (xmax - xmin)) { |
246 | if ((u32) (y0 - ymin) < (u32) (ymax - ymin)) { |
247 | gpuPixelDriver ( |
248 | &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0, y0)], |
249 | (((b0>>GPU_DIGITSC)&0x1F)<<10) | (((g0>>GPU_DIGITSC)&0x1F)<< 5) | ((r0>>GPU_DIGITSC)&0x1F) |
250 | ); |
251 | } |
252 | } |
253 | } |
254 | } |
255 | } |