===============================================================================
    Crystal Space for MacOS/X Server, OpenStep, NextStep

    This document was written by Eric Sunshine <sunshine@sunshineco.com>
    Copyright (C)1999 by Eric Sunshine
    1999/08/06

    Also see INSTALL.NeXT for installation details.
===============================================================================

0. Contents
-----------

    1. Introduction
    2. COM Dilemma
    3. Directories
    4. Files
    5. Run-Loop
    6. Video Optimizations
    7. Frame Buffer Processing
    8. Future Plans
    9. Bugs
   10. History


1. Introduction
---------------

This document contains comprehensive and detailed implementation information
about the MacOS/X Server, OpenStep 4.2, and NextStep 3.3 ports of Crystal
Space.  Installation and usage information can be found in the associated
document, INSTALL.NeXT.

Crystal Space was ported to MacOS/X Server, OpenStep, and NextStep by Eric
Sunshine in February of 1999.  If you have questions or comments about this
port, please contact me at: Eric Sunshine <sunshine@sunshineco.com>.

This project may be built for any of the architectures which are supported by
the standard developer tools, as summarized below.

    Platform        Architectures           Tested
    --------        -------------           ------
    MacOS/X Server  i386 ppc                i386 ppc
    OpenStep        i386 m68k sparc         i386 m68k
    NextStep        i386 m68k sparc hppa    i386 m68k sparc

It is possible to build multi-architecture binaries (MAB) by using the
standard Apple/NeXT makefile variable TARGET_ARCHS on the command-line.  See
the "Architectures" section in INSTALL.NeXT for a full discussion of this
facility.

Although the current trend with non-NeXT ports of Crystal Space is to make use
of dynamically loaded modules, this implementation does not currently provide
such support.  Therefore, at this time, "plug-in" renderers are not supported.
This limitation is subject to change in the future.

This implementation makes use of public AppKit API to interface with the
Window Server for all animation and event handling.  It does not make use of
the private, undocumented, and unsupported Interceptor library.

A future version of the MacOS/X Server port may make use of the new public API
for direct frame-buffer access provided by the NSDirectBitmap,
NSDirectPalette, and NSDirectScreen classes.


2. COM Dilemma
--------------

Crystal Space attempts to conform to the Common Object Model (COM)
specification in order support plug-in module capability.  Unfortunately, in a
couple cases, the COM specification is incompatible with Objective-C.

First, COM defines a 4-byte BOOL type (long), whereas Objective-C defines BOOL
as a 1-byte value (char).  This inequality of type results in a compilation
error when including both COM and Objective-C headers in the same file.  To
work around this problem, the COM BOOL type was renamed to COMBOOL within the
Crystal Space project.  COMBOOL remains binary compatible with the real COM
BOOL while avoiding messy naming complications.

Second, the COM headers define the macro "interface" as having the value
"struct".  This, too, results in a compilation error whenever COM and
Objective-C headers are included in the same compilation unit.  The problem is
that Objective-C uses the keyword "@interface" to introduce Objective-C
classes.  However, the C-preprocessor, which translates C macros prior to the
actual compilation phase, replaces "@interface" with "@struct".  The
Objective-C compiler then complains about "@struct", which is not a recognized
keyword, and the compilation fails.

In order to work around this problem, classes were split apart in such a way
as to ensure that conflicting headers are never included in the same
compilation unit.  In some cases, as many as five files resulted from the
dissection of a single interface / implementation pair in order to accommodate
this conflict.

For example, in most non-NeXT Crystal Space ports, the implementation of
SysSystemDriver can be contained in a single source file and a single header
file.  In this port, however, SysSystemDriver is split across five files as
illustrated below.

    NeXTSystemDriver.h      COM-specific interface of SysSystemDriver.
    NeXTSystemDriver.cpp    COM-specific implementation of SysSystemDriver.
    NeXTSystemProxy.h       Pure C++ interface.  Usable by COM and Objective-C.
    NeXTSystemProxy.cpp     Objective-C-only system driver implementation.
    NeXTSystemProxyCom.cpp  COM-only system driver implementation.

A more thorough discussion of the functionality of these files may be found in
the "Files" section of this document.

Other classes have been dissected in a similar fashion in order to work around
the COM conflict.  In general a class named "SomeClass" is split into
component parts in the following manner.

    SomeClass           A skeleton COM-based class.  Acts as a shell which
                        forwards messages to a proxy which does the real work.
    SomeProxy           A distinct class which implements functionality on
                        behalf of SomeClass.
    SomeProxy.h         The pure C++ interface to SomeProxy.
    SomeProxy.cpp       The Objective-C portion of SomeProxy's implementation.
    SomeProxyCom.cpp    The COM portion of SomeProxy's implementation.


3. Directories
--------------

The root components of this port of Crystal Space are in the directories
CS/libs/cssys/next and CS/libs/cssys/cs2d/next.  Relative to each directory,
in platform-specific subdirectories, are the the files comprising the
associated MacOS/X Server, OpenStep, and NextStep components.  The contents of
the subdirectories of CS/libs/cssys/next and CS/libs/cs2d/next are summarized
below.

    Directory           Contents
    ---------           --------
    shared              Resources common to MacOS/X Server, OpenStep & NextStep
    macosxs             Resources specific to MacOS/X Server.
    openstep            Resources specific to OpenStep & MacOS/X Server.
    nextstep            Resources specific to NextStep.

Functionally, this port is comprised of two distinct system-dependent modules.

1) The core components which provide low-level platform-specific functionality
   to the Crystal Space engine.  These files and resources are located in
   platform-specific subdirectories of CS/libs/cssys/next.  For instance,
   files specific to the MacOS/X Server port reside in
   CS/libs/cssys/next/macosxs, whereas files common to all three platforms
   reside in CS/libs/cssys/next/shared.

2) The library which provides 2D graphics capability into which Crystal Space
   renders its images.  These files and resources are located in
   platform-specific subdirectories of CS/libs/cs2d/next.  For instance, files
   specific to the MacOS/X Server port reside in CS/libs/cs2d/next/nextstep,
   whereas files common to all three platforms reside in
   CS/libs/cs2d/next/shared.


4. Files
--------

This port of Crystal Space makes use of a number of platform-specific
makefiles which are located in CS/mk/system.  A makefile exists for each
target platform.

    macosxs.mak             Defines MacOS/X Server-specific build attributes.
    openstep.mak            Defines OpenStep-specific build attributes.
    nextstep.mak            Defines NextStep-specific build attributes.
    next.mak                Common to all three platforms; controls the build.

An additional makefile, CS/libs/cs2d/next/next2d.mak is common to all three
platforms and controls the build process for the 2D display driver.

The core components provide low-level platform-specific functionality which
Crystal Space requires.  This includes interfaces to the underlying operating
system as well as higher-level event-loop processing as provided by the
AppKit's Application class.  The files comprising this module are:

    NeXTSystemDriver.h      The COM-capable declaration of SysSytemDriver.
                            Does not include Objective-C headers.  This is the
                            sole interface through which Crystal Space
                            communicates with the platform-specific port.

    NeXTSystemDriver.cpp    The COM-based definition of SysSystemDriver.  Does
                            not include Objective-C headers.  This class is
                            essentially a shell which forwards requests
                            through a pure C++ interface to a proxy object
                            which performs the actual functionality on behalf
                            of SysSystemDriver.

    NeXTSystemProxy.h       A pure C++ interface.  Can be included by both COM
                            and Objective-C compilation units.  The core
                            functionality of SysSystemDriver is actually
                            handled by this class on its behalf since
                            SysSystemDriver can not cleanly interface with
                            Objective-C on account of the COM conflict.

    NeXTSystemProxy.cpp     The implementation of the Objective-C-specific
                            functionality used by SysSystemDriver.  Does not
                            include COM headers.

    NeXTSystemProxyCom.cpp  The implementation of the COM-specific
                            functionality used by SysSystemDriver.  Does not
                            include Objective-C headers.

    NeXTSystemInterface.h   A pure COM interface to NeXTSystemDriver.  This
                            defines the NeXTSystemDriver interface which is
                            accessible to other modules via COM.

    NeXTDelegate.cpp        An Objective-C class which acts as the delegate to
    NeXTDelegate.h          both the Application object and the animation
                            window.  This object is responsible for handling
                            AppKit events and forwarding them to Crystal Space
                            via NeXTSystemProxy.  Termination requests by the
                            user on the AppKit side are also forwarded.

    NeXTMenu.cpp            A utility which generates the application's main
    NeXTMenu.h              menu from INI-style configuration information.

    NeXTMenu.cfg            An INI-style configuration file which defines a
                            menu layout appropriate to the platform.

    NeXTfopen.cpp           Platform-specific implementations of
    NeXTprintf.cpp          csSystemDriver::fopen(), csSystemDriver::printf(),
    NeXTTime.cpp            and csSystemDriver::Time() which work on MacOS/X
                            Server, OpenStep, and NextStep.

    malloc.h                A header which works around Crystal Space's misuse
                            of the deprecated <malloc.h> header.

    osdefs.h                Implementation of platform-specific operating
                            system functionality.  Allows Crystal Space to
                            treat the operating system services abstractly.
                            Located in CS/include/cssys/next, and included by
                            CS/include/sysdef.h.

The NeXT 2D graphics library in CS/libs/cs2d/next provides 2D graphics
capability to the Crystal Space engine.  This library is responsible for
providing a hardware-specific frame-buffer into which Crystal Space can draw.
It is also responsible for actually displaying the frame-buffer in a manner
which is appropriate for the given platform.  The files comprising the 2D
graphics library are:

    NeXTDriver2DFactory.cpp The COM server object which knows how to vend
    NeXTDriver2DFactory.h   NeXTDriver2D objects to clients.

    NeXTDriver2D.h          The COM-capable declaration of NeXTDriver2D, a
                            subclass of csGraphics2D.  Does not include
                            Objective-C headers.  This is the sole interface
                            through which Crystal Space communicates with the
                            2D graphics library.

    NeXTDriver2D.cpp        The COM-based implementation of the 2D graphics
                            server.  Does not include Objective-C headers.
                            This is essentially a shell which forwards
                            requests through a pure C++ interface to a proxy
                            object which performs the actual functionality on
                            behalf of NeXTDriver2D.

    NeXTDriver2DCom.cpp     The implementation of the COM-specific
                            functionality used by NeXTDriver2D.  Does not
                            include Objective-C headers.

    NeXTProxy2D.h           A pure C++ interface.  Can be included by both COM
                            and Objective-C compilation units.  The core
                            functionality of NeXTDriver2D is actually handled
                            by this class on its behalf since NeXTDriver2D can
                            not cleanly interface with Objective-C on account
                            of the COM conflict.

    NeXTProxy2D.cpp         The implementation of the Objective-C-specific
                            functionality used by NeXTDriver2D.  Does not
                            include COM headers.

    NeXTView.cpp            An Objective-C subclass of the AppKit's View class.
    NeXTView.h              This is the view where the animation is actually
                            displayed.  Forwards events to NeXTDelegate which
                            propagates them up to Crystal Space.

    NeXTFrameBuffer.cpp     A mostly abstract 2D frame buffer which defines
    NeXTFrameBuffer.h       the interface of objects which are capable of
                            converting a raw Crystal Space frame buffer into a
                            NeXT-format frame buffer.

    NeXTFrameBuffer15.cpp   A concrete subclass of NeXTFrameBuffer which can
    NeXTFrameBuffer15.h     convert Crystal Space RGB:555 to NeXT RGBA:4444.

    NeXTFrameBuffer32.cpp   A concrete subclass of NeXTFrameBuffer which can
    NeXTFrameBuffer32.h     convert Crystal Space RGB:888 to NeXT RGBA:8888.


5. Run-Loop
-----------

The design of Crystal Space assumes that the programmer has full control over
the application's run-loop.  It further assumes that the run-loop is
re-entrant.  The Crystal Space Windowing System (CSWS), for instance,
recursively invokes the run-loop each time it initiates a modal session, such
as when a modal panel is placed on-screen.

With most ports of Crystal Space, this is not a problem since the main
run-loop is generally implemented in this fashion:

    SysSystemDriver::Loop() {
        while (!done) {
            ProcessEvents(); // For platform-specific event handling.
            CheckKeyboard();
            CheckMouse();
            NextFrame();     // Tell the engine to render the next frame.
        }
    }

In this simple form it is generally safe to call Loop() recursively.  Even if
there is some risk involved with recursive invocations, such situations can
usually be handled specially since the run-loop is under programmer control.

With the AppKit, on the other hand, the main run-loop is not accessible to the
programmer and is essentially a black-box.  Furthermore, the application's
-run method which encapsulates the run-loop is not re-entrant.  In other
words, the naive implementation of Loop() as shown below does not work
properly when called recursively.

    SysSystemDriver::Loop() {
        [NXApp run];
    }

This makes it difficult to conform to Crystal Space's assumptions about the
run-loop.  Consequently it was necessary to work around the AppKit's
limitation on recursive invocation of the application's run-loop.

To do so, a category was introduced which extends the AppKit's application
class with the introduction of a method named -runRecursively:.  This method,
as the name implies, provides the capability of recursive run-loop invocation
by patching and overriding the default run-loop behavior.  The implementation
of this method is contained in NeXTSystemProxy.cpp.

In the long run, it may be desirable to re-engineer Crystal Space so that it
runs as a client in a surrounding application framework, rather than forcing
the application environment into the subordinate position.  This would be more
in line with today's "windowed" computing environments where most application
specific functionality is contained within a generic application framework.
The current design is geared more toward outmoded command-line environments,
such as DOS or Unix, where the program can simply take control of the entire
environment without regard to other outside factors.


6. Video Optimizations
----------------------

Unlike programs on some other platforms, OpenStep and NextStep applications do
not have direct access to the display hardware, thus video performance
suffers.  As MacOS/X Server and MacOS/X evolve, they may include facilities
for accessing display hardware directly, but at this time these facilities
have not been finalized.

Under MacOS/X Server, OpenStep, and NextStep, all drawing to the display is
performed by a separate program called the WindowServer.  Whenever an
applications needs to draw to the screen, it actually sends drawing commands
across an IPC connection to the WindowServer and the WindowServer performs the
drawing on the application's behalf.  This negatively impacts video
performance in essentially three ways.

    1) Inter-process communication (IPC) between the application and the
       WindowServer is performed serially and tends to be a bottle-neck.
       Furthermore, IPC is generally slower than direct access.

    2) Image data resides in different address spaces since the application
       and WindowServer are separate processes.  This means that the image
       data must be copied from one address space to the other.  Copying large
       amounts of data is typically very time-consuming.

    3) Since the application does not own the frame-buffer, it also does not
       have access to the frame-buffer's data format.  This means that after
       receiving the image data, the WindowServer generally has to rearrange
       it so that it matches the format of the frame-buffer.  This can be a
       particularly time-consuming operation since it may require quite a lot
       of bit-fiddling over quite a lot of bytes.  For instance, the
       application may supply image data in the format RRRRGGGGBBBBAAAA, which
       may be converted to RRRRRGGGGGGBBBBB by the WindowServer.

This port of Crystal Space implements video optimizations discussed in the
NextStep 3.0 WindowServer release notes in order to work around these problems
as much as possible.  The optimizations are:

    o Image data is aligned on a page boundary, allowing it to be sent to the
      window server as out-of-band data in a Mach message.  This is very fast
      since the data need only be mapped into the WindowServer's address space
      rather than actually copied.  Such alignment is guaranteed by using
      NSAllocateMemoryPages() on MacOS/X & OpenStep, and vm_allocate() on
      NextStep.

    o Image samples are organized in a meshed format.

    o Data for each pixel includes alpha information.

    o 12-bit RGB data is stored in 16-bits with alpha nybble set to 0x0f.
      24-bit RGB data is stored in 32-bits with alpha byte set to 0xff.

    o The image's "rowbytes" modulo 16 equals the destination buffer's
      "rowbytes" modulo 16 and the source data pointer is cacheline-aligned
      (16 byte aligned) with the destination data pointer.  This is
      accomplished by using a Retained-mode window and aligning the left edge
      of the destination View on an x-coordinate which is a multiple of 8 for
      12-bit color depth, and a multiple of 4 for 24-bit color depth.

    o The view displaying the image uses the identity transform.  That is, it
      is not flipped, scaled, rotated, etc.

    o NXDrawBitmap() or -[NXBitmapImageRep draw] is used to draw the image in
      the destination view.  This ensures that the image data is passed to to
      the WindowServer as out-of-band data in a Mach message via the
      proprietary "nextimage" PostScript operator.

Many of these optimizations are actually geared toward traditional NeXT (m68k)
hardware and may not be as effective on other platforms such as Intel.  In
some cases using these optimizations on original NeXT hardware, can result in
a very dramatic improvement in video performance.  In all cases, it is
presumed that the WindowServer has been hand-optimized to perform well on each
platform when presented with data meeting these prerequisites.  Therefore
following these guidelines is sensible even for non-NeXT hardware.

Some further optimizations are employed which are not discussed in the
WindowServer release notes.  These include:

    o Disabling PostScript "clipping" in the View in which the image is
      displayed.  (Not applicable to MacOS/X Server or OpenStep.)

    o Allocating a PostScript "gstate" for the view.  This saves valuable time
      whenever focusing on the view, though at the expense of memory.  Without
      the gstate the view has to perform certain time-consuming actions each
      time it is focused upon.

    o The Window which displays the view is Retained rather than Buffered.
      This means that drawing occurs directly on-screen rather than going to a
      backing-store which would then need be flushed to the screen with an
      expensive memory copy.

It is worth noting that none of the aforementioned video optimizations deal
with 2-bit gray, 8-bit gray, or 8-bit color.  Consequently this implementation
does not even attempt to perform any optimization in these cases and simply
hands the WindowServer 12-bit color data and lets the WindowServer massage it
as appropriate.  The upshot is that for displays other than 12- and 24-bit
RGB, video performance will probably suffer since the WindowServer will have
to massage and dither color data itself.  It is further worth noting, though,
that the majority of OpenStep and NextStep installations on Intel and NeXT
hardware use either 12- or 24-bit RGB frame buffers so the actual impact of
this limitation may not be particularly severe.


7. Frame Buffer Processing
--------------------------

With few exceptions, most MacOS/X Server, OpenStep, and NextStep
configurations use "true color" rather than palettized color.  However, "true
color" is rather relative in this case since the AppKit supports only a
limited number of configurations for image data.  In particular, these are:

    2-bit gray          NX_TwoBitGrayDepth
    8-bit gray          NX_EightBitGrayDepth
    8-bit color         NX_EightBitRGBDepth     (via RGB palette)
    12-bit color        NX_TwelveBitRGBDepth
    24-bit color        NX_TwentyFourBitRGBDepth

MacOS/X Server and OpenStep take a stab at providing more comprehensive color
depth support, but in their current state, these facilities provide little
additional assistance and, consequently, are not discussed further.

At the lowest level, the WindowServer itself supports additional
configurations and adjusts appropriately to the underlying hardware.  The
high-level application, however does not have access to this information
(without resorting to private and unsupported API), and consequently can not
make use of it.  Furthermore, even in 8-bit color mode the application has
neither access to, nor knowledge of the palette.  In this case the 8-bit
number is simply an opaque color value allowing no further interpretation.

To further complicate matters, in order to achieve decent video performance,
image data sent to the WindowServer needs to be specially formatted, as
discussed in the "Video Performance" section.  In particular, for optimal
performance, 12-bit and 24-bit data must include an alpha channel and all
alpha bits must be set to one.

Unfortunately Crystal Space is unable to produce image data in a format usable
by the WindowServer when video performance is a concern.  This is unfortunate
since it means that this port must itself massage the data into a format
suitable to the WindowServer, which can be a time consuming operation.
Crystal Space is unable to produce the proper image format for two reasons.

    1) The rendering engine has no facilities for forcing certain unused bits
       to conform to a certain value.  In this case the alpha bits need to be
       set to one.  It does have facilities for masking off the appropriate
       unused bits, but this is insufficient since the alpha bits would be
       uninitialized.

    2) The rendering engine does not support all of the common AppKit display
       modes.  For instance, the engine can generate 8-bit, 15-bit, and
       16-bit, but not the 12-bit RGB data which is quite common on MacOS/X
       Server, OpenStep, and NextStep platforms.

The upshot is that even though MacOS/X Server, OpenStep, and NextStep support
"true color" data and Crystal Space is capable of generating "true color"
data, the formats are incompatible.

One solution to the problem is to allow Crystal Space to generate 15-bit or
16-bit "true color" data and then have port-specific code massage it into an
appropriate format immediately before passing it to the WindowServer for each
animation frame.  However in the interest of video performance, this is
probably a sub-optimal solution since it tends to be quite time-consuming.

Rather than performing the time-consuming massaging of image data prior to
flusing it to the display, this port attempts to perform most of the
time-consuming work during a one-time initialization phase which simplifies
conversion from Crystal Space format image data to WindowServer format data,
as well as enhancing the speed of the operation.

Crystal Space is automatically configured to generate 32-bit RGB image data
when running on MacOS/X Server, OpenStep, and NextStep machines configured for
24-bit RGBA display.  Conversion of Crystal Space 32-bit RGB:888 data to
RGBA:8888 needed by the WindowServer is encapsulated in the class
NeXTFrameBuffer32.  This class instructs the Crystal Space renderer to
generate RGB data in the first three bytes of a four-byte pixel entity.  Just
prior to flushing the image data to the display, NeXTFrameBuffer32 places 0xff
in every fourth byte to satisfy the requirement that the alpha byte be set to
0xff, as explained in the Video Optimizations section.  This technique is both
simple and efficient and achieves the objective admirably.

Crystal Space is automatically configured to generate 15-bit RGB image data
when running on machines configured for 12-bit RGBA display.  Conversion of
Crsytal Space 15-bit RGB:555 data to RGBA:4444 needed by the WindowServer is
encapsulated in the class NeXTFrameBuffer15.  In order to avoid time-consuming
bit manipulation of image data, this class generates a translation table which
equates each possible RGB:555 color value with the corresponding RGBA:4444
color.  The alpha nybble of the translated color contains 0x0f as explained in
the Video Optimizations section.  To translate incoming RGB:555 data to
RGBA:4444, NeXTFrameBuffer15 enumerates over each color value in the incoming
image data, looks up its corresponding RGBA:4444 value in the translation
table and outputs that color.  This technique is both simple and generally
efficient.


8. Future Plans
---------------
This is a list of items which are planned for future releases of this project.

    o Re-write event handling so that it no longer relies on a timer to drive
      animation.  The problem with using the timer is that (1) it places an
      upper limit on the frame rate, and (2) on slow machines it can fire
      frequently enough to put a strangle hold on the user event queue, since
      the run loop checks for timer events before checking for user events.
      Probably a good way to re-engineer this is to place an "application
      defined" event in the event queue at the end of each animation frame,
      then have the application event trigger the next animation frame.  Since
      the event will be placed at the tail of the event queue, it will not
      smother out user events.
    o Possibly implement sound support.


9. Bugs
-------
This is a list of known problems with the current release of this project.

    o The NextStep compiler generates invalid code at locations which make COM
      queries for the IID_IHaloRasterizer module.  This is the only COM module
      which is derived with multiple-inheritance, and it is the only module
      which causes a crash inside QueryInterface().  The compiler is
      definitely generating funky & incorrect information.  Currently
      conditional compilation directives are used to ignore the offending
      code.
    o When compiling for sparc, the compiler crashes with an internal compiler
      error on graph3d.cpp.  This problem is related to the multiple-
      inheritance used to include IHaloRasterizer in the COM interface table.
      If I comment out the IHaloRasterizer line from the interface table
      (BEGIN_INTERFACE_TABLE) in graph2d.cpp, the problem disappears.
      Currently conditional compilation directives are used to ignore the
      offending code.
    o Keyboard events generated with the "alt" modifier are not correctly
      translated to Crystal Space events.  The reason is that NextStep "cooks"
      the key-code completely into some other character prior to sending the
      key-down event, and there is no way to recover the original unmodified
      key-code.  This is a short-coming in NeXT's event system.  Fortunately
      neither MacOS/X Server nor OpenStep suffer from this problem since both
      provide the much needed ability to recover the uncooked key-code.  One
      possible solution to this problem for NextStep is to use the raw
      keyboard scan-code and manually cook that into the appropriate ASCII
      key-code, but this is a very ugly solution since there are at least
      seven distinct keyboard / hardware combinations that NextStep runs on,
      and it would be necessary to hard-code scan-codes for each one.


10. History
-----------
1999/08/06 (14r000+CVS)
    Added "simulated depth" support via the VideoDriver/SIMULATE_DEPTH
        configuration option and the -simdepth command line argument.  This
	allows testing of 32-bit depth on 15-bit displays, and vice-versa.

1999/07/26 (13r012+CVS)
    Now supports 16-bit and 32-bit RGB instead of being limited to 8-bit, 256
        color palette.  Not only does this improve display quality, but it
        also means that the MacOS/X Server, OpenStep, and NextStep ports can
        take advantage of all the features which are not available in 8-bit
        mode.  For instance, sprites are now lighted correctly, bots and the
        skeletal tree are now properly Gouraud shaded, the translucent green
        ghost is visible, and Crystal Shooter works.  Testing indicates that
        the low-level 15-bit blitter is just as fast as the old 8-bit one, and
        the 32-bit blitter is actually faster on account of the fact that the
        frame buffer is no longer copied.
    Rewrote the code which queries for device depth.  It now queries the
        WindowServer directly instead of the AppKit, since the WindowServer
        has a better notion of its preferred image format.  Under NextStep the
        WindowServer and AppKit will return the same value, however as of
        OpenStep 4.1, the values may differ, and the WindowServer's result
        should be taken as the truth.
    Now rounds the window's position down to a multiple of 8, rather than up.
    Since NeXTSystemProxy.h was identical in the "nextstep" and "openstep"
        directories, it has been moved to the "shared" directory.
    In -[NeXTDelegate isEvent:shift:alt:ctrl], which is called by -mouseDown:
        and reads the shift, alternate, and control flags from a mouse down
        event, the alternate and control flags were being incorrectly
        computed.  Furthermore, the entire method was unnecessary since
        NeXTDelegate already keeps state information concerning these keys.
        Consequently, the method was removed since its functionality was
        redundant.
    Worked around a nasty bug in GNU make on MacOS/X Server.  Specifically, it
        corrupts the contents of MAKE_VOLATILE_H (and probably other
        variables) by truncating values which are appended to it with +=.
    Worked around a bizarre bug in the MacOS/X Server PPC compiler, where it
        would crash with an "internal compiler error" in soft_txt.cpp any time
        find_rgb_map() was called.  A simple textual reorganization of the
        file cured the problem.

1999/07/19 (13r012+CVS)
    Once again create_lighted_texture_true_rgb_priv() was causing HPPA
        compiler to crash with an internal error.  Presumably the argument
        list changed, which made the methods signature longer.  To work
        around this, I shortened the method's name yet again.

1999/07/16 (13r012+CVS)
    Updated all ports to work with Crystal Space beta 13.  Much has changed
        including a new directory hierarchy.  Updated all documentation to
        reflect new beta 13 organization.
    Fixed various compiler warnings in MazeD, impexp.cpp, socket driver,
        math2d.h, and MetaBalls.
    Added a 'distclean' target to the makefile.
    Removed redundant code and hard-coded constants from Makefile and cs.mak.
    Updated makefiles so that drivers2d, drivers3d, netdrivers, snddrivers,
        and drivers targets work even for platforms which specify USE_DLL=no.
    Updated PrimEdit to work with beta 13.
    Now TARGET_ARCHS is a "sticky" option, specified at configuration time.
    Worked around compiler bug in OpenStep 4.2 where compiler corrupts virtual
        table pointers when compiling for debug.  Did so by adding
        -finline-functions flag to compilation statement even for debug.  See
        openstep.mak for a full explanation.
    Added -finline-function when compiling for optimize.

1999/03/02 (12r002)
    Fixed a very nasty crasher where Bot::move() was trying to generate a unit
        vector from <0,0,0>.  Unfortunately Vector3::unit() which computes
        (v / norm) was not checking for (norm == 0) which is the case for
        vector <0,0,0>.  This bug manifested itself in the following manner.
        The result of unit() was NaN, as a consequence of division by zero.
        This NaN value was then used in other computations which resulted in
        NaN for those values as well.  Finally, a NaN value was passed to
        csSector::follow_segment() which resulted in infinite mutual recursion
        with Portal::follow_segment().  Each follow_segment() function
        repeatedly called the other until the stack overflowed.  I fixed this
        problem by making Vector3d::unit() more robust.  It now checks for
        the special case where (norm == 0).
    Fixed NeXTSystemProxy and NeXTDelegate so that when application pauses,
        the clock also pauses.  This prevents program AI from experiencing a
        temporal anomaly when execution is resumed.
    Added a README.Binaries file which will be included in the binary-only
        distributions of Crystal Space for MacOS/X Server, OpenStep, and
        NextStep.

1999/03/02 (12r001)
    Moved the Blocks game into the cryst/src/general directory.  It used to be
        stand-alone which was annoying because it required a special makefile
        for each platform.
    Added data file for Blocks: cryst/data/blocks.zip.
    Moved blocks.cfg directly into cryst/src directory.
    Fixed some compilation warnings in blocks.cpp.
    Added "quit" feature to Blocks.  Program now terminates when Escape is
        pressed.
    Documented the Blocks game in cryst/docs/blocks.txt.
    FILES & docs/whatsnew.txt now mention Blocks.
    Modified Makefile, common.mak, & cs.mak to build Blocks game.
    Changed cs.mak so that it now uses the PROC variable to compose the "out"
        object-file directory.  This way one can cross-compile without having
        to "make clean" first.
    Fixed next.mak so that it sorts TARGET_ARCHS so that when PROC is used to
        compose "out" directory, the same list of architectures will always
        result in the same PROC value regardless of initial order.
    Fixed next2d.mak to refer to NEXT.DESCRIPTION rather than NEXT.FLAVOR.
    Fixed INSTALL document so that it no longer makes invalid claims about
        NeXT ports not working with 24-bit displays.
    Documented new structure of "out" directory in INSTALL.BeOS, INSTALL.Unix,
        INSTALL.General.
    Clarified introduction of INSTALL.General.  It is now easier to understand
        that it may be useful for Unix-like ports, but that one should read
        port-specific documentation as well.  Now mentions "gnumake"
        explicitly.
    Updated INSTALL.NeXT to refer to new package naming conventions:
        csmain.tgz, csnext.tgz, etc.  NeXT port used to be on other.tgz
        package, but now resides in its own package.  Now mentions new
        INSTALL.General instead of INSTALL.Unix.  Now mentions new Blocks
        (csblocks.tgz) game, as well as docs/blocks.txt.
    Fixed a warning in keys.cpp add_bot() which someone introduced in this
        release.

1999/02/25 (11r057)
    Ported to OpenStep 4.2 and Rhapsody (MacOS/X Server) DR2.
    Restructured directory "system/next" to accommodate the new ports.  Added
        port-specific subdirectories "nextstep", "openstep", & "rhapsody", as
        well as "shared" which contains resources common to all ports.  The
        "openstep" directory is used by both the OpenStep & Rhapsody ports.
    Overhauled NeXTSystemProxy to work with OpenStep and Rhapsody.  Completely
        dropped the use of a separate thread for AppKit's run-loop.  Even
        though NextStep did not mind DPS activity from either thread (properly
        synchronized, of course), Rhapsody disallowed it.  Rather than
        complicating the code even more by sending messages between threads, I
        ditched the idea altogether.  As a replacement, I was able to add a
        category to NSApplication defining the method -runRecursively: which
        works a little magic and allows the run-loop to be invoked recursively
        unlike the normal -run method.  This simplified the implementation of
        NeXTSystemProxy considerably.
    Added NeXTMenu module which constructs the application's menu based on a
        menu-definition configuration file (NeXTMenu.cfg).  There are two such
        files.  One defines a NextStep-style menu which is used for NextStep
        and OpenStep, and the other defines a Rhapsody-style menu.  Removed
        the hard-coded NextStep-style menu definition from NeXTSystemProxy.
    Worked around Rhapsody compiler bug.  Use of -fomit-frame-pointer flag was
        causing the program to crash in the constructor of global objects.
    Fixed bug in Andrew Zabolotny's implementation of the NeXT_STDAPI_ macro
        in cscom.cpp.  It was emitting code which tried to return a value from
        a (void) function.  Added NeXT_STDAPI_VOID for this special case.
        NextStep 3.3 compiler did not catch this error, but OpenStep did.
    The OpenStep 4.2 compiler botched the generation of position independent
        code (PIC) in classes which referred to methods which had not yet been
        declared, but were later declared inline.  Specifically, forward usage
        resulted in actual function calls, but since the methods were later
        declared inline, the compiler never emitted any code for them, thus
        resulting in link errors.  I fixed this via a simple textual
        reorganization of the affected files, lghtmap.h & math3d.h, so that
        method declarations now appear before they are referenced.
    Worked around compiler warning from network/sockets/driver/drvsdefs.h.
        CS_NET_SOCKET is defined as (unsigned int), yet CS_NET_INVALID_SOCKET
        was defined as (-1).  The compiler warned about mixing signed and
        unsigned types.  I changed CS_NET_INVALID_SOCKET to (~0) instead.
    Worked around problem caused by radically different (struct stat) on
        Rhapsody leading to compilation error in Archive::read_zip_entries().
    Added NeXTfopen.cpp & NeXTprintf.cpp which define csSystemDriver::fopen()
        & csSystemDriver::printf() since the Rhapsody compiler was generating
        unlinkable object files when using the versions in system/general
        which accessed global ::fopen() && ::printf().  This is a known
        problem with the Rhapsody development tools.
    Added makefiles for each of the supported NeXT variations: nextstep.mak,
        openstep.mak, & rhapsody.mak.  These files define platform specific
        build information and then include next.mak which is common to all
        three.
    The NeXT makefiles, next.mak & next2d.mak, now properly restrict the
        available architectures for TARGET_ARCHS to those allowed by each
        platform: i386, m68k, sparc, hppa for NextStep; i386, m68k, sparc for
        OpenStep; and i386, ppc for Rhapsody DR2.
    Renamed the NeXT 2D graphics library from "libnext2d" to "next2d".
    Fixed version.h to define OS_VERSION appropriately for each NeXT-style
        platform rather than being hard-coded as "NextStep".
    NeXTDelegate no longer eats right-mouse-down when application is paused,
        so the right button can be used for the main-menu in this case.
    NeXTDelegate no longer sends mouse-moved events when the mouse is outside
        the view bounds.  Even though the tracking rectangle is removed when
        the cursor leaves the view bounds, some mouse-moved events tend to get
        sent anyhow.  The code now ignores these anomalous events.
    NeXTDelegate now reveals the mouse pointer when it exits the view bounds
        if it was hidden.
    Fixed three bugs in NeXTProxy2D's handling of 24-bit RGB.
        (a) Was allocating only half the memory needed for the palette.
        (b) set_rgb() was miscomputing the pointer to the palette entry.
        (c) flush_24() was only copying 2-bytes from the palette to the frame
            buffer, rather than 4-bytes.
    Overhauled INSTALL.NeXT & README.NeXT to accurately reflect new OpenStep
        and Rhapsody ports as well as new directory structure and resources.
    Centralized discussion of multi-architecture binaries in INSTALL.NeXT.
    Updated these documents to reflect OpenStep & Rhapsody ports: CREDITS,
        document.txt, faq.html, whatsnew.txt.
    Updated INSTALL document to mention new INSTALL.BeOS file.
    Fixed long-standing bug in cspFileDialog::Reread() where it botched
        handling of root "/" directory by interpreting it as "".  This made it
        impossible to browse the root directory.  This bug affected all
        platforms which use "/" as a path separator.
    Added "const" version of operator[] to csVector so that elements can be
        conveniently retrieved from "const" vectors as well.
    Added missing "const" qualifier to many csIniFile methods to make it
        usable even when read-only.
    Added "const" to first argument of csIniFile::Load(data,data_size) so that
        it is possible to use it with constant data.
    Fixed the "net" target in the top-level makefile so that it works for all
        platforms, instead of just those which use all four network related
        libraries.  Instead of hard-coding netdrvn, netdrvs, netmann, &
        netmans as dependencies, the sub-makefiles now add the dependencies
        themselves; so the dependency is only added if the sub-makefile is
        used.
    Downgraded "NextStep: broken multiple-inheritance" message from #warning
        to simple FIXME in world.cpp & graph3d.cpp.
    Fixed bug in PolygonSet::intersects_camera_z_plane().  It was declared as
        returning a value, but failed to do so.
    Removed unused "cdrt" variable from Being::collision_detect().

1999/02/15 (11r056)
    Implemented NeXT-specific csGraphics2D::SetMouseCursor().
    Now sends cscmdFocusChanged event when window's focus changes.
    Now only captures mouse movement when window is active.
    Application now pauses in background and when hidden.
    Added a "Pause" menu item.

1999/02/14 (11r055)
    Now compiles on all NextStep platforms: m68k, i386, sparc, hppa.
    Worked around compiler crash when compiling tcache.cpp for hppa.  Problem
        was name of TextureCache::create_lighted_texture_true_rgb_private().
        Apparently the name is too long for the hppa compiler.  I simply
        shortened the name to create_lighted_texture_true_rgb_priv() and the
        error disappeared.
    Temporarily worked around compiler crash in graph3d.cpp when compiling for
        sparc.  Problem occurred with multiple-inheritance and the interface
        table which included IHaloRasterizer (BEGIN_INTERFACE_TABLE).  The
        offending code is currently ignored using conditional compilation
        directives.  Ultimately this needs to be fixed by rewriting the
        csGraphics3D class to use COM composition rather than inheritance.

1999/02/12 (11r055)
    All Crystal Space example programs now work on NextStep for m68k.
    Fixed bug: On m68k, WalkTest crashed in ImageFile::set_dimensions().
        Problem was that ImageGifFile constructor was allocating 9KB on the
        stack for local variables.  To fix this, I re-worked gifimage.cpp so
        that these variables are now allocated from the heap instead.  I also
        generally cleaned it up and made it more robust for all platforms.
    Fixed bug: On m68k, WalkTest crashed in Scan::draw_scanline_map().  The
        start of segment screen pointer "d" which is passed to it from
        csGraphics3DSoftware::DrawPolygon() is corrupt.  This value is corrupt
        because its "sy" variable is invalid (in this case it's negative)
        which causes "screenY" to become corrupt, which is then used to index
        into the line_table[] array, thus retrieving a garbage value for "d".
        Problem was that QRound() macro was malfunctioning on m68k NextStep.
        To fix, I introduced CS_USE_FAST_FLOAT_TO_INT into def.h to control
        usage of the fast versus slow QRound() macro.  NextStep now uses the
        slow version.
    Fixed bug: csSystemDriver constructor was not initializing its "world"
        pointer to null.  This led to crashes when other code tried using that
        variable.  Note that client code correctly checked for null, but since
        this was never initialized, the checks were useless.  Evidence of this
        problem was seen in PrimEdit on NextStep for m68k (debug & optimized)
        and NextStep for i386 (optimized).

1999/02/11 (11r055)
    Andrew Zabolotny's recent re-engineering of makefiles and system-specific
        organization in 11r054 broke NextStep port.
    In particular, netdrvs.mak assumed that all platforms require libsocket.a.
        I fixed this by adding a new makefile variable, NEED_SOCKET_LIB.
    His changes to sysdriv.h resulted in inclusion of non-NeXT
        SysSystemDriver, SysKeyboardDriver, & SysMouseDriver in addition to
        NeXT-specific versions, thus causing conflicts.  I patched sysdriv.h
        to fix this problem.
    Added SYSMODIFIERSHELP makefile variable which allows makefiles to add
        system-specific modifier hints to help message in much the same way as
        they can add system-specific target help via SYSHELP.  Previously
        next2d.mak was documenting TARGET_ARCHS via SYSHELP, but the new
        drivers.mak caused problems with that approach.
    There were also a few other minor problems.

1999/02/09 (11r054)
    Added support for makefile variable TARGET_ARCHS.
    Fixed bug: WAV files failed to load on big-endian platforms.  Patched
        defs.h to properly define PORT_BYTESEX_BIG_ENDIAN as appropriate.
    Fixed bug: PNG images failed to load on m68k.  This caused MazeD to crash
        when trying to utilize a mouse pointer image which had failed to load.
        Problem was that PNG loader was assuming that RGBPixel structure was 4
        bytes, however on m68k, compiler was padding it to 6 bytes.  To fix, I
        rewrote RGBPixel and RGBPalEntry to be more resilient to differences
        in compiler padding.

1999/02/01 (11r053)
    Ported Crystal Space to NextStep 3.3 for Intel.
