void Use_Target_Text(edict_t *self, edict_t *other, edict_t *activator) { if(!activator || !activator->client) return; activator->client->showinventory = false; activator->client->showscores = false; activator->client->showhelp = false; Text_Close(activator); Do_Text_Display(activator, self->spawnflags, self->message); }
/* ================== Cmd_Score_f Display the scoreboard ================== */ void Cmd_Score_f (edict_t *ent) { ent->client->showinventory = false; ent->client->showhelp = false; if (ent->client->menu) PMenu_Close(ent); if (ent->client->textdisplay) Text_Close(ent); if (!deathmatch->value && !coop->value) return; if (ent->client->showscores) { ent->client->showscores = false; return; } ent->client->showscores = true; DeathmatchScoreboard (ent); }
void Do_Text_Display(edict_t *activator, int flags, char *message) { int /*i,*/ L; byte *p1, *p2, *p3; // was char * char sound[64]; texthnd_t *hnd; byte *temp_buffer; int line_length; int new_line_length; qboolean alt, centered, right_justified; qboolean linebreak; qboolean do_linebreaks; hnd = gi.TagMalloc(sizeof(*hnd), TAG_LEVEL); // If a file, open and read it if(flags & 1) { #ifdef KMQUAKE2_ENGINE_MOD // use new engine file loading function instead char textname[128]; int textsize; byte *readbuffer; // sprintf(textname,"maps/%s", message); Com_sprintf(textname, sizeof(textname), "maps/%s", message); textsize = gi.LoadFile(textname, (void **)&readbuffer); if (textsize < 2) // file not found { gi.dprintf("File not found: %s\n",textname); return; } hnd->allocated = textsize + 128; // add some slop for additional control characters hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { gi.dprintf("Memory allocation failure on target_text\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); memcpy(hnd->buffer, readbuffer, textsize); hnd->buffer[textsize] = 0; gi.FreeFile(readbuffer); #else cvar_t *basedir, *gamedir; char filename[256]; char pakfile[256]; char textname[128]; int i, k, num, numitems; qboolean in_pak; FILE *f; pak_header_t pakheader; pak_item_t pakitem; basedir = gi.cvar("basedir", "", 0); gamedir = gi.cvar("gamedir", "", 0); // strncpy(filename, basedir->string); Q_strncpyz(filename, basedir->string, sizeof(filename)); if(strlen(gamedir->string)) { // strncat(filename, "\\"); // strncat(filename, gamedir->string); Q_strncatz(filename, "\\", sizeof(filename)); Q_strncatz(filename, gamedir->string, sizeof(filename)); } // First check for existence of text file in pak0.pak -> pak9.pak in_pak = false; for(i=0; i<=9 && !in_pak; i++) { // sprintf(pakfile,"%s\\pak%d.pak",filename,i); Com_sprintf(pakfile, sizeof(pakfile), "%s\\pak%d.pak",filename,i); if (NULL != (f = fopen(pakfile, "rb"))) { num=fread(&pakheader,1,sizeof(pak_header_t),f); if(num >= sizeof(pak_header_t)) { if( pakheader.id[0] == 'P' && pakheader.id[1] == 'A' && pakheader.id[2] == 'C' && pakheader.id[3] == 'K' ) { numitems = pakheader.dsize/sizeof(pak_item_t); // sprintf(textname,"maps/%s",message); Com_sprintf(textname, sizeof(textname), "maps/%s",message); fseek(f,pakheader.dstart,SEEK_SET); for(k=0; k<numitems && !in_pak; k++) { fread(&pakitem,1,sizeof(pak_item_t),f); if(!Q_stricmp(pakitem.name,textname)) { in_pak = true; fseek(f,pakitem.start,SEEK_SET); hnd->allocated = pakitem.size + 128; // add some slop for additional control characters hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { fclose(f); gi.dprintf("Memory allocation failure on target_text\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); fread(hnd->buffer,1,pakitem.size,f); hnd->buffer[pakitem.size] = 0; } } } } fclose(f); } } if(!in_pak) { // strncat(filename, "\\maps\\"); // strncat(filename, message); Q_strncatz(filename, "\\maps\\", sizeof(filename)); Q_strncatz(filename, message, sizeof(filename)); f = fopen(filename,"rb"); if(!f) { gi.dprintf("File not found:%s\n",filename); return; } fseek(f,0,SEEK_END); L = ftell (f); fseek(f,0,SEEK_SET); hnd->allocated = L+128; hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { gi.dprintf("Memory allocation failure on target_text\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); fread(hnd->buffer,1,L,f); fclose(f); } #endif // KMQUAKE2_ENGINE_MOD if(!hnd->buffer) { gi.dprintf("Umm... how'd you get here?\n"); Text_Close(activator); return; } } else { L = strlen(message); hnd->allocated = L+128; hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { gi.dprintf("Memory allocation failure\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); memcpy(hnd->buffer,message,L); } hnd->size = strlen(hnd->buffer) + 1; // Default page length: hnd->page_length = MAX_LINES-2; hnd->page_width = MAX_LINE_LENGTH; // strncpy(hnd->background_image,"textdisplay"); Q_strncpyz(hnd->background_image,"textdisplay", sizeof(hnd->background_image)); hnd->start_char = 0; do_linebreaks = true; // If 1st line starts with $, read page length, width, and image name p1 = hnd->buffer; if(*p1 == '$') { p3 = p1; while((p3 < hnd->buffer+hnd->size) && (*p3 != 13)) p3++; p2 = strstr(p1,"L="); if(p2 && (p2 < p3)) { p2 += 2; sscanf(p2,"%d",&hnd->page_length); hnd->page_length += 1; } p2 = strstr(p1,"W="); if(p2 && (p2 < p3)) { p2 += 2; sscanf(p2,"%d",&hnd->page_width); } p2 = strstr(p1,"I="); if(p2 && (p2 < p3)) { p2 += 2; sscanf(p2,"%s",hnd->background_image); } p3++; if(*p3 == 10) p3++; hnd->start_char = p3-p1; do_linebreaks = false; } // Eliminate all <CR>'s so lines are delineated with <LF>'s only p1 = hnd->buffer+hnd->start_char; while(p1 < hnd->buffer+hnd->size) { if(*p1 == 13) { for(p2=p1, p3=p1+1; p2<hnd->buffer+hnd->size; p2++, p3++) *p2 = *p3; hnd->size--; } else p1++; } // Count number of lines and replace all line feeds with 0's hnd->nlines = 1; for(p1 = hnd->buffer+hnd->start_char; p1 < hnd->buffer+hnd->size; p1++) { if(*p1 == 10) { hnd->nlines++; *p1 = 0; } } // Line break stuff if(!do_linebreaks) goto done_linebreaks; line_length = 0; p1 = hnd->buffer+hnd->start_char; alt = false; centered = false; right_justified = false; while(p1 < hnd->buffer+hnd->size) { // Don't count control characters if(line_length == 0) { if(*p1 == '*') { p1++; alt = true; } else { alt = false; } if(*p1 == '\\') { p1++; if(*p1 == 'c') { p1++; centered = true; right_justified = false; } else if(*p1 == 'r') { p1++; centered = false; right_justified = true; } else { centered = false; right_justified = false; } } else { centered = false; right_justified = false; } } if((line_length == 0) && (*p1 == '\\')) p1 += 2; if(*p1 != 0) line_length++; linebreak = false; if(line_length > hnd->page_width) { if(*p1 == 32) { // We're at a space... good deal, just replace space with // a line-break 0 and move on *p1 = 0; hnd->nlines++; linebreak = true; } else { // back up from current position to last space character and // replace with a 0 (but don't go past previous 0) p2 = p1; while(p1 > hnd->buffer+hnd->start_char && *p1 != 0) { if(*p1 == 32) { *p1 = 0; hnd->nlines++; linebreak = true; } else p1--; } if(!linebreak) { // Must be an ugly Mad Dog test trying my patience - say // a 40-character line with no spaces. Back up one space, // add a hyphen then a 0. hnd->size += 2; if(hnd->size >= hnd->allocated) { hnd->allocated += 128; temp_buffer = hnd->buffer; hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { gi.dprintf("Memory allocation failure\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); memcpy(hnd->buffer,temp_buffer,hnd->size); p1 = hnd->buffer + (p2-temp_buffer); p2 = p1; gi.TagFree(temp_buffer); } p1 = p2-1; p2 = hnd->buffer + hnd->size; p3 = p2 - 2; while(p3 >= p1) { *p2 = *p3; p2--; p3--; } *p1 = '-'; p1++; *p1 = 0; hnd->nlines++; linebreak = true; } } } if(linebreak && alt) { // We broke a line and the line was green text. Insert another // '*' at beginning of next line hnd->size += 1; if(hnd->size > hnd->allocated) { hnd->allocated += 128; temp_buffer = hnd->buffer; hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { gi.dprintf("Memory allocation failure\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); memcpy(hnd->buffer,temp_buffer,hnd->size); p2 = p1; p1 = hnd->buffer + (p2-temp_buffer); gi.TagFree(temp_buffer); } p2 = hnd->buffer + hnd->size; p3 = p2 - 1; while(p3 >= p1) { *p2 = *p3; p2--; p3--; } p2 = p1+1; *p2 = '*'; } if(linebreak && (centered || right_justified)) { // We broke a line and the line had other than left justification. Insert another // '\c' or '\r' at beginning of next line hnd->size += 2; if(hnd->size > hnd->allocated) { hnd->allocated += 128; temp_buffer = hnd->buffer; hnd->buffer = gi.TagMalloc(hnd->allocated, TAG_LEVEL); if(!hnd->buffer) { gi.dprintf("Memory allocation failure\n"); Text_Close(activator); return; } memset(hnd->buffer,0,hnd->allocated); memcpy(hnd->buffer,temp_buffer,hnd->size); p2 = p1; p1 = hnd->buffer + (p2-temp_buffer); gi.TagFree(temp_buffer); } p2 = hnd->buffer + hnd->size; p3 = p2 - 2; while(p3 >= p1) { *p2 = *p3; p2--; p3--; } p2 = p1+1; if(alt) p2++; *p2 = '\\'; p2++; if(centered) *p2 = 'c'; else *p2 = 'r'; } if(*p1=='\\') { p2 = p1+1; if(*p2=='n') { *p1 = 0; p3 = p2 + 1; while(p3 < hnd->buffer + hnd->size) { *p2 = *p3; p2++; p3++; } hnd->nlines++; linebreak = true; centered = false; right_justified = false; alt = false; } } // If we're at a 0, check to see if subsequent words will fit on this line if((!linebreak) && (*p1 == 0) && (p1 < hnd->buffer+hnd->size-1) && (line_length < hnd->page_width) ) { // Don't do this if 2 consecutive 0's are found (end of paragraph) // or if 1st character in next line is '*' or '\' p2 = p1; p2--; if(*p2 != 0) { p2++; p2++; if(*p2 != 0 && *p2 != '*' && *p2 != '\\' && p2 < hnd->buffer+hnd->size) { new_line_length = line_length+2; while(p2 < hnd->buffer+hnd->size && *p2 != 32 && *p2 != 0) { new_line_length++; p2++; } if(new_line_length <= hnd->page_width) { *p1 = 32; line_length++; // include the space that was a 0 hnd->nlines--; } } } } if(*p1 == 0) line_length = 0; p1++; } done_linebreaks: // Finally, scan for a \a code (embedded audio). If present remove that line // and play the sound p1 = hnd->buffer+hnd->start_char; while(p1 < hnd->buffer+hnd->size) { if((*p1 == 0) || (p1 == hnd->buffer+hnd->start_char)) { if(*p1 == 0) p1++; if(*p1 == '\\') { p1++; if(*p1 == 'a') { // strncpy(sound, p1+1); Q_strncpyz(sound, p1+1, sizeof(sound)); p1--; p2=p1; while(*p2 != 0) p2++; p2++; memcpy(p1,p2,hnd->buffer+hnd->size-p2+1); hnd->nlines--; // Found one (only one is allowed) gi.sound (activator, CHAN_AUTO, gi.soundindex (sound), 1, ATTN_NORM, 0); } } } p1++; } hnd->curline = 0; hnd->flags = flags; Text_BuildDisplay(hnd); hnd->lines = text; activator->client->textdisplay = hnd; Text_Open(activator); }