dos fixes and vga modex
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 30 Apr 2022 04:24:15 +0000 (07:24 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 30 Apr 2022 04:24:15 +0000 (07:24 +0300)
16 files changed:
libs/imago/src/conv.c
libs/imago/src/filetga.c
libs/imago/src/inttypes.h [new file with mode: 0644]
libs/imago/src/types.h [deleted file]
src/dos/dosutil.h [new file with mode: 0644]
src/dos/gfx.c
src/dos/keyb.c
src/dos/sball.c
src/dos/timer.c
src/dos/vga.c
src/dos/vga.h
src/dos/vgaregs.h [new file with mode: 0644]
src/glut/w32_dirent.c [deleted file]
src/glut/w32_dirent.h [deleted file]
src/glut/w32dir.c [new file with mode: 0644]
src/glut/w32dir.h [new file with mode: 0644]

index 756469c..94fb87f 100644 (file)
@@ -17,7 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include <string.h>
 #include "imago2.h"
-#include "types.h"
+#include "inttypes.h"
 
 /* pixel-format conversions are sub-optimal at the moment to avoid
  * writing a lot of code. optimize at some point ?
index 2192ff4..97504ca 100644 (file)
@@ -20,7 +20,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <string.h>
 #include <stdlib.h>
-#include "types.h"
+#include "inttypes.h"
 #include "imago2.h"
 #include "ftmodule.h"
 
diff --git a/libs/imago/src/inttypes.h b/libs/imago/src/inttypes.h
new file mode 100644 (file)
index 0000000..cbcc4d0
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+colcycle - color cycling image viewer
+Copyright (C) 2016  John Tsiombikas <nuclear@member.fsf.org>
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef INT_TYPES_H_
+#define INT_TYPES_H_
+
+#if defined(__DOS__) || defined(__MSDOS__)
+typedef char int8_t;
+typedef short int16_t;
+typedef long int32_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+
+typedef unsigned long intptr_t;
+#else
+
+#ifdef _MSC_VER
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+
+#ifdef _WIN64
+typedef __int64 intptr_t;
+#else
+typedef __int32 intptr_t;
+#endif
+#else  /* not msvc */
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900
+#include <stdint.h>
+#else
+#include <sys/types.h>
+#endif
+
+#endif /* end !msvc */
+#endif /* end !dos */
+
+#endif /* INT_TYPES_H_ */
diff --git a/libs/imago/src/types.h b/libs/imago/src/types.h
deleted file mode 100644 (file)
index d06e5c0..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-colcycle - color cycling image viewer
-Copyright (C) 2016  John Tsiombikas <nuclear@member.fsf.org>
-
-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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef INT_TYPES_H_
-#define INT_TYPES_H_
-
-#if defined(__DOS__) || defined(__MSDOS__)
-typedef char int8_t;
-typedef short int16_t;
-typedef long int32_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned long uint32_t;
-
-typedef unsigned long intptr_t;
-#else
-
-#ifdef _MSC_VER
-typedef __int8 int8_t;
-typedef __int16 int16_t;
-typedef __int32 int32_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-
-#ifdef _WIN64
-typedef __int64 intptr_t;
-#else
-typedef __int32 intptr_t;
-#endif
-#else  /* not msvc */
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900
-#include <stdint.h>
-#else
-#include <inttypes.h>
-#endif
-
-#endif /* end !msvc */
-#endif /* end !dos */
-
-#endif /* INT_TYPES_H_ */
diff --git a/src/dos/dosutil.h b/src/dos/dosutil.h
new file mode 100644 (file)
index 0000000..9894251
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef DOSUTIL_H_
+#define DOSUTIL_H_
+
+#include <dos.h>
+#include <conio.h>
+
+#ifdef __DJGPP__
+#include <pc.h>
+
+#define outp(p, v)     outportb(p, v)
+#define outpw(p, v)    outportw(p, v)
+
+#define inp(p)         inportb(p)
+#define inpw(p)                inportw(p)
+#endif
+
+#endif /* DOSUTIL_H_ */
index 48b5c20..29f6349 100644 (file)
@@ -290,8 +290,7 @@ static void blit_frame_banked(void *pixels, int vsync)
        pending = pgsize;
        while(pending > 0) {
                sz = pending > curmode->bank_size ? curmode->bank_size : pending;
-               //memcpy64((void*)0xa0000, pptr, sz >> 3);
-               memcpy((void*)0xa0000, pptr, sz);
+               memcpy((void*)phys_to_virt(0xa0000), pptr, sz);
                pptr += sz;
                pending -= sz;
                vbe_setwin(0, ++offs);
index ac200b3..e35cb7b 100644 (file)
@@ -36,6 +36,7 @@ along with the program. If not, see <http://www.gnu.org/licenses/>
 #include "keyb.h"
 #include "scancode.h"
 #include "inttypes.h"
+#include "dosutil.h"
 
 #define KB_INTR                0x9
 #define KB_PORT                0x60
@@ -55,9 +56,6 @@ static void (INTERRUPT *prev_handler)();
 
 #define DONE_INIT prev_intr.pm_offset
 static _go32_dpmi_seginfo intr, prev_intr;
-
-#define outp(p, v)     outportb(p, v)
-#define inp(p) inportb(p)
 #endif
 
 static void INTERRUPT kbintr();
index 7eb1fd9..6261f1b 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "sball.h"
 #include "inttypes.h"
+#include "dosutil.h"
 
 struct motion {
        int x, y, z;
@@ -142,9 +143,6 @@ static void (INTERRUPT *prev_recv_intr)(void);
 #define INTERRUPT
 
 static _go32_dpmi_seginfo intr, prev_intr;
-
-#define outp(port, val)        outportb(port, val)
-#define inp(port) inportb(port)
 #endif
 
 static void INTERRUPT recv_intr(void);
index 2440bd5..5492f0b 100644 (file)
@@ -22,6 +22,7 @@
 #include "pit8254.h"
 #include "inttypes.h"
 #include "util.h"
+#include "dosutil.h"
 
 #define PIT_TIMER_INTR 8
 #define DOS_TIMER_INTR 0x1c
@@ -45,8 +46,6 @@ static void (INTERRUPT *prev_timer_intr)();
 #define INTERRUPT
 
 static _go32_dpmi_seginfo intr, prev_intr;
-
-#define outp(p, v)     outportb(p, v)
 #endif
 
 static void INTERRUPT timer_irq();
index c829684..376e72b 100644 (file)
@@ -1,5 +1,10 @@
 #include "vga.h"
+#include "vgaregs.h"
 #include "cdpmi.h"
+#include "dosutil.h"
+
+static void crtc_write(int reg, unsigned char val);
+static unsigned char crtc_read(int reg);
 
 int vga_setmode(int mode)
 {
@@ -9,3 +14,57 @@ int vga_setmode(int mode)
        dpmi_int(0x10, &regs);
        return 0;
 }
+
+static unsigned short crtc_modex_regs[] = {
+       0x0d06, /* vertical total */
+       0x3e07, /* vcount overflow bit */
+       0x4109, /* double-scan */
+       0xea10, /* vsync start */
+       0xac11, /* vsync end & protect */
+       0xdf12, /* vertical visible */
+       0x0014, /* no dword mode */
+       0xe715, /* vblank start */
+       0x0616, /* vblank end */
+       0xe317, /* byte mode */
+       0
+};
+
+int vga_setmodex(void)
+{
+       int i;
+       unsigned char val;
+
+       vga_setmode(0x13);
+
+       /* disable chain-4 (C4=0, O/E=1 (sequential), EM=1 (extmem), A/G=0 (gfx) */
+       outpw(VGA_SC_ADDR_PORT, VGA_SC_MEMMODE_REG | 0x0600);
+       /* pull reset low */
+       outpw(VGA_SC_ADDR_PORT, VGA_SC_RESET_REG | 0x0100);
+       /* 25mhz dot clock, 60hz scan */
+       outp(VGA_MISC_PORT, VGA_MISC_480 | VGA_MISC_PG1 | VGA_MISC_CLK25 |
+                       VGA_MISC_CPUEN | VGA_MISC_COLOR);
+       /* return reset high */
+       outpw(VGA_SC_ADDR_PORT, VGA_SC_RESET_REG | 0x0300);
+
+       /* disable CRTC write-protect */
+       crtc_write(CRTC_VRETEND_REG, crtc_read(CRTC_VRETEND_REG) & ~CRTC_VRETEND_PR);
+       /* change CRTC registers */
+       for(i=0; crtc_modex_regs[i]; i++) {
+               outpw(VGA_CRTC_PORT, crtc_modex_regs[i]);
+       }
+
+       vga_planemask(0xf);
+       memset(VGA_FBADDR, 3, 320 * 240 / 4);
+       return 0;
+}
+
+static void crtc_write(int reg, unsigned char val)
+{
+       outpw(VGA_CRTC_ADDR_PORT, reg | ((unsigned int)val << 8));
+}
+
+static unsigned char crtc_read(int reg)
+{
+       outp(VGA_CRTC_ADDR_PORT, reg);
+       return inp(VGA_CRTC_DATA_PORT);
+}
index c6d7070..99738eb 100644 (file)
@@ -2,8 +2,17 @@
 #define VGA_H_
 
 #include "inttypes.h"
+#include "dosutil.h"
+#include "cdpmi.h"
+#include "vgaregs.h"
+
+#define VGA_FBADDR     ((void*)phys_to_virt(0xa0000))
 
 int vga_setmode(int mode);
+int vga_setmodex(void);
+
+#define vga_planemask(mask) \
+       outpw(VGA_SC_ADDR_PORT, VGA_SC_MAPMASK_REG | ((unsigned short)(mask) << 8))
 
 #ifdef __WATCOMC__
 void vga_setpal(int16_t idx, uint8_t r, uint8_t g, uint8_t b);
diff --git a/src/dos/vgaregs.h b/src/dos/vgaregs.h
new file mode 100644 (file)
index 0000000..15c4090
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef VGAREGS_H_
+#define VGAREGS_H_
+
+/* ---- VGA registers ---- */
+#define VGA_AC_PORT            0x3c0
+#define VGA_AC_RD_PORT         0x3c1
+#define VGA_SC_ADDR_PORT       0x3c4
+#define VGA_SC_DATA_PORT       0x3c5
+#define VGA_GC_ADDR_PORT       0x3ce
+#define VGA_GC_DATA_PORT       0x3cf
+#define VGA_CRTC_PORT          0x3d4
+#define VGA_CRTC_ADDR_PORT     0x3d4
+#define VGA_CRTC_DATA_PORT     0x3d5
+#define VGA_STAT0_PORT         0x3c2
+#define VGA_STAT1_PORT         0x3da
+#define VGA_MISC_PORT          0x3c2
+#define VGA_MISC_RD_PORT       0x3cc
+
+/* attribute controller registers */
+#define VGA_AC_EN              0x20
+#define VGA_AC_MODE_REG                0x10
+
+/* sequence controller registers */
+#define VGA_SC_RESET_REG       0x00
+#define VGA_SC_CLOCK_REG       0x01
+#define VGA_SC_MAPMASK_REG     0x02
+#define VGA_SC_MEMMODE_REG     0x04
+
+/* graphics controller registers */
+#define VGA_GC_SR_REG          0x00
+#define VGA_GC_SREN_REG                0x01
+#define VGA_GC_ROT_REG         0x03
+#define VGA_GC_MODE_REG                0x05
+#define VGA_GC_MASK_REG                0x08
+
+/* attribute controller mode register (10h) bits */
+#define VGA_AC_MODE_GFX                0x01
+#define VGA_AC_MODE_MONO       0x02
+#define VGA_AC_MODE_LGE                0x04
+#define VGA_AC_MODE_BLINK      0x08
+#define VGA_AC_MODE_PIXPAN     0x20
+#define VGA_AC_MODE_8BIT       0x40
+
+/* misc register bits */
+#define VGA_MISC_COLOR         0x01
+#define VGA_MISC_CPUEN         0x02
+#define VGA_MISC_CLK25         0
+#define VGA_MISC_CLK28         0x04
+#define VGA_MISC_PG1           0x20
+#define VGA_MISC_400           0
+#define VGA_MISC_350           0x40
+#define VGA_MISC_480           0xc0
+
+
+/* CRTC registers */
+#define CRTC_HTOTAL_REG                0x00
+#define CRTC_HEND_REG          0x01
+#define CRTC_HBLSTART_REG      0x02
+#define CRTC_HBLEND_REG                0x03
+#define CRTC_HRETSTART_REG     0x04
+#define CRTC_HRETEND_REG       0x05
+#define CRTC_VTOTAL_REG                0x06
+#define CRTC_OVF_REG           0x07
+#define CRTC_PRESET_REG                0x08
+#define CRTC_MAXSCAN_REG       0x09
+#define CRTC_CURSTART_REG      0x0a
+#define CRTC_CUREND_REG                0x0b
+#define CRTC_STARTH_REG                0x0c
+#define CRTC_STARTL_REG                0x0d
+#define CRTC_CURH_REG          0x0e
+#define CRTC_CURL_REG          0x0f
+#define CRTC_VRETSTART_REG     0x10
+#define CRTC_VRETEND_REG       0x11
+#define CRTC_VEND_REG          0x12
+#define CRTC_OFFSET_REG                0x13
+#define CRTC_UL_REG            0x14
+#define CRTC_VBLSTART_REG      0x15
+#define CRTC_VBLEND_REG                0x16
+#define CRTC_MODE_REG          0x17
+#define CRTC_LCMP_REG          0x18
+
+/* CRTC register bits */
+#define CRTC_VRETEND_PR                0x80
+
+#endif /* VGAREGS_H_ */
diff --git a/src/glut/w32_dirent.c b/src/glut/w32_dirent.c
deleted file mode 100644 (file)
index d399023..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * dirent.c
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is a part of the mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within the package.
- *
- * Derived from DIRLIB.C by Matt J. Weinstein 
- * This note appears in the DIRLIB.H
- * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
- *
- * Updated by Jeremy Bettis <jeremy@hksys.com>
- * Significantly revised and rewinddir, seekdir and telldir added by Colin
- * Peters <colin@fu.is.saga-u.ac.jp>
- *     
- */
-#ifdef _MSC_VER
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <io.h>
-#include <direct.h>
-#include "w32_dirent.h"
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> /* for GetFileAttributes */
-
-#define SUFFIX "*"
-#define        SLASH   "\\"
-
-/*
- * opendir
- *
- * Returns a pointer to a DIR structure appropriately filled in to begin
- * searching a directory.
- */
-DIR * opendir (const char *szPath)
-{
-  DIR *nd;
-  unsigned int rc;
-  char szFullPath[MAX_PATH];
-       
-  errno = 0;
-
-  if (!szPath)
-    {
-      errno = EFAULT;
-      return (DIR *) 0;
-    }
-
-  if (szPath[0] == ('\0'))
-    {
-      errno = ENOTDIR;
-      return (DIR *) 0;
-    }
-
-  /* Attempt to determine if the given path really is a directory. */
-  rc = GetFileAttributes (szPath);
-  if (rc == (unsigned int)-1)
-    {
-      /* call GetLastError for more error info */
-      errno = ENOENT;
-      return (DIR *) 0;
-    }
-  if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
-    {
-      /* Error, entry exists but not a directory. */
-      errno = ENOTDIR;
-      return (DIR *) 0;
-    }
-
-  /* Make an absolute pathname.  */
-  _fullpath (szFullPath, szPath, MAX_PATH);
-
-  /* Allocate enough space to store DIR structure and the complete
-   * directory path given. */
-  nd = (DIR *) malloc (sizeof (DIR) + (strlen (szFullPath)
-                                          + strlen (SLASH)
-                                          + strlen (SUFFIX) + 1)
-                                         * sizeof (char));
-
-  if (!nd)
-    {
-      /* Error, out of memory. */
-      errno = ENOMEM;
-      return (DIR *) 0;
-    }
-
-  /* Create the search expression. */
-  strcpy (nd->dd_name, szFullPath);
-
-  /* Add on a slash if the path does not end with one. */
-  if (nd->dd_name[0] != ('\0')
-      && strrchr (nd->dd_name, ('/')) != nd->dd_name
-                                           + strlen (nd->dd_name) - 1
-      && strrchr (nd->dd_name, ('\\')) != nd->dd_name
-                                            + strlen (nd->dd_name) - 1)
-    {
-      strcat (nd->dd_name, SLASH);
-    }
-
-  /* Add on the search pattern */
-  strcat (nd->dd_name, SUFFIX);
-
-  /* Initialize handle to -1 so that a premature closedir doesn't try
-   * to call _findclose on it. */
-  nd->dd_handle = -1;
-
-  /* Initialize the status. */
-  nd->dd_stat = 0;
-
-  /* Initialize the dirent structure. ino and reclen are invalid under
-   * Win32, and name simply points at the appropriate part of the
-   * findfirst structure. */
-  nd->dd_dir.d_ino = 0;
-  nd->dd_dir.d_reclen = 0;
-  nd->dd_dir.d_namlen = 0;
-  memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
-
-  return nd;
-}
-
-
-/*
- * readdir
- *
- * Return a pointer to a dirent structure filled with the information on the
- * next entry in the directory.
- */
-struct dirent *
-readdir (DIR * dirp)
-{
-  errno = 0;
-
-  /* Check for valid DIR struct. */
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return (struct dirent *) 0;
-    }
-
-  if (dirp->dd_stat < 0)
-    {
-      /* We have already returned all files in the directory
-       * (or the structure has an invalid dd_stat). */
-      return (struct dirent *) 0;
-    }
-  else if (dirp->dd_stat == 0)
-    {
-      /* We haven't started the search yet. */
-      /* Start the search */
-      dirp->dd_handle = (long)_findfirst (dirp->dd_name, &(dirp->dd_dta));
-
-      if (dirp->dd_handle == -1)
-       {
-         /* Whoops! Seems there are no files in that
-          * directory. */
-         dirp->dd_stat = -1;
-       }
-      else
-       {
-         dirp->dd_stat = 1;
-       }
-    }
-  else
-    {
-      /* Get the next search entry. */
-      if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
-       {
-         /* We are off the end or otherwise error.     
-            _findnext sets errno to ENOENT if no more file
-            Undo this. */ 
-         DWORD winerr = GetLastError ();
-         if (winerr == ERROR_NO_MORE_FILES)
-           errno = 0;  
-         _findclose (dirp->dd_handle);
-         dirp->dd_handle = -1;
-         dirp->dd_stat = -1;
-       }
-      else
-       {
-         /* Update the status to indicate the correct
-          * number. */
-         dirp->dd_stat++;
-       }
-    }
-
-  if (dirp->dd_stat > 0)
-    {
-      /* Successfully got an entry. Everything about the file is
-       * already appropriately filled in except the length of the
-       * file name. */
-      dirp->dd_dir.d_namlen = (unsigned short)strlen (dirp->dd_dta.name);
-      strcpy (dirp->dd_dir.d_name, dirp->dd_dta.name);
-      return &dirp->dd_dir;
-    }
-
-  return (struct dirent *) 0;
-}
-
-
-/*
- * closedir
- *
- * Frees up resources allocated by opendir.
- */
-int
-closedir (DIR * dirp)
-{
-  int rc;
-
-  errno = 0;
-  rc = 0;
-
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return -1;
-    }
-
-  if (dirp->dd_handle != -1)
-    {
-      rc = _findclose (dirp->dd_handle);
-    }
-
-  /* Delete the dir structure. */
-  free (dirp);
-
-  return rc;
-}
-
-/*
- * rewinddir
- *
- * Return to the beginning of the directory "stream". We simply call findclose
- * and then reset things like an opendir.
- */
-void
-rewinddir (DIR * dirp)
-{
-  errno = 0;
-
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return;
-    }
-
-  if (dirp->dd_handle != -1)
-    {
-      _findclose (dirp->dd_handle);
-    }
-
-  dirp->dd_handle = -1;
-  dirp->dd_stat = 0;
-}
-
-/*
- * telldir
- *
- * Returns the "position" in the "directory stream" which can be used with
- * seekdir to go back to an old entry. We simply return the value in stat.
- */
-long
-telldir (DIR * dirp)
-{
-  errno = 0;
-
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return -1;
-    }
-  return dirp->dd_stat;
-}
-
-/*
- * seekdir
- *
- * Seek to an entry previously returned by telldir. We rewind the directory
- * and call readdir repeatedly until either dd_stat is the position number
- * or -1 (off the end). This is not perfect, in that the directory may
- * have changed while we weren't looking. But that is probably the case with
- * any such system.
- */
-void
-seekdir (DIR * dirp, long lPos)
-{
-  errno = 0;
-
-  if (!dirp)
-    {
-      errno = EFAULT;
-      return;
-    }
-
-  if (lPos < -1)
-    {
-      /* Seeking to an invalid position. */
-      errno = EINVAL;
-      return;
-    }
-  else if (lPos == -1)
-    {
-      /* Seek past end. */
-      if (dirp->dd_handle != -1)
-       {
-         _findclose (dirp->dd_handle);
-       }
-      dirp->dd_handle = -1;
-      dirp->dd_stat = -1;
-    }
-  else
-    {
-      /* Rewind and read forward to the appropriate index. */
-      rewinddir (dirp);
-
-      while ((dirp->dd_stat < lPos) && readdir (dirp))
-       ;
-    }
-}
-
-#else
-
-int _utk_w32_dirent_c_shut_up_stupid_compiler_warning;
-
-#endif /* WIN32 */
diff --git a/src/glut/w32_dirent.h b/src/glut/w32_dirent.h
deleted file mode 100644 (file)
index 5b256bc..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * DIRENT.H (formerly DIRLIB.H)
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is a part of the mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within the package.
- *
- */
-#ifndef W32_DIRENT_H_
-#define W32_DIRENT_H_
-
-#include <stdio.h>
-#include <io.h>
-
-#ifndef RC_INVOKED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct dirent
-{
-       long            d_ino;          /* Always zero. */
-       unsigned short  d_reclen;       /* Always zero. */
-       unsigned short  d_namlen;       /* Length of name in d_name. */
-       char            d_name[FILENAME_MAX]; /* File name. */
-};
-
-/*
- * This is an internal data structure. Good programmers will not use it
- * except as an argument to one of the functions below.
- * dd_stat field is now int (was short in older versions).
- */
-typedef struct
-{
-       /* disk transfer area for this dir */
-       struct _finddata_t      dd_dta;
-
-       /* dirent struct to return from dir (NOTE: this makes this thread
-        * safe as long as only one thread uses a particular DIR struct at
-        * a time) */
-       struct dirent           dd_dir;
-
-       /* _findnext handle */
-       long                    dd_handle;
-
-       /*
-         * Status of search:
-        *   0 = not started yet (next entry to read is first entry)
-        *  -1 = off the end
-        *   positive = 0 based index of next entry
-        */
-       int                     dd_stat;
-
-       /* given path for dir with search pattern (struct is extended) */
-       char                    dd_name[1];
-} DIR;
-
-DIR* __cdecl opendir (const char*);
-struct dirent* __cdecl readdir (DIR*);
-int __cdecl closedir (DIR*);
-void __cdecl rewinddir (DIR*);
-long __cdecl telldir (DIR*);
-void __cdecl seekdir (DIR*, long);
-
-
-/* wide char versions */
-
-struct _wdirent
-{
-       long            d_ino;          /* Always zero. */
-       unsigned short  d_reclen;       /* Always zero. */
-       unsigned short  d_namlen;       /* Length of name in d_name. */
-       wchar_t         d_name[FILENAME_MAX]; /* File name. */
-};
-
-/*
- * This is an internal data structure. Good programmers will not use it
- * except as an argument to one of the functions below.
- */
-typedef struct
-{
-       /* disk transfer area for this dir */
-       struct _wfinddata_t     dd_dta;
-
-       /* dirent struct to return from dir (NOTE: this makes this thread
-        * safe as long as only one thread uses a particular DIR struct at
-        * a time) */
-       struct _wdirent         dd_dir;
-
-       /* _findnext handle */
-       long                    dd_handle;
-
-       /*
-         * Status of search:
-        *   0 = not started yet (next entry to read is first entry)
-        *  -1 = off the end
-        *   positive = 0 based index of next entry
-        */
-       int                     dd_stat;
-
-       /* given path for dir with search pattern (struct is extended) */
-       wchar_t                 dd_name[1];
-} _WDIR;
-
-
-
-_WDIR* __cdecl _wopendir (const wchar_t*);
-struct _wdirent*  __cdecl _wreaddir (_WDIR*);
-int __cdecl _wclosedir (_WDIR*);
-void __cdecl _wrewinddir (_WDIR*);
-long __cdecl _wtelldir (_WDIR*);
-void __cdecl _wseekdir (_WDIR*, long);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* Not RC_INVOKED */
-
-#endif /* Not _DIRENT_H_ */
diff --git a/src/glut/w32dir.c b/src/glut/w32dir.c
new file mode 100644 (file)
index 0000000..fc4541e
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * dirent.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein 
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis <jeremy@hksys.com>
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Peters <colin@fu.is.saga-u.ac.jp>
+ *     
+ */
+#ifdef _MSC_VER
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <io.h>
+#include <direct.h>
+#include "w32dir.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> /* for GetFileAttributes */
+
+#define SUFFIX "*"
+#define        SLASH   "\\"
+
+/*
+ * opendir
+ *
+ * Returns a pointer to a DIR structure appropriately filled in to begin
+ * searching a directory.
+ */
+DIR * opendir (const char *szPath)
+{
+  DIR *nd;
+  unsigned int rc;
+  char szFullPath[MAX_PATH];
+       
+  errno = 0;
+
+  if (!szPath)
+    {
+      errno = EFAULT;
+      return (DIR *) 0;
+    }
+
+  if (szPath[0] == ('\0'))
+    {
+      errno = ENOTDIR;
+      return (DIR *) 0;
+    }
+
+  /* Attempt to determine if the given path really is a directory. */
+  rc = GetFileAttributes (szPath);
+  if (rc == (unsigned int)-1)
+    {
+      /* call GetLastError for more error info */
+      errno = ENOENT;
+      return (DIR *) 0;
+    }
+  if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
+    {
+      /* Error, entry exists but not a directory. */
+      errno = ENOTDIR;
+      return (DIR *) 0;
+    }
+
+  /* Make an absolute pathname.  */
+  _fullpath (szFullPath, szPath, MAX_PATH);
+
+  /* Allocate enough space to store DIR structure and the complete
+   * directory path given. */
+  nd = (DIR *) malloc (sizeof (DIR) + (strlen (szFullPath)
+                                          + strlen (SLASH)
+                                          + strlen (SUFFIX) + 1)
+                                         * sizeof (char));
+
+  if (!nd)
+    {
+      /* Error, out of memory. */
+      errno = ENOMEM;
+      return (DIR *) 0;
+    }
+
+  /* Create the search expression. */
+  strcpy (nd->dd_name, szFullPath);
+
+  /* Add on a slash if the path does not end with one. */
+  if (nd->dd_name[0] != ('\0')
+      && strrchr (nd->dd_name, ('/')) != nd->dd_name
+                                           + strlen (nd->dd_name) - 1
+      && strrchr (nd->dd_name, ('\\')) != nd->dd_name
+                                            + strlen (nd->dd_name) - 1)
+    {
+      strcat (nd->dd_name, SLASH);
+    }
+
+  /* Add on the search pattern */
+  strcat (nd->dd_name, SUFFIX);
+
+  /* Initialize handle to -1 so that a premature closedir doesn't try
+   * to call _findclose on it. */
+  nd->dd_handle = -1;
+
+  /* Initialize the status. */
+  nd->dd_stat = 0;
+
+  /* Initialize the dirent structure. ino and reclen are invalid under
+   * Win32, and name simply points at the appropriate part of the
+   * findfirst structure. */
+  nd->dd_dir.d_ino = 0;
+  nd->dd_dir.d_reclen = 0;
+  nd->dd_dir.d_namlen = 0;
+  memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
+
+  return nd;
+}
+
+
+/*
+ * readdir
+ *
+ * Return a pointer to a dirent structure filled with the information on the
+ * next entry in the directory.
+ */
+struct dirent *
+readdir (DIR * dirp)
+{
+  errno = 0;
+
+  /* Check for valid DIR struct. */
+  if (!dirp)
+    {
+      errno = EFAULT;
+      return (struct dirent *) 0;
+    }
+
+  if (dirp->dd_stat < 0)
+    {
+      /* We have already returned all files in the directory
+       * (or the structure has an invalid dd_stat). */
+      return (struct dirent *) 0;
+    }
+  else if (dirp->dd_stat == 0)
+    {
+      /* We haven't started the search yet. */
+      /* Start the search */
+      dirp->dd_handle = (long)_findfirst (dirp->dd_name, &(dirp->dd_dta));
+
+      if (dirp->dd_handle == -1)
+       {
+         /* Whoops! Seems there are no files in that
+          * directory. */
+         dirp->dd_stat = -1;
+       }
+      else
+       {
+         dirp->dd_stat = 1;
+       }
+    }
+  else
+    {
+      /* Get the next search entry. */
+      if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
+       {
+         /* We are off the end or otherwise error.     
+            _findnext sets errno to ENOENT if no more file
+            Undo this. */ 
+         DWORD winerr = GetLastError ();
+         if (winerr == ERROR_NO_MORE_FILES)
+           errno = 0;  
+         _findclose (dirp->dd_handle);
+         dirp->dd_handle = -1;
+         dirp->dd_stat = -1;
+       }
+      else
+       {
+         /* Update the status to indicate the correct
+          * number. */
+         dirp->dd_stat++;
+       }
+    }
+
+  if (dirp->dd_stat > 0)
+    {
+      /* Successfully got an entry. Everything about the file is
+       * already appropriately filled in except the length of the
+       * file name. */
+      dirp->dd_dir.d_namlen = (unsigned short)strlen (dirp->dd_dta.name);
+      strcpy (dirp->dd_dir.d_name, dirp->dd_dta.name);
+      return &dirp->dd_dir;
+    }
+
+  return (struct dirent *) 0;
+}
+
+
+/*
+ * closedir
+ *
+ * Frees up resources allocated by opendir.
+ */
+int
+closedir (DIR * dirp)
+{
+  int rc;
+
+  errno = 0;
+  rc = 0;
+
+  if (!dirp)
+    {
+      errno = EFAULT;
+      return -1;
+    }
+
+  if (dirp->dd_handle != -1)
+    {
+      rc = _findclose (dirp->dd_handle);
+    }
+
+  /* Delete the dir structure. */
+  free (dirp);
+
+  return rc;
+}
+
+/*
+ * rewinddir
+ *
+ * Return to the beginning of the directory "stream". We simply call findclose
+ * and then reset things like an opendir.
+ */
+void
+rewinddir (DIR * dirp)
+{
+  errno = 0;
+
+  if (!dirp)
+    {
+      errno = EFAULT;
+      return;
+    }
+
+  if (dirp->dd_handle != -1)
+    {
+      _findclose (dirp->dd_handle);
+    }
+
+  dirp->dd_handle = -1;
+  dirp->dd_stat = 0;
+}
+
+/*
+ * telldir
+ *
+ * Returns the "position" in the "directory stream" which can be used with
+ * seekdir to go back to an old entry. We simply return the value in stat.
+ */
+long
+telldir (DIR * dirp)
+{
+  errno = 0;
+
+  if (!dirp)
+    {
+      errno = EFAULT;
+      return -1;
+    }
+  return dirp->dd_stat;
+}
+
+/*
+ * seekdir
+ *
+ * Seek to an entry previously returned by telldir. We rewind the directory
+ * and call readdir repeatedly until either dd_stat is the position number
+ * or -1 (off the end). This is not perfect, in that the directory may
+ * have changed while we weren't looking. But that is probably the case with
+ * any such system.
+ */
+void
+seekdir (DIR * dirp, long lPos)
+{
+  errno = 0;
+
+  if (!dirp)
+    {
+      errno = EFAULT;
+      return;
+    }
+
+  if (lPos < -1)
+    {
+      /* Seeking to an invalid position. */
+      errno = EINVAL;
+      return;
+    }
+  else if (lPos == -1)
+    {
+      /* Seek past end. */
+      if (dirp->dd_handle != -1)
+       {
+         _findclose (dirp->dd_handle);
+       }
+      dirp->dd_handle = -1;
+      dirp->dd_stat = -1;
+    }
+  else
+    {
+      /* Rewind and read forward to the appropriate index. */
+      rewinddir (dirp);
+
+      while ((dirp->dd_stat < lPos) && readdir (dirp))
+       ;
+    }
+}
+
+#else
+
+int _utk_w32_dirent_c_shut_up_stupid_compiler_warning;
+
+#endif /* WIN32 */
diff --git a/src/glut/w32dir.h b/src/glut/w32dir.h
new file mode 100644 (file)
index 0000000..5b256bc
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * DIRENT.H (formerly DIRLIB.H)
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ */
+#ifndef W32_DIRENT_H_
+#define W32_DIRENT_H_
+
+#include <stdio.h>
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dirent
+{
+       long            d_ino;          /* Always zero. */
+       unsigned short  d_reclen;       /* Always zero. */
+       unsigned short  d_namlen;       /* Length of name in d_name. */
+       char            d_name[FILENAME_MAX]; /* File name. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ * dd_stat field is now int (was short in older versions).
+ */
+typedef struct
+{
+       /* disk transfer area for this dir */
+       struct _finddata_t      dd_dta;
+
+       /* dirent struct to return from dir (NOTE: this makes this thread
+        * safe as long as only one thread uses a particular DIR struct at
+        * a time) */
+       struct dirent           dd_dir;
+
+       /* _findnext handle */
+       long                    dd_handle;
+
+       /*
+         * Status of search:
+        *   0 = not started yet (next entry to read is first entry)
+        *  -1 = off the end
+        *   positive = 0 based index of next entry
+        */
+       int                     dd_stat;
+
+       /* given path for dir with search pattern (struct is extended) */
+       char                    dd_name[1];
+} DIR;
+
+DIR* __cdecl opendir (const char*);
+struct dirent* __cdecl readdir (DIR*);
+int __cdecl closedir (DIR*);
+void __cdecl rewinddir (DIR*);
+long __cdecl telldir (DIR*);
+void __cdecl seekdir (DIR*, long);
+
+
+/* wide char versions */
+
+struct _wdirent
+{
+       long            d_ino;          /* Always zero. */
+       unsigned short  d_reclen;       /* Always zero. */
+       unsigned short  d_namlen;       /* Length of name in d_name. */
+       wchar_t         d_name[FILENAME_MAX]; /* File name. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+typedef struct
+{
+       /* disk transfer area for this dir */
+       struct _wfinddata_t     dd_dta;
+
+       /* dirent struct to return from dir (NOTE: this makes this thread
+        * safe as long as only one thread uses a particular DIR struct at
+        * a time) */
+       struct _wdirent         dd_dir;
+
+       /* _findnext handle */
+       long                    dd_handle;
+
+       /*
+         * Status of search:
+        *   0 = not started yet (next entry to read is first entry)
+        *  -1 = off the end
+        *   positive = 0 based index of next entry
+        */
+       int                     dd_stat;
+
+       /* given path for dir with search pattern (struct is extended) */
+       wchar_t                 dd_name[1];
+} _WDIR;
+
+
+
+_WDIR* __cdecl _wopendir (const wchar_t*);
+struct _wdirent*  __cdecl _wreaddir (_WDIR*);
+int __cdecl _wclosedir (_WDIR*);
+void __cdecl _wrewinddir (_WDIR*);
+long __cdecl _wtelldir (_WDIR*);
+void __cdecl _wseekdir (_WDIR*, long);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* Not _DIRENT_H_ */