void OpenGL_Blitter::HardSync(uint64 timeout) { GLsync s; if(SupportARBSync) { if((s = p_glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) != NULL) { p_glBegin(GL_POINTS); p_glVertex2f(0.0, 0.0); p_glEnd(); uint32 before = MDFND_GetTime(); p_glClientWaitSync(s, 0, timeout); //50ULL * 1000 * 1000); // 50 milliseconds. printf("Waited: %u\n", MDFND_GetTime() - before); p_glDeleteSync(s); } } }
void MT_SetMovieStatus(StateStatusStruct *status) { if(MovieStatus) { if(MovieStatus->gfx) free(MovieStatus->gfx); free(MovieStatus); } MovieStatus = status; if(status) MovieShow = MDFND_GetTime() + MDFN_GetSettingUI("osd.state_display_time"); else MovieShow = 0; }
void MDFNI_NetplayPing(void) { try { uint64 now_time; now_time = MDFND_GetTime(); // Endianness doesn't matter, since it will be echoed back only to us. SendCommand(MDFNNPCMD_ECHO, sizeof(now_time), &now_time); } catch(std::exception &e) { NetError("%s", e.what()); } }
void DrawSaveStates(SDL_Surface *screen, double exs, double eys, int rs, int gs, int bs, int as) { if(StateShow < MDFND_GetTime()) { SSCleanup(); } if(StateStatus) { if(!PreviewSurface) { PreviewSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, StateStatus->w + 2, StateStatus->h + 2, 32, 0xFF << rs, 0xFF << gs, 0xFF << bs, 0xFF << as); if(!PreviewSurface) { printf("Iyee: %d %d\n", StateStatus->w, StateStatus->h); return; } PreviewRect.x = PreviewRect.y = 0; PreviewRect.w = StateStatus->w + 2; PreviewRect.h = StateStatus->h + 2; MDFN_DrawRectangleAlpha((uint32*)PreviewSurface->pixels, PreviewSurface->pitch >> 2, 0, 0, MK_COLOR_A(PreviewSurface, 0x00, 0x00, 0x9F, 0xFF), MK_COLOR_A(PreviewSurface, 0x00, 0x00, 0x00, 0x80), StateStatus->w + 2, StateStatus->h + 2); uint32 *psp = (uint32*)PreviewSurface->pixels; psp += PreviewSurface->pitch >> 2; psp++; if(StateStatus->gfx) { for(uint32 y = 0; y < StateStatus->h; y++) { uint8 *src_row = StateStatus->gfx + y * StateStatus->w * 3; for(uint32 x = 0; x < StateStatus->w; x++) { psp[x] = MK_COLOR_A(PreviewSurface, src_row[0], src_row[1], src_row[2], 0xFF); src_row += 3; } psp += PreviewSurface->pitch >> 2; } } if(!TextSurface) { TextSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 230, 40, 32, 0xFF << rs, 0xFF << gs, 0xFF << bs, 0xFF << as); SDL_SetColorKey(TextSurface, SDL_SRCCOLORKEY, 0); SDL_SetAlpha(TextSurface, SDL_SRCALPHA, 0); TextRect.x = TextRect.y = 0; TextRect.w = 230; TextRect.h = 40; } if(IsMovie) { UTF8 text[256]; if(StateStatus->current_movie > 0) trio_snprintf((char *)text, 256, _("-recording movie %d-"), StateStatus->current_movie-1); else if (StateStatus->current_movie < 0) trio_snprintf((char *)text, 256, _("-playing movie %d-"),-1 - StateStatus->current_movie); else trio_snprintf((char *)text, 256, _("-select movie-")); DrawStateMovieRow(TextSurface, StateStatus->status, StateStatus->current, StateStatus->recently_saved, text); } else DrawStateMovieRow(TextSurface, StateStatus->status, StateStatus->current, StateStatus->recently_saved, (UTF8 *)_("-select state-")); } } // end if(StateStatus)
void DrawSaveStates(SDL_Surface *screen, double exs, double eys, int rs, int gs, int bs, int as) { StateStatusStruct *tmps; if(StateShow < MDFND_GetTime()) { if(PreviewSurface) { SDL_FreeSurface(PreviewSurface); PreviewSurface = NULL; } if(StateStatus) { if(StateStatus->gfx) free(StateStatus->gfx); free(StateStatus); StateStatus = NULL; } } if(MovieShow < MDFND_GetTime()) { if(PreviewSurface) { SDL_FreeSurface(PreviewSurface); PreviewSurface = NULL; } if(MovieStatus) { if(MovieStatus->gfx) free(MovieStatus->gfx); free(MovieStatus); MovieStatus = NULL; } } tmps = MovieStatus; if(StateStatus) tmps = StateStatus; if(tmps) { if(PreviewSurface) { SDL_FreeSurface(PreviewSurface); PreviewSurface = NULL; } PreviewSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, tmps->w + 2, tmps->h + 2, 32, 0xFF << rs, 0xFF << gs, 0xFF << bs, 0xFF << as); PreviewRect.x = PreviewRect.y = 0; PreviewRect.w = tmps->w + 2; PreviewRect.h = tmps->h + 2; MDFN_DrawRectangleAlpha((uint32*)PreviewSurface->pixels, PreviewSurface->pitch >> 2, 0, 0, MK_COLOR_A(PreviewSurface, 0x00, 0x00, 0x9F, 0xFF), tmps->w + 2, tmps->h + 2); uint32 *psp = (uint32*)PreviewSurface->pixels; psp += PreviewSurface->pitch >> 2; psp++; if(tmps->gfx) for(int y = 0; y < tmps->h; y++) { memcpy(psp, tmps->gfx + y * tmps->pitch, tmps->w * sizeof(uint32)); psp += PreviewSurface->pitch >> 2; } if(!TextSurface) { TextSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 230, 40, 32, 0xFF << rs, 0xFF << gs, 0xFF << bs, 0xFF << as); SDL_SetColorKey(TextSurface, SDL_SRCCOLORKEY, 0); SDL_SetAlpha(TextSurface, SDL_SRCALPHA, 0); TextRect.x = TextRect.y = 0; TextRect.w = 230; TextRect.h = 40; } if(tmps == MovieStatus) { UTF8 text[256]; if(tmps->current_movie > 0) trio_snprintf((char *)text, 256, _("-recording movie %d-"), tmps->current_movie-1); else if (tmps->current_movie < 0) trio_snprintf((char *)text, 256, _("-playing movie %d-"),-1 - tmps->current_movie); else trio_snprintf((char *)text, 256, _("-select movie-")); DrawStateMovieRow(TextSurface, tmps->status, tmps->current, tmps->recently_saved, text); } else DrawStateMovieRow(TextSurface, tmps->status, tmps->current, tmps->recently_saved, (UTF8 *)_("-select state-")); } if(PreviewSurface) { SDL_Rect tdrect, drect; int meow = ((screen->w / CurGame->width) + 1) / 2; if(!meow) meow = 1; tdrect.w = TextRect.w * meow; tdrect.h = TextRect.h * meow; tdrect.x = (screen->w - tdrect.w) / 2; tdrect.y = screen->h - tdrect.h; BlitRaw(TextSurface, &TextRect, &tdrect); drect.w = PreviewRect.w * meow; drect.h = PreviewRect.h * meow; drect.x = (screen->w - drect.w) / 2; drect.y = screen->h - drect.h - tdrect.h - 4; BlitRaw(PreviewSurface, &PreviewRect, &drect); } }
static void ProcessCommand(const uint8 cmd, const uint32 raw_len, const char **PortDNames, void *PortData[], uint32 PortLen[], int NumPorts) { switch(cmd) { case 0: break; // No command default: MDFN_DoSimpleCommand(cmd); break; case MDFNNPCMD_INTEGRITY: SendIntegrity(); break; case MDFNNPCMD_REQUEST_STATE: SendState(); break; case MDFNNPCMD_LOADSTATE: RecvState(raw_len); MDFN_DispMessage(_("Remote state loaded.")); break; case MDFNNPCMD_SERVERTEXT: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; char *textbuf = NULL; const uint32 totallen = raw_len; if(totallen > MaxLength) // Sanity check { throw MDFN_Error(0, _("Text length is too long: %u"), totallen); } MDFND_RecvData(neobuf, totallen); neobuf[totallen] = 0; trio_asprintf(&textbuf, "** %s", neobuf); MDFND_NetplayText((UTF8*)textbuf, FALSE); free(textbuf); } break; case MDFNNPCMD_ECHO: { uint32 totallen = raw_len; uint64 then_time; uint64 now_time; if(totallen != sizeof(then_time)) { throw MDFN_Error(0, _("Echo response length is incorrect size: %u"), totallen); } MDFND_RecvData(&then_time, sizeof(then_time)); now_time = MDFND_GetTime(); char *textbuf = NULL; trio_asprintf(&textbuf, _("*** Round-trip time: %llu ms"), (unsigned long long)(now_time - then_time)); MDFND_NetplayText((UTF8*)textbuf, FALSE); free(textbuf); } break; case MDFNNPCMD_TEXT: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; const uint32 totallen = raw_len; uint32 nicklen; bool NetEcho = false; char *textbuf = NULL; if(totallen < 4) { throw MDFN_Error(0, _("Text command length is too short: %u"), totallen); } if(totallen > MaxLength) // Sanity check { throw MDFN_Error(0, _("Text command length is too long: %u"), totallen); } MDFND_RecvData(neobuf, totallen); nicklen = MDFN_de32lsb(neobuf); if(nicklen > (totallen - 4)) // Sanity check { throw MDFN_Error(0, _("Received nickname length is too long: %u"), nicklen); } neobuf[totallen] = 0; if(nicklen) { uint8 nickbuf[nicklen + 1]; memcpy(nickbuf, neobuf + 4, nicklen); nickbuf[nicklen] = 0; if(OurNick && !strcasecmp(OurNick, (char *)nickbuf)) { trio_asprintf(&textbuf, "> %s", &neobuf[4 + nicklen]); NetEcho = true; } else trio_asprintf(&textbuf, "<%s> %s", nickbuf, &neobuf[4 + nicklen]); } else { trio_asprintf(&textbuf, "* %s", &neobuf[4]); } MDFND_NetplayText((UTF8*)textbuf, NetEcho); free(textbuf); } break; case MDFNNPCMD_NICKCHANGED: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; uint8 *newnick; char *textbuf = NULL; const uint32 len = raw_len; if(len > MaxLength) // Sanity check { throw MDFN_Error(0, _("Nickname change length is too long: %u"), len); } MDFND_RecvData(neobuf, len); neobuf[len] = 0; newnick = (uint8*)strchr((char*)neobuf, '\n'); if(newnick) { bool IsMeow = FALSE; *newnick = 0; newnick++; if(OurNick) { if(!strcasecmp((char*)neobuf, (char*)OurNick)) { free(OurNick); OurNick = strdup((char*)newnick); textbuf = trio_aprintf(_("* You are now known as <%s>."), newnick); IsMeow = TRUE; } } if(!textbuf) textbuf = trio_aprintf(_("* <%s> is now known as <%s>"), neobuf, newnick); MDFND_NetplayText((UTF8*)textbuf, IsMeow); free(textbuf); } } break; case MDFNNPCMD_CTRL_CHANGE: { const uint32 len = raw_len; // // Joined = true; SendCommand(MDFNNPCMD_CTRL_CHANGE_ACK, len); // // LocalInputStateSize = 0; LocalPlayersMask = len; for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++) { if(LocalPlayersMask & (1 << x)) LocalInputStateSize += PortLen[x]; } } break; case MDFNNPCMD_CTRLR_SWAP_NOTIF: { const uint32 cm = raw_len; char textbuf[512]; trio_snprintf(textbuf, sizeof(textbuf), _("* All instances of controllers %u and %u have been swapped."), ((cm & 0xFF) + 1), ((cm >> 8) & 0xFF) + 1); MDFND_NetplayText((UTF8*)textbuf, false); } break; case MDFNNPCMD_CTRLR_TAKE_NOTIF: case MDFNNPCMD_CTRLR_DROP_NOTIF: case MDFNNPCMD_CTRLR_DUPE_NOTIF: { static const uint32 MaxNicknameLength = 1000; static const uint32 MaxLength = 12 + MaxNicknameLength; const char *fstr = NULL; const uint32 len = raw_len; uint8 ntf_buf[MaxLength + 1]; char *textbuf = NULL; if(len < 12) throw MDFN_Error(0, _("Take/drop/dupe notification is too short: %u"), len); if(len > MaxLength) throw MDFN_Error(0, _("Take/drop/dupe notification is too long: %u"), len); MDFND_RecvData(ntf_buf, len); ntf_buf[len] = 0; switch(cmd) { case MDFNNPCMD_CTRLR_TAKE_NOTIF: fstr = _("* <%s> took all instances of %s, and is now %s."); break; case MDFNNPCMD_CTRLR_DUPE_NOTIF: fstr = _("* <%s> took copies of %s, and is now %s."); break; case MDFNNPCMD_CTRLR_DROP_NOTIF: fstr = _("* <%s> dropped %s, and is now %s."); break; } trio_asprintf(&textbuf, fstr, ntf_buf + 12, GenerateMPSString(MDFN_de32lsb(&ntf_buf[0]), true).c_str(), GenerateMPSString(MDFN_de32lsb(&ntf_buf[4]), false).c_str()); MDFND_NetplayText((UTF8*)textbuf, false); free(textbuf); } break; case MDFNNPCMD_YOUJOINED: case MDFNNPCMD_YOULEFT: case MDFNNPCMD_PLAYERLEFT: case MDFNNPCMD_PLAYERJOINED: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; char *textbuf = NULL; uint32 mps; std::string mps_string; const uint32 len = raw_len; if(len < 8) { throw MDFN_Error(0, _("Join/Left length is too short: %u"), len); } if(len > MaxLength) // Sanity check { throw MDFN_Error(0, _("Join/Left length is too long: %u"), len); } MDFND_RecvData(neobuf, len); neobuf[len] = 0; // NULL-terminate the string mps = MDFN_de32lsb(&neobuf[0]); mps_string = GenerateMPSString(mps); if(cmd == MDFNNPCMD_YOULEFT) { // Uhm, not supported yet! LocalPlayersMask = 0; LocalInputStateSize = 0; Joined = FALSE; } else if(cmd == MDFNNPCMD_YOUJOINED) { if(OurNick) // This shouldn't happen, really... { free(OurNick); OurNick = NULL; } OurNick = strdup((char*)neobuf + 8); trio_asprintf(&textbuf, _("* You, %s, have connected as: %s"), neobuf + 8, mps_string.c_str()); LocalPlayersMask = mps; LocalInputStateSize = 0; for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++) { if(LocalPlayersMask & (1U << x)) LocalInputStateSize += PortLen[x]; } Joined = TRUE; SendCommand(MDFNNPCMD_SETFPS, MDFNGameInfo->fps); } else if(cmd == MDFNNPCMD_PLAYERLEFT) { trio_asprintf(&textbuf, _("* %s(%s) has left"), neobuf + 8, mps_string.c_str()); } else { trio_asprintf(&textbuf, _("* %s has connected as: %s"), neobuf + 8, mps_string.c_str()); } MDFND_NetplayText((UTF8*)textbuf, FALSE); free(textbuf); } break; } }