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

📄 netplay.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    S9xNPSendReady (NP_CLNT_RECEIVED_ROM_IMAGE);                break;            case NP_SERV_SRAM_DATA:#ifdef NP_DEBUG                printf ("CLIENT: SRAM_DATA received @%ld\n", S9xGetMilliTime () - START);#endif                S9xNPDiscardHeartbeats ();                S9xNPGetSRAMData (len - 7);                break;            case NP_SERV_FREEZE_FILE:#ifdef NP_DEBUG                printf ("CLIENT: FREEZE_FILE received @%ld\n", S9xGetMilliTime () - START);#endif                S9xNPDiscardHeartbeats ();                S9xNPGetFreezeFile (len - 7);                S9xNPResetJoypadReadPos ();                S9xNPSendReady ();                break;            default:#ifdef NP_DEBUG                printf ("CLIENT: UNKNOWN received @%ld\n", S9xGetMilliTime () - START);#endif                S9xNPDisconnect ();                return (FALSE);	    }	}    }    S9xNPDisconnect ();    return (FALSE);}bool8 S9xNPLoadROMDialog (const char *rom_name){    NetPlay.Answer = FALSE;#ifdef __WIN32__    ResetEvent (NetPlay.ReplyEvent); #ifdef NP_DEBUG    printf ("CLIENT: Asking GUI thread to open ROM load dialog...\n");#endif    PostMessage (GUI.hWnd, WM_USER + 3, (uint32) rom_name, (uint32) rom_name);#ifdef NP_DEBUG    printf ("CLIENT: Waiting for reply from GUI thread...\n");#endif    WaitForSingleObject (NetPlay.ReplyEvent, INFINITE);#ifdef NP_DEBUG    printf ("CLIENT: Got reply from GUI thread (%d)\n", NetPlay.Answer);#endif#endif    return (NetPlay.Answer);}bool8 S9xNPLoadROM (uint32 len){    uint8 *data = new uint8 [len];        S9xNPSetAction ("Receiving ROM name...");    if (!S9xNPGetData (NetPlay.Socket, data, len))    {        S9xNPSetError ("Error while receiving ROM name.");        delete data;        S9xNPDisconnect ();        return (FALSE);    }        S9xNPSetAction ("Opening LoadROM dialog...");    if (!S9xNPLoadROMDialog ((char *) data))    {        S9xNPSetError ("Disconnected from NetPlay server because you are playing a different game!");        delete data;        S9xNPDisconnect ();        return (FALSE);    }    delete data;    return (TRUE);}bool8 S9xNPGetROMImage (uint32 len){    uint8 rom_info [5];    S9xNPSetAction ("Receiving ROM information...");    if (!S9xNPGetData (NetPlay.Socket, rom_info, 5))    {        S9xNPSetError ("Error while receiving ROM information.");        S9xNPDisconnect ();        return (FALSE);    }    uint32 CalculatedSize = READ_LONG (&rom_info [1]);#ifdef NP_DEBUG    printf ("CLIENT: Hi-ROM: %s, Size: %04x\n", rom_info [0] ? "Y" : "N", CalculatedSize);#endif    if (CalculatedSize + 5 >= len ||         CalculatedSize >= CMemory::MAX_ROM_SIZE)    {        S9xNPSetError ("Size error in ROM image data received from server.");        S9xNPDisconnect ();        return (FALSE);    }        Memory.HiROM = rom_info [0];    Memory.LoROM = !Memory.HiROM;    Memory.HeaderCount = 0;    Memory.CalculatedSize = CalculatedSize;    // Load up ROM image#ifdef NP_DEBUG    printf ("CLIENT: Receiving ROM image @%ld...\n", S9xGetMilliTime () - START);#endif    S9xNPSetAction ("Receiving ROM image...");    if (!S9xNPGetData (NetPlay.Socket, Memory.ROM, Memory.CalculatedSize))    {        S9xNPSetError ("Error while receiving ROM image from server.");        Settings.StopEmulation = TRUE;         S9xNPDisconnect ();        return (FALSE);    }#ifdef NP_DEBUG    printf ("CLIENT: Receiving ROM filename @%ld...\n", S9xGetMilliTime () - START);#endif    S9xNPSetAction ("Receiving ROM filename...");    uint32 filename_len = len - Memory.CalculatedSize - 5;    if (filename_len > _MAX_PATH ||        !S9xNPGetData (NetPlay.Socket, (uint8 *) Memory.ROMFilename, filename_len))    {        S9xNPSetError ("Error while receiving ROM filename from server.");        S9xNPDisconnect ();        Settings.StopEmulation = TRUE;        return (FALSE);    }    Memory.InitROM (FALSE);    S9xReset ();    S9xNPResetJoypadReadPos ();    Settings.StopEmulation = FALSE;#ifdef __WIN32__    PostMessage (GUI.hWnd, WM_NULL, 0, 0);#endif        return (TRUE);}void S9xNPGetSRAMData (uint32 len){    if (len > 0x10000)    {        S9xNPSetError ("Length error in S-RAM data received from server.");        S9xNPDisconnect ();        return;    }    S9xNPSetAction ("Receiving S-RAM data...");    if (len > 0 && !S9xNPGetData (NetPlay.Socket, ::SRAM, len))    {        S9xNPSetError ("Error while receiving S-RAM data from server.");        S9xNPDisconnect ();    }}void S9xNPGetFreezeFile (uint32 len){    uint8 frame_count [4];#ifdef NP_DEBUG    printf ("CLIENT: Receiving freeze file information @%ld...\n", S9xGetMilliTime () - START);#endif    S9xNPSetAction ("Receiving freeze file information...");    if (!S9xNPGetData (NetPlay.Socket, frame_count, 4))    {        S9xNPSetError ("Error while receiving freeze file information from server.");        S9xNPDisconnect ();        return;    }    NetPlay.FrameCount = READ_LONG (frame_count);#ifdef NP_DEBUG    printf ("CLIENT: Receiving freeze file @%ld...\n", S9xGetMilliTime () - START);#endif    S9xNPSetAction ("Receiving freeze file...");    uint8 *data = new uint8 [len];    if (!S9xNPGetData (NetPlay.Socket, data, len - 4))    {        S9xNPSetError ("Error while receiving freeze file from server.");        S9xNPDisconnect ();        delete data;        return;    }    char fname [L_tmpnam];    FILE *tmp;    if (tmpnam (fname))    {        if ((tmp = fopen (fname, "wb")))        {            if (fwrite (data, 1, len, tmp) == len)            {                fclose (tmp);                if (!S9xUnfreezeGame (fname))                    S9xNPSetError ("Unable to load freeze file just received.");            }            else                fclose (tmp);        }        remove (fname);    }    delete data;}uint32 S9xNPGetJoypad (int which1){    if (Settings.NetPlay && which1 < 5)	return (NetPlay.Joypads [NetPlay.JoypadReadInd][which1]);    return (0);}void S9xNPStepJoypadHistory (){    if ((NetPlay.JoypadReadInd + 1) % NP_JOYPAD_HIST_SIZE != NetPlay.JoypadWriteInd)    {        NetPlay.JoypadReadInd = (NetPlay.JoypadReadInd + 1) % NP_JOYPAD_HIST_SIZE;        if (NetPlay.FrameCount != NetPlay.Frame [NetPlay.JoypadReadInd])        {            S9xNPSetWarning ("This Snes9X session may be out of sync with the server.");#ifdef NP_DEBUG            printf ("*** CLIENT: client out of sync with server (%d, %d) @%ld\n", NetPlay.FrameCount, NetPlay.Frame [NetPlay.JoypadReadInd], S9xGetMilliTime () - START);#endif        }    }    else    {#ifdef NP_DEBUG        printf ("*** CLIENT: S9xNPStepJoypadHistory NOT OK@%ld\n", S9xGetMilliTime () - START);#endif    }}void S9xNPResetJoypadReadPos (){#ifdef NP_DEBUG    printf ("CLIENT: ResetJoyReadPos @%ld\n", S9xGetMilliTime () - START); fflush (stdout);#endif    NetPlay.JoypadWriteInd = 0;    NetPlay.JoypadReadInd = NP_JOYPAD_HIST_SIZE - 1;    for (int h = 0; h < NP_JOYPAD_HIST_SIZE; h++)        memset ((void *) &NetPlay.Joypads [h], 0, sizeof (NetPlay.Joypads [0]));}bool8 S9xNPSendJoypadUpdate (uint32 joypad){    uint8 data [7];    uint8 *ptr = data;    *ptr++ = NP_CLNT_MAGIC;    *ptr++ = NetPlay.MySequenceNum++;    *ptr++ = NP_CLNT_JOYPAD;    joypad |= 0x80000000;    WRITE_LONG (ptr, joypad);    if (!S9xNPSendData (NetPlay.Socket, data, 7))    {        S9xNPSetError ("Error while sending joypad data server.");	S9xNPDisconnect ();	return (FALSE);    }    return (TRUE);}void S9xNPDisconnect (){    close (NetPlay.Socket);    NetPlay.Socket = -1;    NetPlay.Connected = FALSE;    Settings.NetPlay = FALSE;}bool8 S9xNPSendData (int socket, const uint8 *data, int length){    int len = length;    const uint8 *ptr = data;    NetPlay.PercentageComplete = 0;    do    {        if (NetPlay.Abort)            return (FALSE);        int num_bytes = len;        // Write the data in small chunks, allowing this thread to spot an        // abort request from another thread.        if (num_bytes > 512)            num_bytes = 512;	int sent = write (socket, (char *) ptr, num_bytes);	if (sent < 0)	{	    if (errno == EINTR #ifdef EAGAIN		|| errno == EAGAIN#endif#ifdef EWOULDBLOCK		|| errno == EWOULDBLOCK#endif		)            {#ifdef NP_DEBUG                printf ("CLIENT: EINTR, EAGAIN or EWOULDBLOCK while sending data @%ld\n", S9xGetMilliTime () - START);#endif		continue;            }	    return (FALSE);	}	else	if (sent == 0)	    return (FALSE);	len -= sent;	ptr += sent;        NetPlay.PercentageComplete = (uint8) (((length - len) * 100) / length);    } while (len > 0);    return (TRUE);}bool8 S9xNPGetData (int socket, uint8 *data, int length){    int len = length;    uint8 *ptr = data;    int chunk = length / 50;    if (chunk < 1024)        chunk = 1024;    NetPlay.PercentageComplete = 0;    do    {        if (NetPlay.Abort)            return (FALSE);        int num_bytes = len;        // Read the data in small chunks, allowing this thread to spot an        // abort request from another thread.        if (num_bytes > chunk)            num_bytes = chunk;        int got = read (socket, (char *) ptr, num_bytes);        if (got < 0)        {	    if (errno == EINTR#ifdef EAGAIN		|| errno == EAGAIN#endif#ifdef EWOULDBLOCK		|| errno == EWOULDBLOCK#endif#ifdef WSAEWOULDBLOCK                || errno == WSAEWOULDBLOCK#endif		)            {#ifdef NP_DEBUG                printf ("CLIENT: EINTR, EAGAIN or EWOULDBLOCK while receiving data @%ld\n", S9xGetMilliTime () - START);#endif		continue;            }#ifdef WSAEMSGSIZE            if (errno != WSAEMSGSIZE)                return (FALSE);            else            {                got = num_bytes;#ifdef NP_DEBUG                printf ("CLIENT: WSAEMSGSIZE, actual bytes %d while receiving data @%ld\n", got, S9xGetMilliTime () - START);#endif            }#else            return (FALSE);#endif        }        else        if (got == 0)            return (FALSE);        len -= got;        ptr += got;        if (!Settings.NetPlayServer && length > 1024)        {            NetPlay.PercentageComplete = (uint8) (((length - len) * 100) / length);#ifdef __WIN32__            PostMessage (GUI.hWnd, WM_USER, NetPlay.PercentageComplete,                          NetPlay.PercentageComplete);            Sleep (0);#endif        }                } while (len > 0);    return (TRUE);}bool8 S9xNPInitialise (){    static bool8 initialised = FALSE;#ifdef __WIN32__    if (!initialised)    {        initialised = TRUE;        WSADATA data;#ifdef NP_DEBUG        START = S9xGetMilliTime ();        printf ("CLIENT/SERVER: Initialising WinSock @%ld\n", S9xGetMilliTime () - START);#endif        S9xNPSetAction ("Initialising Windows sockets interface...");        if (WSAStartup (MAKEWORD (1, 0), &data) != 0)        {            S9xNPSetError ("Call to init Windows sockets failed. Do you have WinSock2 installed?");            return (FALSE);         }    }#endif    return (TRUE); }#endifvoid S9xNPDiscardHeartbeats (){    // Discard any pending heartbeats and wait for any frame that is currently    // being emulated to complete.#ifdef NP_DEBUG    printf ("CLIENT: DiscardHeartbeats @%ld, finished @", S9xGetMilliTime () - START);    fflush (stdout);#endif#ifdef __WIN32__    while (WaitForSingleObject (GUI.ClientSemaphore, 200) == WAIT_OBJECT_0)        ;#endif#ifdef NP_DEBUG    printf ("%ld\n", S9xGetMilliTime () - START);#endif    NetPlay.Waiting4EmulationThread = FALSE;}void S9xNPSetAction (const char *action, bool8 force){    if (force || !Settings.NetPlayServer)    {        strncpy (NetPlay.ActionMsg, action, NP_MAX_ACTION_LEN - 1);        NetPlay.ActionMsg [NP_MAX_ACTION_LEN - 1] = 0;#ifdef __WIN32__        PostMessage (GUI.hWnd, WM_USER, 0, 0);        Sleep (0);#endif    }}void S9xNPSetError (const char *error){    strncpy (NetPlay.ErrorMsg, error, NP_MAX_ACTION_LEN - 1);    NetPlay.ErrorMsg [NP_MAX_ACTION_LEN - 1] = 0;#ifdef __WIN32    PostMessage (GUI.hWnd, WM_USER + 1, 0, 0);    Sleep (0);#endif}void S9xNPSetWarning (const char *warning){    strncpy (NetPlay.WarningMsg, warning, NP_MAX_ACTION_LEN - 1);    NetPlay.WarningMsg [NP_MAX_ACTION_LEN - 1] = 0;#ifdef __WIN32__    PostMessage (GUI.hWnd, WM_USER + 2, 0, 0);    Sleep (0);#endif}

⌨️ 快捷键说明

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