void ChatMembershipCallback(TTV_ChatEvent evt, const TTV_ChatChannelInfo* channelInfo, void* /*userdata*/) { switch (evt) { case TTV_CHAT_JOINED_CHANNEL: gChatState = CHAT_STATE(Connected); break; case TTV_CHAT_LEFT_CHANNEL: gChatState = CHAT_STATE(Disconnected); break; default: break; } }
void ChatStatusCallback(TTV_ErrorCode result, void* /*userdata*/) { if (TTV_SUCCEEDED(result)) { } else if (result == TTV_EC_CHAT_LOST_CONNECTION) { gChatState = CHAT_STATE(Disconnected); } else { gChatState = CHAT_STATE(Disconnected); ASSERT_ON_ERROR(result); } }
void FlushChatEvents() { TTV_Chat_FlushEvents(); switch (gChatState) { case CHAT_STATE(Uninitialized): { break; } case CHAT_STATE(Initialized): { gChatState = CHAT_STATE(Connecting); // connect to the channel TTV_ErrorCode ret = TTV_Chat_Connect(gUserName.c_str(), gAuthToken.data); ASSERT_ON_ERROR(ret); // start downloading the emoticon data ret = TTV_Chat_DownloadEmoticonData(USE_TEXTURE_ATLAS != 0, EmoticonDataDownloadCallback, nullptr); ASSERT_ON_ERROR(ret); break; } case CHAT_STATE(Connecting): break; case CHAT_STATE(Connected): break; case CHAT_STATE(Disconnected): break; } }
void InitializeChat(const utf8char* channel) { TTV_ChatCallbacks chatCallbacks; chatCallbacks.statusCallback = ChatStatusCallback; chatCallbacks.membershipCallback = ChatMembershipCallback; chatCallbacks.userCallback = ChatUserCallback; chatCallbacks.messageCallback = ChatMessageCallback; chatCallbacks.clearCallback = ChatClearCallback; chatCallbacks.unsolicitedUserData = nullptr; TTV_ErrorCode ret = TTV_Chat_Init( channel, &chatCallbacks); ASSERT_ON_ERROR(ret); TTV_SetTraceLevel(TTV_ML_CHAT); gChatState = CHAT_STATE(Initialized); }
/** * The main entry point for the application. */ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, gWindowTitle, sizeof(gWindowTitle)); LoadString(hInstance, IDC_INTEGRATION, gWindowClass, sizeof(gWindowClass)); // Register the window class RegisterWindowClass(hInstance); // Perform application initialization: if ( !InitInstance(hInstance, nCmdShow) ) { return FALSE; } // Set the view to the default position ResetView(); // Cache the last mouse position GetCursorPos(&gLastMousePos); // Initialize the Twitch SDK std::string channelName = "<username>"; InitializeStreaming("<username>", "<password>", "<clientId>", "<clientSecret>", GetIntelDllPath()); // Main message loop MSG msg; while (true) { // Check to see if any messages are waiting in the queue while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { // Process window messages TranslateMessage(&msg); DispatchMessage(&msg); // Received a quit message if (msg.message == WM_QUIT) { break; } } // Received a quit message so exit the app if (msg.message == WM_QUIT) { break; } if (gReinitializeRequired) { gReinitializeRequired = false; InitializeRendering(); } // Draw the scene Render(); UpdateWaveMesh(); // Process user input independent of the event queue if (gFocused && !AcceptingChatInput()) { HandleInput(); } // Record the frame time float curTime = GetSystemTimeMs(); // Begin streaming when ready if (gStreamingDesired && !IsStreaming() && IsReadyToStream()) { StartStreaming(gBroadcastWidth, gBroadcastHeight, gBroadcastFramesPerSecond); gLastCaptureTime = 0; } // If you send frames too quickly to the SDK (based on the broadcast FPS you configured) it will not be able // to make use of them all. In that case, it will simply release buffers without using them which means the // game wasted time doing the capture. To mitigate this, the app should pace the captures to the broadcast FPS. float captureDelta = curTime - gLastCaptureTime; bool isTimeForNextCapture = (captureDelta / 1000.0f) >= (1.0f / gBroadcastFramesPerSecond); // streaming is in progress so try and capture a frame if (IsStreaming() && !gPaused && isTimeForNextCapture) { // capture a snapshot of the back buffer unsigned char* pBgraFrame = nullptr; int width = 0; int height = 0; bool gotFrame = false; gotFrame = CaptureFrame(gBroadcastWidth, gBroadcastHeight, pBgraFrame, width, height); // send a frame to the stream if (gotFrame) { SubmitFrame(pBgraFrame); } } // The SDK may generate events that need to be handled by the main thread so we should handle them FlushStreamingEvents(); #undef CHAT_STATE #undef STREAM_STATE #define CHAT_STATE(__state__) CS_##__state__ #define STREAM_STATE(__state__) SS_##__state__ // initialize chat after we have authenticated if (GetChatState() == CHAT_STATE(Uninitialized) && GetStreamState() >= STREAM_STATE(Authenticated)) { InitializeChat(channelName.c_str()); } if (GetChatState() != CHAT_STATE(Uninitialized)) { FlushChatEvents(); } #undef CHAT_STATE #undef STREAM_STATE gLastFrameTime = curTime; // Update the window title to show the state #undef STREAM_STATE #define STREAM_STATE(__state__) #__state__, const char* streamStates[] = { STREAM_STATE_LIST }; #undef STREAM_STATE #undef CHAT_STATE #define CHAT_STATE(__state__) #__state__, const char* chatStates[] = { CHAT_STATE_LIST }; #undef CHAT_STATE char buffer[256]; sprintf_s(buffer, sizeof(buffer), "Twitch Direct3D Integration Sample - %s - Stream:%s Chat:%s", GetUsername().c_str(), streamStates[GetStreamState()], chatStates[GetChatState()]); SetWindowTextA(gWindowHandle, buffer); } StopStreaming(); DeinitChatRenderer(); // Shutdown the Twitch SDK ShutdownChat(); ShutdownStreaming(); DeinitRendering(); // Shutdown the app gGraphicsDevice->Release(); gDirect3D->Release(); // Cleanup the mesh DestroyWaveMesh(); return (int)msg.wParam; }
#include "chat.h" #include "twitchsdk.h" #include "twitchchat.h" #include "chatrenderer.h" #include <assert.h> #include <string> #define USE_TEXTURE_ATLAS 0 extern TTV_AuthToken gAuthToken; extern std::string gUserName; #define CHAT_STATE(__state__) CS_##__state__ static ChatState gChatState = CHAT_STATE(Uninitialized); void ChatStatusCallback(TTV_ErrorCode result, void* /*userdata*/) { if (TTV_SUCCEEDED(result)) { } else if (result == TTV_EC_CHAT_LOST_CONNECTION) { gChatState = CHAT_STATE(Disconnected); } else { gChatState = CHAT_STATE(Disconnected); ASSERT_ON_ERROR(result);