1 /*  Copyright 2003-2006 Guillaume Duhamel
2     Copyright 2004-2007 Theo Berkau
3 
4     This file is part of Yabause.
5 
6     Yabause is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     Yabause is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with Yabause; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 */
20 
21 #ifndef VIDSHARED_H
22 #define VIDSHARED_H
23 
24 #include "core.h"
25 #include "vdp2.h"
26 #include "debug.h"
27 
28 typedef struct
29 {
30    short LineScrollValH;
31    short LineScrollValV;
32    int CoordinateIncH;
33 } vdp2Lineinfo;
34 
35 typedef struct
36 {
37    float Xst;
38    float Yst;
39    float Zst;
40    float deltaXst;
41    float deltaYst;
42    float deltaX;
43    float deltaY;
44    float A;
45    float B;
46    float C;
47    float D;
48    float E;
49    float F;
50    float Px;
51    float Py;
52    float Pz;
53    float Cx;
54    float Cy;
55    float Cz;
56    float Mx;
57    float My;
58    float kx;
59    float ky;
60    float KAst;
61    float deltaKAst;
62    float deltaKAx;
63    u32 coeftbladdr;
64    int coefenab;
65    int coefmode;
66    int coefdatasize;
67    float Xp;
68    float Yp;
69    float dX;
70    float dY;
71    int screenover;
72    int msb;
73 
74    void FASTCALL (* PlaneAddr)(void *, int, Vdp2*);
75    u32 charaddr;
76    int planew, planew_bits, planeh, planeh_bits;
77    int MaxH,MaxV;
78 
79    float Xsp;
80    float Ysp;
81    float dx;
82    float dy;
83    float lkx;
84    float lky;
85    int KtablV;
86    int ShiftPaneX;
87    int ShiftPaneY;
88    int MskH;
89    int MskV;
90    u32 lineaddr;
91    u32 PlaneAddrv[16];
92 
93 } vdp2rotationparameter_struct;
94 
95 typedef struct
96 {
97    int  WinShowLine;
98     int WinHStart;
99     int WinHEnd;
100 } vdp2WindowInfo;
101 
102 typedef u32 FASTCALL (*Vdp2ColorRamGetColor_func)(void *, u32 , int);
103 typedef vdp2rotationparameter_struct * FASTCALL (*Vdp2GetRParam_func)(void *, int, int);
104 
105 typedef struct
106 {
107    float vertices[8];
108    int cellw, cellh;
109    int flipfunction;
110    int priority;
111    int dst;
112    int uclipmode;
113    int blendmode;
114    s32 cor;
115    s32 cog;
116    s32 cob;
117    int linescreen;
118 
119    /* The above fields MUST NOT BE CHANGED (including inserting new fields)
120     * unless YglSprite is also updated in ygl.h */
121 
122    int cellw_bits, cellh_bits;
123    int mapwh;
124    int planew, planew_bits, planeh, planeh_bits;
125    int pagewh, pagewh_bits;
126    int patternwh, patternwh_bits;
127    int patterndatasize, patterndatasize_bits;
128    int specialfunction;
129    int specialcolorfunction;
130    int specialcolormode;
131    int specialcode;
132    u32 addr, charaddr, paladdr;
133    int colornumber;
134    int isbitmap;
135    u16 supplementdata;
136    int auxmode;
137    int enable;
138    int x, y;
139    int sh,sv;
140    int alpha;
141    int coloroffset;
142    int transparencyenable;
143    int specialprimode;
144    float maxzoom;
145    int linecheck_mask;
146    int titan_which_layer;
147    int titan_shadow_type;
148    int titan_shadow_enabled;
149 
150    float coordincx, coordincy;
151    void FASTCALL (* PlaneAddr)(void *, int, Vdp2*);
152    u32 FASTCALL (*Vdp2ColorRamGetColor)(void *, u32 , int );
153    u32 FASTCALL (*PostPixelFetchCalc)(void *, u32);
154    int patternpixelwh;
155    int draww;
156    int drawh;
157    int rotatenum;
158    int rotatemode;
159    int mosaicxmask;
160    int mosaicymask;
161    int islinescroll;
162    u32 linescrolltbl;
163    u32 lineinc;
164    vdp2Lineinfo * lineinfo;
165    int wctl;
166    int islinewindow;
167    int isverticalscroll;
168    u32 verticalscrolltbl;
169    int verticalscrollinc;
170 
171    // WindowMode
172    u8  LogicWin;    // Window Logic AND OR
173    u8  bEnWin0;     // Enable Window0
174    u8  bEnWin1;     // Enable Window1
175    u8  WindowArea0; // Window Area Mode 0
176    u8  WindowArea1; // Window Area Mode 1
177 
178    // Rotate Screen
179    vdp2WindowInfo * pWinInfo;
180    int WindwAreaMode;
181    vdp2rotationparameter_struct * FASTCALL (*GetKValueA)(vdp2rotationparameter_struct*,int);
182    vdp2rotationparameter_struct * FASTCALL (*GetKValueB)(vdp2rotationparameter_struct*,int);
183    vdp2rotationparameter_struct * FASTCALL (*GetRParam)(void *, int h,int v);
184    u32 LineColorBase;
185 
186    void (*LoadLineParams)(void *, void *, int line, Vdp2* lines);
187 
188    int bad_cycle_setting;
189 
190    struct Pipeline
191    {
192       int paladdr;
193       int charaddr;
194       int flipfunction;
195    }pipe[2];
196 
197 
198 } vdp2draw_struct;
199 
200 
201 
202 #define FP_SIZE 16
203 typedef s32 fixed32;
204 
205 typedef struct
206 {
207    fixed32 Xst;
208    fixed32 Yst;
209    fixed32 Zst;
210    fixed32 deltaXst;
211    fixed32 deltaYst;
212    fixed32 deltaX;
213    fixed32 deltaY;
214    fixed32 A;
215    fixed32 B;
216    fixed32 C;
217    fixed32 D;
218    fixed32 E;
219    fixed32 F;
220    fixed32 Px;
221    fixed32 Py;
222    fixed32 Pz;
223    fixed32 Cx;
224    fixed32 Cy;
225    fixed32 Cz;
226    fixed32 Mx;
227    fixed32 My;
228    fixed32 kx;
229    fixed32 ky;
230    fixed32 KAst;
231    fixed32 deltaKAst;
232    fixed32 deltaKAx;
233    u32 coeftbladdr;
234    int coefenab;
235    int coefmode;
236    int coefdatasize;
237    fixed32 Xp;
238    fixed32 Yp;
239    fixed32 dX;
240    fixed32 dY;
241    int screenover;
242    int msb;
243    int linescreen;
244 
245    void FASTCALL (* PlaneAddr)(void *, int, Vdp2*);
246 } vdp2rotationparameterfp_struct;
247 
248 typedef struct
249 {
250    int xstart, ystart;
251    int xend, yend;
252 } clipping_struct;
253 
254 #define tofixed(v) ((v) * (1 << FP_SIZE))
255 #define toint(v) ((v) >> FP_SIZE)
256 #define touint(v) ((u16)((v) >> FP_SIZE))
257 #define tofloat(v) ((float)(v) / (float)(1 << FP_SIZE))
258 #define mulfixed(a,b) ((fixed32)((s64)(a) * (s64)(b) >> FP_SIZE))
259 #define divfixed(a,b) (((s64)(a) << FP_SIZE) / (b))
260 #define decipart(v) (v & ((1 << FP_SIZE) - 1))
261 
262 void FASTCALL Vdp2NBG0PlaneAddr(vdp2draw_struct *info, int i, Vdp2* regs);
263 void FASTCALL Vdp2NBG1PlaneAddr(vdp2draw_struct *info, int i, Vdp2* regs);
264 void FASTCALL Vdp2NBG2PlaneAddr(vdp2draw_struct *info, int i, Vdp2* regs);
265 void FASTCALL Vdp2NBG3PlaneAddr(vdp2draw_struct *info, int i, Vdp2* regs);
266 void Vdp2ReadRotationTable(int which, vdp2rotationparameter_struct *parameter, Vdp2* regs, u8* ram);
267 void Vdp2ReadRotationTableFP(int which, vdp2rotationparameterfp_struct *parameter, Vdp2* regs, u8* ram);
268 void FASTCALL Vdp2ParameterAPlaneAddr(vdp2draw_struct *info, int i, Vdp2* regs);
269 void FASTCALL Vdp2ParameterBPlaneAddr(vdp2draw_struct *info, int i, Vdp2* regs);
270 float Vdp2ReadCoefficientMode0_2(vdp2rotationparameter_struct *parameter, u32 addr, u8* ram);
271 fixed32 Vdp2ReadCoefficientMode0_2FP(vdp2rotationparameterfp_struct *parameter, u32 addr, u8* ram);
272 
273 //////////////////////////////////////////////////////////////////////////////
274 
GenerateRotatedXPos(vdp2rotationparameter_struct * p,int x,int y)275 static INLINE int GenerateRotatedXPos(vdp2rotationparameter_struct *p, int x, int y)
276 {
277    float Xsp = p->A * ((p->Xst + p->deltaXst * y) - p->Px) +
278                p->B * ((p->Yst + p->deltaYst * y) - p->Py) +
279                p->C * (p->Zst - p->Pz);
280 
281    return (int)(p->kx * (Xsp + p->dX * (float)x) + p->Xp);
282 }
283 
284 //////////////////////////////////////////////////////////////////////////////
285 
GenerateRotatedVarFP(vdp2rotationparameterfp_struct * p,fixed32 * xmul,fixed32 * ymul,fixed32 * C,fixed32 * F)286 static INLINE void GenerateRotatedVarFP(vdp2rotationparameterfp_struct *p, fixed32 *xmul, fixed32 *ymul, fixed32 *C, fixed32 *F)
287 {
288    *xmul = p->Xst - p->Px;
289    *ymul = p->Yst - p->Py;
290    *C = mulfixed(p->C, (p->Zst - p->Pz));
291    *F = mulfixed(p->F, (p->Zst - p->Pz));
292 }
293 
294 //////////////////////////////////////////////////////////////////////////////
295 
GenerateRotatedYPos(vdp2rotationparameter_struct * p,int x,int y)296 static INLINE int GenerateRotatedYPos(vdp2rotationparameter_struct *p, int x, int y)
297 {
298    float Ysp = p->D * ((p->Xst + p->deltaXst * y) - p->Px) +
299                p->E * ((p->Yst + p->deltaYst * y) - p->Py) +
300                p->F * (p->Zst - p->Pz);
301 
302    return (int)(p->ky * (Ysp + p->dY * (float)x) + p->Yp);
303 }
304 
305 //////////////////////////////////////////////////////////////////////////////
306 
GenerateRotatedXPosFP(vdp2rotationparameterfp_struct * p,int x,fixed32 xmul,fixed32 ymul,fixed32 C)307 static INLINE int GenerateRotatedXPosFP(vdp2rotationparameterfp_struct *p, int x, fixed32 xmul, fixed32 ymul, fixed32 C)
308 {
309    fixed32 Xsp = mulfixed(p->A, xmul) + mulfixed(p->B, ymul) + C;
310 
311    return touint(mulfixed(p->kx, (Xsp + mulfixed(p->dX, tofixed(x)))) + p->Xp);
312 }
313 
314 //////////////////////////////////////////////////////////////////////////////
315 
GenerateRotatedYPosFP(vdp2rotationparameterfp_struct * p,int x,fixed32 xmul,fixed32 ymul,fixed32 F)316 static INLINE int GenerateRotatedYPosFP(vdp2rotationparameterfp_struct *p, int x, fixed32 xmul, fixed32 ymul, fixed32 F)
317 {
318    fixed32 Ysp = mulfixed(p->D, xmul) + mulfixed(p->E, ymul) + F;
319 
320    return touint(mulfixed(p->ky, (Ysp + mulfixed(p->dY, tofixed(x)))) + p->Yp);
321 }
322 
323 //////////////////////////////////////////////////////////////////////////////
324 
CalculateRotationValues(vdp2rotationparameter_struct * p)325 static INLINE void CalculateRotationValues(vdp2rotationparameter_struct *p)
326 {
327    p->Xp=p->A * (p->Px - p->Cx) +
328          p->B * (p->Py - p->Cy) +
329          p->C * (p->Pz - p->Cz) +
330          p->Cx + p->Mx;
331    p->Yp=p->D * (p->Px - p->Cx) +
332          p->E * (p->Py - p->Cy) +
333          p->F * (p->Pz - p->Cz) +
334          p->Cy + p->My;
335    p->dX=p->A * p->deltaX +
336          p->B * p->deltaY;
337    p->dY=p->D * p->deltaX +
338          p->E * p->deltaY;
339 }
340 
341 //////////////////////////////////////////////////////////////////////////////
342 
CalculateRotationValuesFP(vdp2rotationparameterfp_struct * p)343 static INLINE void CalculateRotationValuesFP(vdp2rotationparameterfp_struct *p)
344 {
345    p->Xp=mulfixed(p->A, (p->Px - p->Cx)) +
346          mulfixed(p->B, (p->Py - p->Cy)) +
347          mulfixed(p->C, (p->Pz - p->Cz)) +
348          p->Cx + p->Mx;
349    p->Yp=mulfixed(p->D, (p->Px - p->Cx)) +
350          mulfixed(p->E, (p->Py - p->Cy)) +
351          mulfixed(p->F, (p->Pz - p->Cz)) +
352          p->Cy + p->My;
353    p->dX=mulfixed(p->A, p->deltaX) +
354          mulfixed(p->B, p->deltaY);
355    p->dY=mulfixed(p->D, p->deltaX) +
356          mulfixed(p->E, p->deltaY);
357 }
358 
359 //////////////////////////////////////////////////////////////////////////////
360 
CalcPlaneAddr(vdp2draw_struct * info,u32 tmp)361 static INLINE void CalcPlaneAddr(vdp2draw_struct *info, u32 tmp)
362 {
363    int deca = info->planeh + info->planew - 2;
364    int multi = info->planeh * info->planew;
365 
366    //if (Vdp2Regs->VRSIZE & 0x8000)
367    //{
368       if (info->patterndatasize == 1)
369       {
370          if (info->patternwh == 1)
371             info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000);
372          else
373             info->addr = (tmp >> deca) * (multi * 0x800);
374       }
375       else
376       {
377          if (info->patternwh == 1)
378             info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000);
379          else
380             info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000);
381       }
382    /*}
383    else
384    {
385       if (info->patterndatasize == 1)
386       {
387          if (info->patternwh == 1)
388             info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000);
389          else
390             info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800);
391       }
392       else
393       {
394          if (info->patternwh == 1)
395             info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000);
396          else
397             info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000);
398       }
399    }*/
400 }
401 
402 //////////////////////////////////////////////////////////////////////////////
403 
ReadBitmapSize(vdp2draw_struct * info,u16 bm,int mask)404 static INLINE void ReadBitmapSize(vdp2draw_struct *info, u16 bm, int mask)
405 {
406    switch(bm & mask)
407    {
408       case 0: info->cellw = 512;  info->cellw_bits = 9;
409               info->cellh = 256;  info->cellh_bits = 8;
410               break;
411       case 1: info->cellw = 512;  info->cellw_bits = 9;
412               info->cellh = 512;  info->cellh_bits = 9;
413               break;
414       case 2: info->cellw = 1024; info->cellw_bits = 10;
415               info->cellh = 256;  info->cellh_bits = 8;
416               break;
417       case 3: info->cellw = 1024; info->cellw_bits = 10;
418               info->cellh = 512;  info->cellh_bits = 9;
419               break;
420    }
421 }
422 
423 //////////////////////////////////////////////////////////////////////////////
424 
ReadPlaneSizeR(vdp2rotationparameter_struct * info,u16 reg)425 static INLINE void ReadPlaneSizeR(vdp2rotationparameter_struct *info, u16 reg)
426 {
427    switch(reg & 0x3)
428    {
429       case 0:
430          info->planew = info->planeh = 1;
431          info->planew_bits = info->planeh_bits = 0;
432          break;
433       case 1:
434          info->planew = 2; info->planew_bits = 1;
435          info->planeh = 1; info->planeh_bits = 0;
436          break;
437       case 3:
438          info->planew = info->planeh = 2;
439          info->planew_bits = info->planeh_bits = 1;
440          break;
441       default: // Not sure what 0x2 does, though a few games seem to use it
442          info->planew = info->planeh = 1;
443          info->planew_bits = info->planeh_bits = 0;
444          break;
445    }
446 
447 
448 }
449 
450 
451 
ReadPlaneSize(vdp2draw_struct * info,u16 reg)452 static INLINE void ReadPlaneSize(vdp2draw_struct *info, u16 reg)
453 {
454    switch(reg & 0x3)
455    {
456       case 0:
457          info->planew = info->planeh = 1;
458 		 info->planew_bits = info->planeh_bits = 0;
459          break;
460       case 1:
461          info->planew = 2; info->planew_bits = 1;
462          info->planeh = 1; info->planeh_bits = 0;
463          break;
464       case 3:
465          info->planew = info->planeh = 2;
466 		 info->planew_bits = info->planeh_bits = 1;
467          break;
468       default: // Not sure what 0x2 does, though a few games seem to use it
469          info->planew = info->planeh = 1;
470 		 info->planew_bits = info->planeh_bits = 0;
471          break;
472    }
473 }
474 
475 //////////////////////////////////////////////////////////////////////////////
476 
ReadPatternData(vdp2draw_struct * info,u16 pnc,int chctlwh)477 static INLINE void ReadPatternData(vdp2draw_struct *info, u16 pnc, int chctlwh)
478 {
479    if(pnc & 0x8000)
480    {
481       info->patterndatasize = 1;
482 	  info->patterndatasize_bits = 0;
483    }
484    else
485    {
486       info->patterndatasize = 2;
487 	  info->patterndatasize_bits = 1;
488    }
489 
490    if(chctlwh)
491    {
492       info->patternwh = 2;
493 	  info->patternwh_bits = 1;
494    }
495    else
496    {
497       info->patternwh = 1;
498 	  info->patternwh_bits = 0;
499    }
500 
501    info->pagewh = 64>>info->patternwh_bits;
502    info->pagewh_bits = 6-info->patternwh_bits;
503    info->cellw = info->cellh = 8;
504    info->cellw_bits = info->cellh_bits = 3;
505    info->supplementdata = pnc & 0x3FF;
506    info->auxmode = (pnc & 0x4000) >> 14;
507 }
508 
509 //////////////////////////////////////////////////////////////////////////////
510 
ReadMosaicData(vdp2draw_struct * info,u16 mask,Vdp2 * regs)511 static INLINE void ReadMosaicData(vdp2draw_struct *info, u16 mask, Vdp2* regs)
512 {
513    if (regs->MZCTL & mask)
514    {
515       info->mosaicxmask = ((regs->MZCTL >> 8) & 0xF) + 1;
516       info->mosaicymask = (regs->MZCTL >> 12) + 1;
517    }
518    else
519    {
520       info->mosaicxmask = 1;
521       info->mosaicymask = 1;
522    }
523 }
524 
525 //////////////////////////////////////////////////////////////////////////////
526 
ReadLineScrollData(vdp2draw_struct * info,u16 mask,u32 tbl)527 static INLINE void ReadLineScrollData(vdp2draw_struct *info, u16 mask, u32 tbl)
528 {
529    if (mask & 0xE)
530    {
531       info->islinescroll = (mask >> 1) & 0x7;
532       info->linescrolltbl = (tbl & 0x7FFFE) << 1;
533 	   info->lineinc = 1 << ((mask >> 4) & 0x03);
534    }
535    else
536    {
537       info->islinescroll = 0;
538 	  info->lineinc = 0;
539    }
540 }
541 
542 
543 //////////////////////////////////////////////////////////////////////////////
544 
ReadWindowCoordinates(int num,clipping_struct * clip,Vdp2 * regs)545 static INLINE void ReadWindowCoordinates(int num, clipping_struct * clip, Vdp2* regs)
546 {
547    if (num == 0)
548    {
549       // Window 0
550       clip->xstart = regs->WPSX0;
551       clip->ystart = regs->WPSY0 & 0x1FF;
552       clip->xend = regs->WPEX0;
553       clip->yend = regs->WPEY0 & 0x1FF;
554    }
555    else
556    {
557       // Window 1
558       clip->xstart = regs->WPSX1;
559       clip->ystart = regs->WPSY1 & 0x1FF;
560       clip->xend = regs->WPEX1;
561       clip->yend = regs->WPEY1 & 0x1FF;
562    }
563 
564    switch ((regs->TVMD >> 1) & 0x3)
565    {
566       case 0: // Normal
567          clip->xstart = (clip->xstart >> 1) & 0x1FF;
568          clip->xend = (clip->xend >> 1) & 0x1FF;
569          break;
570       case 1: // Hi-Res
571          clip->xstart = clip->xstart & 0x3FF;
572          clip->xend = clip->xend & 0x3FF;
573          break;
574       case 2: // Exclusive Normal
575          clip->xstart = clip->xstart & 0x1FF;
576          clip->xend = clip->xend & 0x1FF;
577          break;
578       case 3: // Exclusive Hi-Res
579          clip->xstart = (clip->xstart & 0x3FF) >> 1;
580          clip->xend = (clip->xend & 0x3FF) >> 1;
581          break;
582    }
583 }
584 
585 //////////////////////////////////////////////////////////////////////////////
586 
ReadWindowData(int wctl,clipping_struct * clip,Vdp2 * regs)587 static INLINE void ReadWindowData(int wctl, clipping_struct *clip, Vdp2* regs)
588 {
589    clip[0].xstart = clip[0].ystart = clip[0].xend = clip[0].yend = 0;
590    clip[1].xstart = clip[1].ystart = clip[1].xend = clip[1].yend = 0;
591 
592    if (wctl & 0x2)
593    {
594       ReadWindowCoordinates(0, clip, regs);
595    }
596 
597    if (wctl & 0x8)
598    {
599       ReadWindowCoordinates(1, clip + 1, regs);
600    }
601 
602    if (wctl & 0x20)
603    {
604       // fix me
605    }
606 }
607 
608 //////////////////////////////////////////////////////////////////////////////
609 
ReadLineWindowData(int * islinewindow,int wctl,u32 * linewnd0addr,u32 * linewnd1addr,Vdp2 * regs)610 static INLINE void ReadLineWindowData(int *islinewindow, int wctl, u32 *linewnd0addr, u32 *linewnd1addr, Vdp2* regs)
611 {
612    islinewindow[0] = 0;
613 
614    if (wctl & 0x2 && regs->LWTA0.all & 0x80000000)
615    {
616       islinewindow[0] |= 0x1;
617       linewnd0addr[0] = (regs->LWTA0.all & 0x7FFFE) << 1;
618    }
619    if (wctl & 0x8 && regs->LWTA1.all & 0x80000000)
620    {
621       islinewindow[0] |= 0x2;
622       linewnd1addr[0] = (regs->LWTA1.all & 0x7FFFE) << 1;
623    }
624 }
625 
626 //////////////////////////////////////////////////////////////////////////////
627 
ReadOneLineWindowClip(clipping_struct * clip,u32 * linewndaddr,u8 * ram,Vdp2 * regs)628 static INLINE void ReadOneLineWindowClip(clipping_struct *clip, u32 *linewndaddr, u8* ram, Vdp2* regs)
629 {
630    clip->xstart = T1ReadWord(ram, *linewndaddr);
631    *linewndaddr += 2;
632    clip->xend = T1ReadWord(ram, *linewndaddr);
633    *linewndaddr += 2;
634 
635    /* Ok... that looks insane... but there's at least two games (3D Baseball and
636    Panzer Dragoon Saga) that set the line window end to 0xFFFF and expect the line
637    window to be invalid for those lines... */
638    if (clip->xend == 0xFFFF)
639    {
640       clip->xstart = 0;
641       clip->xend = 0;
642       return;
643    }
644 
645    clip->xstart &= 0x3FF;
646    clip->xend &= 0x3FF;
647 
648    switch ((regs->TVMD >> 1) & 0x3)
649    {
650       case 0: // Normal
651          clip->xstart = (clip->xstart >> 1) & 0x1FF;
652          clip->xend = (clip->xend >> 1) & 0x1FF;
653          break;
654       case 1: // Hi-Res
655          clip->xstart = clip->xstart & 0x3FF;
656          clip->xend = clip->xend & 0x3FF;
657          break;
658       case 2: // Exclusive Normal
659          clip->xstart = clip->xstart & 0x1FF;
660          clip->xend = clip->xend & 0x1FF;
661          break;
662       case 3: // Exclusive Hi-Res
663          clip->xstart = (clip->xstart & 0x3FF) >> 1;
664          clip->xend = (clip->xend & 0x3FF) >> 1;
665          break;
666    }
667 }
668 
ReadLineWindowClip(int islinewindow,clipping_struct * clip,u32 * linewnd0addr,u32 * linewnd1addr,u8 * ram,Vdp2 * regs)669 static INLINE void ReadLineWindowClip(int islinewindow, clipping_struct *clip, u32 *linewnd0addr, u32 *linewnd1addr, u8* ram, Vdp2* regs)
670 {
671    if (islinewindow)
672    {
673       // Fetch new xstart and xend values from table
674       if (islinewindow & 0x1)
675          // Window 0
676          ReadOneLineWindowClip(clip, linewnd0addr, ram, regs);
677       if (islinewindow & 0x2)
678          // Window 1
679          ReadOneLineWindowClip(clip + 1, linewnd1addr, ram, regs);
680    }
681 }
682 
683 //////////////////////////////////////////////////////////////////////////////
684 
IsScreenRotated(vdp2rotationparameter_struct * parameter)685 static INLINE int IsScreenRotated(vdp2rotationparameter_struct *parameter)
686 {
687   return (parameter->deltaXst == 0.0 &&
688           parameter->deltaYst == 1.0 &&
689           parameter->deltaX == 1.0 &&
690           parameter->deltaY == 0.0 &&
691           parameter->A == 1.0 &&
692           parameter->B == 0.0 &&
693           parameter->C == 0.0 &&
694           parameter->D == 0.0 &&
695           parameter->E == 1.0 &&
696           parameter->F == 0.0);
697 }
698 
699 //////////////////////////////////////////////////////////////////////////////
700 
IsScreenRotatedFP(vdp2rotationparameterfp_struct * parameter)701 static INLINE int IsScreenRotatedFP(vdp2rotationparameterfp_struct *parameter)
702 {
703   return (parameter->deltaXst == tofixed(0.0) &&
704           parameter->deltaYst == tofixed(1.0) &&
705           parameter->deltaX == tofixed(1.0) &&
706           parameter->deltaY == tofixed(0.0) &&
707           parameter->A == tofixed(1.0) &&
708           parameter->B == tofixed(0.0) &&
709           parameter->C == tofixed(0.0) &&
710           parameter->D == tofixed(0.0) &&
711           parameter->E == tofixed(1.0) &&
712           parameter->F == tofixed(0.0));
713 }
714 
715 //////////////////////////////////////////////////////////////////////////////
716 
Vdp2ReadCoefficient(vdp2rotationparameter_struct * parameter,u32 addr,u8 * ram)717 static INLINE void Vdp2ReadCoefficient(vdp2rotationparameter_struct *parameter, u32 addr, u8* ram)
718 {
719    switch (parameter->coefmode)
720    {
721       case 0: // coefficient for kx and ky
722          parameter->kx = parameter->ky = Vdp2ReadCoefficientMode0_2(parameter, addr, ram);
723          break;
724       case 1: // coefficient for kx
725          parameter->kx = Vdp2ReadCoefficientMode0_2(parameter, addr, ram);
726          break;
727       case 2: // coefficient for ky
728          parameter->ky = Vdp2ReadCoefficientMode0_2(parameter, addr, ram);
729          break;
730       case 3: // coefficient for Xp
731       {
732          s32 i;
733 
734          if (parameter->coefdatasize == 2)
735          {
736             i = T1ReadWord(ram, addr);
737             parameter->msb = (i >> 15) & 0x1;
738             parameter->Xp = (float) (signed) ((i & 0x7FFF) | (i & 0x4000 ? 0xFFFFC000 : 0x00000000)) / 4;
739          }
740          else
741          {
742             i = T1ReadLong(ram, addr);
743             parameter->msb = (i >> 31) & 0x1;
744             parameter->Xp = (float) (signed) ((i & 0x007FFFFF) | (i & 0x00800000 ? 0xFF800000 : 0x00000000)) / 256;
745          }
746          break;
747       }
748    }
749 }
750 
751 //////////////////////////////////////////////////////////////////////////////
752 
Vdp2ReadCoefficientFP(vdp2rotationparameterfp_struct * parameter,u32 addr,u8 * ram)753 static INLINE void Vdp2ReadCoefficientFP(vdp2rotationparameterfp_struct *parameter, u32 addr, u8* ram)
754 {
755    switch (parameter->coefmode)
756    {
757       case 0: // coefficient for kx and ky
758          parameter->kx = parameter->ky = Vdp2ReadCoefficientMode0_2FP(parameter, addr, ram);
759          break;
760       case 1: // coefficient for kx
761          parameter->kx = Vdp2ReadCoefficientMode0_2FP(parameter, addr, ram);
762          break;
763       case 2: // coefficient for ky
764          parameter->ky = Vdp2ReadCoefficientMode0_2FP(parameter, addr, ram);
765          break;
766       case 3: // coefficient for Xp
767       {
768          s32 i;
769 
770          if (parameter->coefdatasize == 2)
771          {
772             i = T1ReadWord(ram, addr);
773             parameter->msb = (i >> 15) & 0x1;
774             parameter->Xp = (signed) ((i & 0x7FFF) | (i & 0x4000 ? 0xFFFFC000 : 0x00000000)) * 16384;
775          }
776          else
777          {
778             i = T1ReadLong(ram, addr);
779             parameter->msb = (i >> 31) & 0x1;
780             parameter->linescreen = (i >> 24) & 0x7F;
781             parameter->Xp = (signed) ((i & 0x007FFFFF) | (i & 0x00800000 ? 0xFF800000 : 0x00000000)) * 256;
782          }
783 
784          break;
785       }
786    }
787 }
788 
789 //////////////////////////////////////////////////////////////////////////////
790 
791 typedef struct {
792     int normalshadow;
793     int msbshadow;
794     int priority;
795     int colorcalc;
796 } spritepixelinfo_struct;
797 
Vdp1GetSpritePixelInfo(int type,u16 * pixel,spritepixelinfo_struct * spi)798 static INLINE void Vdp1GetSpritePixelInfo(int type, u16 * pixel, spritepixelinfo_struct * spi)
799 {
800    memset(spi, 0, sizeof(spritepixelinfo_struct));
801 
802    switch(type)
803    {
804       case 0x0:
805       {
806          // Type 0(2-bit priority, 3-bit color calculation, 11-bit color data)
807          spi->priority = *pixel >> 14;
808          spi->colorcalc = (*pixel >> 11) & 0x7;
809          *pixel = *pixel & 0x7FF;
810          spi->normalshadow = (*pixel == 0x7FE);
811          break;
812       }
813       case 0x1:
814       {
815          // Type 1(3-bit priority, 2-bit color calculation, 11-bit color data)
816          spi->priority = *pixel >> 13;
817          spi->colorcalc = (*pixel >> 11) & 0x3;
818          *pixel &= 0x7FF;
819          spi->normalshadow = (*pixel == 0x7FE);
820          break;
821       }
822       case 0x2:
823       {
824          // Type 2(1-bit shadow, 1-bit priority, 3-bit color calculation, 11-bit color data)
825          spi->msbshadow = *pixel >> 15;
826          spi->priority = (*pixel >> 14) & 0x1;
827          spi->colorcalc = (*pixel >> 11) & 0x7;
828          *pixel &= 0x7FF;
829          spi->normalshadow = (*pixel == 0x7FE);
830          break;
831       }
832       case 0x3:
833       {
834          // Type 3(1-bit shadow, 2-bit priority, 2-bit color calculation, 11-bit color data)
835          spi->msbshadow = *pixel >> 15;
836          spi->priority = (*pixel >> 13) & 0x3;
837          spi->colorcalc = (*pixel >> 11) & 0x3;
838          *pixel &= 0x7FF;
839          spi->normalshadow = (*pixel == 0x7FE);
840          break;
841       }
842       case 0x4:
843       {
844          // Type 4(1-bit shadow, 2-bit priority, 3-bit color calculation, 10-bit color data)
845          spi->msbshadow = *pixel >> 15;
846          spi->priority = (*pixel >> 13) & 0x3;
847          spi->colorcalc = (*pixel >> 10) & 0x7;
848          *pixel &= 0x3FF;
849          spi->normalshadow = (*pixel == 0x3FE);
850          break;
851       }
852       case 0x5:
853       {
854          // Type 5(1-bit shadow, 3-bit priority, 1-bit color calculation, 11-bit color data)
855          spi->msbshadow = *pixel >> 15;
856          spi->priority = (*pixel >> 12) & 0x7;
857          spi->colorcalc = (*pixel >> 11) & 0x1;
858          *pixel &= 0x7FF;
859          spi->normalshadow = (*pixel == 0x7FE);
860          break;
861       }
862       case 0x6:
863       {
864          // Type 6(1-bit shadow, 3-bit priority, 2-bit color calculation, 10-bit color data)
865          spi->msbshadow = *pixel >> 15;
866          spi->priority = (*pixel >> 12) & 0x7;
867          spi->colorcalc = (*pixel >> 10) & 0x3;
868          *pixel &= 0x3FF;
869          spi->normalshadow = (*pixel == 0x3FE);
870          break;
871       }
872       case 0x7:
873       {
874          // Type 7(1-bit shadow, 3-bit priority, 3-bit color calculation, 9-bit color data)
875          spi->msbshadow = *pixel >> 15;
876          spi->priority = (*pixel >> 12) & 0x7;
877          spi->colorcalc = (*pixel >> 9) & 0x7;
878          *pixel &= 0x1FF;
879          spi->normalshadow = (*pixel == 0x1FE);
880          break;
881       }
882       case 0x8:
883       {
884          // Type 8(1-bit priority, 7-bit color data)
885          spi->priority = (*pixel >> 7) & 0x1;
886          *pixel &= 0x7F;
887          spi->normalshadow = (*pixel == 0x7E);
888          break;
889       }
890       case 0x9:
891       {
892          // Type 9(1-bit priority, 1-bit color calculation, 6-bit color data)
893          spi->priority = (*pixel >> 7) & 0x1;
894          spi->colorcalc = (*pixel >> 6) & 0x1;
895          *pixel &= 0x3F;
896          spi->normalshadow = (*pixel == 0x3E);
897          break;
898       }
899       case 0xA:
900       {
901          // Type A(2-bit priority, 6-bit color data)
902          spi->priority = (*pixel >> 6) & 0x3;
903          *pixel &= 0x3F;
904          spi->normalshadow = (*pixel == 0x3E);
905          break;
906       }
907       case 0xB:
908       {
909          // Type B(2-bit color calculation, 6-bit color data)
910          spi->colorcalc = (*pixel >> 6) & 0x3;
911          *pixel &= 0x3F;
912          spi->normalshadow = (*pixel == 0x3E);
913          break;
914       }
915       case 0xC:
916       {
917          // Type C(1-bit special priority, 8-bit color data - bit 7 is shared)
918          spi->priority = (*pixel >> 7) & 0x1;
919          spi->normalshadow = (*pixel == 0xFE);
920          break;
921       }
922       case 0xD:
923       {
924          // Type D(1-bit special priority, 1-bit special color calculation, 8-bit color data - bits 6 and 7 are shared)
925          spi->priority = (*pixel >> 7) & 0x1;
926          spi->colorcalc = (*pixel >> 6) & 0x1;
927          spi->normalshadow = (*pixel == 0xFE);
928          break;
929       }
930       case 0xE:
931       {
932          // Type E(2-bit special priority, 8-bit color data - bits 6 and 7 are shared)
933          spi->priority = (*pixel >> 6) & 0x3;
934          spi->normalshadow = (*pixel == 0xFE);
935          break;
936       }
937       case 0xF:
938       {
939          // Type F(2-bit special color calculation, 8-bit color data - bits 6 and 7 are shared)
940          spi->colorcalc = (*pixel >> 6) & 0x3;
941          spi->normalshadow = (*pixel == 0xFE);
942          break;
943       }
944       default: break;
945    }
946 }
947 
948 //////////////////////////////////////////////////////////////////////////////
949 
Vdp1ProcessSpritePixel(int type,u16 * pixel,int * shadow,int * priority,int * colorcalc)950 static INLINE void Vdp1ProcessSpritePixel(int type, u16 *pixel, int *shadow, int *priority, int *colorcalc)
951 {
952    spritepixelinfo_struct spi;
953 
954    Vdp1GetSpritePixelInfo(type, pixel, &spi);
955    *shadow = spi.msbshadow;
956    *priority = spi.priority;
957    *colorcalc = spi.colorcalc;
958 }
959 
960 #define VDPLINE_SZ(a) ((a)&0x04)
961 #define VDPLINE_SY(a) ((a)&0x02)
962 #define VDPLINE_SX(a) ((a)&0x01)
963 #define OVERMODE_REPEAT      0
964 #define OVERMODE_SELPATNAME  1
965 #define OVERMODE_TRANSE      2
966 #define OVERMODE_512         3
967 
968 
969 //////////////////////////////////////////////////////////////////////////////
970 
971 #endif
972