> # A Grail Millennium Project

> # White Paper

> History | Preface | TOC

> ##### This document is maintained by the author, Lewis A. Sellers, somewhere in the mountains of East Tennessee, the United States of America. It is an informal technical document for a works in progress project called Grail Millennium, or fully, The Minimal Operating System of Object Class Interfaces Holy Grail for the Millennium. In other words, for a new, easy to use, long-lived operating system.

> ## Copyright Notice

> ##### This document and all material therein, unless otherwise stated, is Copyright © 1995,1996, Lewis A. Sellers. All Rights Reserved. Permission to distribute this document, in part or full, via electronic means (emailed, posted or archived) or printed copy are granted providing that no charges are involved, reasonable attempt is made to use the most current version, and all credits and copyright notices are retained.

> ## Distribution Rights

> ##### All requests for other distribution rights, including incorporation in commercial products, such as books, magazine articles, CD-ROMs, and or computer programs should be made to the primary author Lewis Sellers.

> ## Warranty and disclaimer

> ##### This document is provided as is without any express or implied warranties. This is a work-in-progress, and as such will contain outdated or as yet uncorrected or substanstiated assumptions. The author, maintainer and/or contributors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

> ## WWW Home Sites

> ##### You can currently find home sites to this project at
> - http://www.dwc.edu/grail/
> - http://www.usit.net/public/bcannon/grail/
> If you can not reach them, or they seem to be down, do a key word search on AltaVista, Lycos, or the Web Crawler search engines.

> ## Contact Email

> ##### The primary author of Grail Millennium should be reachable at lsellers@usit.net.

> Preface | TOC

> # OCI/Spec | V I S U A L

> ### DESIGNER

> Lewis A. Sellers (aka Minimalist) lsellers@usit.net

> ### REFERENCES

> - VBE 2.0 and USENET posts of Kendall Bennett
> - rec.games.programmers
> - comp.sys.ibm.pc.hardware.video
> - Our Great Lord "Ferraro", now in his 3rd Incarnation.
> - www.dejanews.com
> - Sergei Savchinko savs@cs.mcgill.ca (3DGPL 1.0)
> - (VGADOC4B.zip)
> - linux, IRC #coders, and the entire internet

> ### ILLUSTRATIONS

> Except where noted, all illustrations, both rendered and drawn, are by myself using POVRAY, MIDNIGHT MODELLER, and bCAD (Russian software).

> ### DRAFTS

> - 0.59
> - 2/1/96 revision .60
> - 2/6/96 revision .61
> - 3/5/96 revision 0.62 (trying to bring the doc into the modern age)
> - 7/19/96 revision 0.63 (changed page one info -- uploaded to WWW)
> - 7/31/96 revision 0.70 (begin www 0.13 editing...)

> TOC

> # (a0.70)

> This document is the combined and enhanced GUI and HLGUI OCIs for GRAIL. This document is concerned with the audio-visual aspects of the human-machine interface. As far as we're concerned there are three kinds or levels of this interface: passive, interactive and emmersive. These functions should be abstractly the most primative and also the foundation of all graphics.

> These documents started out as 7bit ascii, but were changed to RTF and there stayed for a long time. They are currently being translated to HTML.

> "Forbidden Knowledge" or stuff that seems to be hard to find out without an NDA or a whole lot of experimental prodding of the card in question has been moved elsewhere.

> # Table of Contents

> Legal Notices | Who gets sued and why
> History | Changes and who made them
> Preface | About this document and the people that make it

> Overview | An Overview of the Visual Interface

> TOC

> # An Overview of The Visual Interface

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> New terminology is having to be created to talk about the GRAIL and EOS projects intelligibly and without confusion. Most of you are aware that the terms graphic and video are not the same. Video is used to designate visuals originating from cameras and live-video sources, including MPEG1 decoders. Graphic encompasss about every thing else. I've started to call the combination of these visual.

> And as for everything discussed in this document? It's called part of the Human-Machine Interface OCI that deals with visual functions: The HMIVISUL. Each set or group of functions that can be handled by a separate device object or might be on separate cards are called sub-systems.

> [The Digital-Audio sub-system is thusly separate from the MIDI sub-system.... and should be separate drivers even if they do use the same card. Why? Because the end-user might go buy a Gravis Ultrasound and use that for their digital audio while leaving MIDI up to their old SB compatible. Ok? -- If you combine sub-systems into one driver, end-users will bitch at you to no end and curse your company's name forever.]

> Sub-system functions typically directly interface with hardware as device objects, or sit on top of one or more such device objects to coordinate multimedia functions (such as those handling MPEG1 video and Digital Audio).

> Note: The data structures used in this document are for the Grail Assembler and thus use it's syntax, which is a little different. The "dbit" thing merely declares a string of bits is to follow and then tells you how many for each item. The parenthesed number following indicates the minimum number of bytes to reserve. If you have problems with this, the main GA OCI document is available to most anyone who ask, save the damn Microsoft spies. :)

> Each driver or major grouping has it's own prefix name such as VIDEO or MONITOR.

> This document describes the low-level OCI that includes graphics and video subsystems which may or may not be supported in hardware. Each of the subsystems are separate drivers and OCI, but interact with one another sufficiently that in some places their OCIs overlap.

> Grail does not support display modes that predate the VGA. Only bitdepths in the range of 8,15,16,24 and 32. Bitdepths of 1, 2 and 4 are supported internally but require color expansion to be displayed. Monochrome graphics and textmodes are reserved solely for the kernel and kernel debugging routines.

> Mode X/Y/Q are dead. BANK graphics pages are also dead and arcane. They are not directly supported, but certain drivers will emulate other modes using them if they have too. (Ie, maybe you ARE using banked graphics on a certain graphics card, but you need not know it.)

> The card's memory is divided up between the actual mode images (pages, planes, virtual screens etc), cursor icons, character sets and sprites.

> There are four primary configurations for the graphics hardware: Screen, Virtual, Paged and Parallax. There is some work on a high-end mode known as or Ideal. See the next section for details.

> HARDWARE/SOFTWARE-EMULATION

> All the functions in this document MUST be included in their respective drivers. If it is not available in hardware, then software emulation must be provided.

> BANKING

> Videocards that use banks instead of linear apertures have about as much a future as the recently discontinued VLBs. They however must be supported (or else I won't be able to run my own software on my own machine. :)

> Though there are many reasons not to, linear addressable memory is emulated on bank-only cards through the page-fault interrupt. There are no commands to directly do banking. The software as specified here must do this emulation in the background.

> PAGING

> On cards that are not capable of linear memory mapping (mine included) this must be emulated through the page-fault interrupt handler. The benefits to this are obvious--it will SEEM as though you have a fully linear graphics page. The down side is that it adds complexity to the page-handlers, and if your graphics routines are not written with TLB hits in mind, you can DRASTICALLY harm your apps speed.

> ALL low-level primitive written on a bank-only card must take this into consideration and structure their prims so as not to thrash the TLB. This means some circular prims will not be able to save time by mirroring quadrants, etc. Routines must be optimized for the specific vid card. This is one of the reasons that primitive exist in the low-leve functions. It was though better to have us or the manufacturer to design fast primitives code specifically for your hardware rather than have the end-user bitch about how slow your app is. It's a little constraining and tolitarian feeling to some of us, but it does work out better in the end. :)

> Or so I hope.

> GRAPHIC/VIDEO

> There is a distinction between the terms video and graphics. Video is reserved for MPEG1, camcoder and TV inputs.

> CARD SUPPORT

> This set of OCI supports more than one card in a system at a time. In fact it can support one monochrome debugging card, a graphics card, an MPEG accelerator/video-in card, and a stereo VR headset out at a time.

> MEMORY MANAGEMENT

> These OCI manage the memory on your video and graphics card all by themselves. It usually promotes faster operations if you load your sprites into your cards own memory....

> TEXT STREAM CONTROL SEQUENCES

> NULL 0

> FORMFEED 12

> NEWLINE 13

> TAB 8

> TOC

> # Visual Mode Management

> CONCEPT | Lewis A. Sellers lsellers@usit.net
> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> Mode functions for the most part do not draw anything. They setup and manage your graphic modes and talk...

> ### SUGGESTED RESOLUTIONS

> SATURN | 3DO | PS-X | VGA | SVGA | Broadcast NTSC | PAL | HDTV | Macintosh
> --- | --- | --- | --- | --- | --- | --- | --- | ---
> 320x224 | 320x240 | 256x240 | 320x200 | 160x100 | 645x486 | 768x576 | 1920x1035 | 512x342
> 640x224 | 320x480 | 320x240 | 640x400 | 256x256 |  |  | 1920x1152 | 640x870
> 720x576 |  | 512x240 |  | 268x230 |  |  | 1600x1200 | 640x400
> |  | 640x240 |  | 320x240 |  |  |  | 640x480
> |  |  |  | 400x300 |  |  |  | 832x624
> |  |  |  | 640x480 |  |  |  | 800x600
> |  |  |  | 800x600 |  |  |  | 1024x768
> |  |  |  | 1024x768 |  |  |  |
> |  |  |  | 1280x1024 |  |  |  |
> |  |  |  | 1600x1200 |  |  |  |

> ### SUGGESTED BITDEPTHS

> Bits | TYPE | RGB | ColorMode | Name | Display-able Mode?
> --- | --- | --- | --- | --- | ---
> 1 | CLUT | Monochrome | No
> 4 | LUT | Primary | "
> 8 | LUT | (6-6-6) |  | Paletted | Yes, Required
> 15 | DIRECT | 5-5-5 |  | Base Highcolor | Yes, if card allows
> 16 | DIRECT | 5-6-5 |  | Green Highcolor | "
> 24 | DIRECT | 8-8-8 |  | Truecolor | "
> 32 | DIRECT | 8-8-8-8 |  | Alpha Truecolor | "

> TYPE designates whether the colors are directly derived on a pixel-per-pixel basis, or if each pixel is an index into a color lookup table (CLUT).

> Paletted (PC) is also known as Indexed (Mac).

> Base High Color is also known as Sierra Hi-color (PC) and Thousands (Mac).

> Green High Color is also known as XGA Hi-color (PC) or Thousands (Mac). There also exists a Red High Color, but that is not supported. Truecolor is also known as Millions (Mac).

> VISUAL CONFIGURATION MODES

> The visual sub-systems are capable of a six (6) configurations. These modes affect the entire layout of the graphic/video card and are full-screen and independant by nature. That is, your GUI or Metaphor must save it's visual state before initiating an application that requires full-screen control (ie, does not use the __METAPHOR windowing functions, but directly uses graphic primatives).

> Some people will say, "Hey! But I want to do my taxes while I play Quake!". Well, if you must then you should use a GUI/Metaphor that supports what we also call compatability or ideal mode. Be forwarned though, if you don't have an accelerated card, it's a bit slower.

> What is the point of having all these modes? Efficiency. While you could obviously simulate anything we do with just one absolute screen of pixels on a powerful enough machine, these modes each will make use of certain hardware strengths if available and greatly increase the performance of your application in the process. Or at least make it less of a hassle to program.

> SCREEN (NORMAL) MODE

> This is the default normal mode. You have one graphics page/plane which is all that is visible and thusly addressable. The remaining memory on the graphics card is either used by the font, cursor and sprite functions or wasted. This happens to be the default mode for run-of-the-mill GUI Metaphors.

> VIRTUAL MODE

> Very large graphics screen. Only a part of it is on the screen at a time. You can pan the visible screen through the virtual screen. Assuming the graphics card supports extended CRTC registers the panning can be done through hardware and thus is very quick.

> PAGED MODE

> There are several pages which fit the visible screen. Only one can be visible at a time. Used with some GUIs to provide rapid background update by keeping background on 3, working screen on 2 and the blitted/transblitted display on 1. Internally the sub-system keeps a toggle for each page that designates whether it is ready to be seen or not. This is used by the autosyncing features.

> PARALLAX MODE

> Similiar to paged mode, but each of the pages is on screen at once supporting parallax scrolling. Several planes can be on the screen at one time and independantly panned through. If the graphics card has accelerated TransBlit functions this operation is vastly speeded up. Requires at LEAST 4 planes. Two are given to double-buffering scheme, and the others are for the planes.

> When switching to the parallax mode you must specify the number of planes you wish along with the number of buffers. Normally if you'll request either 2 or 3 buffers. There should be two parallax planes as well or there's no reason to use it. You might as well be in virtual mode. If you wish to employ your own parallaxing routines you can of course emulate it yourself using paged, virtual or some other mode.

> RENDER MODE (Z MODE)

> [ed: unfinished!! as time permits this mode will be integrated]

> This mode is specifically for rendering animation to. If you have a 3D graphics card it is idea for DOOM and related games. In this mode each pixel is of the RGBAD type, ie a red/green/blue/alpha/depth ordering. Works best on cards that use a dword (32-bits) for each pixel, etc.

> You must specify the number of rendering buffers you want (usually 2 == double buffering) and ...

> buffers

> z width

> MOVIE MODE

> [ed: unfinished!! as time permits this mode will be integrated]

> This visual mode is optimized for a buffered composition of mostly pre-rendered or illustrated animations, such as MPEG1, MPEG3 or MPEG5 (wavelet?) streams. You can of course modify the composite image before it is displayed.

> composite

> buffer

> STEREO/MONO SUB-MODE

> By default of course it is assumed that the output will go only to one screen or monitor. You can tell the sub-systems to provide for two screen operation, which is mostly of use for 3D headset operation. Takes up twice the memory for pages and planes of course.

> ### IDEAL VISUAL MODE

> Slow on anything less than a P6 200 with MPEG/accelerated vram cards, this mode supports just about everything. Picture in your mind the displays of several monitors scaled onto your GUI/Metaphor background. You get the idea.

> This Visual mode is designed for the power-user with cutting edge hardware. It allows you to have multiple viewports on the screen at once, each indepentally running with their own frame-rates, etc. Supposedly you would just inform your GUI/Metaphor that you wish to run an application in Ideal Visual Mode. The application has no say in the matter. The functions you'd call are virtually the same either way, except there is a little more overhead in setting up the Ideal mode.

> Please look below to the functions themselves and the additional commentary.

> VISUAL.OCI_Info group, ptr_dst

> VISUAL.Card_Info group

> >     	Group 0 - General Compatability
> >     	STRUCT general_compatiability
> >     		dbit.32
> >     			1 monochrome
> >     			1 vga (vga core?)
> >     			1 svga
> >     			1 lag/native
> >     		dbit end
> >     	STRUCT END
> >     	group -- bus
> >     	struct
> >     		width
> >           ;card
> >           dw buswidth      ;32-64
> >           dw cardcpuwidth  ;32-64
> >     	STRUCT END
> >     	Group 1 -- General Functionality
> >           STRUCT General
> >             dbit.32 circuitry
> >               1 crtc
> >               1 extended-crtc
> >               1 vsync-interrupt
> >             dbit end
> >             dbit.32 type
> >               1 crtc
> >               1 extended-crtc
> >               1 banking		;should be yes if not linear.
> >               1 linear		;linear frame buffer?
> >               1 accelerated	;any accelerated functions?
> >               1 mmio		;memory mapped i/o
> >               1 bitBLT
> >               1 transbitBLT
> >               1 hardware_cursor
> >               1 hardware_clipping
> >               1 solid_fill
> >               1 tile_fill
> >               1 stipple_fill
> >             dbit end
> >     	STRUCT END
> >     	group -- accel
> >     	STRUCT
> >     		dbit.32  ;accelerated bitBLTs in hardware?
> >     			1 bitBLT1
> >     			1 bitBLT4
> >     			1 bitBLT8
> >     			1 bitBLT15
> >     			1 bitBLT16
> >     			1 bitBLT24
> >     			1 bitBLT32
> >     		dbit end
> >     		dbit.32 ;accel transbitBLT
> >     			1 transbitBLT1
> >     			1 transbitBLT4
> >     			1 transbitBLT8
> >     			1 transbitBLT15
> >     			1 transbitBLT16
> >     			1 transbitBLT24
> >     			1 transbitBLT32
> >     		dbit end
> >     	STRUCT END
> >     	Group -- Color
> >     	STRUCT
> >     		dbit.32 color
> >     			1 bit1
> >     			1 bit4
> >     			1 bit8DAC6
> >     			1 bit8DAC8
> >     			1 bit16RAMDAC15
> >     			1 bit16RAMDAC16
> >     			1 bit24DAC24
> >     			1 bit24DAC24BGR
> >     			1 bit32DAC24
> >     			1 bit32DAC24BGR
> >     		dbit end
> >     		dbit.32 color_format
> >     			1 RGB ;normal
> >     			1 BGR
> >     		dbit end
> >     	STRUCT END
> >     	Group 1 -- GFB, Graphic Frame Bank
> >     	STRUCT Bank
> >     		dd address	;physical addr of banked buffer
> >     		dd size	;in kb (4 or 64)
> >     		dd gran
> >     		dd ?
> >     	STRUCT END
> >     	Group 1 -- LFA, Linear Frame Address
> >     	STRUCT Linear
> >     		dd address	;beginning address
> >     		dd length	;length of linear buffer
> >     		dd ?
> >     		dd ?
> >     	STRUCT END
> >     	Group 2 -- MMIO, Memory Mapped I/O
> >     	STRUCT MMIO
> >     		dd ?
> >     		dd address
> >     		dptr reserved_length
> >     		dptr allocated_length
> >     	STRUCT END
> >     	Group 2 - Memory
> >     	STRUCT Memory
> >     		dd Total      ;total on card
> >     		dd Free
> >     		dd cursor
> >     		dd ?
> >     		dd mode       ;for current mode ;total size of all pages/planes,etc
> >     		dd Screen     ;size of what's showing on the screen
> >     		dd Virtual    ;size of virtual page, what's showing and what's not
> >     		ptr CURSOR.ptr
> >     		dptr CURSOR.length
> >     		ptr charset_ptr
> >     		dptr charset_length
> >     		ptr sprite_ptr
> >     		dptr sprite_length
> >     	STRUCT END
> >     	group -- video
> >     		dbit.32 VIDEO.flag
> >     			1 chroma-key
> >     			1 framebuffer
> >     		dbit end
> >     		dbit.32 VIDEO.type
> >     			1 MPEG1
> >     			1 MPEG2
> >     			1 QT Quicktime Movie
> >     			1 avi
> >     			1 NTSC
> >     			1 PAL
> >     			1 S-VHS
> >     		dbit end
> >     	group - monitor
> >     		dbit.32 monitor
> >               1 DPMS
> >     		dbit end
> >     	Group 3 -- handler
> >     		STRUCT Handler
> >     			dbit.32
> >     				1  paging?    ;Does the VISUAL handle banking through paging?
> >     			dbit end
> >     			d.32 max_planes
> >     			d.32 max_pages
> >     			d.32 screen_page
> >     			d.32 active_page
> >     		STRUCT END

> VISUAL.Save_ActiveImageRequirements

> This returns a dword indicating the total amount of data being held on the video card for paged, virtual or parallax modes. Used to create a memory block to copy it into.

> VISUAL.Save_ActiveImage ptr_dst

> Copies all the active memory on the graphics card to the destination cursor in system (or godet) memory.

> VISUAL.Restore_ActiveImage ptr_src

> Copies the entire active set for a saved graphics mode back onto the graphics cards memory.

> VISUAL.Save_ModeRequirements

> Returns a dword with a value indicating the number of bytes required for a save of the current mode, not including the actual pixel data.

> VISUAL.Save_Mode ptr_dst

> Saves the entire mode status, including palette if one is being used, and all cursor information and icons. Places this info at the dst cursor. The information saved should NOT be tampered with. It will certainly be different on different machines and/or if written by different authors. Saves everything but the images themselves.

> VISUAL.Restore_Mode ptr_src

> Restores a graphics mode (excluding pixel data) from the data of a previous VISUAL.Save_Mode.

> VISUAL.Request_Mode mode, match, ptr_src

> Requests a specific mode by supplying the sizes, bitdepth, etc. You must create a structure in memory first into which you assign the specifices of the mode you want. The structure is a union of the following:

> STRUCT Normal

> dw zoom_x

> dw zoom _y

> dw aspect_x

> dw aspect_y

> dd width

> dd height

> db bitdepth

> db colororder

> STRUCT END

> STRUCT Paged

> dw zoom_x

> dw zoom_y

> dw aspect_x

> dw aspect_y

> dd width

> dd height

> db bitdepth

> db colororder

> db pages

> STRUCT END

> STRUCT Virtual

> dw zoom_x

> dw zoom_y

> dw aspect_x

> dw aspect_y

> dd width

> dd height

> db bitdepth

> db colororder

> dd v_width

> dd v_height

> STRUCT END

> STRUCT Parallax

> dw zoom_x

> dw zoom_y

> dw aspect_x

> dw aspect_y

> dd width

> dd height

> dd bitdepth

> dd v_width

> dd v_height

> db planes

> db buffering_planes

> STRUCT END

> STRUCT Render

> STRUCT END

> STRUCT Movie

> STRUCT END

> The structure you use of course depends on whether you choose a singular, virtual, paged or parallax mode. After you make the call, you'll check your data structure and see what's available. Yes, the structure is updated with a mode as close as to what you asked for as the driver can come up with. Hopefully it's exactly what you requested. If not... You can either go with what you were given back or fiddle with it a while.

> The zoom_x and zoom_y are normally set to 1 and 1. Usually only if you are porting a 3DO game would you have reason to change it since most hardware acceleration does not help in this area. When zoom is higher than 1 then interpolative display routines are used to make an image seem larger and more detailed than it actually is. You can write the driver to merely multiply pixels, but this is not recommended.

> If you set zoom to other than 1 you also have the added penalty (on most cards) of requiring additional memory for the final full-size buffer.

> Generally aspect is either 4:3, 16:9 or occasionlly 16:10. Choose which you need.

> The match (as in near) parameter defines what is most important to you:

> `0 higher size`

> `1 lower size`

> `2 higher colors`

> `3 lower colors`

> `4 higher virtual size`

> `5 lower virtual size`

> `6 higher Pages/Planes`

> `7 lower Pages/Planes`

> `8 higher z width`

> `9 lower z width`

> `10 higher alpha`

> `11 lower alpha`

> ``This tells the function what to next look for if it can't find an exact match.

> For instance, say I want a 1024x768 256 color mode, normal. I define match as 1, which means if my requested mode isn't exactly available I'm willing to take something a little smaller. Show me what you've got.

> If the function returns with a NULL then your exact request wasn't met.

> The bitorder of a mode only really affects you if plan on directly accessing the graphic area and not use any of the graphic primatives presented here. There are three bit orders available: bitorder, planar, component.

> VISUAL.Request_AutomaticMode mode

> This function automatically chooses a mode for you based on your current card abilities from nine (9) possible selections which follow. In parentheses example modes that would be selected for a SVGA 1MB card.

> `0 LowText (640x480 16)`

> `1 NormalText (640x480 256)`

> `2 HighText (1024x768 256)`

> `3 LowGraphic (320x200 256)`

> `4 NormalGraphic (640x480 256)`

> `5 HighGraphic (1024x768 256)`

> `6 LowPhotographic (640x480 16M)`

> `7 NormalPhotographic (800x600 64k)`

> `8 HighPhotographic (800x600 64k)`

> ``All standard modes must be planar.

> VISUAL.Use_Mode stereo

> After using VISUAL.Request_Mode to find a mode that will work for you, you use this function to switch to it. VISUAL.Request_Mode keeps an internal copy of the last structure you had it look at.

> If there is no visual mode set (ie, you've just booted up or a new application starts off in ideal visual mode) then all the pixels are cleared to black. At other times this function will actually take the old displayed image and scale and bitdepth change it to fit the new mode. What happens to the image next is up to the application.

> If the stereo parameter is set (1) then the display mode produces stereo display buffers. Otherwise (0) you get mono. Stereo mode is only of use on 3D headsets.

> VISUAL.ZoomMethod method

> Defines the default zoom method. A 0 is always simple pixel multiplication, while 1 is interpolation.

> VISUAL.Info_Mode group

> This function returns back important information about the current mode in groups of structures (or cursors).

> Group 0 - Singular

> `STRUCT`

> `d.32 width`

> `d.32 height`

> `d.8 bitdepth`

> `d.32 size`

> `STRUCT END`

> ``

> Group 1 - Virtual

> `STRUCT`

> `d.32 width`

> `d.32 height`

> `d.8 bitdepth`

> `d.32 size`

> `d.32 pan_x`

> `d.32 pan_y`

> `STRUCT END`

> ``

> Group 2 - Paged

> `STRUCT`

> `d.32 width`

> `d.32 height`

> `d.8 bitdepth`

> `dd size`

> `d.8 pages`

> `d.8 current_page`

> `d.8 active_page`

> `...*`

> `pan_x`

> `pan_y`

> `STRUCT END`

> ``

> Group 3 - Parallax

> `STRUCT`

> `d.32 width`

> `d.32 height`

> `d.8 bitdepth`

> `d.32 size`

> `...*`

> `pan_x`

> `pan_y`

> `STRUCT END`

> ;Group 4 - Mode

> ;(1=normal, paged, virtual or parallax)

> Group 5 - Display mode

> (linear, banking, bit-plane (mode x,y,etc))

> Group 6 - Palette

> STRUCT

> dd colors ;colors in palette (256)

> db redbits,greenbits,bluebits

> ;size of red,green,blue in bits (6/6/6)

> db red,green,blue ;size of red,green,blue in "normal" state

> ;in bits (8/8/8)

> dd size ;size of "normal" buffer (768)

> STRUCT END

> Group 7 - Aspect

> STRUCT

> dw aspect_x

> dw aspect_y

> STRUCT END``

> ``

> VISUAL.Display_Page page

> The display page is of course the page that is visible on the screen. It is usually different than the active page. If the current mode is NOT set for paging, then this function does nothing. Otherwise it switches visible pages. If the page does not exist, it also does nothing.

> VISUAL.Active_Page page

> The active page is the page that is drawn to. Usually in 3D simulations you composite a graphic screen on this page, where it's not visible, and shortly the active page will be switched to the display. All drawing occurs on this page unless the primative specifically allows you to draw elsewhere. Also marks this page as not ready. (See VISUAL.PageReady).

> VISUAL.StereoSide side

> This does nothing unless you selected a stereo visual mode. If you did however, you can choose which of the two sets of visual buffers you wish to draw to. For instance, you might render the left side first, then the right. BTW, this function does nothing, and will not even be implemented in the drivers, unless you have a 3D headset.

> VISUAL.Page_Get

> Gets the active page number in EAX and the display in EDX.

> VISUAL.PageReady

> Marks the active page as being ready to be seen. Used by autosync. Note that if you are in stereo there isn't a mark for each eye. Just the one whether you are in mono or stereo.

> VISUAL.Viewport x ,y

> If the current mode is NOT set for virtual oversizing (ie, Virtual or Parallax modes), then this function does nothing. Otherwise it changes the visible window instantly, not bothing to pan or scroll to the new area through the virtual on-card memory. If the mode is parallax this function changes only the active plane. (Ie, while you're changing the active page, you can change it's viewport.)

> VISUAL.Plane_Viewport plane, x, y

> Sets the panning viewport for a specific plane while in parallax mode. This does nothing if you are in anything else.

> VISUAL.Active_Plane plane

> Changes which is the active drawing plane. Only valid for parallax mode. This is actually (currently) just an alias for VISUAL.Active_Page.

> VISUAL.Plane_Get plane

> Returns x (EAX) and y (EDX) of the specified plane. This is currently only an alias for VISUAL.Page_Get.

> VISUAL.PlaneAlpha plane, alpha

> This is the alpha (transparency) of the specified plane.

> VISUAL.Plane_Rotation rotation

> "Rotation? This isn't a damn Sega Saturn! What are you talking about?!"

> Yes, it's true. To my knowledge there isn't hardware to do plane rotation for graphics on the pc. Yet. But why not go ahead and put in the emulation code now. It is the logical thing to do. [Apparently though, MPEG cards, etc can do some scaling/rotation but I haven't information on that.]

> The routines that handle planes should, for speed, have an different set when rotation is ticked on. The rotation is from 0 to 359. The function should be capable of giving differential rotation of at least 5 degree changes. The absolute minimum however is 45 degree increments.

> VISUAL.Plane_Scale scale

> "He's flipped."

> No. :)

> When in parallax mode (the most complicated and powerful of them all) you have total control over each seperate plane. You can individually scale (decimation or interpolation) each plane individually. 'scale' is 32-bit fixed-point number in 16.16 format. It is suggested that scaling functions at minimum support 0, 25, 50, 75, 100, 150, 200, and 400% changes. It is prefered that for commerical use scaling be capable of distinction between each 5% change or better.

> VISUAL.Sync

> Does a loop waiting on the vertical retrace. Expires after about roughly 1 second if the loop fails.

> VISUAL.FrameTarget frames

> Sets the target frame rate. Usually 24, 30 or 60. Note we're talking frames here not fields, so American NTSC television would have a frame-rate of 30fps (approximately).

> VISUAL.FrameSync

> Returns the frame settings, the actual number of frames processed and the current sync interval (monitor mhz) in EAX, EBX, and EDX respectively. In ECX the autosync status is returned.

> VISUAL.AutoSync status

> The function that lets some people sleep more at night. :)

> It doesn't matter HOW this works, but be assured it does. This often used function uses the same routines as VISUAL.Sync to sync and then increase the active and display pages count by 1, bounding them back to 0 as needed. By default the active is initiated to +1 from the display, but this can be changed to anything.

> The status is either 0 (off) or 1 (on).

> The change only occurs if the sync_ok flag is set for that page.

> On most machines this sets up some form of routine in the interrupt timer chain that is pre-synced with the monitor mhz. On some of the better video cards it uses the video cards own retrace sync interrupt which provides better response time and lower overhead.

> VISUAL.Address

> Returns base address of graphic.

> VISUAL.Length

> Returns total amount of memory used by the current screen.

> VISUAL.AddressLength

> This function returns the base address and length associated with the current page/plane (and stereo side) being operated on If for some reason the area is not linear addressable (such as actually being a mode-X or bitplaned mode) then NULL will be returned. In Grail Script this would be:

> (address, length) = VISUAL.AddressLength()

> In general many people will prefer to use the provided graphics primatives since they WILL use any hardware accelerations features available with your graphics card/electronics. Nevertheless, for some complex operations you may sometimes need to be able to directly access each pixel directly. This will give you the addresses you need.

> VISUAL.Fadeout

> Goes from normal lighting to black.

> VISUAL.Fadein

> Goes from black from normal light (current palette).

> VISUAL.Washout

> Goes from normal lighting to white.

> VISUAL.Washin

> Goes from total white to normal lighting.

> VISUAL.Lightlevel level

> For paletted modes, directly modifies the graphics-card palette without changing the on-system palette buffer. The supplied value is a signed number from -128 to 127. For the 256 color paletted modes...

> Hi-color/Truecolor... Oh God. We must hope that there is a way to do this in hardware, otherwise this will really crawl if we must pixel-by-pixel decrease the color after saving a copy of the original. :(

> VISUAL.Palette_Set ptr_src

> You should get mode info before using this function just to be sure, but the palette of course is almost guarenteed to be 768 bytes in length, one byte for each color component.

> VISUAL.Palette_Get ptr_dst

> Copies stream from cursor to the internal palette data area and promptly sends it to the graphics card hardware.

> VISUAL.Natural_Palette

> Sets the palette to a natural color space of 3/3/2.

> VISUAL.Grayscale_Palette

> Sets the palette to a pure grayscale. If in 6bit DAC mode then the colors are spaced out (ie, every four color entries are the same.)

> VISUAL.Set_RGBPalette palette, element

> You should get mode info before using this function just to be sure, but the palette of course is almost guarenteed to be 768 bytes in length, one byte for each color component.

> call VISUAL.Set_RGBPalette palette, element

> STRUCT element

> dw start 1

> dw end 256

> STRUCT width

> dw color 6

> dw element 8

> STRUCT END

> STRUCT END

> IDEAL VISUAL MODE FUNCTIONS

> Alright. So here we are. Ideal visual mode.....

> (fix me)

> As you know, the Ctrl_Esc (ie, controlled escape) key sequence is the only one that the GRAIL operating system reserves for itself besides SysRq (system request). This SHOULD bring your keyboard and mouse, etc back to the attention of the GUI/Metaphor (if that fails, try a SysRq and bring up the Master Control Interface straight from the Operating System). From that vantage point you can move around the ...

> VISUAL.IdealVisualMode status

> This function will attempt to enable or disable Ideal Visual Mode depending on the status parameter (0 is off, 1 is on). There should be no reason for it not to change it at will. Note however, this only affects the policy of creating ideal visual modes, and does not create or destroy them. If you want to know the current status of such things, try VISUAL.Ideal Status.

> So, what if you want to destroy a visual mode that is ideally created?

> You can't. That function is not accessable to applications, but only to the operating system internally. When an application quits, this functions is called and if it was assigned an ideal mode context then it takes care of the situation. In other words, when an Ideal Visual Mode tagged application goes out of scope, the mode also goes out of scope.

> Anyway, when you launch an application and ideal visual mode is active, your current visual mode becomes... NONE. You don't HAVE a visual mode. What I mean by that is that until your app requests a specifc visual mode (say 640x480 256 colors) then you aren't going to see a damned thing. :)

> VISUAL.IdealStatus

> Returns in EAX the visual mode of the curious application, in ECX the count of ideal visual modes, and in EDX the policy and actual ideal status flags.

> The flag part is simple enough. Bit 0 is policy (off or on), and bit 1 is the actual status (full screen or ideal). The current visual mode takes a litle chart however:

> `0 None. Should only get this after boot-up before modes are set or at`

> `the launching of an application when ideal visual mode is set.`

> `1 Singular`

> `2 Paged`

> `3 Virtual`

> `4 Parallax`

> ``

> VISUAL.Idealxy x,y

> VISUAL.Idealscale scale

> Unless and until you say otherwise, the width and height of your screen will be exactly the same as the mode it requests. You can however ask it to be resized. This is the tricky part...

> _________________________________________________________________________

> P O V

> _________________________________________________________________________

> POV.xyz x, y, z

> POV.get_xyz

> POV.anglexyz roll, pitch, yawn

> POV.get_anglezyz

> POV. width, height, / depth

> POV.

> POV.Curvature

> flat

> perspective

> TOC

> # Monitor

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> The following sub-system is for modifying aspects of a monitor that does not neccesairly have anything to do directly with changing the display modes of visual cards.

> MONITOR.Info

> `dbit.32`

> `1 LCD`

> `1 DPMS`

> `dbit end`

> ``

> LCD indicates whether the monitor has a FIXED resolution and color depth (such as an LCD or Plasma Monitor) or if it is something flexible such as an RGB monitor. DPMS Display Power Managment Signaling Standard

> MONITOR.DPMS_Status

> Returns current status of monitor as:

> `0=unknown`

> `1=on`

> `2=standby`

> `3=suspend`

> `4=off`

> ``

> MONITOR.DPMS_Change state

> Orders the monitor to change state. This function returns immediately and does not wait for the change to occur.

> `1=on`

> `2=standby`

> `3=suspend`

> `4=off`

> ``Returns estimate of how long you should have to wait in milliseconds. Should be 1 to 20 seconds. If it is 0 (NULL) then either the routine does known how long to wait or it failed.

> MONITOR.Tweak

> Conversvative

> Aggressive

> image centering x,y

> image scaling w,h

> MONITOR. Probe

> Returns Low_MCLK, Spec_MCLK, High_MCLK, or Mhz

> MONITOR.MCLK_VCLK dword, dword

> Low_VCLK, Spec_VCLK, High_VCLK, or Mhz

> TOC

> # Graphics

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> These functions are the true work horses of the Emmersive User Environment, at least for graphics. They all use the GRAPHICS prefix, for Graphic Object. They primarily use fixed point arguments instead of floating. Each bitdepth mode should have a seperate set of routines for the sake of speed.

> `STRUCT points2_form`

> `dw x`

> `dw y`

> `dw x1`

> `dw y1`

> `STRUCT END`

> ``

> `STRUCT bitBLT_form`

> `dw width`

> `dw height`

> `dw srcleft`

> `dw srctop`

> `dw srcright`

> `dw srcbottom`

> `dw srcpage/plane`

> `dw dstleft`

> `dw dsttop`

> `dw dstpage/plane`

> `dw x_type`

> `dw y_type`

> `db bitdepth`

> `STRUCT END`

> ``

> `STRUCT imageBLT_form`

> `dd ptr`

> `dw dstleft`

> `dw dsttop`

> `dw dstright`

> `dw dstbottom`

> `dw dstpage/plane`

> `dw x_type`

> `dw y_type`

> `db bitdepth`

> `STRUCT END`

> ``

> `STRUCT lumBLT_form`

> `dd srcptr`

> `dw dstleft`

> `dw dsttop`

> `dw dstpage/plane`

> `dw x_type`

> `dw y_type`

> `db bitdepth`

> `STRUCT END`

> ``

> `STRUCT clipping_form`

> `dw left`

> `dw top`

> `dw right`

> `dw bottom`

> `STRUCT END`

> ``

> `STRUCT triangle_form`

> `dw x0`

> `dw y0`

> `dw x1`

> `dw y1`

> `dw x2`

> `dw y2`

> `STRUCT END`

> ``

> `STRUCT circle_form`

> `dw x`

> `dw y`

> `dw radius`

> `STRUCT END`

> ``

> `STRUCT ellipse_form`

> `dw x`

> `dw y`

> `dw minor`

> `dw major`

> `dw tilt`

> `STRUCT END`

> ``

> `STRUCT arc_form`

> `dw x0`

> `dw y0`

> `dw x1`

> `dw y1`

> `dw x2`

> `dw y2`

> `STRUCT END`

> ``

> GRAPHICS.Sync

> Waits for the graphics engine (the graphics card, or the multi-tasking graphics driver, etc) to finish it's job before doing anything else.

> GRAPHICS.Idle

> Checks if the graphics engine (the graphics card, or the multi-tasking graphics driver, etc) is finished it's job. Returns 0 is not, else 1.

> GRAPHICS.ImageBLT src_ptr, ptr_imageBLT_form

> Unlike GRAPHICS.BitBLT which operates entirely in card memory, this blits from main memory to card memory. Essentially it is used to move sprite data or screen images to the card.

> GRAPHICS.BitBLT ptr_bitBLT_form

> Bit Blit. Copies video memory from one place to another. Most new SVGA cards worth anything support hardware BitBLT nowadays (which loosely translated means "Windows Accelerated". :)

> Copies a rectangular area from one part of the screen (on the current or different plane/page) to a new point. If a hardware BitBLT is not available the software should to a series of bitblit lines or use a copy scanlist.

> If the current graphics mode is not the same as the that of the bitmap that is being copied, then color expansion/dithering functions are used. Some cards have these as accelerated functions.

> GRAPHICS.TransBitBLT ptr_bitBLT_form

> Transparent Bit Blit. Copies video memory from one place to another, but does not replace if the pixel is 0. Same as GRAPHICS.BitBLT but uses transparent blitting functions. Also does color expansion/dithering if necessary.

> GRAPHICS.ScaleBLT ptr_bitBLT_form

> GRAPHICS.RotateBLT ptr_bitBLT_form

> GRAPHICS.ScaleRotateBLT ptr_bitBLT_form

> GRAPHICS.NegLumBLT ptr_lumBLT_form

> This function....

> GRAPHICS.PosLumBLT ptr_lumBLT_form

> This function...

> GRAPHICS.Clear_Screen

> Clears the screen. This means all active memory, all pages and planes.

> GRAPHICS.Clear_Page page

> Clears only the specified page when in paged mode. When in other modes it does nothing.

> GRAPHICS.Clear_Plane plane

> Clears only the specified plane when in parallax mode. When in other modes it does nothing.

> GRAPHICS.Page_to_Page pagesrc, pagedst

> BitBLTs one page to the other. Uses GRAPHICS.BitBLT but supplies the args for you.

> GRAPHICS.TransPage_to_Page pagesrc, pagedst

> Uses GRAPHICS.TransBitBLT to copy one page to another. The arguments are computed for you.

> GRAPHICS.Color red, green, blue

> For use when you'll be using multiple bitdepths. Takes the red/green/blue 8-bit components and makes them useful for the current graphics mode. Returns the results in EAX and also stores them for further use.

> If in Truecolor RGB32 (8/8/8/byte)

> red

> green

> blue

> (null)

> If in Truecolor RGB (8/8/8):

> red

> green

> blue

> if in Truecolor BGR (8/8/8)

> blue<-red

> green

> red<-blue

> If in Base Highcolor (5/5/5):

> red>>3

> green>>3

> blue>>3

> If in Green Highcolor (5/6/5):

> red>>3

> green>>2

> blue>>3

> If in Paletted256-Custom6:

> lookup closest in internal palette

> If in Paletted256-Natural6 (3/3/2):

> red>>5

> green>>5

> blue>>6

> If in Paletted256-Custom8:

> lookup

> If in Paletted256-Natural8 (3/3/2):

> red>>5

> green>>5

> blue>>6

> If in Paletted16 (1/2/1):

> red

> green

> blue

> GRAPHICS.Native_Color color

> This supplies the color in a bit-compressed red, green, blue format. If the hardware is bizarre and uses BGR instead of RGB or other formats then routine will compensate and move color-elements to their respective places. The color MUST be in red/green/blue order, unless it is a paletted mode.

> If you are going to being using a set colordepth you may use this.

> GRAPHICS.BackgroundColor red, green, blue

> Same as GRAPHICS.Color but affects the background.

> GRAPHICS.Native_BackgroundColor color

> Same as GRAPHICS.Native_Color but affects background.

> GRAPHICS.Mixing mixing_mode

> The mixing argument refers to the pixel-wise filter operation performed with the current color against the area you are drawing over. This has implications in all BitBLT, TransBLT and Fill operations using either color or pixelmaps. This is for 2-operand BLT raster operations.

> `Code Name Description`

> `00h 0 0 -- Blackness`

> `01h AND And`

> `02h DST Destination`

> `03h SRCanDST Source and Not Destination`

> `04h nDST Not Destination`

> `05h SRC Copy from Source`

> `06h 1 1 -- Whiteness`

> `07h nSRCaDST Not Source and Destination`

> `08h xor Xor (or Invert) Source`

> `09h or Or Source`

> `0Ah nor Not Source`

> `0Bh xnor Exclusive nor Source`

> `0Ch SRConDST Source or not Destination`

> `0Dh nSRC Not Source`

> `0Eh nSRCoDST Not Source or Destination`

> `0Fh nand Not And Source`

> ``

> [PN-DECON.S3M]

> GRAPHICS.Fill arg

> Defines how a filled object is to be filled. The options are either a solid color fill using the currently selected foreground color, tiled fills, or stippled patterns.

> `0 Solid`

> `1 Tile (pattern)`

> `2 Stipple`

> ``

> GRAPHICS.Tile ptr_src, width, height

> Selects the current tile from card memory that is to be used for fills. Generally if the tile is 8x8 it will be faster because hardware assist usually only works for 8x8 patterns. It can be any size you want however.

> GRAPHICS.Stipple stipple, bit_length

> Defines the foreground/background pixel stipple. bitlength should always be 8.

> GRAPHICS.ColorTransparency transparency

> This defines the color to be used for TransBLTs in the current mode.

> GRAPHICS.Swabbing swab

> If Swabbing is ticked on (1) then the transparent and bit BLTs will convert RGB colors to the BGR ordering for the current (annoying) graphics card. This may make your graphics take a big hit. See GRAPHICS.RGB_Swab for more detail.

> GRAPHICS.HardwareTweak group, data

> Tweaks certains things on or off if there is a problem. All tweaks should be adjustable from software. They should also be saved into the Policy/Navigation File as the default sets... to be nice. Tweaks are required when the card and the motherboard, etc aren't entirely compatible or up to specs.

> Group Data

> `0 General Acceleration toggle`

> `1 BitBLT toggle`

> `2 TransBLT toggle`

> `3 ImageBLT toggle`

> `4 FrameBufferAddress address`

> `5 GraphicsCard_TotalMemory memory`

> ``

> GRAPHICS.xy x, y

> Computes the cursor based on the x and y.

> GRAPHICS.xyp x, y, p

> Computes the cursor based on the x, y and page/plane.

> GRAPHICS.Thickness thickness

> Specifies the thickness of wireframe objects: line, circle, ellipse, rectangle.

> GRAPHICS.Clipping clipping_form_ptr, status

> Establishes clipping boundries. Fast when in hardware. If status is 0 (none) then no clipping rectangle is defined or it is set to the size of the full screen.

> GRAPHICS.Scanline y, x0, x1

> Renders a horizontal line at [x0,x1). Uses the color/mix specified by GRAPHICS.Color or GRAPHICS.Native_Color. If stipple is indicated for the fill, then a stipple line is used. Otherwise a hardware/software scanline is used.

> GRAPHICS.Scanlist ptr_src, y

> Renders a list of [x0,x1) scan lines using the current color/mix. The x elements are word pairs terminated by a FFFFh. If stipple is the current fill-type then a list of stipple lines are used. Otherwise true hardware/software scanlist is used. Best I can tell, a stipple list would have to be software emulation.

> GRAPHICS.Point x, y

> Places a pixel at x,y on the current page or plane.

> GRAPHICS.Line x0, y0, x1, y1

> Simple thin line. Drawn on the current page or plane.

> GRAPHICS.Rectangle ptr_rectangle_form

> This is a construct made up of four calls to the line function. Wire-frame.

> GRAPHICS.Quadragon ptr_src

> Four sided polygon.

> GRAPHICS.Polygon ptr_src

> This is a closed set of N x,y corrdinates passed off to the line function. Wire-frame.

> GRAPHICS.ClosedPolyline ptr_src

> This is a closed set of N x,y corrdinates passed off to the line function. Wire-frame.

> GRAPHICS.Triangle ptr_triangle_form

> Creates a triangle.

> GRAPHICS.Circle ptr_circle_form

> Draws a wire-frame circle.

> GRAPHICS.Annulus ptr_annulus_form

> GRAPHICS.SectorCircle ptr_secotrcircle_form

> GRAPHICS.Ellipse ptr_ellipse_form

> Draws a wire-frame ellipse.

> GRAPHICS.Shape ptr_src

> This construct is made up of N x,y coordinates passed off to the line function. Is not closed.

> GRAPHICS.Arc ptr_arc_form

> Draws a non-enclosed wire-frame arc or semi-circle.

> GRAPHICS.FillLine x, y, x1, y1

> Draws a thick solid line.

> GRAPHICS.FillQuadragon ptr_list

> Creates a solid-filled concave quadragon for the list of word sized x,y variables.

> GRAPHICS.FillPolygon ptr_list

> Creates a solid-filled concave polygon for the list of word sized x,y variables. The list is FFFFh terminated, and provides for automatic closure.

> GRAPHICS.FillTriangle ptr_triangle_form

> Creates a solid-filled triangle.

> GRAPHICS.FillRectangle ptr_form1

> Creates a solid filled rectangle.

> GRAPHICS.FillCircle ptr_circle_form

> Creates a solid-filled circle of a specified radius.

> GRAPHICS.FillEllipse ptr_ellipse_form

> Draws a solid-filled ellipse of varible axises and tilt.

> GRAPHICS.FillArc ptr_arc_form

> Draws a filled arc or semi-circle.

> **********************fix

> GRAPHICS.RGB_Swab ptr_src, length, bitdepth

> Grail assume RGBADS pixel orders.

> This routine will correct your >=15 bit depth bitmaps to the RGB ordering used by your graphics card. Some are ass-backward and use BGR ordering. Note that you should only call this ONCE per bitmap since the routine has no idea if a bitmap has been corrected already or not.

> If your card operates in the normal RGB ordering this function does nothing but immediately return.

> You can either use this routine, or flag your BLTing routines to do the BGR->RGB conversions for you. However, it is generally preferred to use this routine to process your images beforehand if they do not need color expansion and you plan on using them as sprites, etc. There is a marked slow-down if the BLTers must convert every pixel they output every single damn time the image is redrawn.

> Call up VISUAL.Info to see if the card currently being used requires RGB swabbing or not.

> GRAPHICS.Lense x, y, ptr_lensingdata, ptr_lensingbuffer

> This function performs a matrix displacement of pixels. The matrix has a header consisting of a word width, and a word height. Then follows the raw data which is simply sets of signed words for x and y. Before the screen area is lensed it is saved to the lensing buffer, which YOU must create beforehand.

> GRAPHICS.Unlense x, y, ptr_lensingbuffer

> Actually this just calls one of the other GRAPHICS functions to blit the data from the lensing buffer back to where it should go after a little data swabbing.

> GRAPHICS.Shade x, y, ptr_shadingdata, ptr_shadingbuffer

> Similiar to a lense, but the data only holds a single signed word which is used to increase or decrease the intensity of each pixel in the matrix on screen.

> GRAPHICS.Unshade x, y, ptr_shadingbuffer

> GRAPHICS.Image x, y, rotation, scale, lumshift, transparency, ptr_imagesrc

> The image source has a header:

> `STRUCT`

> `dw width`

> `dw height`

> `dw bitdepth`

> `dw ?`

> `STRUCT END`

> TOC

> # 3D Graphics

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> Because there are now electronics packages becoming available to the general public that support accelerated hardware rendering of primative 3D objects it is also necessary to define such for Grail so that you may be able to take advantage of them, if so present on a system. Current some of the most interesting hardware could be found by searching for the keywords Lockheed-Martin, Mpact or Verite.

> DEFERRED PERFORMANCE

> There may be available several different settings you can choose from that will affect the quality and systems-hit of graphics renderings, and it can be somewhat difficult at times to choose the best mix on a specific system for performance. To that end, you can call the deferred performance setting function to choose the mix for you. Who know it's capabilities better than the system hardware itself? There are four settings to choose:

> Preview

> Generally this means fast and not exactly accurate wireframe rendering.

> Realtime

> This is generally solid rendering with possibly gouraud shading and probably no antialiasing filters.

> Quality Realtime

> The best the system can do in realtime.

> Non-realtime

> The absolute best quality the system can render without regards to the amount of time required.

> The difference between Preview and Non-realtime is hard to qauge, but for example it might be similiar to that of figs 3A and 3B below.

> Click here for Picture

> MODE

> For 3D rendering cards (and software) there are two general modes of operation you will encounter. Either primatives will be rendered to the screen sequentially at an accelerated pace (called primative mode), or the primatives will be held in memory as objects in a model upon which you can modify (called model mode). For the best effects, the latter is of course preferred.

> _Mode rendering, filter, perspective, alpha, lighting

> ANTI-ALIASING FILTERS

> Anti-aliasing filters enhance the areas around the edges of graphic objects, smoothing one into the other. For example, the first image on the left was rendered without any ant-aliasing. Notice the jaggedness of the edges. The next image used anti-aliasing techniques to smooth the edges of the image into the background.

> NORMAL Click here for Picture Click here for Picture ANTI-ALIASED

> Single Sample

> Texel information is derived from one pixel.

> Bilinear Filter

> Texel information is dervied from the main pixel and the closest neighbors in the horizontal and vertical directions (5 pixels).

> Trilinear Filter

> Texel information is dervied from the main pixel and the closest neighbors in the horizontal, vertical, and left/right diagonal directions (9 pixels).

> MIP-mapped antialiasing

> SHADING

> Wireframe

> Flat

> Gouraud

> Phong (Reflection Model)

> The Phong equation is

> I = ka * Ia + kd * Il * (N . L) + ks * Il * (N . H) ^ n

> where ka, kd, and ks are the material ambient, diffuse, and specular coefficients; n is the Phong shininess xponent; Ia and Il are the ambient and light intensities; N, L, and H are the plane normal, light, and halfway vectors. Recall that ka, kd, ks, Ia, & Il represent RGB triples.

> FLAT Click here for Picture Click here for Picture PHONG

> REFLECTION

> Ambient

> Diffuse

> Specular

> Environment (reflection) mapping

> Radiosity

> RENDERING

> Wireframe

> Flat

> Gouraud

> Phong

> *Environment (reflection) mapping

> PERSPECTIVE

> None

> Correct Perspective Interpolation

> ALPHA-TRANSPARENCY

> ?

> LIGHTING

> You can define a couple different standard lighting sources. This dungeon rendering by Bethesada is a good example of some of the lighting effects we're talking about.

> (illustration removed)

> Point

> A simple point-source. Could be a torch, a fire, a light-bulb, etc.

> Spot (conical)

> Defines a cone of light.

> Directional

> Defines in effect an infinite plane from which light falls at right angles of its primary side.

> Ambient

> Defines the ambient light across the entire of the world. (A little like the Gamma Factor in DOOM, if that helps.)

> delete

> list

> PRIMATIVES

> [ed: Some of the illustrations of 3D object primatives have temporarily been scanned in from Kurt Gieck's ENGINEERING FORMULAS 5th Edition, which no good engineer should be without. As time permits, and before this document becomes public, these drawings will be replaced by custom works by the document's author.]

> I know that ...

> 3DGRAPHICS.Point ptr_point

> STRUCT

> dd x, y, z

> STRUCT END

> 3DGRAPHICS.Cube

> STRUCT

> dd x0, y0, z0

> dd x1, y1, z1

> STRUCT END

> 3DGRAPHICS.Cuboid

> STRUCT

> dd x0, y0, z0

> dd width, height, depth

> STRUCT END

> 3DGRAPHICS.Parallelepiped

> 3DGRAPHICS.FrustrumPyramid

> 3DGRAPHICS.Pyramid

> 3DGRAPHICS.Cylinder

> 3DGRAPHICS.HollowCylinder

> 3DGRAPHICS.Cone

> 3DGRAPHICS.FrustumCone

> 3DGRAPHICS.Sphere

> STRUCT

> dd x, y, z

> dd surface

> STRUCT END

> 3DGRAPHICS.ZoneSphere

> 3DGRAPHICS.SegmentSphere

> 3DGRAPHICS.SphereCylindricalBoring

> 3DGRAPHICS.SphereConicalBoring

> 3DGRAPHICS.Torus

> 3DGRAPHICS.SlicedCylinder

> 3DGRAPHICS.Ungula

> 3DGRAPHICS.Barrel

> 3DGRAPHICS.Prismod

> 3DGRAPHICS.Mesh

> Probably the most complicated of the "primatives". You can supply this function with a list of simple three or four sided polygons and they will be rendered more quickly than you could do individually. Some hardware supports 3 or 4 sided polygon list acceleration, so the use of this function could substantionally increase performance. By default Grail favours 3-sided polygons however.

> The mesh will use the currently selected surface attributes. The elements in the list ....

> dd x0, y0, z0

> dd x1, y1, z1

> dd x2, y2, z2

> SURFACE

> All 3D objects use a common surface type that must first be defined elsewhere for efficiency. Depending on the card, you may have a wide selection of surface options such as:

> For those with predefined textures, you also have extra options to compensate for lack of detail in tight camera positions.

> 3DGRAPHICS.SurfaceDefine n, type, ptr_src

> base color r,g,b

> alpha

> reflectivity

> lighting (glow)

> bump ...

> texture map? --> ptr

> 3DGRAPHICS.Surfaces

> (total, free, used) = 3DGRAPHICS.Surfaces

> AREA EFFECTS

> When in modeling mode, these effects typically use up one 3D object (ie, polygon). They effect the entire specified area. There are currently three general groupings of area effects available:

> Lighting

> Occlusion (fog/haze/clouds)

> This creates an effect of either stationary fog or haze, or cloud layers. You can adjust it's granularity (clumpiness) either through presets or time-sensitive equations.

> presets

> uniform

> aggragate

> gradual

> static

> moving

> fill

> radial

> perimitary

> Distortion (water/fumes/heat)

> These create effects similiar to the rippling of water, gas fumes, or heat rising. There are many other uses you can find of course for these distortions, such as simple lensing.

> static

> (

> )

> moving

> vector

> conical (linear expansive)

> sheet

> radial

> out

> in

> 3DGRAPHICS.Area

> flat

> cuboid

> spheroid

> lighting

> fog/haze

> water/fumes/heat

> LIGHTING

> 3DGRAPHICS.LightingPoint x, y, z, ............

> 3DGRAPHICS.AmbientLighting ......

> TOC

> # An Overview of The Visual Interface

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> A cursor is a flexible graphic on-screen pointer icon. It may or may not be generated by the hardware. The default hardware cursor is usually 1-bit depth (monochrome) and either 32 by 32 or 64 by 64. Sometimes it is 128 by 128. As long as you stay within these parameters, the hardware cursor will stay enabled. Otherwise software takes over. (Unless, of course, you're using a very nice Accelerator card that uses one of it's sprites for the cursor.)

> The cursor routines are hooked into the timer-interrupt (metronome).

> The bitmaps that are used should be of the same bitdepth as the current mode. They also SHOULD be of 8,16,32,64,128, or 256 pixels of width/height, as driver authors are not required to write for other sizes because of the added complexity when rotating. Also, the driver does not have to rotate the image if the width and height are non-equal.

> If rotation is flagged as on, the image can be rotated within 360 degrees. The driver must at least differentiate between each 45 degrees of angle. The more the better of course. It is suggested that rotation and non-rotation use different internals for reasons of speed.

> The cursor can have multiple icons loaded at one time. It is highly suggested to allow at least a minimum of 32. You can at will select from this wide palette, or toggle 'looping' on. When looping is on the driver will cycle through the icons. This is for animation.

> If matting is on then the color 0 will be transparent.

> The depth variable is to show where the cursor is in relation to various planes in parallax mode. When depth equals a plane, the cursor is ON TOP of it.

> Xoffset and Yoffset deliniate the offset of the icon from it's point on screen.

> CURSOR.ON

> In actuality this basically just calls up the PIC chaining functions and adds in the cursor routines to the metronome interrupt chain after doing a little data setup.

> CURSOR.OFF

> Removes the cursor routine from the metronome chain, then cleans up the screen.

> CURSOR.Info dst_ptr

> Returns information back to the structure at the supplied cursor. The structure is:

> `STRUCT`

> `d.32 width,height`

> `d.8 bitdepth,pages`

> `d.32 xoffset,dd xoffset`

> `dbit.8 flags`

> `1 matte?`

> `1 pages?`

> `1 loop_pages?`

> `1 rotation?`

> `; (reserved for scale)`

> `; (reserved for antialias)`

> `dbit end`

> `d.8 frames,depth`

> `d.32 x,y`

> `d.8 current_page`

> `STRUCT END`

> ``

> CURSOR.Definition src_ptr

> Takes the data from the following structure and places it in the internal structure used by the indictor handler.

> `STRUCT`

> `dd width`

> `dd height`

> `db bitdepth`

> `db pages`

> `dd xoffset`

> `dd yoffset`

> `dbit flags`

> `??`

> `dbit end`

> `db frames`

> `db depth`

> `db loop_update`

> `STRUCT END`

> ``

> The default image in memory is one of a top/left pointing arrow. The defaults, btw, are:

> width 32

> height 32

> bitdepth 8

> pages 1

> xoffset 0

> yoffset 0

> frames 10 (in 1/60 sec)

> loop_update

> depth=0

> flags

> matte? 1

> pages? 0

> loop_pages? 0

> rotation? 0

> CURSOR.xy x, y

> This small routine places the values of EAX and EDX into the internal x and y of the cursor handler, and kicks the update flag.

> CURSOR.Page page

> Sets the icon page currently used. This is course will immediately change is looping is on.

> CURSOR.Rotation rotation

> Sets the current rotational translation. 0-359.

> CURSOR.Load src_ptr

> The loads in a stream of cursor icons at cursor 'src'. The data is loaded to fit the width, height and pages parameters as currently defined.

> CURSOR.Save dst_ptr

> Saves all of the current icons loaded up for the cursor at the cursor 'dst'.

> TOC

> # Font Functions

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> This set of font functions are among the higher level in this document since they reply upon GRAPHICS.BitBLT and GRAPHICS.TransBitBLT to operate.

> FONT.Font src_pmap_fontheader

> Gives the graphics text characters function a cursor to the current bitmapped font set. (No, unlike the Cursor functions, the graphics are not copied. Trust me on this.) The font set is composed of two parts: The actual character-per-character graphics and a charset map. The header to all this is:

> `STRUCT pmap_fontheader`

> `db type ;0=fixed,1=variable width`

> `db bitdepth`

> `dw width`

> `dw height`

> `dw characters`

> `ptr map`

> `ptr charset`

> `STRUCT END`

> ``

> The type indicates whether the font set is fixed width or variable. Variable width characters each have a tiny header that tells the width and height of each char in pixels:

> `STRUCT char_struct`

> `dw width`

> `dw height`

> `STRUCT END`

> ``

> If it is not variable width capable this structure will not preceed each character in the font set.

> FONT.xy x, y

> Computes a new position to render the text at. Refer to GRAPHICS.FONT.Effect point for further detail.

> FONT.Effect data_form

> This function sets up all the current defaults as used by the graphics set for representing text data on a graphics screen.

> `STRUCT data_form`

> `db flow`

> `db deformation`

> `db luminacy`

> `db point`

> `dbit`

> `1 matte?`

> `1 antialias?`

> `1 scaling?`

> `1 rotation?`

> `dbit end (4)`

> `dw compress 0--> 100.0 -->`

> `dw scale 0-> 100.0 -> 1000.0%`

> `dw rotate 0-360`

> `dw alpha 0-100.0`

> `STRUCT END`

> ``

> By default all text is fixed width. If a font supports variable width lettering, you can request that the characters be printed so. When flow is 0, text is fixed width. When 1 it is variable width.

> There are a set of deformations which are rather useful. They are:

> `0 none`

> `1 italics`

> `2 bold`

> `3 shadow`

> `4 bottom-compress`

> `5 top-compress`

> ``Italic of course distorts the sentence so that it seems to lean to the right....

> Luminacy modifies the visible parts of the text either mixing it with the pixels underneath or by lightening or darkening the image the text is laid over.

> `0 normal (GRAPHICS.BitBLT)`

> `1 transparent (GRAPHICS.TransBitBLT)`

> `2 negative translucence (GRAPHICS.NegLumBLT)`

> `3 positive translucence (GRAPHICS.PosLumBLT)`

> ``

> You can control where the rotation and scaling origin is through the point parameter:

> `0 center`

> `1 top/left`

> `2 top/right`

> `3 bottom/right`

> `4 bottom/left`

> ``

> If scaling is on, a different set of routines come into play that scale the text around point. Same with rotation. If antialiasing is on (and this is an optional function) then blending occurs that makes the character look more natural.

> FONT.Print src_ptr

> Hey, this actually prints something to the screen! The source (ESI) must point to asciiz plaintext.

> FONT.Print_Size src_ptr

> Returns the width of the string in pixels (EAX) and it's maximum height (EDX). The source string must be asciiz.

> TOC

> # Video Motion Decoding

> CONCEPT | Lewis A. Sellers lsellers@usit.net

> ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

> This set of routines is actually a seperate driver from the rest of the low-level graphics OCI. The reasoning is that many MPEG, etc cards *ARE* physically seperate. :)

> Like all low-level functions, whether or not a card supports them in hardware, they still must exist. All versions of the video sub-system (VIDEO) are required to support MPEG1 and MPEG audio layer 2 and layer 3. Everything else is optional. Apple's Quicktime Movie format (.MOV) is not directly supported but highly encouraged for use as a secondary movie format.

> Video cards may supply vid from remote sources (tv,camcorder,etc) or generate it by feeding off of a video format file such as MPEG. MPEG decoders either use a chroma-key (ie, like using a green screen require one color to be sacrificed for video-transparency) or write directly to an area in the graphics framebuffer. For the sake of portability, both of these must be subsumed into one OCI and a chroma-key declared whether it's used or not.

> The bottom requirements for MPEG1 are that it should support the 352x240 x30frames/s and 720x480 x30frame/s. MPEG1 is a YUV 4:2:2 format using 16x16 macroblocks, thus your software emulation should support scaling that will decimate or interpolate into groups of 16 pixels at least, but this is not required. It is entirely possible that MPEG1 software only solutions will be more flexible than hardware, though they will be considerably slower and memory expensive naturally. Hardware developers are encouraged to develop drivers that enhance their hardware through software where possible.

> The VMD functions are parasitic to both the graphic and audio low-level OCI routines (which, perhaps should be imported into this document).

> And yes, it is quite true that there is a possibility to do sprite handling here. The code and OCI should flow in such a way to cOCItalise upon this possibility in the future (ie, vidboards with multiple outputs generating sprite animations.) In fact, if you look at the sprite handling functions, you'll see there is an option to link into the VIDEO functions.

> VIDEO.Info

> Retrieves information on the primary graphics card. Most of this doesn't really matter since the drivers take care of everything.

> `dbit.32`

> `1 Seperate? ;seperate card`

> `1 feature_connector ;vga 8-bit / vesa`

> ``

> `1 Chromakey`

> `1 DirectFrameWrite`

> ``

> `1 smooth_scaling`

> `1`

> ``

> `1 scaling`

> `1 freefixed`

> `1`

> `dbit end`

> ``

> `d.16 max_sources`

> `d.16 max_outputs`

> ``

> VIDEO.Chroma_Key no, chroma_key

> Defines the video chroma-key. A chroma-key is the color to be used as video-transparent similiar to the blue or green screens used in movies. This is actually ignored if your vidcard writes directly to the framebuffer, but you MUST use it anyway because some people WILL have chroma-cards.

> Traditionally you'd probably wish to have seperate colors designated for both the chroma-key and your bitBLT transparency. The later is almost always 0. It's suggested to use a chroma-key of 1 (or 1/1/1 in RGB terms.) Default chroma-key is always 1 (or 1/1/1) for all sources.

> Both should, if possible, be set to your background color. Chroma-key cards are faster, but can cause intermediate flashs of the chroma-key background color when they cut off on occasion.

> VIDEO.Source no, action

> This defines and dis/enables video sources.

> `STRUCT`

> `dd x`

> `dd y`

> `dd width`

> `dd height`

> `dd bitdepth`

> `....`

> `dd sources`

> `dbit source_type`

> `1 external ;0=feed from file/memory`

> `;1=externally generated (cd,cam,etc)`

> `dbit end (4)`

> `STRUCT END`

> ``

> VIDEO.Query no, action

> no:

> 0=query?

> Action

> 0 query

> 1 enable

> 2 disable

> VIDEO.Area no, area_form

> `STRUCT`

> `dd x`

> `dd y`

> `dd width`

> `dd height`

> `dd xscale`

> `dd yscale`

> `dd rotation`

> `dd ?`

> `STRUCT END`

> ``

> VIDEO.Feed no, ...

> Defines the feed type for the video source. There are only three types supported. An external source, a file (that needs be processed) residing in memory (virtual,godet or otherwise) and an off-memory file. The first two are straight forward. The last requires a little more info to set up.

> `STRUCT`

> `dd general_type ;0=external 1=memory 2=file`

> `dd specific_type`

> `ptr stream ;cursor to feed stream...`

> `STRUCT END`

> ``

> The specific type that might be supported are listed below. The only ones that are REQUIRED to be supported are MPEG1 and MPEG2 video and layer 1,2 and 3 audio.

> `MPEG1 ISO 11172`

> `MPEG2`

> `MPEG4`

> `NTSC/M ;500 lines`

> `PAL/BGH,I,D`

> `SECAM/BGH,D,D,K,K1,L`

> `YUV`

> `VHS ;250 lines`

> `S-VHS ;300 lines`

> `AVI`

> `MOV`

> ``[Note: MPEG3 is obsolete and should not be supported.]