Beispiel #1
0
static INLINE int32 CMD_PolygonG_T(const uint16* cmd_data)
{
 const uint16 mode = cmd_data[0x2];
 line_vertex p[4];
 int32 ret = 0;
 //
 //
 bool SPD_Opaque = true;	// Abusing the SPD bit passed to the line draw function to denote non-transparency when == 1, transparent when == 0.

 LineSetup.tex_base = 0;
 LineSetup.color = cmd_data[0x3];
 LineSetup.PCD = mode & 0x800;

 if(((mode >> 3) & 0x7) < 0x6)
  SPD_Opaque = (int32)(TexFetchTab[(mode >> 3) & 0x1F](0xFFFFFFFF)) >= 0;
 //
 //
 //
 auto* fnptr = LineFuncTab[(bool)(FBCR & FBCR_DIE)][(TVMR & TVMR_8BPP) ? ((TVMR & TVMR_ROTATE) ? 2 : 1) : 0][((mode >> 6) & 0x1E) | SPD_Opaque /*(mode >> 6) & 0x1F*/][(mode & 0x8000) ? 8 : (mode & 0x7)];

 CheckUndefClipping();

 for(unsigned i = 0; i < 4; i++)
 {
  p[i].x = sign_x_to_s32(13, cmd_data[0x6 + (i << 1)]) + LocalX;
  p[i].y = sign_x_to_s32(13, cmd_data[0x7 + (i << 1)]) + LocalY;
 }

 if(gourauden)
 {
  const uint16* gtb = &VRAM[cmd_data[0xE] << 2];

  ret += 4;
  for(unsigned i = 0; i < 4; i++)
   p[i].g = gtb[i];
 }
 //
 //
 //
 const int32 dmax = std::max<int32>(std::max<int32>(abs(p[3].x - p[0].x), abs(p[3].y - p[0].y)),
				    std::max<int32>(abs(p[2].x - p[1].x), abs(p[2].y - p[1].y)));
 EdgeStepper<gourauden> e[2];

 e[0].Setup(p[0], p[3], dmax);
 e[1].Setup(p[1], p[2], dmax);

 for(int32 i = 0; i <= dmax; i++)
 {
  e[0].GetVertex(&LineSetup.p[0]);
  e[1].GetVertex(&LineSetup.p[1]);
  //
  //printf("%d:%d -> %d:%d\n", lp[0].x, lp[0].y, lp[1].x, lp[1].y);
  ret += fnptr();
  //
  e[0].Step();
  e[1].Step();
 }

 return ret;
}
Beispiel #2
0
int32 CMD_SetLocalCoord(const uint16* cmd_data)
{
 LocalX = sign_x_to_s32(11, cmd_data[0x6] & 0x7FF);
 LocalY = sign_x_to_s32(11, cmd_data[0x7] & 0x7FF);

 return 0;
}
Beispiel #3
0
INLINE void PS_GPU::DrawSpan(int y, const int32 x_start, const int32 x_bound, i_group ig, const i_deltas &idl)
{
  if(LineSkipTest(y))
   return;

  int32 x_ig_adjust = x_start;
  int32 w = x_bound - x_start;
  int32 x = sign_x_to_s32(11, x_start);

  if(x < ClipX0)
  {
   int32 delta = ClipX0 - x;
   x_ig_adjust += delta;
   x += delta;
   w -= delta;
  }

  if((x + w) > (ClipX1 + 1))
   w = ClipX1 + 1 - x;

  if(w <= 0)
   return;

  //printf("%d %d %d %d\n", x, w, ClipX0, ClipX1);

  AddIDeltas_DX<goraud, textured>(ig, idl, x_ig_adjust);
  AddIDeltas_DY<goraud, textured>(ig, idl, y);

  if(goraud || textured)
   DrawTimeAvail -= w * 2;
  else if((BlendMode >= 0) || MaskEval_TA)
   DrawTimeAvail -= w + ((w + 1) >> 1);
  else
Beispiel #4
0
static INLINE int32 CMD_Line_Polyline_T(const uint16* cmd_data)
{
 const uint16 mode = cmd_data[0x2];
 int32 ret = 0;
 //
 //
 bool SPD_Opaque = true;	// Abusing the SPD bit passed to the line draw function to denote non-transparency when == 1, transparent when == 0.

 LineSetup.tex_base = 0;
 LineSetup.color = cmd_data[0x3];
 LineSetup.PCD = mode & 0x800;

 if(((mode >> 3) & 0x7) < 0x6)
  SPD_Opaque = (int32)(TexFetchTab[(mode >> 3) & 0x1F](0xFFFFFFFF)) >= 0;
 //
 //
 //
 auto* fnptr = LineFuncTab[(bool)(FBCR & FBCR_DIE)][(TVMR & TVMR_8BPP) ? ((TVMR & TVMR_ROTATE) ? 2 : 1) : 0][((mode >> 6) & 0x1E) | SPD_Opaque /*(mode >> 6) & 0x1F*/][(mode & 0x8000) ? 8 : (mode & 0x7)];

 CheckUndefClipping();

 for(unsigned n = 0; n < num_lines; n++)
 {
  LineSetup.p[0].x = sign_x_to_s32(13, cmd_data[0x6 + (((n << 1) + 0) & 0x7)] & 0x1FFF) + LocalX;
  LineSetup.p[0].y = sign_x_to_s32(13, cmd_data[0x7 + (((n << 1) + 0) & 0x7)] & 0x1FFF) + LocalY;
  LineSetup.p[1].x = sign_x_to_s32(13, cmd_data[0x6 + (((n << 1) + 2) & 0x7)] & 0x1FFF) + LocalX;
  LineSetup.p[1].y = sign_x_to_s32(13, cmd_data[0x7 + (((n << 1) + 2) & 0x7)] & 0x1FFF) + LocalY;

  if(mode & 0x4) // Gouraud
  {
   const uint16* gtb = &VRAM[cmd_data[0xE] << 2];

   ret += 2;
   LineSetup.p[0].g = gtb[(n + 0) & 0x3];
   LineSetup.p[1].g = gtb[(n + 1) & 0x3];
  }

  ret += fnptr();
 }

 return ret;
}
Beispiel #5
0
static INLINE int8 Mask9ClampS8(int32 v)
{
 v = sign_x_to_s32(9, v);

 if(v < -128)
  v = -128;

 if(v > 127)
  v = 127;

 return v;
}
static NO_INLINE NO_CLONE void MVIInstr(void)
{
 const uint32 instr = DSP_InstrPre<looped>();
 uint32 imm;

 if(cond & 0x40)
  imm = sign_x_to_s32(19, instr);
 else
  imm = sign_x_to_s32(25, instr);

 if(DSP_TestCond<cond>())
 {
  switch(dest)
  {
   default:
	SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] MVI unknown dest 0x%01x --- Instr=0x%08x, Next_Instr=0x%08x, PC=0x%02x\n", dest, instr, (unsigned)(DSP.NextInstr >> 32), DSP.PC);
	break;

   case 0x0:
   case 0x1:
   case 0x2:
   case 0x3:
	DSP.DataRAM[dest][DSP.CT[dest]] = imm;
	DSP.CT[dest] = (DSP.CT[dest] + 1) & 0x3F;
	break;

   case 0x4: DSP.RX = imm; break;
   case 0x5: DSP.P.T = (int32)imm; break;
   case 0x6: DSP.RAO = imm; break;
   case 0x7: DSP.WAO = imm; break;
 
   case 0xA: DSP.LOP = imm & 0x0FFF; break;
   case 0xC: DSP.TOP = DSP.PC - 1; DSP.PC = imm & 0xFF; break;
  }
 }
}
Beispiel #7
0
static INLINE void ClockMod(void)
{
 if(!mod_disabled)
 {
  prev_mod_pos = mod_pos;

  mod_pos += mod_freq;

  if((mod_pos & (0x3F << 12)) != (prev_mod_pos & (0x3F << 12)))
  {
   const int32 mw = mwave[((mod_pos >> 17) & 0x1F)];

   sweep_bias = (sweep_bias + mw) & 0x7FF;
   //printf("%d %d\n", mod_pos >> 17, sweep_bias);
   if(mw == 0x10)
    sweep_bias = 0;
  }

  temp = sign_x_to_s32(11, sweep_bias) * ((volume[1] > 0x20) ? 0x20 : volume[1]);

  // >> 4 or / 16?  / 16 sounds better in Zelda...
  if(temp & 0x0F0)
  {
   temp /= 256;
   if(sweep_bias & 0x400)
    temp--;
   else
    temp += 2;
  }
  else
   temp /= 256;

  if(temp >= 194)
  {
   //printf("Oops: %d\n", temp);
   temp -= 258;
  }
  if(temp < -64)
  {
   //printf("Oops2: %d\n", temp);
   temp += 256;
  }
 }