struct graphicstexture *graphicstexture_createHWSDL( struct graphicstexture *gt, void *data, size_t width, size_t height, int format, uint64_t time) { // create hw texture #ifdef DEBUGUPLOADTIMING uint64_t ts1 = time_getMilliseconds(); #endif gt->sdltex = SDL_CreateTexture(mainrenderer, graphicstexture_pixelFormatToSDLFormat(format), SDL_TEXTUREACCESS_STREAMING, gt->width, gt->height); if (!gt->sdltex) { graphicstexture_destroy(gt); return NULL; } #ifdef DEBUGUPLOADTIMING uint64_t ts2 = time_getMilliseconds(); #endif // lock texture void *pixels; int pitch; if (SDL_LockTexture(gt->sdltex, NULL, &pixels, &pitch) != 0) { graphicstexture_destroy(gt); return NULL; } #ifdef DEBUGUPLOADTIMING uint64_t ts3 = time_getMilliseconds(); #endif // copy pixels into texture memcpy(pixels, data, gt->width * gt->height * 4); // FIXME: we probably need to handle pitch here?? #ifdef DEBUGUPLOADTIMING uint64_t ts4 = time_getMilliseconds(); #endif // unlock texture SDL_UnlockTexture(gt->sdltex); #ifdef DEBUGUPLOADTIMING uint64_t ts5 = time_getMilliseconds(); if (ts5-ts1 > 100) { printwarning("[sdltex] texture upload duration: %dms total, " "%dms creation, %dms lock, %dms copy, %dms unlock", (int)(ts5-ts1), (int)(ts2-ts1), (int)(ts3-ts2), (int)(ts4-ts3), (int)(ts5-ts4)); } #endif // set blend mode SDL_SetTextureBlendMode(gt->sdltex, SDL_BLENDMODE_BLEND); return gt; }
void kunit_test_suiteRun(kunit_test_suite_t *suite) { assert(kunit_test_suite_currentSuite == NULL); kunit_test_suite_currentSuite = suite; info("Test suite '%s' started.\n", suite->name); suite->started = time_getTimestamp(); kunit_test_t *test = suite->firstTest; while(test) { suite->currentTest = test; suite->run ++; kunit_testRun(test); if(test->state == kunit_test_state_failed) suite->failed += test->failures; test = test->next; } suite->finished = time_getTimestamp(); timestamp_t diff = suite->finished - suite->started; uint32_t seconds = time_getSeconds(diff); uint32_t millisecs = time_getMilliseconds(diff); info("Executed %i tests with %i failures (%i.%03i s).\n\n", suite->run, suite->failed, seconds, millisecs); kunit_test_suite_currentSuite = NULL; if(suite->destroyAfterRun) kunit_test_suiteDestroy(suite); }
void graphicssdlrender_startFrame(void) { #ifdef USE_SDL_GRAPHICS_OPENGL_EFFECTS if (maincontext) { GLenum err; if ((err = glGetError()) != GL_NO_ERROR) { printwarning("graphicsrender_startFrame: earlier error " "around: %s", gluErrorString(err)); } renderts = time_getMilliseconds(); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); if ((err = glGetError()) != GL_NO_ERROR) { printwarning("graphicsrender_startFrame: " "glClear error: %s", gluErrorString(err)); } glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); int actualwidth, actualheight; SDL_GetWindowSize(mainwindow, &actualwidth, &actualheight); glOrtho(0, actualwidth, actualheight, 0, -1, 1); return; } #endif SDL_SetRenderDrawColor(mainrenderer, 0, 0, 0, 1); SDL_RenderClear(mainrenderer); }
// Initialise the given connection struct and open the connection void connections_Init(struct connection* c, const char* target, int port, int linebuffered, int lowdelay, int canautoclose, void (*autoclosecallback)(struct connection* c), void* userdata) { int oldluaref = c->luarefcount; memset(c, 0, sizeof(*c)); c->luarefcount = oldluaref; c->socket = -1; c->error = -1; c->canautoclose = canautoclose; c->autoclosecallback = autoclosecallback; c->userdata = userdata; c->lowdelay = lowdelay; c->targetport = port; c->linebuffered = linebuffered; c->lastreadtime = time_getMilliseconds(); if (connectionlist) { c->next = connectionlist; } connectionlist = c; #ifdef CONNECTIONSDEBUG printinfo("[connections] Adding connection to list"); #endif // initialise socket system (just in case it's not done yet): if (!so_Startup()) { c->error = CONNECTIONERROR_INITIALISATIONFAILED; return; } // with an empty target, we simply won't do anything except instant-error: if (!target) { c->error = CONNECTIONERROR_NOSUCHHOST; return; } // allocate buffers: c->inbuf = malloc(CONNECTIONINBUFSIZE); if (!c->inbuf) { c->error = CONNECTIONERROR_INITIALISATIONFAILED; return; } c->inbufsize = CONNECTIONINBUFSIZE; c->outbuf = malloc(CONNECTIONOUTBUFSIZE); if (!c->outbuf) { c->error = CONNECTIONERROR_INITIALISATIONFAILED; return; } c->outbufsize = CONNECTIONOUTBUFSIZE; // get a socket if (isipv4ip(target)) { // only take ipv4 when it's obvious if (!connections_SetSocket(c, IPTYPE_IPV4)) { c->error = CONNECTIONERROR_INITIALISATIONFAILED; return; } } else { // otherwise, try ipv6 first if (!connections_SetSocket(c, IPTYPE_IPV6)) { c->error = CONNECTIONERROR_INITIALISATIONFAILED; return; } } // we probably need to resolve the host first: if (!isipv4ip(target) && !isipv6ip(target)) { c->hostresolveptr = hostresolv_LookupRequest(target, 0); c->hostresolveptrv6 = hostresolv_LookupRequest(target, 1); if (!c->hostresolveptrv6) { // we really want v6 resolution, so we work well with ipv6-only if (c->hostresolveptr) { hostresolv_CancelRequest(c->hostresolveptr); } c->hostresolveptr = NULL; } #ifdef CONNECTIONSDEBUG printinfo("[connections] resolving target: %s",target); #endif return; } // connect: int result = connections_TryConnect(c, target); if (!result) { return; } // we want to know when ready for writing, since that means we're connected: so_SelectWantWrite(c->socket, 1); #ifdef CONNECTIONSDEBUG printinfo("[connections] connecting to ip: %s", target); #endif }
// Check all connections for events, updates etc int connections_CheckAll(int (*connectedcallback)(struct connection* c), int (*readcallback)(struct connection* c, char* data, unsigned int datalength), int (*errorcallback)(struct connection* c, int error)) { // initialise socket system (just in case it's not done yet): if (!so_Startup()) { return 1; } struct connection* c = connectionlist; while (c) { struct connection* cnext = c->next; // don't process connections with errors if (c->error >= 0) { if (!c->errorreported) { c->errorreported = 1; if (errorcallback) { if (!errorcallback(c, c->error)) { // an error occured. proceed to next connect: c = cnext; continue; } } } } // check for auto close: if (c->canautoclose && c->wantautoclose && (c->error >= 0 || c->lastreadtime + 30000 < time_getMilliseconds()) && !c->closewhensent) { if (c->error >= 0) { // connection already error'd, we can get rid of it: #ifdef CONNECTIONSDEBUG printinfo("[connections] autoclosing connection %d", c->socket); #endif c->autoclosecallback(c); connections_Close(c); c = cnext; } else { // make the connection error: connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONAUTOCLOSE); } continue; } // check for close after send: if (c->outbufbytes <= 0 && c->closewhensent) { if (c->luarefcount <= 0) { #ifdef CONNECTIONSDEBUG printinfo("[connections] closing connection %d " "since data is sent", c->socket); #endif connections_Close(c); } else { // lua still has a reference, don't close } c = cnext; continue; } // check host resolve requests first: if (c->error < 0 && !c->closewhensent && (c->hostresolveptr || c->hostresolveptrv6)) { int rqstate1 = RESOLVESTATUS_SUCCESS; if (c->hostresolveptr) { rqstate1 = hostresolv_GetRequestStatus(c->hostresolveptr); } int rqstate2 = RESOLVESTATUS_SUCCESS; if (c->hostresolveptrv6) { rqstate2 = hostresolv_GetRequestStatus(c->hostresolveptrv6); } if (rqstate1 != RESOLVESTATUS_PENDING && rqstate2 != RESOLVESTATUS_PENDING) { // requests are done, get ips: char* ipv4 = NULL; char* ipv6 = NULL; // ipv4 ip: const char* p = NULL; if (rqstate1 == RESOLVESTATUS_SUCCESS && c->hostresolveptr) { p = hostresolv_GetRequestResult(c->hostresolveptr); } if (p) { ipv4 = strdup(p); } // ipv6 ip: p = NULL; if (rqstate2 == RESOLVESTATUS_SUCCESS && c->hostresolveptrv6) { p = hostresolv_GetRequestResult(c->hostresolveptrv6); } if (p) { ipv6 = strdup(p); } // free requests: if (c->hostresolveptr) { hostresolv_CancelRequest(c->hostresolveptr); } if (c->hostresolveptrv6) { hostresolv_CancelRequest(c->hostresolveptrv6); } c->hostresolveptr = NULL; c->hostresolveptrv6 = NULL; #ifdef CONNECTIONSDEBUG printinfo("[connections] resolved host, results: v4: %s, v6: %s", ipv4, ipv6); #endif // if we got a v6 ip, connect there first: int result; if (ipv6) { // Prefer an IPv6 connection: result = connections_TryConnect(c, ipv6); free(ipv6); if (!result) { if (ipv4) { c->error = -1; // Try an IPv4 connection: result = connections_TryConnect(c, ipv4); free(ipv4); if (!result) { connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONFAILED); } } c = cnext; continue; } // ok we are about to connect, preserve v4 ip for later trying in case it fails: c->retryv4ip = ipv4; // then continue: c = cnext; continue; } else { if (ipv4) { // Attempt an IPv4 connection: result = connections_TryConnect(c, ipv4); if (result) { free(ipv4); c = cnext; continue; } // Didn't work, so nothing we can do: free(ipv4); connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONFAILED); } else { connections_E(c, errorcallback, CONNECTIONERROR_NOSUCHHOST); } c = cnext; continue; } } } // if the connection is attempting to connect, check if it succeeded: if (c->error < 0 && !c->closewhensent && !c->connected && c->socket >= 0) { if (so_SelectSaysWrite(c->socket, &c->sslptr)) { if (c->outbufbytes <= 0) { so_SelectWantWrite(c->socket, 0); } if (so_CheckIfConnected(c->socket, &c->sslptr)) { #ifdef CONNECTIONSDEBUG printinfo("[connections] now connected"); #endif c->connected = 1; if (connectedcallback) { if (!connectedcallback(c)) { // a callback error occured. // we will simply continue. } } } else { // we aren't connected! if (c->retryv4ip) { // we tried ipv6, now try ipv4 #ifdef CONNECTIONSDEBUG printinfo("[connections] retrying v4 after v6 " "fail..."); #endif // attempt to connect: int result = connections_TryConnect(c, c->retryv4ip); free(c->retryv4ip); c->retryv4ip = NULL; if (!result) { connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONFAILED); } c = cnext; continue; } #ifdef CONNECTIONSDEBUG printinfo("[connections] connection couldn't be " "established"); #endif connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONFAILED); c = cnext; continue; } } } // read things if we can: if (c->error < 0 && c->socket >= 0 && !c->closewhensent && c->connected) { if (so_SelectSaysRead(c->socket, &c->sslptr)) { if (c->inbufbytes >= c->inbufsize && c->linebuffered == 1) { // we will break this mega line into two: // first, send without line processing: c->linebuffered = 0; int closed = 0; if (!connections_ProcessReceivedData(c, readcallback, &closed)) { // an error occured in te read callback. // we will simply continue. } if (closed) { // connection was closed by callback c = cnext; continue; } if (c->error >= 0) { // lua closed this connection c = cnext; continue; } // then, turn it back on: c->linebuffered = 1; } // read new bytes into the buffer: int r = so_ReceiveSSLData(c->socket, c->inbuf + c->inbufbytes, c->inbufsize - c->inbufbytes, &c->sslptr); if (r == 0) { // connection closed. send out all data we still have: if (c->inbufbytes > 0) { int closed = 0; if (!connections_ProcessReceivedData( c, readcallback, &closed)) { // an error occured in the read callback. // we will simply continue. } if (closed) { // connection was closed by callback c = cnext; continue; } } // then error: connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONCLOSED); #ifdef CONNECTIONSDEBUG printinfo("[connections] receive on %d returned " "end of stream", c->socket); #endif c = cnext; continue; } if (r > 0) { // we successfully received new bytes c->inbufbytes += r; c->lastreadtime = time_getMilliseconds(); int closed = 0; if (!connections_ProcessReceivedData(c, readcallback, &closed)) { // an error occured in the read callback. // we will simply continue. } if (closed) { // connection was closed by callback c = cnext; continue; } } } } // write things if we can: if ((c->error < 0 || (c->closewhensent)) && c->connected && c->outbufbytes > 0 && c->socket >= 0) { if (so_SelectSaysWrite(c->socket, &c->sslptr)) { int r = so_SendSSLData(c->socket, c->outbuf + c->outbufoffset, c->outbufbytes, &c->sslptr); if (r == 0) { // connection closed: connections_E(c, errorcallback, CONNECTIONERROR_CONNECTIONCLOSED); #ifdef CONNECTIONSDEBUG printinfo("[connections] send returned end of stream"); #endif c = cnext; continue; } // remove sent bytes from buffer: if (r > 0) { c->outbufbytes -= r; c->outbufoffset += r; so_SelectWantWrite(c->socket, 1); if (c->outbufbytes <= 0) { c->outbufoffset = 0; so_SelectWantWrite(c->socket, 0); } else { if (c->outbufoffset > CONNECTIONOUTBUFSIZE/2) { // move buffer contents back to beginning memmove(c->outbuf, c->outbuf + c->outbufoffset, c->outbufbytes); c->outbufoffset = 0; } } } } } // check for close after send: if (c->outbufbytes <= 0 && c->closewhensent) { if (c->luarefcount <= 0) { #ifdef CONNECTIONSDEBUG printinfo("[connections] closing connection %d since data is sent", c->socket); #endif connections_Close(c); } else { // lua still has a reference, but close at least the socket: so_CloseSSLSocket(c->socket, &c->sslptr); c->socket = -1; } c = cnext; continue; } c = cnext; } return 1; }