char *dStrnew(const char *src) { char *buffer = new char[dStrlen(src) + 1]; dStrcpy(buffer, src); return buffer; }
void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList ) { AssertFatal( SDL_WasInit(SDL_INIT_VIDEO), ""); PlatformGL::init(); // for hints about context creation // Create a dummy window & openGL context so that gl functions can be used here SDL_Window* tempWindow = SDL_CreateWindow( "", // window title SDL_WINDOWPOS_UNDEFINED, // initial x position SDL_WINDOWPOS_UNDEFINED, // initial y position 640, // width, in pixels 480, // height, in pixels SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN // flags - see below ); SDL_ClearError(); SDL_GLContext tempContext = SDL_GL_CreateContext( tempWindow ); if( !tempContext ) { const char *err = SDL_GetError(); Con::printf( err ); AssertFatal(0, err ); return; } SDL_ClearError(); SDL_GL_MakeCurrent( tempWindow, tempContext ); const char *err = SDL_GetError(); if( err && err[0] ) { Con::printf( err ); AssertFatal(0, err ); } //check minimun Opengl 3.2 int major, minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); if( major < 3 || ( major == 3 && minor < 2 ) ) { Con::errorf("GFXGLDevice: Error! Need OpenGL 3.2 at least, have %i.%i.", major, minor); return; } loadGLCore(); GFXAdapter *toAdd = new GFXAdapter; toAdd->mIndex = 0; const char* renderer = (const char*) glGetString( GL_RENDERER ); AssertFatal( renderer != NULL, "GL_RENDERER returned NULL!" ); if (renderer) { dStrcpy(toAdd->mName, renderer); dStrncat(toAdd->mName, " OpenGL", GFXAdapter::MaxAdapterNameLen); } else dStrcpy(toAdd->mName, "OpenGL"); toAdd->mType = OpenGL; toAdd->mShaderModel = 0.f; toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance; // Enumerate all available resolutions: EnumerateVideoModes(toAdd->mAvailableModes); // Add to the list of available adapters. adapterList.push_back(toAdd); // Cleanup window & open gl context SDL_DestroyWindow( tempWindow ); SDL_GL_DeleteContext( tempContext ); }
char *dStrdup_r(const char *src, const char *file, dsize_t line) { char *buffer = (char *) dMalloc_r(dStrlen(src) + 1, file, line); dStrcpy(buffer, src); return buffer; }
bool Net::stringToAddress(const char *addressString, NetAddress *address) { if(!dStrnicmp(addressString, "ipx:", 4)) // ipx support deprecated return false; if(!dStrnicmp(addressString, "ip:", 3)) addressString += 3; // eat off the ip: sockaddr_in ipAddr; char remoteAddr[256]; if(strlen(addressString) > 255) return false; dStrcpy(remoteAddr, addressString); char *portString = dStrchr(remoteAddr, ':'); if(portString) *portString++ = '\0'; if(!dStricmp(remoteAddr, "broadcast")) ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); else { ipAddr.sin_addr.s_addr = inet_addr(remoteAddr); if (ipAddr.sin_addr.s_addr == INADDR_NONE) // error { // On the Xbox, 'gethostbyname' does not exist so... #ifndef TORQUE_OS_XENON struct hostent *hp; if((hp = gethostbyname(remoteAddr)) == 0) return false; else memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(in_addr)); #else // On the Xbox do XNetDnsLookup XNDNS *pxndns = NULL; HANDLE hEvent = CreateEvent(NULL, false, false, NULL); XNetDnsLookup(remoteAddr, hEvent, &pxndns); // Wait for event (passing NULL as a handle to XNetDnsLookup will NOT // cause it to behave synchronously, so do not remove the handle/wait while(pxndns->iStatus == WSAEINPROGRESS) WaitForSingleObject(hEvent, INFINITE); bool foundAddr = pxndns->iStatus == 0 && pxndns->cina > 0; if(foundAddr) { // Lets just grab the first address returned, for now memcpy(&ipAddr.sin_addr, pxndns->aina, sizeof(IN_ADDR)); } XNetDnsRelease(pxndns); CloseHandle(hEvent); // If we didn't successfully resolve the DNS lookup, bail after the // handles are released if(!foundAddr) return false; #endif } } if(portString) ipAddr.sin_port = htons(dAtoi(portString)); else ipAddr.sin_port = htons(defaultPort); ipAddr.sin_family = AF_INET; IPSocketToNetAddress(&ipAddr, address); return true; }
NetSocket Net::openConnectTo(const char *addressString) { if(!dStrnicmp(addressString, "ipx:", 4)) // ipx support deprecated return InvalidSocket; if(!dStrnicmp(addressString, "ip:", 3)) addressString += 3; // eat off the ip: char remoteAddr[256]; dStrcpy(remoteAddr, addressString); char *portString = dStrchr(remoteAddr, ':'); U16 port; if(portString) { *portString++ = 0; port = htons(dAtoi(portString)); } else port = htons(defaultPort); if(!dStricmp(remoteAddr, "broadcast")) return InvalidSocket; if(Journal::IsPlaying()) { U32 ret; Journal::Read(&ret); return NetSocket(ret); } NetSocket sock = openSocket(); setBlocking(sock, false); sockaddr_in ipAddr; dMemset(&ipAddr, 0, sizeof(ipAddr)); ipAddr.sin_addr.s_addr = inet_addr(remoteAddr); if(ipAddr.sin_addr.s_addr != INADDR_NONE) { ipAddr.sin_port = port; ipAddr.sin_family = AF_INET; if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) == -1) { S32 err = getLastError(); if(err != Net::WouldBlock) { Con::errorf("Error connecting %s: %s", addressString, strerror(err)); ::closesocket(sock); sock = InvalidSocket; } } if(sock != InvalidSocket) { // add this socket to our list of polled sockets addPolledSocket(sock, ConnectionPending); } } else { // need to do an asynchronous name lookup. first, add the socket // to the polled list addPolledSocket(sock, NameLookupRequired, remoteAddr, port); // queue the lookup gNetAsync.queueLookup(remoteAddr, sock); } if(Journal::IsRecording()) Journal::Write(U32(sock)); return sock; }
//----------------------------------------------------------------------------- // preload //----------------------------------------------------------------------------- bool ParticleData::preload(bool server, String &errorStr) { if (Parent::preload(server, errorStr) == false) return false; bool error = false; if(!server) { // Here we attempt to load the particle's texture if specified. An undefined // texture is *not* an error since the emitter may provide one. if (textureName && textureName[0]) { textureHandle = GFXTexHandle(textureName, &GFXDefaultStaticDiffuseProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__)); if (!textureHandle) { errorStr = String::ToString("Missing particle texture: %s", textureName); error = true; } } if (animateTexture) { // Here we parse animTexFramesString into byte-size frame numbers in animTexFrames. // Each frame token must be separated by whitespace. // A frame token must be a positive integer frame number or a range of frame numbers // separated with a '-'. // The range separator, '-', cannot have any whitspace around it. // Ranges can be specified to move through the frames in reverse as well as forward. // Frame numbers exceeding the number of tiles will wrap. // example: // "0-16 20 19 18 17 31-21" S32 n_tiles = animTexTiling.x * animTexTiling.y; AssertFatal(n_tiles > 0 && n_tiles <= 256, "Error, bad animTexTiling setting." ); animTexFrames.clear(); char* tokCopy = new char[dStrlen(animTexFramesString) + 1]; dStrcpy(tokCopy, animTexFramesString); char* currTok = dStrtok(tokCopy, " \t"); while (currTok != NULL) { char* minus = dStrchr(currTok, '-'); if (minus) { // add a range of frames *minus = '\0'; S32 range_a = dAtoi(currTok); S32 range_b = dAtoi(minus+1); if (range_b < range_a) { // reverse frame range for (S32 i = range_a; i >= range_b; i--) animTexFrames.push_back((U8)(i % n_tiles)); } else { // forward frame range for (S32 i = range_a; i <= range_b; i++) animTexFrames.push_back((U8)(i % n_tiles)); } } else { // add one frame animTexFrames.push_back((U8)(dAtoi(currTok) % n_tiles)); } currTok = dStrtok(NULL, " \t"); } // Here we pre-calculate the UVs for each frame tile, which are // tiled inside the UV region specified by texCoords. Since the // UVs are calculated using bilinear interpolation, the texCoords // region does *not* have to be an axis-aligned rectangle. if (animTexUVs) delete [] animTexUVs; animTexUVs = new Point2F[(animTexTiling.x+1)*(animTexTiling.y+1)]; // interpolate points on the left and right edge of the uv quadrangle Point2F lf_pt = texCoords[0]; Point2F rt_pt = texCoords[3]; // per-row delta for left and right interpolated points Point2F lf_d = (texCoords[1] - texCoords[0])/(F32)animTexTiling.y; Point2F rt_d = (texCoords[2] - texCoords[3])/(F32)animTexTiling.y; S32 idx = 0; for (S32 yy = 0; yy <= animTexTiling.y; yy++) { Point2F p = lf_pt; Point2F dp = (rt_pt - lf_pt)/(F32)animTexTiling.x; for (S32 xx = 0; xx <= animTexTiling.x; xx++) { animTexUVs[idx++] = p; p += dp; } lf_pt += lf_d; rt_pt += rt_d; } // cleanup delete [] tokCopy; numFrames = animTexFrames.size(); } } return !error; }
static void _printf(ConsoleLogEntry::Level level, ConsoleLogEntry::Type type, const char* fmt, va_list argptr) { if (!active) return; Con::active = false; char buffer[8192]; U32 offset = 0; if( gEvalState.traceOn && gEvalState.getStackDepth() > 0 ) { offset = gEvalState.getStackDepth() * 3; for(U32 i = 0; i < offset; i++) buffer[i] = ' '; } if (useTimestamp) { static U32 startTime = Platform::getRealMilliseconds(); U32 curTime = Platform::getRealMilliseconds() - startTime; offset += dSprintf(buffer + offset, sizeof(buffer) - offset, "[+%4d.%03d]", U32(curTime * 0.001), curTime % 1000); } dVsprintf(buffer + offset, sizeof(buffer) - offset, fmt, argptr); for(S32 i = 0; i < gConsumers.size(); i++) gConsumers[i](level, buffer); if(logBufferEnabled || consoleLogMode) { char *pos = buffer; while(*pos) { if(*pos == '\t') *pos = '^'; pos++; } pos = buffer; for(;;) { char *eofPos = dStrchr(pos, '\n'); if(eofPos) *eofPos = 0; log(pos); if(logBufferEnabled && !consoleLogLocked) { ConsoleLogEntry entry; entry.mLevel = level; entry.mType = type; #ifndef TORQUE_SHIPPING // this is equivalent to a memory leak, turn it off in ship build entry.mString = (const char *)consoleLogChunker.alloc(dStrlen(pos) + 1); dStrcpy(const_cast<char*>(entry.mString), pos); // This prevents infinite recursion if the console itself needs to // re-allocate memory to accommodate the new console log entry, and // LOG_PAGE_ALLOCS is defined. It is kind of a dirty hack, but the // uses for LOG_PAGE_ALLOCS are limited, and it is not worth writing // a lot of special case code to support this situation. -patw const bool save = Con::active; Con::active = false; consoleLog.push_back(entry); Con::active = save; #endif } if(!eofPos) break; pos = eofPos + 1; } } Con::active = true; }
U32 tabComplete(char* inputBuffer, U32 cursorPos, U32 maxResultLength, bool forwardTab) { // Check for null input. if (!inputBuffer[0]) { return cursorPos; } // Cap the max result length. if (maxResultLength > MaxCompletionBufferSize) { maxResultLength = MaxCompletionBufferSize; } // See if this is the same partial text as last checked. if (dStrcmp(tabBuffer, inputBuffer)) { // If not... // Save it for checking next time. dStrcpy(tabBuffer, inputBuffer); // Scan backward from the cursor position to find the base to complete from. S32 p = cursorPos; while ((p > 0) && (inputBuffer[p - 1] != ' ') && (inputBuffer[p - 1] != '.') && (inputBuffer[p - 1] != '(')) { p--; } completionBaseStart = p; completionBaseLen = cursorPos - p; // Is this function being invoked on an object? if (inputBuffer[p - 1] == '.') { // If so... if (p <= 1) { // Bail if no object identifier. return cursorPos; } // Find the object identifier. S32 objLast = --p; while ((p > 0) && (inputBuffer[p - 1] != ' ') && (inputBuffer[p - 1] != '(')) { p--; } if (objLast == p) { // Bail if no object identifier. return cursorPos; } // Look up the object identifier. dStrncpy(completionBuffer, inputBuffer + p, objLast - p); completionBuffer[objLast - p] = 0; tabObject = Sim::findObject(completionBuffer); if (tabObject == NULL) { // Bail if not found. return cursorPos; } } else { // Not invoked on an object; we'll use the global namespace. tabObject = 0; } } // Chop off the input text at the cursor position. inputBuffer[cursorPos] = 0; // Try to find a completion in the appropriate namespace. const char *newText; if (tabObject != 0) { newText = tabObject->tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab); } else { // In the global namespace, we can complete on global vars as well as functions. if (inputBuffer[completionBaseStart] == '$') { newText = gEvalState.globalVars.tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab); } else { newText = Namespace::global()->tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab); } } if (newText) { // If we got something, append it to the input text. S32 len = dStrlen(newText); if (len + completionBaseStart > maxResultLength) { len = maxResultLength - completionBaseStart; } dStrncpy(inputBuffer + completionBaseStart, newText, len); inputBuffer[completionBaseStart + len] = 0; // And set the cursor after it. cursorPos = completionBaseStart + len; } // Save the modified input buffer for checking next time. dStrcpy(tabBuffer, inputBuffer); // Return the new (maybe) cursor position. return cursorPos; }