Exemple #1
0
static void Freeze()
{
   char buffer[1024];
   int i;

   S9xSetSoundMute(TRUE);

   S9xSRTCPreSaveState();

   for (i = 0; i < 8; i++)
   {
      SoundData.channels [i].previous16 [0] = (int16) SoundData.channels [i].previous [0];
      SoundData.channels [i].previous16 [1] = (int16) SoundData.channels [i].previous [1];
   }
   sprintf(buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
   statef_write(buffer, strlen(buffer));
   sprintf(buffer, "NAM:%06d:%s%c", strlen(Memory.ROMFilename) + 1,
           Memory.ROMFilename, 0);
   statef_write(buffer, strlen(buffer) + 1);
   FreezeStruct("CPU", &CPU, SnapCPU, COUNT(SnapCPU));
   FreezeStruct("REG", &Registers, SnapRegisters, COUNT(SnapRegisters));
   FreezeStruct("PPU", &PPU, SnapPPU, COUNT(SnapPPU));
   FreezeStruct("DMA", DMA, SnapDMA, COUNT(SnapDMA));

   // RAM and VRAM
   FreezeBlock("VRA", Memory.VRAM, 0x10000);
   FreezeBlock("RAM", Memory.RAM, 0x20000);
   FreezeBlock("SRA", SRAM, 0x20000);
   FreezeBlock("FIL", Memory.FillRAM, 0x8000);
   if (Settings.APUEnabled)
   {
      // APU
      FreezeStruct("APU", &APU, SnapAPU, COUNT(SnapAPU));
      // copy all SPC700 regs to savestate compatible struct
      SAPURegisters spcregs;
      spcregs.P  = IAPU.P;
      spcregs.YA.W = IAPU.YA.W;
      spcregs.X  = IAPU.X;
      spcregs.S  = IAPU.S;
      spcregs.PC = IAPU.PC - IAPU.RAM;
      FreezeStruct("ARE", &spcregs, SnapAPURegisters,
                   COUNT(SnapAPURegisters));

      FreezeBlock("ARA", IAPU.RAM, 0x10000);
      FreezeStruct("SOU", &SoundData, SnapSoundData,
                   COUNT(SnapSoundData));
   }
#ifdef USE_SA1
   if (Settings.SA1)
   {
      SA1Registers.PC = SA1.PC - SA1.PCBase;
      S9xSA1PackStatus();
      FreezeStruct("SA1", &SA1, SnapSA1, COUNT(SnapSA1));
      FreezeStruct("SAR", &SA1Registers, SnapSA1Registers,
                   COUNT(SnapSA1Registers));
   }
#endif
   S9xSetSoundMute(FALSE);
}
Exemple #2
0
void FreezeStruct(char* name, void* base, FreezeData* fields,
                  int num_fields)
{
   // Work out the size of the required block
   int len = 0;
   int i;
   int j;

   for (i = 0; i < num_fields; i++)
   {
      if (fields [i].offset + FreezeSize(fields [i].size,
                                         fields [i].type) > len)
         len = fields [i].offset + FreezeSize(fields [i].size,
                                              fields [i].type);
   }

   //    uint8 *block = new uint8 [len];
   uint8* block = (uint8*)malloc(len);
   uint8* ptr = block;
   uint16 word;
   uint32 dword;
   int64  qword;

   // Build the block ready to be streamed out
   for (i = 0; i < num_fields; i++)
   {
      switch (fields [i].type)
      {
      case INT_V:
         switch (fields [i].size)
         {
         case 1:
            *ptr++ = *((uint8*) base + fields [i].offset);
            break;
         case 2:
            word = *((uint16*)((uint8*) base + fields [i].offset));
            *ptr++ = (uint8)(word >> 8);
            *ptr++ = (uint8) word;
            break;
         case 4:
            dword = *((uint32*)((uint8*) base + fields [i].offset));
            *ptr++ = (uint8)(dword >> 24);
            *ptr++ = (uint8)(dword >> 16);
            *ptr++ = (uint8)(dword >> 8);
            *ptr++ = (uint8) dword;
            break;
         case 8:
            qword = *((int64*)((uint8*) base + fields [i].offset));
            *ptr++ = (uint8)(qword >> 56);
            *ptr++ = (uint8)(qword >> 48);
            *ptr++ = (uint8)(qword >> 40);
            *ptr++ = (uint8)(qword >> 32);
            *ptr++ = (uint8)(qword >> 24);
            *ptr++ = (uint8)(qword >> 16);
            *ptr++ = (uint8)(qword >> 8);
            *ptr++ = (uint8) qword;
            break;
         }
         break;
      case uint8_ARRAY_V:
         memmove(ptr, (uint8*) base + fields [i].offset, fields [i].size);
         ptr += fields [i].size;
         break;
      case uint16_ARRAY_V:
         for (j = 0; j < fields [i].size; j++)
         {
            word = *((uint16*)((uint8*) base + fields [i].offset + j * 2));
            *ptr++ = (uint8)(word >> 8);
            *ptr++ = (uint8) word;
         }
         break;
      case uint32_ARRAY_V:
         for (j = 0; j < fields [i].size; j++)
         {
            dword = *((uint32*)((uint8*) base + fields [i].offset + j * 4));
            *ptr++ = (uint8)(dword >> 24);
            *ptr++ = (uint8)(dword >> 16);
            *ptr++ = (uint8)(dword >> 8);
            *ptr++ = (uint8) dword;
         }
         break;
      }
   }

   FreezeBlock(name, block, len);

   free(block);
}
Exemple #3
0
/**
 *  응용프로그램의 C 언어 엔트리 포인트
 */
int Main( char* pcArgument )
{
    QWORD qwWindowID;
    EVENT stEvent;
    KEYEVENT *pstKeyEvent;
    QWORD qwLastTickCount;
    char* pcStartMessage = "Please LButton Down To Start~!";
    RECT stScreenArea;
    int iX;
    int iY;
    BYTE bBlockKind;
    
    //--------------------------------------------------------------------------
    // 윈도우를 화면 가운데에 생성
    //--------------------------------------------------------------------------
    GetScreenArea( &stScreenArea );
    iX = ( GetRectangleWidth( &stScreenArea ) - WINDOW_WIDTH ) / 2;
    iY = ( GetRectangleHeight( &stScreenArea ) - WINDOW_HEIGHT ) / 2;
    qwWindowID = CreateWindow( iX, iY, WINDOW_WIDTH, WINDOW_HEIGHT,
                               WINDOW_FLAGS_DEFAULT, "Hexa" );
    if( qwWindowID == WINDOW_INVALIDID )
    {
        printf( "Window create fail\n" );
        return -1;
    }

    //--------------------------------------------------------------------------
    // 게임에 관련된 정보를 초기화하고 사용할 버퍼를 할당
    //--------------------------------------------------------------------------
    // 게임 정보를 초기화
    Initialize();

    // 난수 초깃값(Random Seed) 설정
    srand( GetTickCount() );

    //--------------------------------------------------------------------------
    // 게임 정보와 게임 영역을 출력하고 게임 시작 대기 메시지를 표시
    //--------------------------------------------------------------------------
    DrawInformation( qwWindowID );
    DrawGameArea( qwWindowID );
    DrawText( qwWindowID, 7, 200, RGB( 255, 255, 255 ), RGB( 0, 0, 0 ),
            pcStartMessage, strlen( pcStartMessage ) );

    // 출력된 메시지를 화면에 표시
    ShowWindow( qwWindowID, TRUE );

    //--------------------------------------------------------------------------
    // GUI 태스크의 이벤트와 게임 루프를 처리하는 부분
    //--------------------------------------------------------------------------
    qwLastTickCount = GetTickCount();
    while( 1 )
    {
        //----------------------------------------------------------------------
        // 이벤트 처리 부분
        //----------------------------------------------------------------------
        // 이벤트 큐에서 이벤트를 수신
        if( ReceiveEventFromWindowQueue( qwWindowID, &stEvent ) == TRUE )
        {
            // 수신된 이벤트를 타입에 따라 나누어 처리
            switch( stEvent.qwType )
            {
                // 마우스 클릭 처리
            case EVENT_MOUSE_LBUTTONDOWN:
                // 게임 시작을 원하는 클릭이면 게임을 시작
                if( g_stGameInfo.bGameStart == FALSE )
                {
                    // 게임 정보를 초기화
                    Initialize();

                    // 게임 시작 플래그를 설정
                    g_stGameInfo.bGameStart = TRUE;
                    break;
                }
                break;

                // 키보드 눌림 처리
            case EVENT_KEY_DOWN:
                pstKeyEvent = &( stEvent.stKeyEvent );
                if( g_stGameInfo.bGameStart == FALSE )
                {
                    break;
                }

                switch( pstKeyEvent->bASCIICode )
                {
                    // 왼쪽으로 이동
                case KEY_LEFT:
                    if( IsMovePossible( g_stGameInfo.iBlockX - 1,
                                        g_stGameInfo.iBlockY ) == TRUE )
                    {
                        g_stGameInfo.iBlockX -= 1;
                        DrawGameArea( qwWindowID );
                    }
                    break;

                    // 오른쪽으로 이동
                case KEY_RIGHT:
                    if( IsMovePossible( g_stGameInfo.iBlockX + 1,
                                        g_stGameInfo.iBlockY ) == TRUE )
                    {
                        g_stGameInfo.iBlockX += 1;
                        DrawGameArea( qwWindowID );
                    }
                    break;

                    // 움직이는 블록을 구성하는 작은 블록의 순서를 변경
                case KEY_UP:
                    bBlockKind = g_stGameInfo.vbBlock[ 0 ];
                    memcpy( &( g_stGameInfo.vbBlock ), &( g_stGameInfo.vbBlock[ 1 ] ),
                            BLOCKCOUNT - 1 );
                    g_stGameInfo.vbBlock[ BLOCKCOUNT - 1 ] = bBlockKind;

                    DrawGameArea( qwWindowID );
                    break;

                    // 블록을 아래로 이동
                case KEY_DOWN:
                    if( IsMovePossible( g_stGameInfo.iBlockX,
                                        g_stGameInfo.iBlockY + 1 ) == TRUE )
                    {
                        g_stGameInfo.iBlockY += 1;
                    }
                    DrawGameArea( qwWindowID );
                    break;

                    // 블록을 아래로 끝까지 이동
                case ' ':
                    while( IsMovePossible( g_stGameInfo.iBlockX,
                                           g_stGameInfo.iBlockY + 1 ) == TRUE )
                    {
                        g_stGameInfo.iBlockY += 1;
                    }
                    DrawGameArea( qwWindowID );
                    break;
                }

                // 변경된 내용을 화면에 표시
                ShowWindow( qwWindowID, TRUE );
                break;

                // 윈도우 닫기 버튼 처리
            case EVENT_WINDOW_CLOSE:
                // 윈도우를 삭제
                DeleteWindow( qwWindowID );
                return 0;
                break;
            }
        }

        //----------------------------------------------------------------------
        // 게임 루프 처리 부분
        //----------------------------------------------------------------------
        // 게임이 시작 되었다면 레벨에 따라 일정 시간 대기한 뒤에 블록을 아래로 이동
        if( ( g_stGameInfo.bGameStart == TRUE ) &&
            ( ( GetTickCount() - qwLastTickCount ) >
              ( 300 - ( g_stGameInfo.qwLevel * 10 ) ) ) )
        {
            qwLastTickCount = GetTickCount();

            // 블록을 한 칸 아래로 내리고 더 이상 내릴 수 없다면 블록을 고정
            if( IsMovePossible( g_stGameInfo.iBlockX, g_stGameInfo.iBlockY + 1 ) ==
                    FALSE )
            {
                // 블록 고정할 수 없으면 게임 종료
                if( FreezeBlock( g_stGameInfo.iBlockX, g_stGameInfo.iBlockY ) ==
                        FALSE )
                {
                    g_stGameInfo.bGameStart = FALSE;

                    // 게임 종료 메시지를 출력
                    DrawText( qwWindowID, 82, 230, RGB( 255, 255, 255 ), RGB( 0, 0, 0 ),
                            "Game Over~!!!", 13 );
                    DrawText( qwWindowID, 7, 250, RGB( 255, 255, 255 ), RGB( 0, 0, 0 ),
                            pcStartMessage, strlen( pcStartMessage ) );
                }

                // 보드에 블록을 검사하여 3개 이상 연속된 블록을 삭제하고 화면에 표시
                EraseAllContinuousBlockOnBoard( qwWindowID );

                // 새로운 블록을 생성
                CreateBlock();
            }
            else
            {
                g_stGameInfo.iBlockY++;

                // 게임 영역을 새로 그림
                DrawGameArea( qwWindowID );
            }

            // 변경된 내용을 화면에 표시
            ShowWindow( qwWindowID, TRUE );
        }
        else
        {
            Sleep( 0 );
        }
    }

    return 0;
}