⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snd_gus.c

📁 quake1 dos源代码最新版本
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
//=============================================================================
// Routines for GUS support in QUAKE
//
// Author(s): Jayeson Lee-Steere
//=============================================================================

#include "quakedef.h"
#include "dosisms.h"

//=============================================================================
// Author(s): Jayeson Lee-Steere

#define INI_STRING_SIZE 0x100

FILE *ini_fopen(const char *filename, const char *modes);
int ini_fclose(FILE *f);
void ini_fgets(FILE *f, const char *section, const char *field, char *s);

// Routines for reading from .INI files
// The read routines are fairly efficient.
//
// Author(s): Jayeson Lee-Steere

#define MAX_SECTION_WIDTH 20
#define MAX_FIELD_WIDTH 20

#define NUM_SECTION_BUFFERS 10
#define NUM_FIELD_BUFFERS 20

struct section_buffer
{
   long offset;
   char name[MAX_SECTION_WIDTH+1];
};

struct field_buffer
{
   long offset;
   int  section;
   char name[MAX_FIELD_WIDTH+1];
};

static FILE *current_file=NULL;
static int   current_section;

static int current_section_buffer=0;
static int current_field_buffer=0;

static struct section_buffer section_buffers[NUM_SECTION_BUFFERS];
static struct field_buffer field_buffers[NUM_FIELD_BUFFERS];
//***************************************************************************
// Internal routines
//***************************************************************************
static char toupper(char c)
{
   if (c>='a' && c<='z')
      c-=('a'-'A');
   return(c);
}

static void reset_buffer(FILE *f)
{
   int i;

   for (i=0;i<NUM_SECTION_BUFFERS;i++)
      section_buffers[i].name[0]=0;
   for (i=0;i<NUM_FIELD_BUFFERS;i++)
      field_buffers[i].name[0]=0;

   current_file=f;
}

// Sees if the current string is section "name" (i.e. ["name"]).
// If "name"=="*", sees if the current string is any section
// (i.e. [....]). Returns 1 if true else 0 if false.
static int is_section(char *s,const char *name)
{
   int wild=0;

   // See if wild search
   if (strcmp("*",name)==0)
      wild=1;

   // Skip leading spaces
   while (s[0]==' ')
      s++;
   // Look for leading "["
   if (s[0]!='[')
      return(0);
   s++;
   // Make sure name matches
   while (s[0]!=']' && s[0]!=13 && s[0]!=10 && s[0]!=0 && name[0]!=0)
   {
      if (!wild)
         if (toupper(s[0])!=toupper(name[0]))
            return(0);
      s++;
      if (!wild)
         name++;
   }
   if (!wild)
      if (name[0]!=0)
         return(0);
   // Skip trailing spaces
   while (s[0]==' ')
      s++;
   // Make sure we have trailing "]"
   if (s[0]!=']')
      return(0);
   return(1);
}

// Sees if the current string is field "name" (i.e. "name"=...).
// If "name"=="*", sees if the current string is any field
// (i.e. ...=...). Returns 1 if true else 0 if false.
static int is_field(char *s,const char *name)
{
   int wild=0;

   // See if wild search
   if (strcmp("*",name)==0)
      wild=1;

   // Skip leading spaces
   while (s[0]==' ')
      s++;

   // Make sure name matches
   while (s[0]!='=' && s[0]!=13 && s[0]!=10 && s[0]!=0 && name[0]!=0)
   {
      if (!wild)
         if (toupper(s[0])!=toupper(name[0]))
            return(0);
      s++;
      if (!wild)
         name++;
   }
   if (!wild)
      if (name[0]!=0)
         return(0);
   // Skip trailing spaces
   while (s[0]==' ')
      s++;
   // Make sure we have an "="
   if (s[0]!='=')
      return(0);

   return(1);
}

// Extracts the section name from a section heading
// e.g. in="[hey man]" gives out="hey man"
static void get_section_name(char *out, char *in)
{
   int i=0;

   // Skip spaces before '['
   while (in[0]==' ')
      in++;
   // Make sure there is a '['
   if (in[0]!='[')
   {
      out[0]=0;
      return;
   }
   // Skip past '['
   in++;
   // Copy string if any to output string.
   while (in[0]!=']' && in[0]!=13 && in[0]!=10 && in[0]!=0)
   {
      if (i<MAX_SECTION_WIDTH)
      {
         out[i]=in[0];
         i++;
      }
      in++;
   }
   // Make sure string was terminated with ']'
   if (in[0]!=']')
   {
      out[0]=0;
      return;
   }
   // Remove trailing spaces
   while (i>0 && out[i-1]==' ')
      i--;
   // Null terminate the output string.
   out[i]=0;
}

// Extracts the field name from a field line
// e.g. in="sooty=life be in it" gives out="sooty"
static void get_field_name(char *out, char *in)
{
   int i=0;

   // Skip leading spaces
   while (in[0]==' ')
      in++;
   // Copy name to output string
   while (in[0]!='=' && in[0]!=13 && in[0]!=10 && in[0]!=0)
   {
      if (i<MAX_FIELD_WIDTH)
      {
         out[i]=in[0];
         i++;
      }
      in++;
   }
   // Make sure we stopped on "="
   if (in[0]!='=')
   {
      out[0]=0;
      return;
   }
   // Remove trailing spaces
   while (i>0 && out[i-1]==' ')
      i--;
   // Null terminate the output string.
   out[i]=0;
}

// Returns the field data from string s.
// e.g. in="wally = golly man" gives out="golly man"
static void get_field_string(char *out, char *in)
{
   int i=0;

   // Find '=' if it exists
   while (in[0]!='=' && in[0]!=13 && in[0]!=10 && in[0]!=0)
      in++;
   // If there is an '=', skip past it.
   if (in[0]=='=')
      in++;
   // Skip any spaces between the '=' and string.
   while (in[0]==' ' || in[0]=='[')
      in++;
   // Copy string, if there is one, to the output string.
   while (in[0]!=13 && in[0]!=10 && in[0]!=0 && i<(INI_STRING_SIZE-1))
   {
      out[i]=in[0];
      in++;
      i++;
   }
   // Null terminate the output string.
   out[i]=0;
}

// Adds a section to the buffer
static int add_section(char *instring, long offset)
{
   int i;
   char section[MAX_SECTION_WIDTH+1];

   // Extract section name
   get_section_name(section,instring);
   // See if section already exists.
   for (i=0;i<NUM_SECTION_BUFFERS;i++)
      if (stricmp(section,section_buffers[i].name)==0)
         return(i);
   // Increment current_section_buffer
   current_section_buffer++;
   if (current_section_buffer>NUM_SECTION_BUFFERS)
      current_section_buffer=0;
   // Delete any field buffers that correspond to this section
   for (i=0;i<NUM_FIELD_BUFFERS;i++)
      if (field_buffers[i].section==current_section_buffer)
         field_buffers[i].name[0]=0;
   // Set buffer information
   strcpy(section_buffers[current_section_buffer].name,section);
   section_buffers[current_section_buffer].offset=offset;
   return(current_section_buffer);
}

// Adds a field to the buffer
static void add_field(char *instring, int section, long offset)
{
   int i;
   char field[MAX_FIELD_WIDTH+1];

   // Extract field name
   get_field_name(field,instring);
   // See if field already exists
   for (i=0;i<NUM_FIELD_BUFFERS;i++)
      if (field_buffers[i].section==section)
         if (stricmp(field_buffers[i].name,field)==0)
            return;
   // Increment current_field_buffer
   current_field_buffer++;
   if (current_field_buffer>NUM_FIELD_BUFFERS)
      current_field_buffer=0;
   // Set buffer information
   strcpy(field_buffers[current_field_buffer].name,field);
   field_buffers[current_field_buffer].section=section;
   field_buffers[current_field_buffer].offset=offset;
}

// Identical to fgets except the string is trucated at the first ';',
// carriage return or line feed.
static char *stripped_fgets(char *s, int n, FILE *f)
{
   int i=0;

   if (fgets(s,n,f)==NULL)
      return(NULL);

   while (s[i]!=';' && s[i]!=13 && s[i]!=10 && s[i]!=0)
      i++;
   s[i]=0;

   return(s);
}

//***************************************************************************
// Externally accessable routines
//***************************************************************************
// Opens an .INI file. Works like fopen
FILE *ini_fopen(const char *filename, const char *modes)
{
   return(fopen(filename,modes));
}

// Closes a .INI file. Works like fclose
int ini_fclose(FILE *f)
{
   if (f==current_file)
      reset_buffer(NULL);
   return(fclose(f));
}

// Puts "field" from "section" from .ini file "f" into "s".
// If "section" does not exist or "field" does not exist in
// section then s="";
void ini_fgets(FILE *f, const char *section, const char *field, char *s)
{
   int i;
   long start_pos,string_start_pos;
   char ts[INI_STRING_SIZE*2];

   if (f!=current_file)
      reset_buffer(f);

   // Default to "Not found"
   s[0]=0;

   // See if section is in buffer
   for (i=0;i<NUM_SECTION_BUFFERS;i++)
      if (strnicmp(section_buffers[i].name,section,MAX_SECTION_WIDTH)==0)
         break;

   // If section is in buffer, seek to it if necessary
   if (i<NUM_SECTION_BUFFERS)
   {
      if (i!=current_section)
      {
         current_section=i;
         fseek(f,section_buffers[i].offset,SEEK_SET);
      }
   }
   // else look through .ini file for it.
   else
   {
      // Make sure we are not at eof or this will cause trouble.
      if (feof(f))
         rewind(f);
      start_pos=ftell(f);
      while (1)
      {
         stripped_fgets(ts,INI_STRING_SIZE*2,f);
         // If it is a section, add it to the section buffer
         if (is_section(ts,"*"))
            current_section=add_section(ts,ftell(f));
         // If it is the section we are looking for, break.
         if (is_section(ts,section))
            break;
         // If we reach the end of the file, rewind to the start.
         if (feof(f))
            rewind(f);
         if (ftell(f)==start_pos)
            return;
      }
   }

   // See if field is in buffer
   for (i=0;i<NUM_FIELD_BUFFERS;i++)
      if (field_buffers[i].section==current_section)
         if (strnicmp(field_buffers[i].name,field,MAX_FIELD_WIDTH)==0)
            break;

   // If field is in buffer, seek to it and read it
   if (i<NUM_FIELD_BUFFERS)
   {
      fseek(f,field_buffers[i].offset,SEEK_SET);
      stripped_fgets(ts,INI_STRING_SIZE*2,f);
      get_field_string(s,ts);
   }
   else
   // else search through section for field.
   {
      // Make sure we do not start at eof or this will cause problems.
      if (feof(f))
         fseek(f,section_buffers[current_section].offset,SEEK_SET);
      start_pos=ftell(f);
      while (1)
      {
         string_start_pos=ftell(f);
         stripped_fgets(ts,INI_STRING_SIZE*2,f);
         // If it is a field, add it to the buffer
         if (is_field(ts,"*"))
            add_field(ts,current_section,string_start_pos);
         // If it is the field we are looking for, save it
         if (is_field(ts,field))
         {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -