[MSVCRT] Fix get/set pos (fixes Supreme Snowboarding demo).

Lionel Ulmer lionel.ulmer at free.fr
Fri Dec 24 08:42:30 CST 2004


Hi all,

With the help of Mike (M.) on IRC to point me to the right direction, I
finally managed to nail down the problem that was plaguing TD's snowboarding
game demo (oh well, it's better doing it in real life but well, if you are
blocked in England it's better than nothing :-) ).

Basically, there was two issues: the first is that the 'fpos_t' is 64 bits
in Windows (Mike M. checked on VC++ and I checked on MinGW and both
confirmed this). And, the real problem, 'fsetpos' did not handle file
buffering (which lead to corruption of the current file position).

     Lionel

Changelog:
 - fpos_t should be 64 bits (verified by Mike on VC++ 6)
 - handle buffering in fgetpos / fsetpos

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: include/msvcrt/stdio.h
===================================================================
RCS file: /home/wine/wine/include/msvcrt/stdio.h,v
retrieving revision 1.20
diff -u -r1.20 stdio.h
--- include/msvcrt/stdio.h	25 Jun 2004 01:19:15 -0000	1.20
+++ include/msvcrt/stdio.h	24 Dec 2004 14:36:08 -0000
@@ -71,7 +71,7 @@
 #endif  /* _FILE_DEFINED */
 
 #ifndef _FPOS_T_DEFINED
-typedef long fpos_t;
+typedef __int64 fpos_t;
 #define _FPOS_T_DEFINED
 #endif
 
Index: dlls/msvcrt/file.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/file.c,v
retrieving revision 1.78
diff -u -r1.78 file.c
--- dlls/msvcrt/file.c	14 Dec 2004 11:59:43 -0000	1.78
+++ dlls/msvcrt/file.c	24 Dec 2004 14:36:10 -0000
@@ -2518,7 +2530,20 @@
  */
 int MSVCRT_fsetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
 {
-  return _lseek(file->_file,*pos,SEEK_SET);
+  /* Note that all this has been lifted 'as is' from fseek */
+  if(file->_flag & MSVCRT__IOWRT)
+	msvcrt_flush_buffer(file);
+
+  /* Discard buffered input */
+  file->_cnt = 0;
+  file->_ptr = file->_base;
+  
+  /* Reset direction of i/o */
+  if(file->_flag & MSVCRT__IORW) {
+        file->_flag &= ~(MSVCRT__IOREAD|MSVCRT__IOWRT);
+  }
+
+  return _lseeki64(file->_file,*pos,SEEK_SET);
 }
 
 /*********************************************************************
@@ -2545,8 +2570,23 @@
  */
 int MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
 {
-  *pos = MSVCRT_ftell(file);
-  return (*pos == -1? -1 : 0);
+  /* This code has been lifted form the MSVCRT_ftell function */
+  int off=0;
+
+  *pos = _lseeki64(file->_file,0,SEEK_CUR);
+
+  if (*pos == -1) return -1;
+  
+  if(file->_bufsiz)  {
+	if( file->_flag & MSVCRT__IOWRT ) {
+		off = file->_ptr - file->_base;
+	} else {
+		off = -file->_cnt;
+	}
+  }
+  *pos += off;
+  
+  return 0;
 }
 
 /*********************************************************************
Index: dlls/msvcrt/msvcrt.h
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/msvcrt.h,v
retrieving revision 1.33
diff -u -r1.33 msvcrt.h
--- dlls/msvcrt/msvcrt.h	14 Dec 2004 15:13:54 -0000	1.33
+++ dlls/msvcrt/msvcrt.h	24 Dec 2004 14:36:10 -0000
@@ -55,7 +55,7 @@
 typedef int  MSVCRT__off_t;
 typedef long MSVCRT_clock_t;
 typedef long MSVCRT_time_t;
-typedef long MSVCRT_fpos_t;
+typedef __int64 MSVCRT_fpos_t;
 
 typedef void (*MSVCRT_terminate_handler)();
 typedef void (*MSVCRT_terminate_function)();


More information about the wine-patches mailing list