⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 infones_system_win.cpp

📁 游戏模拟器InfoNes的原代码。有兴趣的可以将它移植到linux下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  /* Clear SRAM */
  memset( SRAM, 0, SRAM_SIZE );

  /* If trainer presents Read Triner at 0x7000-0x71ff */
  if ( NesHeader.byInfo1 & 4 )
  {
    fread( &SRAM[ 0x1000 ], 512, 1, fp );
  }

  /* Allocate Memory for ROM Image */
  ROM = (BYTE *)malloc( NesHeader.byRomSize * 0x4000 );

  /* Read ROM Image */
  fread( ROM, 0x4000, NesHeader.byRomSize, fp );

  if ( NesHeader.byVRomSize > 0 )
  {
    /* Allocate Memory for VROM Image */
    VROM = (BYTE *)malloc( NesHeader.byVRomSize * 0x2000 );

    /* Read VROM Image */
    fread( VROM, 0x2000, NesHeader.byVRomSize, fp );
  }

  /* File close */
  fclose( fp );

  /* Successful */
  return 0;
}

/*===================================================================*/
/*                                                                   */
/*           InfoNES_ReleaseRom() : Release a memory for ROM           */
/*                                                                   */
/*===================================================================*/
void InfoNES_ReleaseRom()
{
/*
 *  Release a memory for ROM
 *
 */

  if ( ROM )
  {
    free( ROM );
    ROM = NULL;
  }

  if ( VROM )
  {
    free( VROM );
    VROM = NULL;
  }
}

/*===================================================================*/
/*                                                                   */
/*      InfoNES_LoadFrame() :                                        */
/*           Transfer the contents of work frame on the screen       */
/*                                                                   */
/*===================================================================*/
void InfoNES_LoadFrame()
{
/*
 *  Transfer the contents of work frame on the screen
 *
 */

  // Set screen data
  memcpy( pScreenMem, WorkFrame, NES_DISP_WIDTH * NES_DISP_HEIGHT * 2 );

  // Screen update
  HDC hDC = GetDC( hWndMain );

  HDC hMemDC = CreateCompatibleDC( hDC );

  HBITMAP hOldBmp = (HBITMAP)SelectObject( hMemDC, hScreenBmp );

  StretchBlt( hDC, 0, 0, NES_DISP_WIDTH * wScreenMagnification,
              NES_DISP_HEIGHT * wScreenMagnification, hMemDC,
              0, 0, NES_DISP_WIDTH, NES_DISP_HEIGHT, SRCCOPY );

  SelectObject( hMemDC, hOldBmp );

  DeleteDC( hMemDC );
  ReleaseDC( hWndMain, hDC );
}

/*===================================================================*/
/*                                                                   */
/*             InfoNES_PadState() : Get a joypad state               */
/*                                                                   */
/*===================================================================*/
void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
{
/*
 *  Get a joypad state
 *
 *  Parameters
 *    DWORD *pdwPad1                   (Write)
 *      Joypad 1 State
 *
 *    DWORD *pdwPad2                   (Write)
 *      Joypad 2 State
 *
 *    DWORD *pdwSystem                 (Write)
 *      Input for InfoNES
 *
 */

  static DWORD dwSysOld;
  DWORD dwTemp;

  /* Joypad 1 */
  *pdwPad1 =   ( GetAsyncKeyState( 'X' )        < 0 ) |
             ( ( GetAsyncKeyState( 'Z' )        < 0 ) << 1 ) |
             ( ( GetAsyncKeyState( 'A' )        < 0 ) << 2 ) |
             ( ( GetAsyncKeyState( 'S' )        < 0 ) << 3 ) |
             ( ( GetAsyncKeyState( VK_UP )      < 0 ) << 4 ) |
             ( ( GetAsyncKeyState( VK_DOWN )    < 0 ) << 5 ) |
             ( ( GetAsyncKeyState( VK_LEFT )    < 0 ) << 6 ) |
             ( ( GetAsyncKeyState( VK_RIGHT )   < 0 ) << 7 );

  *pdwPad1 = *pdwPad1 | ( *pdwPad1 << 8 );

  /* Joypad 2 */
  *pdwPad2 = 0;

  /* Input for InfoNES */
  dwTemp = ( GetAsyncKeyState( VK_ESCAPE )  < 0 );

  /* Only the button pushed newly should be inputted */
  *pdwSystem = ~dwSysOld & dwTemp;

  /* keep this input */
  dwSysOld = dwTemp;

  /* Deal with a message */
  MSG msg;
  while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  {
    if ( GetMessage( &msg, NULL, 0, 0 ) )
    {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }
  }
}

/*===================================================================*/
/*                                                                   */
/*             InfoNES_MemoryCopy() : memcpy                         */
/*                                                                   */
/*===================================================================*/
void *InfoNES_MemoryCopy( void *dest, const void *src, int count )
{
/*
 *  memcpy
 *
 *  Parameters
 *    void *dest                       (Write)
 *      Points to the starting address of the copied block乫s destination
 *
 *    const void *src                  (Read)
 *      Points to the starting address of the block of memory to copy
 *
 *    int count                        (Read)
 *      Specifies the size, in bytes, of the block of memory to copy
 *
 *  Return values
 *    Pointer of destination
 */

  CopyMemory( dest, src, count );
  return dest;
}

/*===================================================================*/
/*                                                                   */
/*             InfoNES_MemorySet() : Get a joypad state              */
/*                                                                   */
/*===================================================================*/
void *InfoNES_MemorySet( void *dest, int c, int count )
{
/*
 *  memset
 *
 *  Parameters
 *    void *dest                       (Write)
 *      Points to the starting address of the block of memory to fill
 *
 *    int c                            (Read)
 *      Specifies the byte value with which to fill the memory block
 *
 *    int count                        (Read)
 *      Specifies the size, in bytes, of the block of memory to fill
 *
 *  Return values
 *    Pointer of destination
 */

  FillMemory( dest, count, c );
  return dest;
}

/*===================================================================*/
/*                                                                   */
/*                DebugPrint() : Print debug message                 */
/*                                                                   */
/*===================================================================*/
void InfoNES_DebugPrint( char *pszMsg )
{
  _RPT0( _CRT_WARN, pszMsg );
}

/*===================================================================*/
/*                                                                   */
/*        InfoNES_SoundInit() : Sound Emulation Initialize           */
/*                                                                   */
/*===================================================================*/
void InfoNES_SoundInit( void ) {}

/*===================================================================*/
/*                                                                   */
/*        InfoNES_SoundOpen() : Sound Open                           */
/*                                                                   */
/*===================================================================*/
int InfoNES_SoundOpen( int samples_per_sync, int sample_rate )
{
  lpSndDevice = new DIRSOUND( hWndMain );

  if ( !lpSndDevice->SoundOpen( samples_per_sync, sample_rate ) )
  {
    InfoNES_MessageBox( "SoundOpen() Failed." );
    exit(0);
  }

  // if sound mute, stop sound
  if ( APU_Mute )
  {
    if (!lpSndDevice->SoundMute( APU_Mute ) )
    {
      InfoNES_MessageBox( "SoundMute() Failed." );
      exit(0);
    }
  }

  return(TRUE);
}

/*===================================================================*/
/*                                                                   */
/*        InfoNES_SoundClose() : Sound Close                         */
/*                                                                   */
/*===================================================================*/
void InfoNES_SoundClose( void )
{
  lpSndDevice->SoundClose();
  delete lpSndDevice;
}

/*===================================================================*/
/*                                                                   */
/*            InfoNES_SoundOutput4() : Sound Output 4 Waves          */
/*                                                                   */
/*===================================================================*/
void InfoNES_SoundOutput4( int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4 )
{
  BYTE wave[ rec_freq ];

  for ( int i = 0; i < rec_freq; i++)
  {

    wave[i] = ( wave1[i] + wave2[i] + wave3[i] + wave4[i] ) >> 2;

  }
#if 1
  if (!lpSndDevice->SoundOutput( samples, wave ) )
#else
  if (!lpSndDevice->SoundOutput( samples, wave3 ) )
#endif
  {
    InfoNES_MessageBox( "SoundOutput() Failed." );
    exit(0);
  }
}

/*===================================================================*/
/*                                                                   */
/*            InfoNES_StartTimer() : Start MM Timer                  */
/*                                                                   */
/*===================================================================*/
static void InfoNES_StartTimer()
{
  TIMECAPS caps;

  timeGetDevCaps( &caps, sizeof(caps) );
  timeBeginPeriod( caps.wPeriodMin );

  uTimerID =
    timeSetEvent( caps.wPeriodMin * TIMER_PER_LINE, caps.wPeriodMin, TimerFunc, 0, (UINT)TIME_PERIODIC );

  // Calculate proper timing
  wLinePerTimer = LINE_PER_TIMER * caps.wPeriodMin;

  // Initialize timer variables
  wLines = 0;
  bWaitFlag = TRUE;

  // Initialize Critical Section Object
  InitializeCriticalSection( &WaitFlagCriticalSection );
}

/*===================================================================*/
/*                                                                   */
/*            InfoNES_StopTimer() : Stop MM Timer                    */
/*                                                                   */
/*===================================================================*/
static void InfoNES_StopTimer()
{
  if ( 0 != uTimerID )
  {
    TIMECAPS caps;
    timeKillEvent( uTimerID );
    uTimerID = 0;
    timeGetDevCaps( &caps, sizeof(caps) );
    timeEndPeriod( caps.wPeriodMin * TIMER_PER_LINE );
  }
  // Delete Critical Section Object
  DeleteCriticalSection( &WaitFlagCriticalSection );
}

/*===================================================================*/
/*                                                                   */
/*           TimerProc() : MM Timer Callback Function                */
/*                                                                   */
/*===================================================================*/
static void CALLBACK TimerFunc( UINT nID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
  if ( NULL != m_hThread )
  {
    EnterCriticalSection( &WaitFlagCriticalSection );
    bWaitFlag = FALSE;
    LeaveCriticalSection( &WaitFlagCriticalSection );
  }
}

/*===================================================================*/
/*                                                                   */
/*            InfoNES_Wait() : Wait Emulation if required            */
/*                                                                   */
/*===================================================================*/
void InfoNES_Wait()
{
  wLines++;
  if ( wLines < wLinePerTimer )
    return;
  wLines = 0;

  if ( bAutoFrameskip )
  {
    // Auto Frameskipping
    if ( !bWaitFlag )
    {
      // Increment Frameskip Counter
	    FrameSkip++;
    }
#if 1
    else {
      // Decrement Frameskip Counter
      if ( FrameSkip > 2 )
      {
		    FrameSkip--;
      }
    }
#endif
  }

  // Wait if bWaitFlag is TRUE
  if ( bAutoFrameskip )
  {
    while ( bWaitFlag )
      Sleep(0);
  }

  // set bWaitFlag is TRUE
  EnterCriticalSection( &WaitFlagCriticalSection );
  bWaitFlag = TRUE;
  LeaveCriticalSection( &WaitFlagCriticalSection );
}

/*===================================================================*/
/*                                                                   */
/*            InfoNES_MessageBox() : Print System Message            */
/*                                                                   */
/*===================================================================*/
void InfoNES_MessageBox( char *pszMsg )
{
  MessageBox( hWndMain, pszMsg, APP_NAME, MB_OK | MB_ICONSTOP );
}

/*===================================================================*/
/*                                                                   */
/*            SetWindowSize() : Set Window Size                      */
/*                                                                   */
/*===================================================================*/
void SetWindowSize( WORD wMag )
{
  wScreenMagnification = wMag;

  SetWindowPos( hWndMain, HWND_TOPMOST, 0, 0, NES_DISP_WIDTH * wMag,
                NES_DISP_HEIGHT * wMag + NES_MENU_HEIGHT, SWP_NOMOVE );

  // Show title screen if emulation thread dosent exist
  if ( NULL == m_hThread )
    ShowTitle( hWndMain );
}

⌨️ 快捷键说明

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