dsp4emu.c

来自「linux下的任天堂模拟器代码。供大家参考。」· C语言 代码 · 共 2,173 行 · 第 1/5 页

C
2,173
字号
  DSP4_vars.world_dx = DSP4_READ_DWORD();  DSP4_vars.distance = DSP4_READ_WORD();  DSP4_READ_WORD(); // 0x0000  DSP4_vars.world_xenv = SEX78(DSP4_READ_WORD());  DSP4_vars.world_ddy = DSP4_READ_WORD();  DSP4_vars.world_ddx = DSP4_READ_WORD();  DSP4_vars.view_yofsenv = DSP4_READ_WORD();  // initial (x,y,offset) at starting DSP4_vars.raster line  DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16);  DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16);  DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16);  DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;  // first DSP4_vars.raster line  DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];  do  {    ////////////////////////////////////////////////////    // process one iteration of projection    // perspective projection of world (x,y,scroll) points    // based on the current projection lines    DSP4_vars.view_x2 = (int16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ));    DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15);    DSP4_vars.view_xofs2 = DSP4_vars.view_x2;    DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;    // 1. World x-location before transformation    // 2. Viewer x-position at the current    // 3. World y-location before perspective projection    // 4. Viewer y-position below the horizon    // 5. Number of DSP4_vars.raster lines drawn in this iteration    DSP4_CLEAR_OUT();    DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16));    DSP4_WRITE_WORD(DSP4_vars.view_x2);    DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16));    DSP4_WRITE_WORD(DSP4_vars.view_y2);    //////////////////////////////////////////////////////////    // SR = 0x00    // determine # of DSP4_vars.raster lines used    DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2;    // prevent overdraw    if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])      DSP4_vars.segments = 0;    else      DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;    // don't draw outside the window    if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])    {      DSP4_vars.segments = 0;      // flush remaining DSP4_vars.raster lines      if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])        DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];    }    // SR = 0x80    DSP4_WRITE_WORD(DSP4_vars.segments);    //////////////////////////////////////////////////////////    // scan next command if no SR check needed    if (DSP4_vars.segments)    {      int32 px_dx, py_dy;      int32 x_scroll, y_scroll;      // SR = 0x00      // linear interpolation (lerp) between projected points      px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;      py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;      // starting step values      x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);      y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);      // SR = 0x80      // rasterize line      for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)      {        // 1. HDMA memory pointer (bg1)        // 2. vertical scroll offset ($210E)        // 3. horizontal scroll offset ($210D)        DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);        DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16));        DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16));        // update memory address        DSP4_vars.poly_ptr[0][0] -= 4;        // update screen values        x_scroll += px_dx;        y_scroll += py_dy;      }    }    /////////////////////////////////////////////////////    // Post-update    // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn    DSP4_vars.view_x1 = DSP4_vars.view_x2;    DSP4_vars.view_y1 = DSP4_vars.view_y2;    DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;    DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;    // add deltas for projection lines    DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx);    DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy);    // update projection lines    DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv);    DSP4_vars.world_y += DSP4_vars.world_dy;    ////////////////////////////////////////////////////    // command check    // scan next command    DSP4.in_count = 2;    DSP4_WAIT(1) resume1 :    // inspect input    DSP4_vars.distance = DSP4_READ_WORD();    // terminate op    if (DSP4_vars.distance == -0x8000)      break;    // already have 2 bytes in queue    DSP4.in_count = 6;    DSP4_WAIT(2) resume2:    // inspect inputs    DSP4_vars.world_ddy = DSP4_READ_WORD();    DSP4_vars.world_ddx = DSP4_READ_WORD();    DSP4_vars.view_yofsenv = DSP4_READ_WORD();    // no envelope here    DSP4_vars.world_xenv = 0;  }  while (1);  DSP4.waiting4command = TRUE;}//////////////////////////////////////////////////////////////void DSP4_OP0E(){  DSP4_vars.OAM_RowMax = 16;  memset(DSP4_vars.OAM_Row, 0, 64);}//////////////////////////////////////////////////////////////void DSP4_OP0F(){  DSP4.waiting4command = FALSE;  // op flow control  switch (DSP4_vars.DSP4_Logic)  {    case 1:      goto resume1; break;    case 2:      goto resume2; break;    case 3:      goto resume3; break;    case 4:      goto resume4; break;  }  ////////////////////////////////////////////////////  // process initial inputs  // sort inputs  DSP4_READ_WORD(); // 0x0000  DSP4_vars.world_y = DSP4_READ_DWORD();  DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();  DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();  DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();  DSP4_vars.viewport_bottom = DSP4_READ_WORD();  DSP4_vars.world_x = DSP4_READ_DWORD();  DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();  DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();  DSP4_vars.world_yofs = DSP4_READ_WORD();  DSP4_vars.world_dy = DSP4_READ_DWORD();  DSP4_vars.world_dx = DSP4_READ_DWORD();  DSP4_vars.distance = DSP4_READ_WORD();  DSP4_READ_WORD(); // 0x0000  DSP4_vars.world_xenv = DSP4_READ_DWORD();  DSP4_vars.world_ddy = DSP4_READ_WORD();  DSP4_vars.world_ddx = DSP4_READ_WORD();  DSP4_vars.view_yofsenv = DSP4_READ_WORD();  // initial (x,y,offset) at starting DSP4_vars.raster line  DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16);  DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16);  DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16);  DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;  DSP4_vars.view_turnoff_x = 0;  DSP4_vars.view_turnoff_dx = 0;  // first DSP4_vars.raster line  DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];  do  {    ////////////////////////////////////////////////////    // process one iteration of projection    // perspective projection of world (x,y,scroll) points    // based on the current projection lines    DSP4_vars.view_x2 = (int16)(((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16) * DSP4_vars.distance >> 15);    DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15);    DSP4_vars.view_xofs2 = DSP4_vars.view_x2;    DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;    // 1. World x-location before transformation    // 2. Viewer x-position at the next    // 3. World y-location before perspective projection    // 4. Viewer y-position below the horizon    // 5. Number of DSP4_vars.raster lines drawn in this iteration    DSP4_CLEAR_OUT();    DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16));    DSP4_WRITE_WORD(DSP4_vars.view_x2);    DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16));    DSP4_WRITE_WORD(DSP4_vars.view_y2);    //////////////////////////////////////////////////////    // SR = 0x00    // determine # of DSP4_vars.raster lines used    DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2;    // prevent overdraw    if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])      DSP4_vars.segments = 0;    else      DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;    // don't draw outside the window    if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])    {      DSP4_vars.segments = 0;      // flush remaining DSP4_vars.raster lines      if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])        DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];    }    // SR = 0x80    DSP4_WRITE_WORD(DSP4_vars.segments);    //////////////////////////////////////////////////////    // scan next command if no SR check needed    if (DSP4_vars.segments)    {      int32 px_dx, py_dy;      int32 x_scroll, y_scroll;      for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++)      {        // grab inputs        DSP4.in_count = 4;        DSP4_WAIT(1);        resume1 :        for (;;)        {          int16 distance;          int16 color, red, green, blue;          distance = DSP4_READ_WORD();          color = DSP4_READ_WORD();          // U1+B5+G5+R5          red = color & 0x1f;          green = (color >> 5) & 0x1f;          blue = (color >> 10) & 0x1f;          // dynamic lighting          red = (red * distance >> 15) & 0x1f;          green = (green * distance >> 15) & 0x1f;          blue = (blue * distance >> 15) & 0x1f;          color = red | (green << 5) | (blue << 10);          DSP4_CLEAR_OUT();          DSP4_WRITE_WORD(color);          break;        }      }      //////////////////////////////////////////////////////      // SR = 0x00      // linear interpolation (lerp) between projected points      px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;      py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;      // starting step values      x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);      y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);      // SR = 0x80      // rasterize line      for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)      {        // 1. HDMA memory pointer        // 2. vertical scroll offset ($210E)        // 3. horizontal scroll offset ($210D)        DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);        DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16));        DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16));        // update memory address        DSP4_vars.poly_ptr[0][0] -= 4;        // update screen values        x_scroll += px_dx;        y_scroll += py_dy;      }    }    ////////////////////////////////////////////////////    // Post-update    // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn    DSP4_vars.view_x1 = DSP4_vars.view_x2;    DSP4_vars.view_y1 = DSP4_vars.view_y2;    DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;    DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;    // add deltas for projection lines    DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx);    DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy);    // update projection lines    DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv);    DSP4_vars.world_y += DSP4_vars.world_dy;    // update road turnoff position    DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx;    ////////////////////////////////////////////////////    // command check    // scan next command    DSP4.in_count = 2;    DSP4_WAIT(2) resume2:    // check for termination    DSP4_vars.distance = DSP4_READ_WORD();    if (DSP4_vars.distance == -0x8000)      break;    // road splice    if( (uint16) DSP4_vars.distance == 0x8001 )    {      DSP4.in_count = 6;      DSP4_WAIT(3) resume3:      DSP4_vars.distance = DSP4_READ_WORD();      DSP4_vars.view_turnoff_x = DSP4_READ_WORD();      DSP4_vars.view_turnoff_dx = DSP4_READ_WORD();      // factor in new changes      DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 );      DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 );      // update stepping values      DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx;      DSP4.in_count = 2;      DSP4_WAIT(2)    }    // already have 2 bytes in queue    DSP4.in_count = 6;    DSP4_WAIT(4) resume4 :    // inspect inputs    DSP4_vars.world_ddy = DSP4_READ_WORD();    DSP4_vars.world_ddx = DSP4_READ_WORD();    DSP4_vars.view_yofsenv = DSP4_READ_WORD();    // no envelope here    DSP4_vars.world_xenv = 0;  }  while (1);  // terminate op  DSP4.waiting4command = TRUE;}//////////////////////////////////////////////////////////////void DSP4_OP10(){  DSP4.waiting4command = FALSE;  // op flow control  switch (DSP4_vars.DSP4_Logic)  {    case 1:      goto resume1; break;    case 2:      goto resume2; break;    case 3:      goto resume3; break;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?