void COGLGraphicsContext::UpdateFrame(bool swapOnly)
{
    status.gFrameCount++;

    glFlush();
    OPENGL_CHECK_ERRORS;

    // if emulator defined a render callback function, call it before buffer swap
    if (renderCallback)
        (*renderCallback)(status.bScreenIsDrawn);

   retro_return(true);
   
    glDepthMask(GL_TRUE);
    OPENGL_CHECK_ERRORS;
    glClearDepth(1.0f);
    OPENGL_CHECK_ERRORS;
    if (!g_curRomInfo.bForceScreenClear)
    {
        glClear(GL_DEPTH_BUFFER_BIT);
        OPENGL_CHECK_ERRORS;
    }
    else
    {
        needCleanScene = true;
    }

    status.bScreenIsDrawn = false;
}
Exemplo n.º 2
0
void angrylionUpdateScreen(void)
{
    static int counter;

#ifdef HAVE_FRAMESKIP
    if (counter++ < skip)
        return;
    counter = 0;
#endif
    rdp_update();
    retro_return(true);
#if 0
    if (step != 0)
        MessageBox(NULL, "Updated screen.\nPaused.", "Frame Step", MB_OK);
#endif
    return;
}
Exemplo n.º 3
0
void glide64UpdateScreen (void)
{
   bool forced_update = false;
   uint32_t width = (*gfx_info.VI_WIDTH_REG) << 1;

   if (*gfx_info.VI_ORIGIN_REG  > width)
      update_screen_count++;

   if (
         (settings.frame_buffer & fb_cpu_write_hack) &&
         (update_screen_count > ((settings.hacks&hack_Lego) ? 15U : 30U)) &&
         (rdp.last_bg == 0)
      )
   {
      //DirectCPUWrite hack
      update_screen_count = 0;
      no_dlist = true;
      ClearCache ();
      width = (*gfx_info.VI_WIDTH_REG) << 1;
      if (*gfx_info.VI_ORIGIN_REG  > width)
         update_screen_count++;
   }

   if( no_dlist )
   {
      if( *gfx_info.VI_ORIGIN_REG  > width )
      {
         ChangeSize();
         LRDP("ChangeSize done\n");
         if (rdp.vi_height != 0)
            drawViRegBG();
         rdp.updatescreen = 1;
         forced_update = true;
      }
      else
         return;
   }

   if (settings.swapmode == 0 || forced_update)
      newSwapBuffers ();

   if (settings.swapmode_retro && BUFFERSWAP)
      retro_return(true);
}
void COGLGraphicsContext::UpdateFrame(bool swapOnly)
{
    status.gFrameCount++;

    glFlush();
    OPENGL_CHECK_ERRORS;
    //glFinish();
    //wglSwapIntervalEXT(0);

    /*
    if (debuggerPauseCount == countToPause)
    {
        static int iShotNum = 0;
        // get width, height, allocate buffer to store image
        int width = windowSetting.uDisplayWidth;
        int height = windowSetting.uDisplayHeight;
        printf("Saving debug images: width=%i  height=%i\n", width, height);
        short *buffer = (short *) malloc(((width+3)&~3)*(height+1)*4);
        glReadBuffer( GL_FRONT );
        // set up a BMGImage struct
        struct BMGImageStruct img;
        memset(&img, 0, sizeof(BMGImageStruct));
        InitBMGImage(&img);
        img.bits = (unsigned char *) buffer;
        img.bits_per_pixel = 32;
        img.height = height;
        img.width = width;
        img.scan_width = width * 4;
        // store the RGB color image
        char chFilename[64];
        sprintf(chFilename, "dbg_rgb_%03i.png", iShotNum);
        glReadPixels(0,0,width,height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
        WritePNG(chFilename, img);
        // store the Z buffer
        sprintf(chFilename, "dbg_Z_%03i.png", iShotNum);
        glReadPixels(0,0,width,height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, buffer);
        //img.bits_per_pixel = 16;
        //img.scan_width = width * 2;
        WritePNG(chFilename, img);
        // dump a subset of the Z data
        for (int y = 0; y < 480; y += 16)
        {
            for (int x = 0; x < 640; x+= 16)
                printf("%4hx ", buffer[y*640 + x]);
            printf("\n");
        }
        printf("\n");
        // free memory and get out of here
        free(buffer);
        iShotNum++;
    }
    */

    // if emulator defined a render callback function, call it before buffer swap
    if (renderCallback)
        (*renderCallback)(status.bScreenIsDrawn);

   retro_return(true);
   
   /*if (options.bShowFPS)
    {
        static unsigned int lastTick=0;
        static int frames=0;
        unsigned int nowTick = SDL_GetTicks();
        frames++;
        if (lastTick + 5000 <= nowTick)
        {
            char caption[200];
            sprintf(caption, "%s v%i.%i.%i - %.3f VI/S", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION), frames/5.0);
            CoreVideo_SetCaption(caption);
            frames = 0;
            lastTick = nowTick;
        }
    }*/

    glDepthMask(GL_TRUE);
    OPENGL_CHECK_ERRORS;
    glClearDepth(1.0f);
    OPENGL_CHECK_ERRORS;
    if (!g_curRomInfo.bForceScreenClear)
    {
        glClear(GL_DEPTH_BUFFER_BIT);
        OPENGL_CHECK_ERRORS;
    }
    else
    {
        needCleanScene = true;
    }

    status.bScreenIsDrawn = false;
}
void gen_interrupt(void)
{
   if (stop == 1)
   {
      g_gs_vi_counter = 0; /* debug */
      dyna_stop();
   }

   if (!interrupt_unsafe_state)
   {
      if (reset_hard_job)
      {
         reset_hard();
         reset_hard_job = 0;
         return;
      }
   }

   if (skip_jump)
   {
      uint32_t dest  = skip_jump;
      uint32_t count = g_cp0_regs[CP0_COUNT_REG];
      skip_jump = 0;

      next_interrupt = (q.first->data.count > count 
            || (count - q.first->data.count) < UINT32_C(0x80000000))
         ? q.first->data.count
         : 0;

      last_addr = dest;
      generic_jump_to(dest);
      return;
   } 

   switch(q.first->data.type)
   {
      case SPECIAL_INT:
         special_int_handler();
         break;

      case VI_INT:
         remove_interrupt_event();
         vi_vertical_interrupt_event(&g_dev.vi);
         retro_return(false);
         break;

      case COMPARE_INT:
         compare_int_handler();
         break;

      case CHECK_INT:
         remove_interrupt_event();
         wrapped_exception_general();
         break;

      case SI_INT:
         remove_interrupt_event();
         si_end_of_dma_event(&g_dev.si);
         break;

      case PI_INT:
         remove_interrupt_event();
         pi_end_of_dma_event(&g_dev.pi);
         break;

      case AI_INT:
         remove_interrupt_event();
         ai_end_of_dma_event(&g_dev.ai);
         break;

      case SP_INT:
         remove_interrupt_event();
         rsp_interrupt_event(&g_dev.sp);
         break;

      case DP_INT:
         remove_interrupt_event();
         rdp_interrupt_event(&g_dev.dp);
         break;

      case HW2_INT:
         hw2_int_handler();
         break;

      case NMI_INT:
         nmi_int_handler();
         break;

      case CART_INT:
         g_cp0_regs[CP0_CAUSE_REG] |= 0x00000800; /* set IP3 */
         g_cp0_regs[CP0_CAUSE_REG] &= 0xFFFFFF83; /* mask out old exception code */
         remove_interrupt_event();

#if 0
         if (dd_end_of_dma_event(&g_dd) == 1)
         {
            remove_interrupt_event();
            g_cp0_regs[CP0_CAUSE_REG] &= ~0x00000800;
         }
#endif
         break;

      default:
         DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q.first->data.type);
         remove_interrupt_event();
         wrapped_exception_general();
         break;
   }
}
EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void)
{
   retro_return(true);
   return M64ERR_SUCCESS;
}
Exemplo n.º 7
0
void parallelUpdateScreen(void)
{
	VI::complete_frame();
	retro_return(true);
}
Exemplo n.º 8
0
void gen_interupt(void)
{
   if (stop == 1)
   {
#ifndef SINGLE_THREAD
      g_gs_vi_counter = 0; /* debug */
#endif
      dyna_stop();
   }

   if (!interupt_unsafe_state)
   {
      if (reset_hard_job)
      {
         reset_hard();
         reset_hard_job = 0;
         return;
      }
   }

   if (skip_jump)
   {
      uint32_t dest = skip_jump;
      skip_jump = 0;

      next_interupt = (q.first->data.count > g_cp0_regs[CP0_COUNT_REG]
            || (g_cp0_regs[CP0_COUNT_REG] - q.first->data.count) < UINT32_C(0x80000000))
         ? q.first->data.count
         : 0;

      last_addr = dest;
      generic_jump_to(dest);
      return;
   } 

   switch(q.first->data.type)
   {
      case SPECIAL_INT:
         special_int_handler();
         break;
      case VI_INT:
         remove_interupt_event();
         vi_vertical_interrupt_event(&g_vi);
#ifdef __LIBRETRO__
         retro_return(false);
#endif
         break;
      case COMPARE_INT:
         compare_int_handler();
         break;
      case CHECK_INT:
         remove_interupt_event();
         wrapped_exception_general();
         break;
      case SI_INT:
         remove_interupt_event();
         si_end_of_dma_event(&g_si);
         break;
      case PI_INT:
         remove_interupt_event();
         pi_end_of_dma_event(&g_pi);
         break;
      case AI_INT:
         remove_interupt_event();
         ai_end_of_dma_event(&g_ai);
         break;
      case SP_INT:
         remove_interupt_event();
         rsp_interrupt_event(&g_sp);
         break;
      case DP_INT:
         remove_interupt_event();
         rdp_interrupt_event(&g_dp);
         break;
      case HW2_INT:
         hw2_int_handler();
         break;
      case NMI_INT:
         nmi_int_handler();
         break;
      default:
         DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q.first->data.type);
         remove_interupt_event();
         break;
   }
}
Exemplo n.º 9
0
void gen_interupt(void)
{
    if (stop == 1)
    {
        vi_counter = 0; // debug
        dyna_stop();
    }

    if (!interupt_unsafe_state)
    {
        if (reset_hard_job)
        {
            reset_hard();
            reset_hard_job = 0;
            return;
        }
    }
   
    if (skip_jump)
    {
        unsigned int dest = skip_jump;
        skip_jump = 0;

        if (q->count > Count || (Count - q->count) < 0x80000000)
            next_interupt = q->count;
        else
            next_interupt = 0;
        
        last_addr = dest;
        generic_jump_to(dest);
        return;
    } 

    switch(q->type)
    {
        case SPECIAL_INT:
            if (Count > 0x10000000) return;
            remove_interupt_event();
            add_interupt_event_count(SPECIAL_INT, 0);
            return;
            break;
        case VI_INT:
            if (retro_return(false) != savestates_job_nothing)
            {
                gen_interupt();
                return;
            }

            gfx.updateScreen();

            refresh_stat();
            if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000;
            else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500);
            next_vi += vi_register.vi_delay;
            if (vi_register.vi_status&0x40) vi_field=1-vi_field;
            else vi_field=0;

            remove_interupt_event();
            add_interupt_event_count(VI_INT, next_vi);
    
            MI_register.mi_intr_reg |= 0x08;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case COMPARE_INT:
            remove_interupt_event();
            Count+=2;
            add_interupt_event_count(COMPARE_INT, Compare);
            Count-=2;
    
            Cause = (Cause | 0x8000) & 0xFFFFFF83;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case CHECK_INT:
            remove_interupt_event();
            break;
    
        case SI_INT:
            PIF_RAMb[0x3F] = 0x0;
            remove_interupt_event();
            MI_register.mi_intr_reg |= 0x02;
            si_register.si_stat |= 0x1000;
            //si_register.si_stat &= ~0x1;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case PI_INT:
            remove_interupt_event();
            MI_register.mi_intr_reg |= 0x10;
            pi_register.read_pi_status_reg &= ~3;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case AI_INT:
            if (ai_register.ai_status & 0x80000000) // full
            {
                unsigned int ai_event = get_event(AI_INT);
                remove_interupt_event();
                ai_register.ai_status &= ~0x80000000;
                ai_register.current_delay = ai_register.next_delay;
                ai_register.current_len = ai_register.next_len;
                add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay);
         
                MI_register.mi_intr_reg |= 0x04;
                if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                    Cause = (Cause | 0x400) & 0xFFFFFF83;
                else
                    return;
                if ((Status & 7) != 1) return;
                if (!(Status & Cause & 0xFF00)) return;
            }
            else
            {
                remove_interupt_event();
                ai_register.ai_status &= ~0x40000000;

                //-------
                MI_register.mi_intr_reg |= 0x04;
                if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                    Cause = (Cause | 0x400) & 0xFFFFFF83;
                else
                    return;
                if ((Status & 7) != 1) return;
                if (!(Status & Cause & 0xFF00)) return;
            }
            break;

        case SP_INT:
            remove_interupt_event();
            sp_register.sp_status_reg |= 0x203;
            // sp_register.sp_status_reg |= 0x303;
    
            if (!(sp_register.sp_status_reg & 0x40)) return; // !intr_on_break
            MI_register.mi_intr_reg |= 0x01;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case DP_INT:
            remove_interupt_event();
            dpc_register.dpc_status &= ~2;
            dpc_register.dpc_status |= 0x81;
            MI_register.mi_intr_reg |= 0x20;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;

        case HW2_INT:
            // Hardware Interrupt 2 -- remove interrupt event from queue
            remove_interupt_event();
            // setup r4300 Status flags: reset TS, and SR, set IM2
            Status = (Status & ~0x00380000) | 0x1000;
            Cause = (Cause | 0x1000) & 0xFFFFFF83;
            /* the exception_general() call below will jump to the interrupt vector (0x80000180) and setup the
             * interpreter or dynarec
             */
            break;

        case NMI_INT:
            // Non Maskable Interrupt -- remove interrupt event from queue
            remove_interupt_event();
            // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR
            Status = (Status & ~0x00380000) | 0x00500004;
            Cause  = 0x00000000;
            // simulate the soft reset code which would run from the PIF ROM
            r4300_reset_soft();
            // clear all interrupts, reset interrupt counters back to 0
            Count = 0;
            vi_counter = 0;
            init_interupt();
            // clear the audio status register so that subsequent write_ai() calls will work properly
            ai_register.ai_status = 0;
            // set ErrorEPC with the last instruction address
            ErrorEPC = PC->addr;
            // reset the r4300 internal state
            if (r4300emu != CORE_PURE_INTERPRETER)
            {
                // clear all the compiled instruction blocks and re-initialize
                free_blocks();
                init_blocks();
            }
            // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags
            if(delay_slot==1 || delay_slot==3)
            {
                ErrorEPC-=4;
            }
            delay_slot = 0;
            dyna_interp = 0;
            // set next instruction address to reset vector
            last_addr = 0xa4000040;
            generic_jump_to(0xa4000040);
            return;

        default:
            DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q->type);
            remove_interupt_event();
            break;
    }

#ifdef NEW_DYNAREC
    if (r4300emu == CORE_DYNAREC) {
        EPC = pcaddr;
        pcaddr = 0x80000180;
        Status |= 2;
        Cause &= 0x7FFFFFFF;
        pending_exception=1;
    } else {
        exception_general();
    }
#else
    exception_general();
#endif
}