Merge pull request #389 from notaz/master
[pcsx_rearmed.git] / plugins / gpu_unai / gpu_raster_image.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 #ifndef USE_GPULIB
23 void gpuLoadImage(PtrUnion packet)
24 {
25         u16 x0, y0, w0, h0;
26         x0 = packet.U2[2] & 1023;
27         y0 = packet.U2[3] & 511;
28         w0 = packet.U2[4];
29         h0 = packet.U2[5];
30
31         if ((y0 + h0) > FRAME_HEIGHT)
32         {
33                 h0 = FRAME_HEIGHT - y0;
34         }
35
36         gpu_unai.dma.FrameToWrite = ((w0)&&(h0));
37
38         gpu_unai.dma.px = 0;
39         gpu_unai.dma.py = 0;
40         gpu_unai.dma.x_end = w0;
41         gpu_unai.dma.y_end = h0;
42         gpu_unai.dma.pvram = &((u16*)gpu_unai.vram)[x0+(y0*1024)];
43
44         gpu_unai.GPU_GP1 |= 0x08000000;
45 }
46 #endif // !USE_GPULIB
47
48 ///////////////////////////////////////////////////////////////////////////////
49 #ifndef USE_GPULIB
50 void gpuStoreImage(PtrUnion packet)
51 {
52         u16 x0, y0, w0, h0;
53         x0 = packet.U2[2] & 1023;
54         y0 = packet.U2[3] & 511;
55         w0 = packet.U2[4];
56         h0 = packet.U2[5];
57
58         if ((y0 + h0) > FRAME_HEIGHT)
59         {
60                 h0 = FRAME_HEIGHT - y0;
61         }
62         gpu_unai.dma.FrameToRead = ((w0)&&(h0));
63
64         gpu_unai.dma.px = 0;
65         gpu_unai.dma.py = 0;
66         gpu_unai.dma.x_end = w0;
67         gpu_unai.dma.y_end = h0;
68         gpu_unai.dma.pvram = &((u16*)gpu_unai.vram)[x0+(y0*1024)];
69         
70         gpu_unai.GPU_GP1 |= 0x08000000;
71 }
72 #endif // !USE_GPULIB
73
74 void gpuMoveImage(PtrUnion packet)
75 {
76         u32 x0, y0, x1, y1;
77         s32 w0, h0;
78         x0 = packet.U2[2] & 1023;
79         y0 = packet.U2[3] & 511;
80         x1 = packet.U2[4] & 1023;
81         y1 = packet.U2[5] & 511;
82         w0 = packet.U2[6];
83         h0 = packet.U2[7];
84
85         if( (x0==x1) && (y0==y1) ) return;
86         if ((w0<=0) || (h0<=0)) return;
87         
88         #ifdef ENABLE_GPU_LOG_SUPPORT
89                 fprintf(stdout,"gpuMoveImage(x0=%u,y0=%u,x1=%u,y1=%u,w0=%d,h0=%d)\n",x0,y0,x1,y1,w0,h0);
90         #endif
91         
92         if (((y0+h0)>512)||((x0+w0)>1024)||((y1+h0)>512)||((x1+w0)>1024))
93         {
94                 u16 *psxVuw=gpu_unai.vram;
95                 s32 i,j;
96             for(j=0;j<h0;j++)
97                  for(i=0;i<w0;i++)
98                   psxVuw [(1024*((y1+j)&511))+((x1+i)&0x3ff)]=
99                    psxVuw[(1024*((y0+j)&511))+((x0+i)&0x3ff)];
100         }
101         else if ((x0&1)||(x1&1))
102         {
103                 u16 *lpDst, *lpSrc;
104                 lpDst = lpSrc = (u16*)gpu_unai.vram;
105                 lpSrc += FRAME_OFFSET(x0, y0);
106                 lpDst += FRAME_OFFSET(x1, y1);
107                 x1 = FRAME_WIDTH - w0;
108                 do {
109                         x0=w0;
110                         do { *lpDst++ = *lpSrc++; } while (--x0);
111                         lpDst += x1;
112                         lpSrc += x1;
113                 } while (--h0);
114         }
115         else
116         {
117                 u32 *lpDst, *lpSrc;
118                 lpDst = lpSrc = (u32*)(void*)gpu_unai.vram;
119                 lpSrc += ((FRAME_OFFSET(x0, y0))>>1);
120                 lpDst += ((FRAME_OFFSET(x1, y1))>>1);
121                 if (w0&1)
122                 {
123                         x1 = (FRAME_WIDTH - w0 +1)>>1;
124                         w0>>=1;
125                         if (!w0) {
126                                 do {
127                                         *((u16*)lpDst) = *((u16*)lpSrc);
128                                         lpDst += x1;
129                                         lpSrc += x1;
130                                 } while (--h0);
131                         } else
132                         do {
133                                 x0=w0;
134                                 do { *lpDst++ = *lpSrc++; } while (--x0);
135                                 *((u16*)lpDst) = *((u16*)lpSrc);
136                                 lpDst += x1;
137                                 lpSrc += x1;
138                         } while (--h0);
139                 }
140                 else
141                 {
142                         x1 = (FRAME_WIDTH - w0)>>1;
143                         w0>>=1;
144                         do {
145                                 x0=w0;
146                                 do { *lpDst++ = *lpSrc++; } while (--x0);
147                                 lpDst += x1;
148                                 lpSrc += x1;
149                         } while (--h0);
150                 }
151         }
152 }
153
154 void gpuClearImage(PtrUnion packet)
155 {
156         s32   x0, y0, w0, h0;
157         x0 = packet.S2[2];
158         y0 = packet.S2[3];
159         w0 = packet.S2[4] & 0x3ff;
160         h0 = packet.S2[5] & 0x3ff;
161          
162         w0 += x0;
163         if (x0 < 0) x0 = 0;
164         if (w0 > FRAME_WIDTH) w0 = FRAME_WIDTH;
165         w0 -= x0;
166         if (w0 <= 0) return;
167         h0 += y0;
168         if (y0 < 0) y0 = 0;
169         if (h0 > FRAME_HEIGHT) h0 = FRAME_HEIGHT;
170         h0 -= y0;
171         if (h0 <= 0) return;
172
173         #ifdef ENABLE_GPU_LOG_SUPPORT
174                 fprintf(stdout,"gpuClearImage(x0=%d,y0=%d,w0=%d,h0=%d)\n",x0,y0,w0,h0);
175         #endif
176         
177         if (x0&1)
178         {
179                 u16* pixel = (u16*)gpu_unai.vram + FRAME_OFFSET(x0, y0);
180                 u16 rgb = GPU_RGB16(packet.U4[0]);
181                 y0 = FRAME_WIDTH - w0;
182                 do {
183                         x0=w0;
184                         do { *pixel++ = rgb; } while (--x0);
185                         pixel += y0;
186                 } while (--h0);
187         }
188         else
189         {
190                 u32* pixel = (u32*)gpu_unai.vram + ((FRAME_OFFSET(x0, y0))>>1);
191                 u32 rgb = GPU_RGB16(packet.U4[0]);
192                 rgb |= (rgb<<16);
193                 if (w0&1)
194                 {
195                         y0 = (FRAME_WIDTH - w0 +1)>>1;
196                         w0>>=1;
197                         do {
198                                 x0=w0;
199                                 do { *pixel++ = rgb; } while (--x0);
200                                 *((u16*)pixel) = (u16)rgb;
201                                 pixel += y0;
202                         } while (--h0);
203                 }
204                 else
205                 {
206                         y0 = (FRAME_WIDTH - w0)>>1;
207                         w0>>=1;
208                         do {
209                                 x0=w0;
210                                 do { *pixel++ = rgb; } while (--x0);
211                                 pixel += y0;
212                         } while (--h0);
213                 }
214         }
215 }