int Center_Text(const char* string) { int width = 0; char t = 0; int id = 0; int len = 0; int i = 0; float scale; len = dstrlen(string); for(i = 0; i < len; i++) { t = string[i]; switch(t) { case 0x20: width += 6; break; case '-': width += symboldata[SM_MISCFONT].w; break; case '%': width += symboldata[SM_MISCFONT + 1].w; break; case '!': width += symboldata[SM_MISCFONT + 2].w; break; case '.': width += symboldata[SM_MISCFONT + 3].w; break; case '?': width += symboldata[SM_MISCFONT + 4].w; break; case ':': width += symboldata[SM_MISCFONT + 5].w; break; default: if(t >= 'A' && t <= 'Z') { id = t - 'A'; width += symboldata[SM_FONT1 + id].w; } if(t >= 'a' && t <= 'z') { id = t - 'a'; width += symboldata[SM_FONT2 + id].w; } if(t >= '0' && t <= '9') { id = t - '0'; width += symboldata[SM_NUMBERS + id].w; } break; } } scale = GL_GetOrthoScale(); if(scale != 1.0f) { return ((int)(160.0f / scale) - (width / 2)); } return (160 - (width / 2)); }
char *(Z_Strdup) (const char *s, int tag, void *user, const char *file, int line) { #ifdef ZONEFILE Z_LogPrintf("* Z_Strdup(file=%s:%d)\n", file, line); #endif return dstrcpy((Z_Malloc) (dstrlen(s) + 1, tag, user, file, line), s); }
int FileDelete(char *filename) { int inode_handle; if(dstrlen(filename) > FILE_MAX_FILENAME_LENGTH) { printf("FileDelete -- Filename is too large!\n"); return(FILE_FAIL); } inode_handle = DfsInodeFilenameExists(filename); if(inode_handle == -1) { printf("FileDelete -- File does not exist!\n"); return(FILE_FAIL); } if(DfsInodeDelete(inode_handle) == -1) { printf("FileDelete -- Unable to delete inode\n"); return(FILE_FAIL); } printf("FileDelete -- Successfully deleted file: %s\n", filename); return(FILE_SUCCESS); }
static void TrapProcessCreateHandler(uint32 *trapArgs, int sysmode) { char allargs[SIZE_ARG_BUFF]; char name[100]; int i=0, j=0, k=0; uint32 args[MAX_ARGS]; char *destination; // The first argument is the name of the executable file i=0; for(i=0;i<100; i++) allargs[i] = 0; i=0; if(!sysmode) { //Get the arguments into the sytem space MemoryCopyUserToSystem (currentPCB, trapArgs, args, sizeof (args)); do { MemoryCopyUserToSystem (currentPCB,((char*)args[0])+i,name+i,1); i++; } while ((i < sizeof (name)) && (name[i-1] != '\0')); } else { bcopy (trapArgs, args, sizeof (args)); dstrncpy ((char *)args[0], name, sizeof (name)); } name[sizeof(name)-1] = '\0'; // null terminate the name i=0; if(!sysmode) { //Copy the rest of the arguments to the system space for(j=0; (j<11)&&(args[j]!=0); j++) { k=0; do { MemoryCopyUserToSystem (currentPCB,((char*)args[j])+k,allargs+i,1); i++; k++; } while ((i<sizeof(allargs)) && (allargs[i-1]!='\0')); } } else { destination = &allargs[0]; for(j=0; (j<11)&&(args[j]!=0); j++) { k = dstrlen((char *)args[j]); //length of the argument if(&destination[k]-allargs>100) { printf("Fatal: Cumulative length of all arguments > 100\n"); exitsim(); } dstrcpy(destination, (char *)args[j]); destination[k] = '\0'; } } allargs[sizeof(allargs)-1] = '\0'; // null terminate the name ProcessFork(0, (uint32)allargs, name, 1); }
/** Print some text as-is. */ static int bfs_printf_literal(FILE *file, const struct bfs_printf *directive, struct BFTW *ftwbuf) { size_t len = dstrlen(directive->str); if (fwrite(directive->str, 1, len, file) == len) { return 0; } else { return -1; } }
void CON_CvarAutoComplete(char *partial) { cvar_t* cvar; int len; char* name = NULL; int spacinglength; dboolean match = false; char* spacing = NULL; dstrlwr(partial); len = dstrlen(partial); if(!len) return; // check functions for(cvar = cvarcap; cvar; cvar = cvar->next) { if(!dstrncmp(partial, cvar->name, len)) { if(!match) { match = true; CON_Printf(0, "\n"); } name = cvar->name; // setup spacing spacinglength = 24 - dstrlen(cvar->name); spacing = Z_Malloc(spacinglength + 1, PU_STATIC, NULL); dmemset(spacing, 0x20, spacinglength); spacing[spacinglength] = 0; // print all matching cvars CON_Printf(AQUA, "%s%s= %s (%s)\n", name, spacing, cvar->string, cvar->defvalue); Z_Free(spacing); CONCLEARINPUT(); sprintf(console_inputbuffer+1, "%s ", name); console_inputlength = dstrlen(console_inputbuffer); } } }
size_t dstrfcatn(dstring_t dest, FILE *fp, size_t n) { size_t count; /* number of characters successfully read from fp */ dstring_t temp; /* will store the string which will be appended to dest */ int olddstrerrno; /* saves dstrerrno value from call to dstrfreadn() */ /* allocate space for our temporary string */ if (DSTR_SUCCESS != dstrnalloc(&temp, dstrlen(dest))) { /* 0 items are successfully read if we can't get the memory ;) dstrerrno should have been set by dstralloc() */ return 0; } /* read a line of input from the file, and make sure dstrerrno will be set properly */ count = dstrfreadn(temp, fp, n); if (DSTR_SUCCESS != dstrerrno) { if (0 == dstrlen(temp)) { dstrfree(&temp); return 0; } } /* save dstrerrno value at this point, so that any file read errors will be reported */ olddstrerrno = dstrerrno; /* cat temp to dest - dstrcat will see if dest is initialized for us :) */ dstrcat(dest, temp); if (DSTR_SUCCESS != dstrerrno) { dstrfree(&temp); return 0; } /* free our temp string and return successfully */ dstrfree(&temp); _setdstrerrno(olddstrerrno); return count; }
//! \internal process a credits definition line //! //! returns true if a new line was written //! static bool handleLine(SoBkgCreditScroll *a_This) { int row = (a_This->m_ScrollPos + SO_SCREEN_HEIGHT - 1) >> 3; switch(a_This->m_Lines[a_This->m_LineNum].m_Code & SO_CREDIT_CODE_COMMANDMASK) { case SO_CREDIT_CODE_TEXT: { int ipos = dstrlen(a_This->m_Lines[a_This->m_LineNum].m_Data); SoBkgFillBlock(a_This->m_Bkg, 0, row&0x1f, 0x1f, 1, 0); switch(a_This->m_Lines[a_This->m_LineNum].m_Code & SO_CREDIT_CODE_ALIGNMASK) { case SO_CREDIT_CODE_ALIGNLEFT: ipos = 0; break; case SO_CREDIT_CODE_ALIGNRIGHT: ipos = (SO_SCREEN_WIDTH/8 - ipos); break; case SO_CREDIT_CODE_ALIGNCENTER: ipos = (SO_SCREEN_WIDTH/8 - ipos) / 2; break; } // draw new line if(ipos < 0) ipos = 0; SoBkgPrintAt(a_This->m_Bkg, ipos, row&0x1f, a_This->m_Lines[a_This->m_LineNum].m_Data); ++a_This->m_LineNum; return true; } case SO_CREDIT_CODE_SPACE: if(!a_This->m_LineArg) a_This->m_LineArg = (u16)(u32)a_This->m_Lines[a_This->m_LineNum].m_Data; SoBkgFillBlock(a_This->m_Bkg, 0, row&0x1f, 0x1f, 1, 0); if(!(--a_This->m_LineArg)) { ++a_This->m_LineNum; } return true; case SO_CREDIT_CODE_FONT: SoBkgSetFont(a_This->m_Bkg, ((const SoBkgFont*)(a_This->m_Lines[a_This->m_LineNum].m_Data))); ++a_This->m_LineNum; break; case SO_CREDIT_CODE_SPEED: a_This->m_UpdSpeed = (u16)(u32)a_This->m_Lines[a_This->m_LineNum].m_Data; ++a_This->m_LineNum; break; // case SO_CREDIT_CODE_PAUSE: default: break; } return false; }
const char * dstrstr (const char *buf, const char *pattern) { int n = dstrlen (pattern); while (*buf != '\0') { if (dstrncmp (buf, pattern, n) == 0) { return (buf); } buf++; } return ((char *)0); }
void G_GetActionBindings(char *buff, char *action) { int i; char *p; p = buff; *p = 0; for(i = 0; i < NUMKEYS; i++) { if(IsSameAction(action, KeyActions[i])) { if(p != buff) *(p++) = ','; M_GetKeyName(p, i); p += dstrlen(p); if(p - buff >= MAX_MENUACTION_LENGTH) return; } } for(i = 0; i < MOUSE_BUTTONS; i++) { if(IsSameAction(action, MouseActions[i])) { if(p != buff) *(p++) = ','; if(i < MOUSE_BUTTONS-2) { dstrcpy(p, "mouse?"); p[5] = i + '1'; p += 6; } if(p - buff >= MAX_MENUACTION_LENGTH) return; } if(IsSameAction(action, Mouse2Actions[i])) { if(p != buff) *(p++) = ','; dstrcpy(p, "mouse2?"); p[6] = i + '1'; p += 7; if(p - buff >= MAX_MENUACTION_LENGTH) return; } } }
size_t dstrfreadn(dstring_t dest, FILE *fp, size_t n) { int count; /* number of characters read from fp */ /* make sure dest is initialized */ if (NULL == dest) { _setdstrerrno(DSTR_UNINITIALIZED); return 0; } /* make sure fp is an opened file */ if (NULL == fp) { _setdstrerrno(DSTR_UNOPENED_FILE); return 0; } /* if size is 0, return DSTR_SUCCESS without doing anything */ if (0 == n) { _setdstrerrno(DSTR_SUCCESS); return 0; } /* make sure dest's buffer is big enough */ if (DSTRBUFLEN(dest) < n + 1) { if (DSTR_SUCCESS != dstrealloc(&dest, n + 1)) { return 0; } } /* now, read our new string, up to n characters */ count = fread((void *)(DSTRBUF(dest)), sizeof(char), n, fp); /* make sure we got something; if not, find out what happened */ if (0 == count) { if (feof(fp)) { _setdstrerrno(DSTR_EOF); } else { _setdstrerrno(DSTR_FILE_ERROR); } return 0; } /* NULL terminate the new string */ if (count > 0) { DSTRBUF(dest)[count] = '\0'; } /* indicate success and return */ _setdstrerrno(DSTR_SUCCESS); return dstrlen(dest); }
void CON_CvarRegister(cvar_t *variable) { char *oldstr; // first check to see if it has allready been defined if(CON_CvarGet(variable->name)) { CON_Printf(WHITE, "CON_CvarRegister: Can't register variable %s, already defined\n", variable->name); return; } // copy the value off, because future sets will Z_Free it oldstr = variable->string; variable->string = Z_Malloc(dstrlen(variable->string)+1, PU_STATIC, 0); dstrcpy(variable->string, oldstr); variable->value = datof(variable->string); variable->defvalue = Z_Malloc(dstrlen(variable->string)+1, PU_STATIC, 0); dstrcpy(variable->defvalue, variable->string); // link the variable in variable->next = cvarcap; cvarcap = variable; }
void CON_AddLine(char *line, int len) { conline_t *cline; int i; dboolean recursed = false; if(!console_linebuffer) { //not initialised yet return; } if(recursed) { //later call to Z_Malloc can fail and call I_Error/I_Printf... return; } recursed = true; if(!line) { return; } if(len == -1) { len = dstrlen(line); } cline = (conline_t *)Z_Malloc(sizeof(conline_t)+len, PU_STATIC, NULL); cline->len = len; if(len) { dmemcpy(cline->line, line, len); } cline->line[len] = 0; console_head = (console_lineoffset + CONSOLETEXT_MASK) & CONSOLETEXT_MASK; console_minline = console_head; console_lineoffset = console_head; console_buffer[console_head] = cline; console_buffer[console_head]->color = WHITE; i = (console_head + CONSOLETEXT_MASK) & CONSOLETEXT_MASK; if(console_buffer[i]) { Z_Free(console_buffer[i]); console_buffer[i] = NULL; } recursed = false; }
/// /// BuildKeywordString static char *BuildKeywordString(void) { char *keywords = NULL; ULONG i; ENTER(); dstrcpy(&keywords, C->AttachmentKeywords); for(i=0; IntMimeTypeArray[i].ContentType != NULL; i++) { if(IsStrEmpty(IntMimeTypeArray[i].Extension) == FALSE) { char *copy; // split the space separated extensions and build a string of // comma separated extensions with leading '.' if((copy = strdup(IntMimeTypeArray[i].Extension)) != NULL) { char *ext = copy; do { char *e; if((e = strpbrk(ext, " ")) != NULL) *e++ = '\0'; if(dstrlen(keywords) != 0) dstrcat(&keywords, ","); dstrcat(&keywords, "."); dstrcat(&keywords, ext); ext = e; } while(ext != NULL); free(copy); } } } D(DBF_GUI, "build keyword string '%s'", keywords); RETURN(keywords); return keywords; }
void CON_CvarSet(char *var_name, char *value) { cvar_t *var; dboolean changed; var = CON_CvarGet(var_name); if(!var) { // there is an error in C code if this happens CON_Printf(WHITE, "CON_CvarSet: variable %s not found\n", var_name); return; } changed = dstrcmp(var->string, value); Z_Free(var->string); // free the old value string var->string = Z_Malloc(dstrlen(value)+1, PU_STATIC, 0); dstrcpy(var->string, value); var->value = datof(var->string); if(var->callback) var->callback(var); }
//-------------------------------------------------------------------- // // int process_create(char *exec_name, ...); // // Here we support reading command-line arguments. Maximum MAX_ARGS // command-line arguments are allowed. Also the total length of the // arguments including the terminating '\0' should be less than or // equal to SIZE_ARG_BUFF. // //-------------------------------------------------------------------- static void TrapProcessCreateHandler(uint32 *trapArgs, int sysmode) { char allargs[SIZE_ARG_BUFF]; // Stores full string of arguments (unparsed) char name[PROCESS_MAX_NAME_LENGTH]; // Local copy of name of executable (100 chars or less) char *username=NULL; // Pointer to user-space address of exec_name string int i=0, j=0; // Loop index variables char *args[MAX_ARGS]; // All parsed arguments (char *'s) int allargs_position = 0; // Index into current "position" in allargs char *userarg = NULL; // Current pointer to user argument string int numargs = 0; // Number of arguments passed on command line dbprintf('p', "TrapProcessCreateHandler: function started\n"); // Initialize allargs string to all NULL's for safety for(i=0;i<SIZE_ARG_BUFF; i++) { allargs[i] = '\0'; } // First deal with user-space addresses if(!sysmode) { dbprintf('p', "TrapProcessCreateHandler: creating user process\n"); // Get the known arguments into the kernel space. // Argument 0: user-space pointer to name of executable MemoryCopyUserToSystem (currentPCB, (char *)(trapArgs+0), (char *)&username, sizeof(char *)); // Copy the user-space string at user-address "username" into kernel space for(i=0; i<PROCESS_MAX_NAME_LENGTH; i++) { MemoryCopyUserToSystem(currentPCB, (char *)(username+i), (char *)&(name[i]), sizeof(char)); // Check for end of user-space string if (name[i] == '\0') break; } dbprintf('p', "TrapProcessCreateHandler: just parsed executable name (%s) from trapArgs\n", name); if (i == PROCESS_MAX_NAME_LENGTH) { printf("TrapProcessCreateHandler: length of executable filename longer than allowed!\n"); exitsim(); } // Copy the program name into "allargs", since it has to be the first argument (i.e. argv[0]) allargs_position = 0; dstrcpy(&(allargs[allargs_position]), name); allargs_position += dstrlen(name) + 1; // The "+1" is so we're pointing just beyond the NULL // Rest of arguments: a series of char *'s until we hit NULL or MAX_ARGS for(i=0; i<MAX_ARGS; i++) { // First, must copy the char * itself into kernel space in order to read its value MemoryCopyUserToSystem(currentPCB, (char *)(trapArgs+1+i), (char *)&userarg, sizeof(char *)); // If this is a NULL in the set of char *'s, this is the end of the list if (userarg == NULL) break; // Store a pointer to the kernel-space location where we're copying the string args[i] = &(allargs[allargs_position]); // Copy the string into the allargs, starting where we left off last time through this loop for (j=0; j<SIZE_ARG_BUFF; j++) { MemoryCopyUserToSystem(currentPCB, (char *)(userarg+j), (char *)&(allargs[allargs_position]), sizeof(char)); // Move current character in allargs to next spot allargs_position++; // Check that total length of arguments is still ok if (allargs_position == SIZE_ARG_BUFF) { printf("TrapProcessCreateHandler: strlen(all arguments) > maximum length allowed!\n"); exitsim(); } // Check for end of user-space string if (allargs[allargs_position-1] == '\0') break; } } if (i == MAX_ARGS) { printf("TrapProcessCreateHandler: too many arguments on command line (did you forget to pass a NULL?)\n"); exitsim(); } numargs = i+1; // Arguments are now setup } else { // Addresses are already in kernel space, so just copy into our local variables // for simplicity // Argument 0: (char *) name of program dstrncpy(name, (char *)(trapArgs[0]), PROCESS_MAX_NAME_LENGTH); // Copy the program name into "allargs", since it has to be the first argument (i.e. argv[0]) allargs_position = 0; dstrcpy(&(allargs[allargs_position]), name); allargs_position += dstrlen(name) + 1; // The "+1" is so that we are now pointing just beyond the "null" in the name allargs_position = 0; for (i=0; i<MAX_ARGS; i++) { userarg = (char *)(trapArgs[i+1]); if (userarg == NULL) break; // found last argument // Store the address of where we're copying the string args[i] = &(allargs[allargs_position]); // Copy string into allargs for(j=0; j<SIZE_ARG_BUFF; j++) { allargs[allargs_position] = userarg[j]; allargs_position++; if (allargs_position == SIZE_ARG_BUFF) { printf("TrapProcessCreateHandler: strlen(all arguments) > maximum length allowed!\n"); exitsim(); } // Check for end of user-space string if (allargs[allargs_position-1] == '\0') break; } } if (i == MAX_ARGS) { printf("TrapProcessCreateHandler: too many arguments on command line (did you forget to pass a NULL?)\n"); exitsim(); } numargs = i+1; } ProcessFork(0, (uint32)allargs, name, 1); }
//---------------------------------------------------------------------- // // TrapPrintfHandler // // Handle a printf trap.here. // Note that the maximum format string length is PRINTF_MAX_FORMAT_LENGTH // characters. Exceeding this length could have unexpected results. // //---------------------------------------------------------------------- static void TrapPrintfHandler(uint32 *trapArgs, int sysMode) { char formatstr[PRINTF_MAX_FORMAT_LENGTH]; // Copy user format string here char *userformatstr=NULL; // Holds user-space address of format string int i,j; // Loop index variables int numargs=0; // Keeps track of number of %'s (i.e. number of arguments) uint32 args[PRINTF_MAX_ARGS]; // Keeps track of all our args char *userstr; // Holds user-space address of the string that goes with any "%s"'s char strings_storage[PRINTF_MAX_STRING_ARGS][PRINTF_MAX_STRING_ARG_LENGTH]; // Places to copy strings for "%s" into int string_argnum=0; // Keeps track of how many "%s"'s we have received (index into strings_storage) if (!sysMode) { // Copy user-space format string into kernel space // Argument 0: format string MemoryCopyUserToSystem(currentPCB, (char *)(trapArgs+0), (char *)&userformatstr, sizeof(char *)); // Copy format string itself from user space to kernel space for(i=0; i<PRINTF_MAX_FORMAT_LENGTH; i++) { MemoryCopyUserToSystem(currentPCB, (char *)(userformatstr + i), (char *)&(formatstr[i]), sizeof(char)); // Check for end of string if (formatstr[i] == '\0') break; } if (i == PRINTF_MAX_FORMAT_LENGTH) { // format string too long printf("TrapPrintfHandler: format string too long!\n"); return; } } else { // Not in system mode, can just copy string directly dstrncpy(formatstr, (char *)(trapArgs+0), PRINTF_MAX_FORMAT_LENGTH); } // Now read format string to find all the %'s numargs = 0; string_argnum = 0; for(i=0; i<dstrlen(formatstr); i++) { if (formatstr[i] == '%') { // Check for "%%" i++; // Skip over % symbol to look at the next character switch(formatstr[i]) { case '%': continue; // Skip over "%%" break; case 'c': // chars // This argument is a single char value, but I think it's stored as a full int value. // If it isn't, then I'm not sure how to call the *real* printf below with some non-4-byte arguments. // The "+1" is because trapArgs[0] is the format string if (!sysMode) { MemoryCopyUserToSystem(currentPCB, (char *)(trapArgs+numargs+1), (char *)&(args[numargs]), sizeof(int)); } else { args[numargs] = trapArgs[numargs+1]; } numargs++; break; case 'l': if (formatstr[i+1] != 'f') { printf("TrapPrintfHandler: unrecognized format character (l%c)\n", formatstr[i+1]); return; } i++; // There is intentionally no "break" here so that the %lf and %f cases do the same thing. // This is what the previous Printf did, but I'm not sure yet that it is right. case 'f': // double floating points (64 bits) case 'g': case 'e': if (!sysMode) { MemoryCopyUserToSystem(currentPCB, (char *)(trapArgs+numargs+1), (char *)&(args[numargs]), sizeof(double)); } else { args[numargs] = trapArgs[numargs+1]; args[numargs+1] = trapArgs[numargs+2]; } numargs += 2; // numargs is incremented by 2 since a double is the size of 2 ints break; case 'd': // integers if (!sysMode) { MemoryCopyUserToSystem(currentPCB, (char *)(trapArgs+numargs+1), (char *)&(args[numargs]), sizeof(int)); } else { args[numargs] = trapArgs[numargs+1]; } numargs++; break; case 's': // string if (!sysMode) { // First make sure we still have local string storage space available if (string_argnum == PRINTF_MAX_STRING_ARGS) { printf("TrapPrintfHandler: too many %%s arguments passed!\n"); return; } // Now copy the user-space address of the string into kernel space MemoryCopyUserToSystem(currentPCB, (char *)(trapArgs+numargs+1), (char *)&userstr, sizeof(char *)); // Now copy each individual character from that string into kernel space for(j=0; j<PRINTF_MAX_STRING_ARG_LENGTH; j++) { MemoryCopyUserToSystem(currentPCB, (char *)(userstr+j), (char *)&(strings_storage[string_argnum][j]), sizeof(char)); // Check for end of user-space string if (strings_storage[string_argnum][j] == '\0') break; } if (j == PRINTF_MAX_STRING_ARG_LENGTH) { // String was too long! printf("TrapPrintfHandler: argument #%d (a string) was too long to print!\n", numargs); return; } // Put the address of this kernel-space string as the argument for printf args[numargs] = (int)(strings_storage[string_argnum]); string_argnum++; } else { // kernel space already, just copy address out of trapArgs args[numargs] = trapArgs[numargs+1]; } numargs++; break; default: printf("TrapPrintfHandler: unrecognized format character (%c)!\n", formatstr[i+1]); return; } } } // Now we can print them all out switch(numargs) { case 0: printf(formatstr); break; case 1: printf(formatstr, args[0]); break; case 2: printf(formatstr, args[0], args[1]); break; case 3: printf(formatstr, args[0], args[1], args[2]); break; case 4: printf(formatstr, args[0], args[1], args[2], args[3]); break; case 5: printf(formatstr, args[0], args[1], args[2], args[3], args[4]); break; case 6: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5]); break; case 7: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; case 8: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); break; case 9: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); break; case 10: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); break; case 11: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]); break; case 12: printf(formatstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11]); break; default: printf("TrapPrintfHandler: too many arguments (%d) passed!\n", numargs); } // Done! }
size_t dstrfreadl(dstring_t dest, FILE *fp) { char *start; /* points to beginning of buffer */ char *bufpos; /* our current position in DSTRBUF(dest) */ char *status; /* tests for NULL when we encounter EOF */ ptrdiff_t bufcount = 0; /* how many characters we've read so far */ dstring_t temp; /* temporary dstring_t object */ /* make sure dest is initialized */ if (NULL == dest) { _setdstrerrno(DSTR_UNINITIALIZED); return 0; } /* make sure fp is an opened file */ if (NULL == fp) { _setdstrerrno(DSTR_UNOPENED_FILE); return 0; } /* allocate space for temp */ if (DSTR_SUCCESS != dstrnalloc(&temp, dstrallocsize(dest))) { return 0; } bufpos = start = DSTRBUF(temp); /* *start = '\0'; */ /* loop until we've read a whole line */ while (1) { status = fgets(bufpos, DSTRBUFLEN(temp) - bufcount, fp); /* EOF or read error encountered */ if (status == NULL) { /* if we read something, we should keep it */ if (dstrlen(temp) > 0) { break; } /* there's nothing to read */ if (feof(fp)) { _setdstrerrno(DSTR_EOF); } else { _setdstrerrno(DSTR_FILE_ERROR); } dstrfree(&temp); return 0; } /* make sure bufpos points to our current position */ bufpos = start + dstrlen(temp); /* we're done */ if ('\n' == bufpos[-1]) { break; } /* if we can't get more memory, we can't finish the line */ if (DSTR_SUCCESS != dstrealloc(&temp, DSTRBUFLEN(temp) * 2)) { dstrfree(&temp); return 0; } /* make sure you update start, lest you suffer the wrath of glibc... */ start = DSTRBUF(temp); bufpos = start + dstrlen(temp); /* the +1 at the end is to make sure the '\0' is counted */ bufcount = bufpos - start + 1; } /* copy our new string into dest only if we read something */ if (dstrlen(temp) > 0) { /* does dest need more space than it already has? */ if (DSTRBUFLEN(dest) < dstrlen(temp) + 1) { if (DSTR_SUCCESS != dstrealloc(&dest, dstrlen(temp) + 1)) { dstrfree(&temp); return 0; } } dstrcpy(dest, temp); if (DSTR_SUCCESS != dstrerrno) { dstrfree(&temp); return 0; } } /* indicate success and return */ _setdstrerrno(DSTR_SUCCESS); dstrfree(&temp); return dstrlen(dest); }
int FileOpen(char *filename, char *mode){ int inode_handle; int i; if(dstrlen(filename) > FILE_MAX_FILENAME_LENGTH) { printf("FileOpen -- Filename is too large!\n"); return(FILE_FAIL); } if((dstrlen(mode) == 2) && (*mode == 'r') && (*(mode+1) == 'w')) { printf("RW MODE\n"); // get inode_handle (create if doesn't exist) inode_handle = DfsInodeOpen(filename); if(inode_handle == -1) { printf("FileOpen -- Unable to open file in read/write mode\n"); return(FILE_FAIL); } } else if((dstrlen(mode) == 1) && (*mode == 'r')) { printf("R MODE\n"); // get inode_handle (create if doesn't exist) inode_handle = DfsInodeOpen(filename); if(inode_handle == -1) { printf("FileOpen -- Unable to open file in read mode\n"); return(FILE_FAIL); } } else if((dstrlen(mode) == 1) && (*mode == 'w')) { printf("W MODE\n"); // check if exists inode_handle = DfsInodeFilenameExists(filename); if(inode_handle != -1) // if it exists, delete { dbprintf('F', "FileOpen -- Opening in W mode and file exists... deleting inode!\n"); if(DfsInodeDelete(inode_handle) == -1) { printf("FileOpen -- Unable to delete inode\n"); return(FILE_FAIL); } // TODO: invalidate all file descriptors corresponding to the deleted inode. } // then open inode_handle = DfsInodeOpen(filename); if(inode_handle == -1) { printf("FileOpen -- Unable to open file in read mode\n"); return(FILE_FAIL); } } else { printf("FileOpen -- Invalid mode!\n"); return(FILE_FAIL); } // We now have an inode descriptor for a given file // Find an available file descriptor to hold data for(i=0; i<FILE_MAX_OPEN_FILES; i++) { if(fd_array[i].FD_Valid == 0) { // Populate file descriptor with appropriate data dstrncpy ((char*)&fd_array[i].FD_FileName, filename, FILE_MAX_FILENAME_LENGTH); fd_array[i].FD_InodeHandle = inode_handle; fd_array[i].FD_CurrentPosition = 0; fd_array[i].FD_EOF_Flag = 0; if(dstrlen(mode) == 2) fd_array[i].FD_Mode = FILE_READWRITE; else if((dstrlen(mode) == 1) && (*mode == 'r')) fd_array[i].FD_Mode = FILE_READ; else fd_array[i].FD_Mode = FILE_WRITE; fd_array[i].FD_PID = GetCurrentPid(); // mark as valid, and return handle to file descriptor fd_array[i].FD_Valid = 1; dbprintf('F', "FileOpen -- Using file descriptor #%d for newly opened file\n", i); return(i); } } printf("FileOpen -- Unable to find an empty file descriptor!\n"); return(FILE_FAIL); }
void ST_Drawer(void) { dboolean checkautomap; // // flash overlay // if ((st_flashoverlay.value || gl_max_texture_units <= 2 || r_texturecombiner.value <= 0) && flashcolor) { ST_FlashingScreen(st_flash_r, st_flash_g, st_flash_b, st_flash_a); } if (iwadDemo) return; checkautomap = (!automapactive || am_overlay.value); // // draw hud // if (checkautomap && st_drawhud.value) { //Status graphics ST_DrawStatus(); // original hud layout if (st_drawhud.value == 1) { //Draw Ammo counter if (weaponinfo[plyr->readyweapon].ammo != am_noammo) Draw_Number(160, 215, plyr->ammo[weaponinfo [plyr->readyweapon]. ammo], 0, REDALPHA(0x7f)); //Draw Health Draw_Number(49, 215, plyr->health, 0, REDALPHA(0x7f)); //Draw Armor Draw_Number(271, 215, plyr->armorpoints, 0, REDALPHA(0x7f)); } // arranged hud layout else if (st_drawhud.value >= 2) { int wpn; if (plyr->pendingweapon == wp_nochange) wpn = plyr->readyweapon; else wpn = plyr->pendingweapon; // display ammo sprite switch (weaponinfo[wpn].ammo) { case am_clip: Draw_Sprite2D(SPR_CLIP, 0, 0, 524, 460, 0.5f, 0, WHITEALPHA(0xC0)); break; case am_shell: Draw_Sprite2D(SPR_SHEL, 0, 0, 524, 460, 0.5f, 0, WHITEALPHA(0xC0)); break; case am_misl: Draw_Sprite2D(SPR_RCKT, 0, 0, 524, 464, 0.5f, 0, WHITEALPHA(0xC0)); break; case am_cell: Draw_Sprite2D(SPR_CELL, 0, 0, 524, 464, 0.5f, 0, WHITEALPHA(0xC0)); break; default: break; } // display artifact sprites if (plyr->artifacts & (1 << ART_TRIPLE)) Draw_Sprite2D(SPR_ART3, 0, 0, 260, 872, 0.275f, 0, WHITEALPHA(0xC0)); if (plyr->artifacts & (1 << ART_DOUBLE)) Draw_Sprite2D(SPR_ART2, 0, 0, 296, 872, 0.275f, 0, WHITEALPHA(0xC0)); if (plyr->artifacts & (1 << ART_FAST)) Draw_Sprite2D(SPR_ART1, 0, 0, 332, 872, 0.275f, 0, WHITEALPHA(0xC0)); // display medkit/armor Draw_Sprite2D(SPR_MEDI, 0, 0, 50, 662, 0.35f, 0, WHITEALPHA(0xC0)); Draw_Sprite2D(SPR_ARM1, 0, 0, 50, 632, 0.35f, 0, WHITEALPHA(0xC0)); GL_SetOrthoScale(0.5f); //Draw Health Draw_Number(96, 448, plyr->health, 2, REDALPHA(0xC0)); Draw_BigText(104, 450, REDALPHA(0xC0), "%"); //Draw Armor Draw_Number(96, 424, plyr->armorpoints, 2, REDALPHA(0xC0)); Draw_BigText(104, 426, REDALPHA(0xC0), "%"); //Draw Ammo counter if (weaponinfo[wpn].ammo != am_noammo) Draw_Number(550, 448, plyr->ammo[weaponinfo[wpn].ammo], 1, REDALPHA(0xC0)); GL_SetOrthoScale(1.0f); } } // // draw messages // if (st_hasjmsg && st_regionmsg.value && plyr->messagepic >= 0) { ST_DrawJMessage(plyr->messagepic); } else if (st_msg && (int)m_messages.value) { Draw_Text(20, 20, ST_MSGCOLOR(automapactive ? 0xff : st_msgalpha), 1, false, st_msg); } else if (automapactive) { char str[128]; mapdef_t *map = P_GetMapInfo(gamemap); if (map) { dmemset(&str, 0, 128); if (map->type == 2) sprintf(str, "%s", map->mapname); else sprintf(str, "Level %i: %s", gamemap, map->mapname); Draw_Text(20, 20, ST_MSGCOLOR(0xff), 1, false, str); } } // // draw chat text and player names // if (netgame) { ST_DrawChatText(); if (checkautomap) { int i; for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) ST_DisplayName(i); } } } // // draw crosshairs // if (st_crosshairs && !automapactive) { int x = (SCREENWIDTH / 2) - (ST_CROSSHAIRSIZE / 8); int y = (SCREENHEIGHT / 2) - (ST_CROSSHAIRSIZE / 8); int alpha = (int)st_crosshairopacity.value; if (alpha > 0xff) alpha = 0xff; if (alpha < 0) alpha = 0; ST_DrawCrosshair(x, y, (int)st_crosshair.value, 2, WHITEALPHA(alpha)); } // // use action context // if (p_usecontext.value) { if (P_UseLines(&players[consoleplayer], true)) { char usestring[16]; char contextstring[32]; float x; #ifdef _USE_XINPUT // XINPUT if (xgamepad.connected) { M_DrawXInputButton(140, 156, XINPUT_GAMEPAD_A); Draw_Text(213, 214, WHITEALPHA(0xA0), 0.75, false, "Use"); } else #endif { G_GetActionBindings(usestring, "+use"); sprintf(contextstring, "(%s)Use", usestring); x = (160 / 0.75f) - ((dstrlen(contextstring) * 8) / 2); Draw_Text((int)x, 214, WHITEALPHA(0xA0), 0.75f, false, contextstring); } } } // // damage indicator // if (p_damageindicator.value) ST_DrawDamageMarkers(); // // display pending weapon // if (st_showpendingweapon.value) ST_DrawPendingWeapon(); // // display stats in automap // if (st_showstats.value && automapactive) { Draw_Text(20, 430, WHITE, 0.5f, false, "Monsters: %i / %i", plyr->killcount, totalkills); Draw_Text(20, 440, WHITE, 0.5f, false, "Items: %i / %i", plyr->itemcount, totalitems); Draw_Text(20, 450, WHITE, 0.5f, false, "Secrets: %i / %i", plyr->secretcount, totalsecret); Draw_Text(20, 460, WHITE, 0.5f, false, "Time: %2.2d:%2.2d", (leveltime / TICRATE) / 60, (leveltime / TICRATE) % 60); } }
alist_t *DoRunActions(alist_t *al, dboolean free) { alist_t *next = NULL; action_t *action; cvar_t *cvar; while(al) { next = al->next; if(dstrcmp(al->cmd, "wait") == 0) break; action = FindAction(al->cmd); if(action) { action->proc(action->data, al->param); } else if(cvar = CON_CvarGet(al->cmd)) { if(netgame) { if(cvar->nonclient) { // I'll just have to assume for now that // player# 0 is the server.. if(consoleplayer != 0) { CON_Warnf("Cannot change cvar that's locked by server\n"); goto next; } } } if(!al->param[0]) { char str[256]; sprintf(str, "%s: %s (%s)", cvar->name, cvar->string, cvar->defvalue); CON_AddLine(str, dstrlen(str)); } else { CON_CvarSet(cvar->name, al->param[0]); if(netgame) { if(playeringame[0] && consoleplayer == 0) NET_SV_UpdateCvars(cvar); } } } else CON_Warnf("Unknown command \"%s\"\n", al->cmd); next: if(free) DerefSingleAction(al); al = next; } if(al) // reached wait command { if(free) DerefSingleAction(al); if(next != NULL) return next; } return al; }
static void saveg_write_header(char *description) { int i; int size; char date[32]; byte* tbn; for(i = 0; description[i] != '\0'; i++) { saveg_write8(description[i]); } for(; i < SAVESTRINGSIZE; i++) { saveg_write8(0); } sprintf(date, "%s", saveg_gettime()); size = dstrlen(date); for(i = 0; i < size; i++) { saveg_write8(date[i]); } for(; i < 32; i++) { saveg_write8(0); } size = M_CacheThumbNail(&tbn); saveg_write32(size); for(i = 0; i < size; i++) { saveg_write8(tbn[i]); } Z_Free(tbn); for(i = 0; i < 16; i++) { saveg_write8(passwordData[i]); } saveg_write8(gameskill); saveg_write8(gamemap); saveg_write8(nextmap); saveg_write_pad(); saveg_write16(globalint); // // [kex] 12/26/11 - write total stat info // saveg_write_pad(); saveg_write32(totalkills); saveg_write32(totalitems); saveg_write32(totalsecret); for(i = 0; i < MAXPLAYERS; i++) { saveg_write8(playeringame[i]); } saveg_write8((leveltime >> 16) & 0xff); saveg_write8((leveltime >> 8) & 0xff); saveg_write8(leveltime & 0xff); saveg_write_pad(); }
int Draw_Text(int x, int y, rcolor color, float scale, dboolean wrap, const char* string, ...) { int c; int i; int vi = 0; int col; const float size = 0.03125f; float fcol, frow; int start = 0; dboolean fill = false; char msg[MAX_MESSAGE_SIZE]; va_list va; const int ix = x; va_start(va, string); vsprintf(msg, string, va); va_end(va); GL_SetState(GLSTATE_BLEND, 1); if(!r_fillmode.value) { dglEnable(GL_TEXTURE_2D); dglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); r_fillmode.value = 1.0f; fill = true; } GL_BindGfxTexture("SFONT", true); dglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, DGL_CLAMP); dglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, DGL_CLAMP); GL_SetOrthoScale(scale); GL_SetOrtho(0); dglSetVertex(vtxstring); for(i = 0, vi = 0; i < dstrlen(msg); i++, vi += 4) { c = toupper(msg[i]); if(c == '\t') { while(x % 64) { x++; } continue; } if(c == '\n') { y += ST_FONTWHSIZE; x = ix; continue; } if(c == 0x20) { if(wrap) { if(x > 192) { y += ST_FONTWHSIZE; x = ix; continue; } } } else { start = (c - ST_FONTSTART); col = start & (ST_FONTNUMSET - 1); fcol = (col * size); frow = (start >= ST_FONTNUMSET) ? 0.5f : 0.0f; vtxstring[vi + 0].x = (float)x; vtxstring[vi + 0].y = (float)y; vtxstring[vi + 0].tu = fcol + 0.0015f; vtxstring[vi + 0].tv = frow + size; vtxstring[vi + 1].x = (float)x + ST_FONTWHSIZE; vtxstring[vi + 1].y = (float)y; vtxstring[vi + 1].tu = (fcol + size) - 0.0015f; vtxstring[vi + 1].tv = frow + size; vtxstring[vi + 2].x = (float)x + ST_FONTWHSIZE; vtxstring[vi + 2].y = (float)y + ST_FONTWHSIZE; vtxstring[vi + 2].tu = (fcol + size) - 0.0015f; vtxstring[vi + 2].tv = frow + 0.5f; vtxstring[vi + 3].x = (float)x; vtxstring[vi + 3].y = (float)y + ST_FONTWHSIZE; vtxstring[vi + 3].tu = fcol + 0.0015f; vtxstring[vi + 3].tv = frow + 0.5f; dglSetVertexColor(vtxstring + vi, color, 4); dglTriangle(vi + 0, vi + 1, vi + 2); dglTriangle(vi + 0, vi + 2, vi + 3); if(devparm) { vertCount += 4; } } x += ST_FONTWHSIZE; } if(vi) { dglDrawGeometry(vi, vtxstring); } GL_ResetViewport(); if(fill) { dglDisable(GL_TEXTURE_2D); dglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); r_fillmode.value = 0.0f; } GL_SetState(GLSTATE_BLEND, 0); GL_SetOrthoScale(1.0f); return x; }
int dstrvsprintf(dstring_t str, const char *format, va_list args) { /* flags containing information about a single conversion specifier */ struct specifier conversion; /* keeps track of our position in format */ char *curpos; char *end; /* keeps track of the return value of append* functions */ int r; curpos = (char *)format; /* make sure the string is empty */ if (dstrlen(str) != 0) { dstrtrunc(str, 0); if (dstrerrno != DSTR_SUCCESS) { return -1; } } while (*curpos != '\0') { /* possible conversion specifier */ if ('%' == *curpos) { end = parsearg(curpos, &conversion); if (dstrerrno != DSTR_SUCCESS) { return -1; } /* it wasn't a valid specifier */ if (end == curpos) { dstrinsertc(str, dstrlen(str), *curpos); if (dstrerrno != DSTR_SUCCESS) { return -1; } curpos++; continue; } /* it was a valid specifier */ else { /* make sure we update curpos */ curpos = end; switch(CONVERSIONBITS & conversion.format) { case PERCENT: dstrinsertc(str, dstrlen(str) - 1, '%'); if (DSTR_SUCCESS != dstrerrno) { return -1; } break; case SIGNED_INT: if (conversion.format & LONG) { r = appendsignedint(str, conversion, va_arg(args, long int), 10); } else if (conversion.format & SHORT) { r = appendsignedint(str, conversion, (long int)va_arg(args, int), 10); } else {
static CMD(Cheat) { player_t *player; if(gamestate != GS_LEVEL) { return; } player = &players[consoleplayer]; switch(data) { case 0: M_CheatGod(player, NULL); break; case 1: M_CheatClip(player, NULL); break; case 2: if(param[0] == NULL) { CON_Printf(GREEN, "Available give cheats:\n"); CON_Printf(GREEN, "-------------------------\n"); CON_Printf(AQUA, "all\n"); CON_Printf(AQUA, "weapon\n"); CON_Printf(AQUA, "artifact\n"); CON_Printf(AQUA, "key\n"); return; } if(!dstricmp(param[0], "all")) { M_CheatKfa(player, NULL); } else if(!dstricmp(param[0], "weapon")) { if(param[1] == NULL) { CON_Printf(GREEN, "Weapons:\n"); CON_Printf(GREEN, "-------------------------\n"); CON_Printf(AQUA, "1: Chainsaw\n"); CON_Printf(AQUA, "2: Shotgun\n"); CON_Printf(AQUA, "3: Super Shotgun\n"); CON_Printf(AQUA, "4: Chaingun\n"); CON_Printf(AQUA, "5: Rocket Launcher\n"); CON_Printf(AQUA, "6: Plasma Rifle\n"); CON_Printf(AQUA, "7: BFG 9000\n"); CON_Printf(AQUA, "8: Demon Artifact\n"); return; } if(dstrlen(param[1]) == 1) { M_CheatGiveWeapon(player, param[1]); } } else if(!dstricmp(param[0], "artifact")) { if(param[1] == NULL) { CON_Printf(GREEN, "Artifacts:\n"); CON_Printf(GREEN, "-------------------------\n"); CON_Printf(AQUA, "1: Red\n"); CON_Printf(AQUA, "2: Aqua\n"); CON_Printf(AQUA, "3: Violet\n"); return; } if(dstrlen(param[1]) == 1) { M_CheatArtifacts(player, param[1]); } } else if(!dstricmp(param[0], "key")) { if(param[1] == NULL) { CON_Printf(GREEN, "Keys:\n"); CON_Printf(GREEN, "-------------------------\n"); CON_Printf(AQUA, "1: Blue Card\n"); CON_Printf(AQUA, "2: Yellow Card\n"); CON_Printf(AQUA, "3: Red Card\n"); CON_Printf(AQUA, "4: Blue Skull\n"); CON_Printf(AQUA, "5: Yellow Skull\n"); CON_Printf(AQUA, "6: Red Skull\n"); return; } if(dstrlen(param[1]) == 1) { M_CheatGiveKey(player, param[1]); } } break; case 3: M_CheatBoyISuck(player, NULL); break; case 4: if(amCheating) { amCheating = 0; } else if(!amCheating) { amCheating = 2; } break; } }
int Draw_BigText(int x, int y, rcolor color, const char* string) { int c = 0; int i = 0; int vi = 0; int index = 0; float vx1 = 0.0f; float vy1 = 0.0f; float vx2 = 0.0f; float vy2 = 0.0f; float tx1 = 0.0f; float tx2 = 0.0f; float ty1 = 0.0f; float ty2 = 0.0f; float smbwidth; float smbheight; int pic; if(x <= -1) { x = Center_Text(string); } y += 14; pic = GL_BindGfxTexture("SYMBOLS", true); smbwidth = (float)gfxwidth[pic]; smbheight = (float)gfxheight[pic]; dglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, DGL_CLAMP); dglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, DGL_CLAMP); dglSetVertex(vtxstring); GL_SetState(GLSTATE_BLEND, 1); GL_SetOrtho(0); for(i = 0, vi = 0; i < dstrlen(string); i++, vi += 4) { vx1 = (float)x; vy1 = (float)y; c = string[i]; if(c == '\n' || c == '\t') { continue; // villsa: safety check } else if(c == 0x20) { x += 6; continue; } else { if(c >= '0' && c <= '9') { index = (c - '0') + SM_NUMBERS; } if(c >= 'A' && c <= 'Z') { index = (c - 'A') + SM_FONT1; } if(c >= 'a' && c <= 'z') { index = (c - 'a') + SM_FONT2; } if(c == '-') { index = SM_MISCFONT; } if(c == '%') { index = SM_MISCFONT + 1; } if(c == '!') { index = SM_MISCFONT + 2; } if(c == '.') { index = SM_MISCFONT + 3; } if(c == '?') { index = SM_MISCFONT + 4; } if(c == ':') { index = SM_MISCFONT + 5; } // [kex] use 'printf' style formating for special symbols if(c == '/') { c = string[++i]; switch(c) { // up arrow case 'u': index = SM_MICONS + 17; break; // down arrow case 'd': index = SM_MICONS + 16; break; // right arrow case 'r': index = SM_MICONS + 18; break; // left arrow case 'l': index = SM_MICONS; break; // cursor box case 'b': index = SM_MICONS + 1; break; // thermbar case 't': index = SM_THERMO; break; // thermcursor case 's': index = SM_THERMO + 1; break; default: return 0; } } vx2 = vx1 + symboldata[index].w; vy2 = vy1 - symboldata[index].h; tx1 = ((float)symboldata[index].x / smbwidth) + 0.001f; tx2 = (tx1 + (float)symboldata[index].w / smbwidth) - 0.002f; ty1 = ((float)symboldata[index].y / smbheight); ty2 = ty1 + (((float)symboldata[index].h / smbheight)); vtxstring[vi + 0].x = vx1; vtxstring[vi + 0].y = vy1; vtxstring[vi + 0].tu = tx1; vtxstring[vi + 0].tv = ty2; vtxstring[vi + 1].x = vx2; vtxstring[vi + 1].y = vy1; vtxstring[vi + 1].tu = tx2; vtxstring[vi + 1].tv = ty2; vtxstring[vi + 2].x = vx2; vtxstring[vi + 2].y = vy2; vtxstring[vi + 2].tu = tx2; vtxstring[vi + 2].tv = ty1; vtxstring[vi + 3].x = vx1; vtxstring[vi + 3].y = vy2; vtxstring[vi + 3].tu = tx1; vtxstring[vi + 3].tv = ty1; dglSetVertexColor(vtxstring + vi, color, 4); dglTriangle(vi + 2, vi + 1, vi + 0); dglTriangle(vi + 3, vi + 2, vi + 0); if(devparm) { vertCount += 4; } x += symboldata[index].w; } } if(vi) { dglDrawGeometry(vi, vtxstring); } GL_ResetViewport(); GL_SetState(GLSTATE_BLEND, 0); return x; }