]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
fixed hl sprite additive mode
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index 8e0708d1cd855c390c0932cb048d150964007005..03ac2a98527d9c4a7e1d216bc4257bb985c4ab22 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -853,17 +853,21 @@ FS_AddGameHierarchy
 */
 void FS_AddGameHierarchy (const char *dir)
 {
+#ifndef WIN32
        const char *homedir;
+#endif
 
        strlcpy (com_modname, dir, sizeof (com_modname));
 
        // Add the common game directory
        FS_AddGameDirectory (va("%s/%s", fs_basedir, dir));
 
+#ifndef WIN32
        // Add the personal game directory
        homedir = getenv ("HOME");
        if (homedir != NULL && homedir[0] != '\0')
                FS_AddGameDirectory (va("%s/.%s/%s", homedir, gameuserdirname, dir));
+#endif
 }
 
 
@@ -1053,8 +1057,10 @@ static qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean non
                }
        }
 
+#ifndef WIN32
        if (nonblocking)
                opt |= O_NONBLOCK;
+#endif
 
        file = Mem_Alloc (fs_mempool, sizeof (*file));
        memset (file, 0, sizeof (*file));
@@ -1067,12 +1073,13 @@ static qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean non
                return NULL;
        }
 
-       // For files opened in read mode, we now need to get the length
-       if (mod == O_RDONLY)
-       {
-               file->real_length = lseek (file->handle, 0, SEEK_END);
+       file->real_length = lseek (file->handle, 0, SEEK_END);
+
+       // For files opened in append mode, we start at the end of the file
+       if (mod & O_APPEND)
+               file->position = file->real_length;
+       else
                lseek (file->handle, 0, SEEK_SET);
-       }
 
        return file;
 }
@@ -1401,7 +1408,21 @@ Write "datasize" bytes into a file
 */
 size_t FS_Write (qfile_t* file, const void* data, size_t datasize)
 {
-       ssize_t result = write (file->handle, data, datasize);
+       ssize_t result;
+
+       // If necessary, seek to the exact file position we're supposed to be
+       if (file->buff_ind != file->buff_len)
+               lseek (file->handle, file->buff_ind - file->buff_len, SEEK_CUR);
+
+       // Purge cached data
+       FS_Purge (file);
+
+       // Write the buffer and update the position
+       result = write (file->handle, data, datasize);
+       file->position = lseek (file->handle, 0, SEEK_CUR);
+       if (file->real_length < file->position)
+               file->real_length = file->position;
+
        if (result < 0)
                return 0;
 
@@ -1420,12 +1441,26 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
 {
        size_t count, done;
 
+       if (buffersize == 0)
+               return 0;
+
+       // Get rid of the ungetc character
+       if (file->ungetc != EOF)
+       {
+               ((char*)buffer)[0] = file->ungetc;
+               buffersize--;
+               file->ungetc = EOF;
+               done = 1;
+       }
+       else
+               done = 0;
+
        // First, we copy as many bytes as we can from "buff"
        if (file->buff_ind < file->buff_len)
        {
                count = file->buff_len - file->buff_ind;
 
-               done = (buffersize > count) ? count : buffersize;
+               done += (buffersize > count) ? count : buffersize;
                memcpy (buffer, &file->buff[file->buff_ind], done);
                file->buff_ind += done;
 
@@ -1433,8 +1468,6 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
                if (buffersize == 0)
                        return done;
        }
-       else
-               done = 0;
 
        // NOTE: at this point, the read buffer is always empty
 
@@ -1458,9 +1491,8 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
                                done += nb;
                                file->position += nb;
 
-                               // Invalidate the output data (for FS_Seek)
-                               file->buff_len = 0;
-                               file->buff_ind = 0;
+                               // Purge cached data
+                               FS_Purge (file);
                        }
                }
                else
@@ -1552,9 +1584,8 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
                        count = buffersize - ztk->zstream.avail_out;
                        file->position += count;
 
-                       // Invalidate the output data (for FS_Seek)
-                       file->buff_len = 0;
-                       file->buff_ind = 0;
+                       // Purge cached data
+                       FS_Purge (file);
                }
 
                done += count;
@@ -1632,19 +1663,14 @@ int FS_VPrintf (qfile_t* file, const char* format, va_list ap)
 ====================
 FS_Getc
 
-Get stored ungetc character or the next character of a file
+Get the next character of a file
 ====================
 */
 int FS_Getc (qfile_t* file)
 {
        char c;
 
-       if (file->ungetc != EOF)
-       {
-               c = file->ungetc;
-               file->ungetc = EOF;
-       }
-       else if (FS_Read (file, &c, 1) != 1)
+       if (FS_Read (file, &c, 1) != 1)
                return EOF;
 
        return c;
@@ -1655,12 +1681,17 @@ int FS_Getc (qfile_t* file)
 ====================
 FS_UnGetc
 
-Put a character back into the Getc buffer (only supports one character!)
+Put a character back into the read buffer (only supports one character!)
 ====================
 */
-void FS_UnGetc (qfile_t* file, unsigned char c)
+int FS_UnGetc (qfile_t* file, unsigned char c)
 {
+       // If there's already a character waiting to be read
+       if (file->ungetc != EOF)
+               return EOF;
+
        file->ungetc = c;
+       return c;
 }
 
 
@@ -1677,11 +1708,6 @@ int FS_Seek (qfile_t* file, long offset, int whence)
        qbyte* buffer;
        size_t buffersize;
 
-       // if this is an uncompressed real file we can just call the kernel seek
-       // (necessary when writing files)
-       if (file->offset == 0 && ! (file->flags & QFILE_FLAG_DEFLATED))
-               return lseek (file->handle, offset, whence);
-
        // Compute the file offset
        switch (whence)
        {
@@ -1710,9 +1736,8 @@ int FS_Seek (qfile_t* file, long offset, int whence)
                return 0;
        }
 
-       // Invalidate the read buffer contents
-       file->buff_ind = 0;
-       file->buff_len = 0;
+       // Purge cached data
+       FS_Purge (file);
 
        // Unpacked or uncompressed files can seek directly
        if (! (file->flags & QFILE_FLAG_DEFLATED))
@@ -1775,12 +1800,22 @@ Give the current position in a file
 */
 long FS_Tell (qfile_t* file)
 {
-       // if this is an uncompressed real file we can just call the kernel tell
-       // (necessary when writing files)
-       if (file->offset == 0 && ! (file->flags & QFILE_FLAG_DEFLATED))
-               return lseek (file->handle, 0, SEEK_CUR);
-       else
-               return file->position - file->buff_len + file->buff_ind;
+       return file->position - file->buff_len + file->buff_ind;
+}
+
+
+/*
+====================
+FS_Purge
+
+Erases any buffered input or output data
+====================
+*/
+void FS_Purge (qfile_t* file)
+{
+       file->buff_len = 0;
+       file->buff_ind = 0;
+       file->ungetc = EOF;
 }