mirror of
https://github.com/cc65/cc65.git
synced 2024-08-18 10:29:06 +00:00
1674 lines
67 KiB
Plaintext
1674 lines
67 KiB
Plaintext
<!doctype linuxdoc system>
|
|
|
|
<article>
|
|
|
|
<!-- Title information -->
|
|
|
|
<title>GEOSLib docs
|
|
<author>Maciej Witkowiak, <htmlurl url="mailto:ytm@elysium.pl" name="ytm@elysium.pl">
|
|
<date>v1.5, 26.12.1999, 2000, 2001, 2002, 2003
|
|
<abstract>
|
|
This is the documentation of cc65's GEOSLib, but information contained here may be also
|
|
useful for writing GEOS applications in general.
|
|
</abstract>
|
|
|
|
<!-- Table of contents -->
|
|
<toc>
|
|
|
|
<!-- Begin the document -->
|
|
|
|
<sect>Introduction
|
|
<p>
|
|
As we all know that the best computers in the world are c64 and c128. They have their GUI too -
|
|
excellent GEOS. GEOS seems very difficult and cryptic for many people, from programmer's point
|
|
of view. That's not true. The designers of GEOS created flexible and powerful system, which
|
|
is easy to use and program.
|
|
<p>
|
|
Coding GEOS in C? That's something new. It is possible now - with Ulrich von Bassewitz's cc65
|
|
package and my GEOSLib you are able to create GEOS applications in no-time.
|
|
<p>
|
|
GEOSLib supports a subset of standard cc65 libraries. Whenever possible native Kernal functions
|
|
are used (e.g. <tt/memset/ is an alias for <tt/FillRam/), however not all are supported. E.g.
|
|
string functions like <tt/strcmp/, <tt/strcpy/ are doubled with native <tt/CmpString/,
|
|
<tt/CopyString/ because the latter can handle only 256 byte strings. Keep this in mind when
|
|
you will write your program. If you don't need long strings simply use functions from Kernal,
|
|
resulting code will be smaller.
|
|
<p>
|
|
<tt/dio/ - direct disk access is available, but you might have problems with devices other
|
|
than 1541, 1571 or 1581. RAM drives emulating these should work.
|
|
<p>
|
|
<tt/conio/ - simple console input-output is available for command line applications.
|
|
This implementation assumes that one character will fit in 8x8 cell, so output with
|
|
default BSW font, which is has 9 points, might be a bit messy.
|
|
<tt/cputs/ will output characters with fixed width, for proportional spacing use
|
|
<tt/cpputs/ but this function does not update cursor. There is no color support in
|
|
GEOS 2.0 so color functions are disabled. Both 40 and 80 columns modes are supported
|
|
and automatically detected.
|
|
<p>
|
|
<tt/tgi/ - TGI driver for GEOS that supports both 40 and 80 columns modes but mode can not be
|
|
changed between <tt/tgi_init/ and <tt/tgi_done/.
|
|
<p>
|
|
<tt/joy/ - JOY driver for GEOS supports only joystick, not current pointing device.
|
|
<p>
|
|
It is safe to use these standard includes and their contents:
|
|
<tt/assert.h, conio.h, dio.h, errno.h, em.h, geos.h, joystick.h, modload.h, mouse.h, stdlib.h, string.h, tgi.h, time.h/
|
|
<p>
|
|
It was not tested enough, but functions from these includes might work under GEOS:
|
|
<tt/rs232.h, zlib.h/
|
|
<p>
|
|
Functions from the headers above are either standard C library functions or cc65-specific, in
|
|
either case they are not GEOS specific and so they are not described here.
|
|
<p>
|
|
I am an assembler programmer and GEOSLib was designed in such way that cc65 could emit the best
|
|
available code (well, the best as for machine :). Many of the <tt/void foo (void)/ functions are
|
|
just raw calls to Kernal (assembled just as <tt/jsr _foo/), look in <tt/gsym.h/, where you
|
|
will find many definitions of standard GEOS locations. Access to these addresses is optimized by
|
|
cc65 to simple <tt/lda/ and <tt/sta/. Don't be afraid to use C syntax.
|
|
|
|
<sect1>Requirements
|
|
<p>
|
|
You will not need c64 or c128 for development. The only hardware requirement is a PC capable of
|
|
running cc65. You will however need c64 or c128 emulator and GEOS image disks (.d64) to test your
|
|
programs.
|
|
|
|
The software needed:
|
|
<itemize>
|
|
<item><em/cc65/ Excellent package containing C crosscompiler, crossassembler and linker, you
|
|
can get it from: <htmlurl url="http://www.von-bassewitz.de/uz/cc65/"
|
|
name="http://www.von-bassewitz.de/uz/cc65/">
|
|
<item><em/VICE/ This is portable C64, C128 and few other Commodore computers emulator, you
|
|
can obtain it from: <htmlurl url="http://www.cs.cmu.edu/~dsladic/vice/vice.html"
|
|
name="http://www.cs.cmu.edu/~dsladic/vice/vice.html">. VICE package contains
|
|
c1541 program that is able to convert/unconvert GEOS files to disk images.
|
|
<item><em/Star Commander/ This tool is only for DOS. You will need it for transferring
|
|
object files from PC to 1541. There's also one important ability of this
|
|
tool - it automatically un-converts .cvt files into GEOS native format on
|
|
disk image files.
|
|
<item><em/cbm4linux/ A Linux kernel module that allows for communication with 1541 and
|
|
other Commodore IEC bus drives. It can be replacement for Star Commander if
|
|
you want only to transfer files to a disk and unconvert using GEOS program for
|
|
this purpose. Check out: <htmlurl url="http://www.lb.shuttle.de/puffin/cbm4linux/"
|
|
name="http://www.lb.shuttle.de/puffin/cbm4linux">
|
|
</itemize>
|
|
<p>
|
|
VICE and cc65 are portable - they run on variety of platforms - DOS, Win32 and UNIX. GEOSLib only
|
|
needs cc65.
|
|
<p>
|
|
<em/Update:/ starting from v2.5.0 GEOSLib is a part of cc65 package as its GEOS support library.
|
|
|
|
<sect1>Legal
|
|
<p>
|
|
I want to thank Uz for his cc65 package, Alexander Boyce for his excellent GEOS Programmer's
|
|
Reference Guide and BSW for GEOS.
|
|
<p>
|
|
GEOSLib is covered by the same license as cc65. You can find the whole text among documentation.
|
|
I would really appreciate if you would like to send me your comments, suggestions, questions,
|
|
changes, bug reports etc. I will also appreciate if you will just give me a sign that you are
|
|
using GEOSLib - not especially something big and important, mail me even if you are just playing
|
|
with it.
|
|
<p>
|
|
You can send postcards with hellos to:
|
|
<p>
|
|
Maciej Witkowiak, ul. Slowackiego 6/57, 77-400 ZLOTOW
|
|
<p>
|
|
POLAND
|
|
<p>
|
|
e-mail: <tt/ytm@elysium.pl/
|
|
|
|
<sect>What have you got and what to do with it?
|
|
<p>
|
|
This chapter describes some rules you ought to obey, and how to use GEOSLib.
|
|
|
|
<sect1>Usage
|
|
<p>
|
|
Apart from this file, which merely describes only standard GEOS library functions, you should read
|
|
<tt/grc/ (GEOS resource compiler) documentation. There are informations about necessary resource
|
|
files (each GEOS application needs at least one) and the building process - what should be done
|
|
and in what order. Please also read cc65's documentation on how to compile C, assembler and link
|
|
everything together.
|
|
<p>
|
|
All in all, you just need to place
|
|
<tscreen><verb>
|
|
#include <geos.h>
|
|
</verb></tscreen>
|
|
on top of your source.
|
|
<p>
|
|
As a general rule read the sources of example programs and read the headers. These are the most
|
|
reliable sources of knowledge ;). You will also find there many C macros representing various
|
|
arguments passed to functions. Please use them. You will find your sources easier to understand,
|
|
and it will be easier to find bugs.
|
|
<p>
|
|
All types used in GEOSLib are <tt/unsigned/.
|
|
<p>
|
|
Screen coordinates are given in pixels unless stated differently.
|
|
|
|
<sect1>Notes on style
|
|
<p>
|
|
Contrary to typical GEOS assembly program which has a main function called after loading that
|
|
setups the screen, menus, icons etc. exiting from <tt/main/ function in C is equivalent to
|
|
calling <tt/exit()/. These two are the only safe methods of terminating applications. DO NOT
|
|
USE <tt/EnterDeskTop/! Your data may be lost as library destructors and functions registered
|
|
with <tt/atexit/ will not be called.
|
|
<p>
|
|
For GEOS GUI applications the recommended program structure is to have everything initialized
|
|
in <tt/main/ function and at the end of it a call to <tt/MainLoop()/ function. WARNING! This
|
|
function never returns, any code between <tt/MainLoop();/ and the end of <tt/main/ will not
|
|
be executed. You have to call <tt/exit()/ explicitly somewhere in your code (e.g. in a menu
|
|
handler or via DialogBox action).
|
|
<p>
|
|
Whenever possible use definitions from <tt/gsym.h/. The resulting code is translated by cc65 into
|
|
series of <tt/lda/ and <tt/sta/, so you can't do it better :-).
|
|
<p>
|
|
Don't hesitate to use library functions. Everything was written with size and speed in mind. In
|
|
fact many calls are just redirections to GEOS kernal which results in simple <tt/jsr/.
|
|
<p>
|
|
The <tt/main/ function receives the standard <tt/argc/ and <tt/argv/ parameters. There are
|
|
always either 1 or 3 parameters. DOS application name is always set as <tt/argv[0]/.
|
|
If present, <tt/argv[1]/ and <tt/argv[2]/ will be set to data filename and data diskname (it only
|
|
works if user double-clicks on data file associated with your application). Note that it is up
|
|
to your application to determine which of the available (up to four) disk drives has the disk
|
|
with given diskname inside. If this fails your program should ask to insert the proper disk into
|
|
one of available drives.
|
|
<p>
|
|
You might wonder why I have chosen sometimes weird order of arguments in functions. I just
|
|
wanted to avoid unnecessary pushing and popping arguments from stack because cc65 can pass single
|
|
<tt/unsigned int/ through CPU registers.
|
|
<p>
|
|
Do not try to compile in strict ANSI mode. Library uses cc65 extensions which are not available in
|
|
ANSI.
|
|
<p>
|
|
It is possible to use dynamically loaded modules, three such modules are provided:
|
|
GEOS TGI driver, GEOS EMD driver (for VDC extended memory) and GEOS JOY driver.
|
|
Just make sure that their filenames appear UPPERCASE in DeskTop. There are no more special
|
|
recommendations, read cc65 documentation about modules and demo programs source code.
|
|
|
|
<sect>Library Functions
|
|
<p>
|
|
Functions here are sorted more or less in the way they appear in header files. This way I am able
|
|
to keep functions covering similar task near each other. All function names are identical to those
|
|
from <tt/geosSym/ file provided with GeoProgrammer package. Only my extensions to <tt/geosSym/
|
|
are covered by new names, but I tried to keep them in the naming convention.
|
|
|
|
<sect1>Graphics
|
|
<p>
|
|
This section covers drawing package of GEOS along with text output routines.
|
|
|
|
<sect2>SetPattern
|
|
<p>
|
|
<tt/void SetPattern (char pattern)/
|
|
<p>
|
|
This function sets current pattern to given. There are 32 different patterns in GEOS. You can
|
|
see them together in the filling box in GeoPaint.
|
|
|
|
<sect2>GraphicsString
|
|
<p>
|
|
<tt/void GraphicsString (char *myGString)/
|
|
<p>
|
|
One of the more powerfull routines of GEOS. This function calls other graphic functions depending
|
|
on given command string. See structures chapter for more detailed description of the structure of it.
|
|
|
|
<sect2>Rectangle functions
|
|
<p>
|
|
Parameters to those functions are grouped in <tt/struct window drawWindow/. To speed up things and
|
|
reduce overhead this structure is glued to zero page locations, where all rectangle functions
|
|
expect their parameters. You can modify data directly (e.g. <tt/drawWindow.top=10/) or via
|
|
<tt/InitDrawWindow/ function. Contents of <tt/drawWindow/ are guaranteed not to change only when
|
|
using graphics functions. In other case you should keep your data in separate <tt/struct window/
|
|
and use <tt/InitDrawWindow/ before first call to rectangle functions.
|
|
|
|
<sect3>InitDrawWindow
|
|
<p>
|
|
<tt/void InitDrawWindow (struct window *myWindow)/
|
|
<p>
|
|
This function only copies contents of <tt/myWindow/ into system area of <tt/drawWindow/. Use it
|
|
if for some reason you have to keep window data out of zero page space.
|
|
|
|
<sect3>Rectangle
|
|
<p>
|
|
<tt/void Rectangle (void)/
|
|
<p>
|
|
This draws on screen rectangle filled with current pattern.
|
|
|
|
<sect3>FrameRectangle
|
|
<p>
|
|
<tt/void FrameRectangle (char pattern)/
|
|
<p>
|
|
This one draws frame with given bit pattern (not a pattern from GEOS palette).
|
|
|
|
<sect3>InvertRectangle
|
|
<p>
|
|
<tt/void InvertRectangle (void)/
|
|
<p>
|
|
Just as the name says...
|
|
|
|
<sect3>ImprintRectangle and RecoverRectangle
|
|
<p>
|
|
<tt/void ImprintRectangle (void)/
|
|
<p>
|
|
<tt/void RecoverRectangle (void)/
|
|
<p>
|
|
These two functions are for copying parts of the screen to (<tt/Imprint/) and from (<tt/Recover/)
|
|
backbuffer of the screen. For example when drawing new menu box GEOS first uses
|
|
<tt/ImprintRectangle/ to save the area under the box, and restores it by <tt/RecoverRectangle/ upon
|
|
destroying the menu.
|
|
|
|
<sect2>Line Functions
|
|
<p>
|
|
GEOS drawing package is optimized so there are different functions for drawing vertical and
|
|
horizontal lines.
|
|
|
|
<sect3>HorizontalLine
|
|
<p>
|
|
<tt/void HorizontalLine (char pattern, char y, unsigned xStart, unsigned xEnd)/
|
|
<p>
|
|
This function draws horizontal line using given pattern - here it is a true bit pattern, not
|
|
pattern set by <tt/SetPattern/.
|
|
|
|
<sect3>InvertLine
|
|
<p>
|
|
<tt/void InvertLine (char y, unsigned xStart, unsigned xEnd)/
|
|
<p>
|
|
There is only horizontal version.
|
|
|
|
<sect3>RecoverLine
|
|
<p>
|
|
<tt/void RecoverLine (char y, unsigned xStart, unsigned xEnd)/
|
|
<p>
|
|
This function recovers only one line. It is utilized by <tt/RecoverRectangle/. See its description
|
|
for more details.
|
|
|
|
<sect3>VerticalLine
|
|
<p>
|
|
<tt/void VerticalLine (char pattern, char yStart, char yEnd, unsigned x)/
|
|
<p>
|
|
This function draws vertical line using given pattern. Note that <tt/pattern/ is not a pattern
|
|
number as set in <tt/SetPattern/ but a true bit pattern.
|
|
|
|
<sect3>DrawLine
|
|
<p>
|
|
<tt/void DrawLine (char mode, struct window *myWindow)/
|
|
<p>
|
|
<tt/top/ parameters of <tt/struct window/ describe the starting point of the line, while
|
|
<tt/bottom/ are for the ending point. If <tt/mode/ is <tt/DRAW_DRAW/ then current pattern from
|
|
<tt/SetPattern/ is used for drawing. If <tt/mode/ is <tt/DRAW_ERASE/ then line is erased from the
|
|
screen. If <tt/mode/ is <tt/DRAW_COPY/ then line is copied from/to back/frontbuffer, according to
|
|
<tt/dispBufferOn/ setting.
|
|
|
|
<sect2>Point Functions
|
|
<p>
|
|
Parameters to these two functions are passed by a pointer to own <tt/struct pixel/ filled with
|
|
proper values.
|
|
|
|
<sect3>DrawPoint
|
|
<p>
|
|
<tt/void DrawPoint (char mode, struct pixel *myPixel)/
|
|
<p>
|
|
Depending on <tt/mode/ (see <tt/DrawLine/) draws/erases/copies a single point
|
|
on the screen.
|
|
|
|
<sect3>TestPoint
|
|
<p>
|
|
<tt/char TestPoint (struct pixel *myPixel)/
|
|
<p>
|
|
This function tests if given pixel is set and returns <tt/true/ (non-zero) or <tt/false/ (zero).
|
|
|
|
<sect2>Character and string output
|
|
|
|
<sect3>cpputs
|
|
<p>
|
|
<tt/cpputsxy (char x, char y, char *myString)/
|
|
<p>
|
|
<tt/cpputs (char *myString)/
|
|
<p>
|
|
Actually this is a part of <tt/conio/, but this function is non-standard. It is
|
|
a variety of <tt/cputs/ that will output string with proportional spacing, not
|
|
fixed like <tt/cputs/.
|
|
|
|
<sect3>PutChar
|
|
<p>
|
|
<tt/void PutChar (char character, char y, unsigned x)/
|
|
<p>
|
|
This function outputs single character using current style and font to screen.
|
|
|
|
<sect3>PutString
|
|
<p>
|
|
<tt/void PutString (char *myString, char y, unsigned x)/
|
|
<p>
|
|
Same as <tt/PutChar/ except the fact that you can output whole <tt/NULL/-terminated string.
|
|
See <tt/ggraph.h/ for list of tokens that you can also place in the string - like <tt/CBOLDON/ or
|
|
<tt/COUTLINEON/.
|
|
|
|
<sect3>PutDecimal
|
|
<p>
|
|
<tt/void PutDecimal (char parameter, unsigned value, char y, unsigned x)/
|
|
<p>
|
|
This function converts <tt/value/ to its decimal representation and outputs it to the screen.
|
|
The <tt/parameter/ is the field width in pixels (range 1-31) and mode bits. Depending on them
|
|
the string can be filled with zeroes (string always 5 characters long) or not and left or right
|
|
justified to given pixel. See <tt/ggraph.h/ for predefined values for <tt/parameter/.
|
|
|
|
<sect2>Font Handling
|
|
|
|
<sect3>GetCharWidth
|
|
<p>
|
|
<tt/char GetCharWidth (char character)/
|
|
<p>
|
|
This function returns real width (in pixels) of given character with current font. It can be used
|
|
for counting the length of string on screen, allowing for indentation or justification.
|
|
|
|
<sect3>LoadCharSet
|
|
<p>
|
|
<tt/void LoadCharSet (struct fontdesc *myFont)/
|
|
<p>
|
|
This function forces GEOS to use given font instead of own. <tt/myFont/ should be casted from
|
|
pointer to the start of area where was loaded record from font file (VLIR structure).
|
|
|
|
<sect3>UseSystemFont
|
|
<p>
|
|
<tt/void UseSystemFont (void)/
|
|
<p>
|
|
This function forces GEOS to use built-in BSW font.
|
|
|
|
<sect2>Bitmap handling
|
|
<p>
|
|
I'm not quite sure how are these functions working (except <tt/BitmapUp/) so you should
|
|
probably look into library sources and compare it with your knowledge. Please let me know
|
|
if something is wrong or broken.
|
|
|
|
<sect3>BitmapUp
|
|
<p>
|
|
<tt/void BitmapUp (struct iconpic *myPic)/
|
|
<p>
|
|
This function unpacks the bitmap and places it on the screen - just as you set it in the
|
|
<tt/struct iconpic/ pointer to which you pass. See <tt/gstruct.h/ for description of this
|
|
structure. Note that you can only use packed GEOS bitmaps - simple Photo Scrap is in this format.
|
|
|
|
<sect3>BitmapClip
|
|
<p>
|
|
<tt/void BitmapClip (char skipLeft, char skipRight, unsigned skipTop, struct iconpic *myPic)/
|
|
<p>
|
|
This function acts similar to <tt/BitmapUp/ but you can also define which parts of the bitmap are
|
|
to be drawn - you give the number of columns (8-pixel) to skip on the right and left of the bitmap,
|
|
and the number of rows to skip from the top if it.
|
|
|
|
<sect3>BitOtherClip
|
|
<p>
|
|
<tt/void BitOtherClip (void *proc1, void *proc2, char skipLeft, char skip Right, unsigned skipTop,
|
|
struct iconpic *myPic)/
|
|
<p>
|
|
Similar to the previous one with some extension. <tt/proc1/ is called before reading a byte (it
|
|
returns in .A next value), and <tt/proc2/ is called every time the parser reads a byte which is
|
|
not a piece of pattern (byte of code greater than 219). Both procedures should be written
|
|
separately in assembler and declared as <tt/__fastcall__/ returning char.
|
|
|
|
<sect1>Menus and Icons
|
|
<p>
|
|
Here you will find information about functions related with menus and icons.
|
|
|
|
<sect2>Menus
|
|
<p>
|
|
Menus are essential for GUI. GEOS can handle only one menu at a time, but each menu can call
|
|
another one, which results in submenu tree. There can be up to 8 menu levels, each one with up
|
|
to 32 items.
|
|
<p>
|
|
Menus are initialized with <tt/DoMenu/ and then Kernal takes care for everything. Your code
|
|
(called from event handler) should be a function without parameters, returning void. You should
|
|
use <tt/DoPreviousMenu/ or <tt/GotoFirstMenu/ at least once in its code to have the screen clean.
|
|
|
|
<sect3>DoMenu
|
|
<p>
|
|
<tt/void DoMenu (struct menu *myMenu)/
|
|
<p>
|
|
This function initializes GEOS menu processor and exits. See <tt/DoMenu structure/ for more
|
|
information about it. Know that many GEOS application just initializes the screen, menu and
|
|
exits to main Kernal loop, this proves the power of <tt/DoMenu/.
|
|
|
|
<sect3>ReDoMenu
|
|
<p>
|
|
<tt/void ReDoMenu (void)/
|
|
<p>
|
|
This simply redraws the menu at lowest level. It works like calling <tt/DoMenu/ again with
|
|
the same parameters.
|
|
|
|
<sect3>RecoverMenu
|
|
<p>
|
|
<tt/void RecoverMenu (void)/
|
|
<p>
|
|
This function erases current menu from the screen. It doesn't change the menu level.
|
|
|
|
<sect3>RecoverAllMenus
|
|
<p>
|
|
<tt/void RecoverAllMenus (void)/
|
|
<p>
|
|
This calls <tt/RecoverMenu/ and erases all menus from the screen. Then the menu level is
|
|
set to 0 (topmost).
|
|
|
|
<sect3>DoPreviousMenu
|
|
<p>
|
|
<tt/void DoPreviousMenu (void)/
|
|
<p>
|
|
This functions causes menu processor to go back one menu level. You should use it in menu
|
|
handler code to have the screen clean.
|
|
|
|
<sect3>GotoFirstMenu
|
|
<p>
|
|
<tt/void GotoFirstMenu (void)/
|
|
<p>
|
|
This one jumps back to the topmost menu. If there is only menu and submenu it works the
|
|
same as <tt/DoPreviousMenu/.
|
|
|
|
<sect2>Icon Functions
|
|
<p>
|
|
Icons are working similar to menus except the fact that there is only one level. Icons are
|
|
defined as a screen area filled with a bitmap, but if you would setup icons and erase the
|
|
screen they are still active and clicking in the place where formerly an icon was will cause
|
|
an effect. Similarly if you would setup icons and then turn them off with <tt/ClearMouseMode/
|
|
the bitmap will be still on the screen but clicking on it would not cause any action.
|
|
There is only one, but powerful icon function.
|
|
|
|
<sect3>DoIcons
|
|
<p>
|
|
<tt/void DoIcons (struct icontab *myIconTab)/
|
|
<p>
|
|
This function initializes all icons that are present on the screen at once. For more information
|
|
look at <tt/Icons/ chapter in this manual.
|
|
|
|
<sect1>DialogBoxes
|
|
<p>
|
|
This chapter covers the most powerful GEOS user interface function - <tt/DoDlgBox/.
|
|
|
|
<sect2>GEOS standard
|
|
|
|
<sect3>DoDlgBox
|
|
<p>
|
|
<tt/char DoDlgBox (char *dialogString)/
|
|
<p>
|
|
DialogBox returns one byte. It can be the value of one of six standard icons (see <tt/gdlgbox.h/)
|
|
or whatever closing routine passes. Register <tt/r0L/ also contains this value.
|
|
<p>
|
|
Read structures chapter for the specs of the <tt/dialogString/.
|
|
|
|
<sect3>RstrFrmDialogue
|
|
<p>
|
|
<tt/char RstrFrmDialogue/
|
|
<p>
|
|
This function called from within DialogBox event immediately closes the DialogBox and returns
|
|
the owner ID (or whatever caller has in the .A register).
|
|
|
|
<sect2>GEOSLib extensions
|
|
<p>
|
|
To simplify usage of DoDlgBox from C I've wrote some help functions - wrappers for DoDlgBox,
|
|
with predefined data. In one word - these are standard DialogBoxes you can see in almost every
|
|
GEOS application.
|
|
|
|
<sect3>DlgBoxYesNo, DlgBoxOkCancel, DlgBoxOk
|
|
<p>
|
|
<tt/char DlgBoxYesNo (char *line1, char *line2)/
|
|
<p>
|
|
<tt/char DlgBoxOkCancel (char *line1, char *line2)/
|
|
<p>
|
|
<tt/void DlgBoxOk (char *line1, char *line2)/
|
|
<p>
|
|
These function show two lines of text in standard-sized DialogBox. You can read the code of
|
|
pressed icon from return value. E.g. for <tt/DlgBoxYesNo/ it can only be <tt/YES/ or <tt/NO/.
|
|
You can pass an empty string or NULL to get a blank line.
|
|
|
|
<sect3>DlgBoxGetString
|
|
<p>
|
|
<tt/char DlgBoxGetString (char *string, char strlen, char *line1, char *line2)/
|
|
<p>
|
|
This function prompts user for entering a string of at most <tt/strlen/ characters. It is returned
|
|
in <tt/string/. The two given lines of text are shown above the input line. Please remember
|
|
that there is also <tt/CANCEL/ icon in the DialogBox and you should test if user confirmed his
|
|
input or gave up. The <tt/string/ is also shown so you can place default input there or remember
|
|
to place <tt/NULL/ at start.
|
|
|
|
<sect3>DlgBoxFileSelect
|
|
<p>
|
|
<tt/char DlgBoxFileSelect (char *class, char filetype, char *filename)/
|
|
<p>
|
|
This routine is the standard file selector. It can return <tt/OPEN/, <tt/CANCEL/ or disk error
|
|
on reading the directory or opening the disk.
|
|
There is also <tt/DISK/ icon shown, but it is handled internally. You pass as input parameters
|
|
<tt/filetype/ and pointer to string containing the first part of file's class. If this string is
|
|
empty (<tt/NULL/ at the start), then all files with given filetype will be shown.
|
|
<p>
|
|
At present this file selector handles only first 16 files of given type and supports only one
|
|
(current) drive.
|
|
|
|
<sect3>MessageBox
|
|
<p>
|
|
<tt/char MessageBox (char mode, const char *format, ...)/
|
|
<p>
|
|
This function is a more general one. It works very much like <tt/printf/ in a
|
|
box. The only difference is <tt/mode/ parameter which allows for placing
|
|
default icons (see <tt/gdlgbox.h/ for list of possible <tt/MB_/ values).
|
|
Any too wide text will be clipped to the size of the default window. If mode
|
|
parameter is invalid or equal to <tt/MB_EMPTY/ then the window will be closed
|
|
after a click. Otherwise the user must choose an icon.
|
|
<p>
|
|
Note: use it if you really need (or if you will use it in many places) as
|
|
it adds quite amount of code to your program.
|
|
<p>
|
|
Note: the formatted text <em/cannot exceed/ 255 bytes in length, there is no check
|
|
for that.
|
|
|
|
<sect1>Mouse, Sprites and Cursors
|
|
<p>
|
|
You will find here functions related to sprite and mouse drawing and handling.
|
|
|
|
<sect2>Mouse related functions
|
|
<p>
|
|
These cover mouse - as a general pointing device, but expect user to utilize as different devices
|
|
as digital or analog joystick, mouse, lightpen or koalapad (whatever it is).
|
|
|
|
<sect3>StartMouseMode
|
|
<p>
|
|
<tt/void StartMouseMode (void)/
|
|
<p>
|
|
This function initializes mouse vectors - <tt/mouseVector/ and <tt/mouseFaultVec/, and then
|
|
calls <tt/MouseUp/.
|
|
|
|
<sect3>ClearMouseMode
|
|
<p>
|
|
<tt/void ClearMouseMode (void)/
|
|
<p>
|
|
This function disables all mouse activities - icons and menus stop to respond to mouse events,
|
|
but they are not cleared from the screen.
|
|
|
|
<sect3>MouseUp and MouseOff
|
|
<p>
|
|
<tt/void MouseUp (void)/
|
|
<p>
|
|
<tt/void MouseOff (void)/
|
|
<p>
|
|
The first function turns the mouse pointer on. It will appear on next IRQ. The second one does
|
|
the opposite - it turns off the pointer, but its position is still updated by input driver.
|
|
|
|
<sect3>IsMseInRegion
|
|
<p>
|
|
<tt/char IsMseInRegion (struct window *myWindow)/
|
|
<p>
|
|
This function tests if mouse pointer is actually in given range of screen. See <tt/gsprite.h/ for
|
|
description of bits in return values - they describe the position in detail.
|
|
|
|
<sect2>Sprites
|
|
<p>
|
|
You are free to use any of the eight sprites, but keep in mind that sprite 0 is actually the mouse
|
|
pointer and sprite 1 can be overwritten when using text prompt. You don't have to worry about
|
|
40/80 column issues because GEOS128 has pretty good sprite emulator for VDC.
|
|
|
|
<sect3>DrawSprite
|
|
<p>
|
|
<tt/void DrawSprite (char sprite, char *mySprite)/
|
|
<p>
|
|
This function initializes the sprite data. <tt/mySprite/ is a 63-byte table with bitmap data, which
|
|
is copied to system sprite area (at <tt/sprpic/ - see <tt/gsym.h/). Hardware sprite registers are
|
|
not initialized and sprite is not yet visible.
|
|
|
|
<sect3>PosSprite
|
|
<p>
|
|
<tt/void PosSprite (char sprite, struct pixel *myPixel)/
|
|
<p>
|
|
This function positions the sprite on the screen. Given coordinates are screen ones - they are
|
|
converted to sprite coordinates by GEOS. Due to this you cannot use this function to position your
|
|
sprite off the left or top to the screen.
|
|
|
|
<sect3>EnablSprite and DisablSprite
|
|
<p>
|
|
<tt/void EnablSprite (char sprite)/
|
|
<p>
|
|
<tt/void DisablSprite (char sprite)/
|
|
<p>
|
|
These two functions are responsible for making the sprite visible or not.
|
|
|
|
<sect2>Cursors and Console
|
|
|
|
<sect3>InitTextPrompt
|
|
<p>
|
|
<tt/void InitTextPrompt (char height)/
|
|
<p>
|
|
This function initializes sprite 1 for text prompt with given <tt/height/. This parameter can be in
|
|
range 1-48.
|
|
|
|
<sect3>PromptOn and PromptOff
|
|
<p>
|
|
<tt/void PromptOn (struct pixel *myPixel)/
|
|
<p>
|
|
<tt/void PromptOff (void)/
|
|
<p>
|
|
The first function places text prompt in given place and enables blinking.
|
|
The second one is pretty self-explanatory.
|
|
|
|
<sect3>GetNextChar
|
|
<p>
|
|
<tt/char GetNextChar (void)/
|
|
<p>
|
|
This function gets next character from the keyboard queue. If the queue is empty it returns
|
|
<tt/NULL/, otherwise you receive true ASCII code of a character or value of special (function)
|
|
key. See <tt/gsprite.h/ for list of them.
|
|
|
|
<sect1>Disk
|
|
<p>
|
|
This chapter covers slightly low-level disk routines. You should use them with care, because
|
|
you may easily corrupt data on disks. Also remember that contemporary GEOS supports many various
|
|
devices and sticking to 1541 track layout (e.g. expecting the directory on track 18) might be
|
|
dangerous.
|
|
<p>
|
|
For some purposes you might consider using <tt/dio.h/ interface to disk access. It is native.
|
|
<p>
|
|
All GEOS disk functions return error code in X register. In some cases this is returned by
|
|
GEOSLib function (if its type is <tt/char/), but in all cases last error is saved in <tt/__oserror/
|
|
location. If it is nonzero - an error occured. See <tt/gdisk.h/ for the list of possible errorcodes.
|
|
You need to include <tt/errno.h/ to get <tt/__oserror/, together with standard <tt/errno/. The
|
|
latter gives less verbose, but still usable information and can be used with <tt/strerror/.
|
|
Probably you will get more information using <tt/_stroserror/ in similar way.
|
|
<p>
|
|
For passing parameters use almost always pointer to your data e.g. <tt/ReadBuff (&myTrSe)/.
|
|
|
|
<sect2>Buffer functions
|
|
<p>
|
|
These functions are taking single data sector (256 bytes) to read or write on a disk.
|
|
|
|
<sect3>ReadBuff and Writebuff
|
|
<p>
|
|
<tt/char ReadBuff (struct tr_se *myTrSe)/
|
|
<p>
|
|
<tt/char WriteBuff (struct tr_se *myTrSe)/
|
|
<p>
|
|
These functions read and write sector placed at <tt/diskBlkBuf/.
|
|
|
|
<sect3>GetBlock and ReadBlock
|
|
<p>
|
|
<tt/char GetBlock (struct tr_se *myTrSe, char *buffer)/
|
|
<p>
|
|
<tt/char ReadBlock (struct tr_se *myTrSe, char *buffer)/
|
|
<p>
|
|
These two functions are reading a single block directly at 256 byte array placed at <tt/buffer/.
|
|
The difference between them is that <tt/GetBlock/ will initialize TurboDos in drive if it was not
|
|
enabled. <tt/ReadBlock/ assumes that it is already enabled thus being slightly faster.
|
|
|
|
<sect3>PutBlock, WriteBlock, VerWriteBlock
|
|
<p>
|
|
<tt/char PutBlock (struct tr_se *myTrSe, char *buffer)/
|
|
<p>
|
|
<tt/char WriteBlock (struct tr_se *myTrSe, char *buffer)/
|
|
<p>
|
|
<tt/char VerWriteBlock (struct tr_se *myTrSe, char *buffer)/
|
|
<p>
|
|
Similar to previous but needed for writing the disk. <tt/VerWriteBlock/ verifies the data after
|
|
writing. In case of error five tries are attempted before error code is returned.
|
|
|
|
<sect2>Directory header
|
|
<p>
|
|
Functions described here are operating on <tt/curDirHeader/ where current disk header is stored.
|
|
On larger capacity drives (than 1541) the second part of directory header in <tt/dir2Head/.
|
|
|
|
<sect3>GetPtrCurDkNm
|
|
<p>
|
|
<tt/void GetPtrCurDkNm (char *diskName)/
|
|
<p>
|
|
This function fills given character string with the name of current disk. It is converted to C
|
|
standard - string is terminated with <tt/NULL/ character instead of code 160 as in Commodore DOS.
|
|
Note that passed pointer must point to an array of at least 17 bytes.
|
|
|
|
<sect3>GetDirHead and PutDirHead
|
|
<p>
|
|
<tt/char GetDirHead (void)/
|
|
<p>
|
|
<tt/char PutDirHead (void)/
|
|
<p>
|
|
These functions are reading and writing the directory header. You should use <tt/GetDirHead/ before
|
|
using any functions described below, and you should use <tt/PutDirHead/ to save the changes on the
|
|
disk. Otherwise they will be lost. Operating area is the <tt/curDirHead/.
|
|
|
|
<sect3>CalcBlksFree
|
|
<p>
|
|
<tt/unsigned CalcBlksFree (void)/
|
|
<p>
|
|
This function returns the number of free blocks on current disk. It is counted using data in
|
|
<tt/curDirHead/ so you must initialize the disk before calling it.
|
|
|
|
<sect3>ChkDskGEOS
|
|
<p>
|
|
<tt/char ChkDskGEOS (void)/
|
|
<p>
|
|
This functions checks <tt/curDirHead/ for GEOS Format identifier. It returns either true or false,
|
|
and also sets <tt/isGEOS/ properly. You must initialize the disk before using this.
|
|
|
|
<sect3>SetGEOSDisk
|
|
<p>
|
|
<tt/char SetGEOSDisk (void)/
|
|
<p>
|
|
This function initializes disk for use with GEOS. It sets indicator in directory header and
|
|
allocates a sector for the directory of border files. You don't need to initialize the disk before
|
|
using.
|
|
|
|
<sect3>FindBAMBit
|
|
<p>
|
|
<tt/char FindBAMBit (struct tr_se *myTrSe)/
|
|
<p>
|
|
This function returns the bit value from BAM (Block Allocation Map) for given sector. The bit is
|
|
set if the sector is free to use. Returned value is always zero if the sector is already allocated.
|
|
In fact, this function could be used in a following way:
|
|
<tscreen><verb>
|
|
#define BlockInUse FindBAMBit
|
|
...
|
|
if (!BlockInUse(&myTrSe)) {
|
|
... block not allocated ...
|
|
}
|
|
</verb></tscreen>
|
|
<p>
|
|
Anyway, I feel that this function is too low-level.
|
|
|
|
<sect3>BlkAlloc and NxtBlkAlloc
|
|
<p>
|
|
<tt/char BlkAlloc (struct tr_se output[&rsqb, unsigned length)/
|
|
<p>
|
|
<tt/char NxtBlkAlloc (struct tr_se *myTrSe, struct tr_se output[&rsqb, unsigned length)/
|
|
<p>
|
|
Both functions are allocating enough disk sectors to fit the number of <tt/length/ in them. You
|
|
will find output in <tt/output/ which is table of <tt/struct tr_se/. The last entry will have the
|
|
number of track equal to 0 and sector equal to 255. The simplest way of using them is to use
|
|
predefined space in GEOS data space and pass <tt/fileTrScTab/, which is a predefined table.
|
|
<p>
|
|
The difference between those two is that <tt/NextBlkAlloc/ will start allocating from given sector,
|
|
and <tt/BlkAlloc/ starts from the first nonused sector.
|
|
<p>
|
|
You need to use <tt/PutDirHead/ later to save any changes in BAM.
|
|
|
|
<sect3>FreeBlock
|
|
<p>
|
|
<tt/char FreeBlock (struct tr_se *myTrSe)/
|
|
<p>
|
|
Simply deallocates a block in BAM. You need to update BAM with <tt/PutDirHead/.
|
|
|
|
<sect3>SetNextFree
|
|
<p>
|
|
<tt/struct tr_se SetNextFree (struct tr_se *myTrSe)/
|
|
<p>
|
|
This function finds the first free sector starting from given track and sector and allocates it.
|
|
It might return the same argument if the given block is not allocated. I wanted it to be type
|
|
clean, but it made usage a bit tricky. To assign a value to own <tt/struct tr_se/ you have to
|
|
cast both variables to <tt/unsigned/. E.g.
|
|
<tscreen><verb>
|
|
struct tr_se myTrSe;
|
|
...
|
|
(unsigned)myTrSe=(unsigned)SetNextFree(&otherTrSe);
|
|
</verb></tscreen>
|
|
<p>
|
|
In this example <tt/otherTrSe/ can be replaced by <tt/myTrSe/.
|
|
<p>
|
|
Note: you <em/must/ use casting to have correct values.
|
|
|
|
<sect2>Low-level disk IO
|
|
<p>
|
|
Functions described here are more usable in kernal or drivers code, less common in applications,
|
|
but who knows, maybe someone will need them.
|
|
|
|
<sect3>EnterTurbo, ExitTurbo, PurgeTurbo
|
|
<p>
|
|
<tt/void EnterTurbo (void)/
|
|
<p>
|
|
<tt/void ExitTurbo (void)/
|
|
<p>
|
|
<tt/void PurgeTurbo (void)/
|
|
<p>
|
|
These functions are interface to GEOS TurboDos feature which makes slow Commodore drives a bit
|
|
more usable. <tt/EnterTurbo/ enables TurboDos unless it is already enabled. If not, then you will
|
|
have to wait a bit to transfer TurboDos code into disk drive RAM. <tt/ExitTurbo/ disables TurboDos.
|
|
This is useful for sending some DOS commands for drive e.g. for formatting. Note that before any
|
|
interaction with Kernal in ROM you have to call <tt/InitForIO/. You don't have to worry about speed.
|
|
<tt/EnterTurbo/ will only enable TurboDos (no code transfer) if TurboDos was disabled with
|
|
<tt/ExitTurbo/. <tt/PurgeTurbo/ acts different from <tt/ExitTurbo/ - it not only disables TurboDos,
|
|
but also removes it from drive RAM (not quite true, but it works like that). After using
|
|
<tt/PurgeTurbo/ the next call to <tt/EnterTurbo/ will reload drive RAM.
|
|
|
|
<sect3>ChangeDiskDevice
|
|
<p>
|
|
<tt/char ChangeDiskDevice (char newDevice)/
|
|
<p>
|
|
This function changes logical number of current device (in fact drives only) with given one. It is
|
|
usable for swapping drives. There's no check if given <tt/newDevice/ already exist, so if you want
|
|
to change the logical number of drive 8 to 9 and you have drive number 9 then GEOS will probably
|
|
hang on disk access. Use safe, large numbers. Note that safe IEC range is 8-31.
|
|
|
|
<sect2>Disk Initialization
|
|
<p>
|
|
GEOS has two functions for initialization ('logging in' as they say on CP\M) the disk.
|
|
<sect3>OpenDisk
|
|
<p>
|
|
<tt/char OpenDisk (void)/
|
|
<p>
|
|
This function initializes everything for a new disk. It loads and enables TurboDos if needed.
|
|
Then the disk is initialized with <tt/NewDisk/. Next, <tt/GetDirHead/ initializes <tt/curDirHead/.
|
|
Disk names are compared and if they differ then disk cache on REU is cleared. Finally format is
|
|
checked with <tt/ChkDkGEOS/ and disk name is updated in internal tables.
|
|
|
|
<sect3>NewDisk
|
|
<p>
|
|
<tt/char NewDisk (void)/
|
|
<p>
|
|
This function is similar to DOS command I. It clears REU cache and enables TurboDos if needed.
|
|
|
|
<sect1>Files
|
|
<p>
|
|
This section cover GEOS file interface.
|
|
|
|
<sect2>Directory handling
|
|
<p>
|
|
Functions described here are common for SEQ and VLIR structures.
|
|
|
|
<sect3>Get1stDirEntry and GetNxtDirEntry
|
|
<p>
|
|
<tt/struct filehandle *Get1stDirEntry (void)/
|
|
<p>
|
|
<tt/struct filehandle *GetNxtDirEntry (void)/
|
|
<p>
|
|
These two functions are best suited for scanning whole directory for particular files. Note that
|
|
returned filehandles describes all file slots in the directory - even those with deleted files.
|
|
The return value can be obtained by casting both sides to <tt/unsigned/ - as in <tt/SetNextFree/
|
|
function or read directly after call to those two functions from <tt/r5/. Current sector number
|
|
is in <tt/r1/ and sector data itself is in <tt/diskBlkBuf/.
|
|
|
|
<sect3>FindFile
|
|
<p>
|
|
<tt/char FindFile (char *fName)/
|
|
<p>
|
|
This function scans whole directory for the given filename. It returns either 0 (success) or 5
|
|
(FILE_NOT_FOUND, defined in <tt/gdisk.h/) or any other fatal disk read error. After successful
|
|
<tt/FindFile/ you will have <tt/struct filehandle/ at <tt/dirEntryBuf/ filled with file's data and
|
|
other registers set as described in <tt/GetNxtDirEntry/.
|
|
|
|
<sect3>FindFTypes
|
|
<p>
|
|
<tt/char FindFTypes (char *buffer, char fType, char fMaxNum, char *classTxt)/
|
|
<p>
|
|
This function scans directory and fills a table at <tt/buffer/ with <tt/char [17]/ entries.
|
|
<tt/fType/ is GEOS type of searched files and <tt/classTxt/ is a string for Class field in file
|
|
header. Class will match if given will be equal or shorter than that found in file's header block.
|
|
If you want just to find all files with given GEOS type you should pass empty string or <tt/NULL/ as
|
|
<tt/classTxt/. Be warned that for searching <tt/NON_GEOS/ files must pass <tt/NULL/ as <tt/classTxt/.
|
|
<tt/fMaxNum/ is the maximal number of found files, thus the <tt/buffer/ must
|
|
provide area of size equal to <tt/17 * fMaxNum/.
|
|
This function returns the number of found files, ranging from 0 to number passed as <tt/fMaxNum/.
|
|
Return value can be also restored from <tt/r7H/.
|
|
|
|
<sect3>DeleteFile
|
|
<p>
|
|
<tt/char DeleteFile (char *fName)/
|
|
<p>
|
|
This function deletes a file by its name. It works for SEQ and VLIR files.
|
|
|
|
<sect3>RenameFile
|
|
<p>
|
|
<tt/char RenameFile (char *oldName, char *newName)/
|
|
<p>
|
|
I think it is obvious...
|
|
|
|
<sect3>GetFHdrInfo
|
|
<p>
|
|
<tt/char GetFHdrInfo (struct filehandle *myFile)/
|
|
<p>
|
|
This function loads the file header into <tt/fileHeader/ buffer. Using after e.g. <tt/FindFile/
|
|
you can pass address of <tt/dirEntryBuf/.
|
|
|
|
<sect2>Common and SEQ structure
|
|
<p>
|
|
Functions described here are common for SEQ and VLIR structures because arguments passed are
|
|
starting track and sector which may point either to start of a chain for VLIR or data for SEQ.
|
|
|
|
<sect3>GetFile
|
|
<p>
|
|
<tt/char __fastcall__ GetFile(char flag, const char *fname, const char *loadaddr, const char *datadname, const char *datafname)/
|
|
<p>
|
|
This routine loads and runs a given file <tt/fname/. The file must be one of following types:
|
|
<tt/SYSTEM, DESK_ACC, APPLICATION, APPL_DATA, PRINTER,/ or <tt/INPUT_DEVICE/. The execution
|
|
address is taken from file header. If it is zero, then file is only loaded. Only the first chain
|
|
from VLIR files is loaded. If <tt/flag/ has bit 0 set then load address is taken from <tt/loadaddr/
|
|
and not from file header. In this case <tt/APPLICATION/ files will be only loaded, not executed.
|
|
This does not apply to <tt/DESK_ACC/. If either bit 6 or 7 of <tt/flag/ are set, then 16 bytes from
|
|
<tt/datadname/ is copied to <tt/dataDiskName/ and 16 bytes from <tt/datafname/ goes to <tt/dataFileName/
|
|
thus becoming parameters for the new application. Pass <tt/NULL/ as any unused parameter.
|
|
|
|
<sect3>ReadFile
|
|
<p>
|
|
<tt/char ReadFile (struct tr_se *myTrSe, char *buffer, unsigned fLength)/
|
|
<p>
|
|
This function reads at most <tt/fLength/ bytes into <tt/buffer/ from chained sectors starting at
|
|
<tt/myTrSe/.
|
|
|
|
<sect3>ReadByte
|
|
<p>
|
|
<tt/char ReadByte (void)/
|
|
<p>
|
|
This function returns next byte from a file. Before the first call to it you must load <tt/r5/
|
|
with <tt/NULL/, <tt/r4/ with sector buffer address and <tt/r1/ with track and sector of the
|
|
first block of a file.
|
|
Remember to not modify <tt/r1/, <tt/r4/ and <tt/r5/. These registers must be preserved between
|
|
calls to <tt/ReadByte/.
|
|
<p>
|
|
Returned value is valid only if there was no error. End of file is marked as <tt/BFR_OVERFLOW/
|
|
in <tt/__oserror/, this is set when trying to read one byte after the end of file, in this case
|
|
returned value is invalid.
|
|
|
|
<sect3>SaveFile
|
|
<p>
|
|
<tt/char SaveFile (char skip, struct fileheader *myHeader)/
|
|
<p>
|
|
<tt/SaveFile/ will take care of everything needed to create a GEOS file, no matter VLIR of SEQ
|
|
structure. All you need to do is to place data in proper place and prepare a header which will
|
|
contain all information about a file. The <tt/skip/ parameter says how many directory pages you
|
|
want to skip before searching for a free slot for directory entry. In most cases you will put
|
|
<tt/0/ there.
|
|
<p>
|
|
You have to declare a <tt/struct fileheader/ and fill it with proper values. There is only one
|
|
difference - the first two bytes which are link to nonexistent next sector are replaced by a
|
|
pointer to the DOS filename of the file.
|
|
<p>
|
|
When saving sequential files two most important fields in <tt/struct fileheader/ are <tt/fileheader.load_address/
|
|
and <tt/fileheader.end_address/.
|
|
|
|
<sect3>FreeFile
|
|
<p>
|
|
<tt/char FreeFile (struct tr_se myTable[])/
|
|
<p>
|
|
This function deallocates all sectors contained in passed table.
|
|
|
|
<sect3>FollowChain
|
|
<p>
|
|
<tt/char FollowChain(struct tr_se *myTrSe, char *buffer)/
|
|
<p>
|
|
This function fills a <tt/struct tr_se/ table at <tt/buffer/ with sector numbers for chain of
|
|
sectors starting with <tt/myTrSe/. You can pass such data (<tt/buffer/) to e.g. <tt/FreeFile/.
|
|
|
|
<sect2>VLIR structure
|
|
<p>
|
|
Here are informations about VLIR files (called later as RecordFile) and functions.
|
|
<p>
|
|
VLIR is a file which consists of up to 127 SEQ-like files called records. Each record is like one
|
|
SEQ structure file. Records are grouped together, described by common name - VLIR file name and
|
|
own number. Each record pointed by its number is described by starting track and sector numbers.
|
|
VLIR structures allow records to be empty (<tt/tr_se/ of such record is equal to <tt/{NULL,$ff}/),
|
|
or even non-exist (<tt/{NULL,NULL}/). Any other numbers represent starting track and sector of
|
|
particular file.
|
|
<p>
|
|
In GEOS there can be only one file opened at a time. Upon opening VLIR file some information
|
|
about it are copied into memory. You can retrieve records table at <tt/fileTrScTab/ (table of
|
|
128 <tt/struct tr_se/) and from <tt/VLIRInfo/ (<tt/struct VLIR_info/.
|
|
E.g. size of whole VLIR file can be retrieved by reading <tt/VLIRInfo.fileSize/.
|
|
|
|
<sect3>OpenRecordFile
|
|
<p>
|
|
<tt/char OpenRecordFile (char *fName)/
|
|
<p>
|
|
This function finds and opens given file. An error is returned if file is not found or if it is not
|
|
in VLIR format. Information in <tt/VLIRInfo/ is initialized. VLIR track and sector table is
|
|
loaded at <tt/fileTrScTab/ and will be valid until call to <tt/CloseRecordFile/ so don't modify it.
|
|
You should <tt/PointRecord/ before trying to do something with file.
|
|
|
|
<sect3>CloseRecordFile
|
|
<p>
|
|
<tt/char CloseRecordFile (void)/
|
|
<p>
|
|
This function calls <tt/UpdateRecordFile/ and clears internal GEOS variables.
|
|
|
|
<sect3>UpdateRecordFile
|
|
<p>
|
|
<tt/char UpdateRecordFile (void)/
|
|
<p>
|
|
This function will check <tt/VLIRInfo.fileWritten/ flag and if it is set, then <tt/curDirHead/ is
|
|
updated along with size and date stamps in directory entry.
|
|
|
|
<sect3>PointRecord
|
|
<p>
|
|
<tt/char PointRecord (char recordNumber)/
|
|
<p>
|
|
This function will setup internal variables (and <tt/VLIRInfo.curRecord/) and return the track and
|
|
sector of given record in <tt/r1/. Note that the data may not be valid (if record is non-existing
|
|
you will get 0,0 and if it is empty - 255, 0).
|
|
|
|
<sect3>NextRecord and PreviousRecord
|
|
<p>
|
|
<tt/char NextRecord (void)/
|
|
<p>
|
|
<tt/char PreviousRecord (void)/
|
|
<p>
|
|
These two work like <tt/PointRecord/. Names are self-explanatory.
|
|
|
|
<sect3>AppendRecord
|
|
<p>
|
|
<tt/char AppendRecord (void)/
|
|
<p>
|
|
This function will append an empty record ( pair of 255,0 ) to current VLIR track and sector
|
|
table. It will also set <tt/VLIRInfo.curRecord/ to its number.
|
|
|
|
<sect3>DeleteRecord
|
|
<p>
|
|
<tt/char DeleteRecord (void)/
|
|
<p>
|
|
This function will remove current record from the table, and move all current+1 records one place
|
|
back (in the table). Note that there's no BAM update and you must call <tt/UpdateRecordFile/ to
|
|
commit changes.
|
|
|
|
<sect3>InsertRecord
|
|
<p>
|
|
<tt/char InsertRecord (void)/
|
|
<p>
|
|
This function will insert an empty record in place of <tt/VLIRInfo.curRecord/ and move all following
|
|
records in table one place forward (contents of <tt/VLIRInfo.curRecord/ after call to <tt/InsertRecord/
|
|
can be found in <tt/VLIRInfo.curRecord + 1/).
|
|
|
|
<sect3>ReadRecord and WriteRecord
|
|
<p>
|
|
<tt/char ReadRecord (char *buffer, unsigned fLength)/
|
|
<p>
|
|
<tt/char WriteRecord (char *buffer, unsigned fLength)/
|
|
<p>
|
|
This function will load or save at most <tt/fLength/ bytes from currently pointed record into or from
|
|
<tt/buffer/.
|
|
|
|
<sect1>Memory and Strings
|
|
<p>
|
|
Functions covered in this section are common for whole C world - copying memory parts and
|
|
strings is one of the main computer tasks. GEOS also has interface to do this. These functions
|
|
are replacement for those like <tt/memset, memcpy, strcpy/ etc. from standard libraries.
|
|
If you are dealing with short strings (up to 255 characters) you should use these functions
|
|
instead of standard ones. E.g. <tt/CopyString/ instead of <tt/strcpy/. It will work faster.
|
|
<p>
|
|
However some of them have slightly different calling convention (order of arguments to be specific),
|
|
so please check their syntax here before direct replacing.
|
|
<p>
|
|
Please note that the memory areas described here as <em/strings/ are up to 255 characters (without
|
|
counting the terminating <tt/NULL/), and <em/regions/ can cover whole 64K of memory.
|
|
|
|
<sect2>CopyString
|
|
<p>
|
|
<tt/void CopyString (char *dest, char *src)/
|
|
<p>
|
|
This function copies string from <tt/src/ to <tt/dest/, until it reaches <tt/NULL/. <tt/NULL/
|
|
is also copied.
|
|
|
|
<sect2>CmpString
|
|
<p>
|
|
<tt/char CmpString (char *s1, char *s2)/
|
|
<p>
|
|
This function compares string <tt/s1/ to <tt/s2/ for equality - this is case sensitive, and both
|
|
strings have to have the same length. It returns either <tt/true/ (non-zero) or <tt/false/ (zero).
|
|
|
|
<sect2>CopyFString and CmpFString
|
|
<p>
|
|
<tt/void CopyFString (char length, char *dest, char *src)/
|
|
<p>
|
|
<tt/char CmpFString (char length, char *s1, char *s2)/
|
|
<p>
|
|
These two are similar to <tt/CopyString/ and <tt/CmpString/ except the fact, that you provide
|
|
the length of copied or compared strings. The strings can also contain several <tt/NULL/
|
|
characters - they are not treated as delimiters.
|
|
|
|
<sect2>CRC
|
|
<p>
|
|
<tt/unsigned CRC (char *src, unsigned length)/
|
|
<p>
|
|
This function calculates the CRC checksum for given memory range. I don't know if it is
|
|
compatible with standard CRC routines.
|
|
|
|
<sect2>FillRam and ClearRam
|
|
<p>
|
|
<tt/void *FillRam (char *dest, char value, unsigned length)/
|
|
<p>
|
|
<tt/void *ClearRam (char *dest, unsigned length)/
|
|
<p>
|
|
Both functions are filling given memory range. <tt/ClearRam/ fills with <tt/0s/, while
|
|
<tt/FillRam/ uses given <tt/value/. Be warned that these functions destroy <tt/r0, r1 and
|
|
r2L/ registers. These are aliases for <tt/memset/ and <tt/bzero/, respectively.
|
|
|
|
<sect2>MoveData
|
|
<p>
|
|
<tt/void *MoveData (char *dest, char *src, unsigned length)/
|
|
<p>
|
|
This functions copies one memory region to another. There are checks for overlap and the
|
|
non-destructive method is chosen. Be warned that this function destroys contents of
|
|
<tt/r0, r1 and r2/ registers. This is also alias for <tt/memcpy/
|
|
|
|
<sect2>InitRam
|
|
<p>
|
|
<tt/void InitRam (char *table)/
|
|
<p>
|
|
This function allows to initialize multiple memory locations with single bytes or strings.
|
|
This is done with <tt/table/ where everything is defined. See structures chapter for description of
|
|
<tt/InitRam's/ command string.
|
|
|
|
<sect2>Stash, Fetch, Swap, and VerifyRAM
|
|
<p>
|
|
<tt/void StashRAM (char bank, unsigned length, char *reuAddress, char *cpuAddress)/
|
|
<p>
|
|
<tt/void FetchRAM (char bank, unsigned length, char *reuAddress, char *cpuAddress)/
|
|
<p>
|
|
<tt/void SwapRAM (char bank, unsigned length, char *reuAddress, char *cpuAddress)/
|
|
<p>
|
|
<tt/ char VerifyRAM (char bank, unsigned length, char *reuAddress, char *cpuAddress)/
|
|
<p>
|
|
These functions are interface to REU - Ram Expansion Unit. I think that they are self-explanatory.
|
|
You can check for REU presence by taking value of <tt/ramExpSize/. You have to do it before
|
|
using any of these functions.
|
|
|
|
<sect1>Processes and Multitasking
|
|
<p>
|
|
Weird? Not at all. GEOS has limited multitasking ability. You can set up a chain of functions
|
|
called in specified intervals and you can put the main program to sleep without disturbing other
|
|
tasks and making user interface unresponsive.
|
|
|
|
<sect2>InitProcesses
|
|
<p>
|
|
<tt/void InitProcesses (char number, struct process *processTab)/
|
|
<p>
|
|
This is the main initialization routine. After calling it processes are set up, but not
|
|
enabled. The parameters for <tt/InitProcesses/ are:
|
|
<itemize>
|
|
<item><tt/number/ - number of processes
|
|
<item><tt/processTab/ - table of <tt/struct process/, with size equal to <tt/number/
|
|
</itemize>
|
|
<p>
|
|
Single task is described by entry in <tt/processTab/, it contains two values - <tt/pointer/ to
|
|
task function and number of <tt/jiffies/ which describe the delay between calls to task. On PAL
|
|
systems there are 50 jiffies per second, while on NTSC there are 60.
|
|
<p>
|
|
The maximum number of tasks is 20. Be warned that GEOS doesn't check if parameters are valid and
|
|
if <tt/processTab/ would be too large it would overwrite existing data in GEOS space.
|
|
<p>
|
|
There's one important thing - the last entry in <tt/processTab/ has to be <tt/NULL,NULL/, so the
|
|
maximum size of <tt/processTab/ is equal to 21.
|
|
<p>
|
|
See description of <tt/process/ structure for more detailed discussion on this.
|
|
|
|
<sect2>RestartProcess and EnableProcess
|
|
<p>
|
|
<tt/void RestartProcess (char processNumber)/
|
|
<p>
|
|
<tt/void EnableProcess (char processNumber)/
|
|
<p>
|
|
These two functions start the task counter. <tt/RestartProcess/ for each process should be called
|
|
after <tt/InitProcesses/, because it resets all flags and counters and it starts the counters.
|
|
<p>
|
|
<tt/RestartProcess/ enables counters and sets their initial value to that given in <tt/processTab/.
|
|
<p>
|
|
<tt/EnableProcess/ forces given process to execute by simulating the timer running out of time.
|
|
|
|
<sect2>BlockProcess and UnBlockProcess
|
|
<p>
|
|
<tt/void BlockProcess (char processNumber)/
|
|
<p>
|
|
<tt/void UnBlockProcess (char processNumber)/
|
|
<p>
|
|
<tt/BlockProcess/ disables the execution of given process, but this does not disable the timers.
|
|
It means that if you call <tt/UnBlockProcess/ before timer runs out, the process will be executed.
|
|
<p>
|
|
<tt/UnBlockProcess/ does the opposite.
|
|
|
|
<sect2>FreezeProcess and UnFreezeProcess
|
|
<p>
|
|
<tt/void FreezeProcess (char processNumber)/
|
|
<p>
|
|
<tt/void UnFreezeProcess (char processNumber)/
|
|
<p>
|
|
<tt/FreezeProcess/ disables timer for given process. <tt/UnFreezeProcess/ does the opposite.
|
|
This is not equal to <tt/RestartProcess/ as timers are not reloaded with initial value.
|
|
|
|
<sect2>Sleep
|
|
<p>
|
|
<tt/void Sleep (unsigned jiffies)/
|
|
<p>
|
|
This function is multitasking sleep - the program is halted, but it doesn't block other functions
|
|
e.g. callbacks from menus and icons.
|
|
The only argument here is the number of jiffies to wait until app will wake up. It depends on
|
|
video mode (PAL or NTSC) how many jiffies there are per second (50 or 60, respectively).
|
|
If you don't want to worry about it and need only full second resolution, call standard
|
|
<tt/sleep/ function from <tt/unistd.h/.
|
|
|
|
<sect1>System Functions
|
|
|
|
<sect2>FirstInit
|
|
<p>
|
|
<tt/void FirstInit (void)/
|
|
<p>
|
|
This function initializes some GEOS variables and mouse parameters. This is called on GEOS boot
|
|
up. You shouldn't use this unless you know what you are doing.
|
|
|
|
<sect2>InitForIO and DoneWithIO
|
|
<p>
|
|
<tt/void InitForIO (void)/
|
|
<p>
|
|
<tt/void DoneWithIO (void)/
|
|
<p>
|
|
These functions are called by some disk routines. You should call them only if you want to
|
|
do something with IO registers or call one of Kernal ROM routines. Note that this is rather an
|
|
expensive way of turning off IRQs and enabling IO.
|
|
|
|
<sect2>MainLoop
|
|
<p>
|
|
<tt/void MainLoop (void)/
|
|
<p>
|
|
Returns control to the system. Any code between call to <tt/MainLoop/ and the end of current
|
|
function will never be executed. When in <tt/MainLoop/ systems waits for your action - using
|
|
icons, keyboard or menus to force some specific action from program. You have to define
|
|
proper handlers before that.
|
|
|
|
<sect2>EnterDeskTop
|
|
<p>
|
|
<tt/void EnterDeskTop (void)/
|
|
<p>
|
|
This is an alias for <tt/exit(0)/ so you will never burn yourself. Anyway, you should not
|
|
use it. Always use <tt/exit()/ instead. Library destructors and functions registered with
|
|
<tt/atexit()/ are called.
|
|
|
|
<sect2>ToBASIC
|
|
<p>
|
|
<tt/void ToBASIC (void)/
|
|
<p>
|
|
This one is another way of finishing application - forcing GEOS to shutdown and exit to BASIC.
|
|
I was considering whether to include it or not, but maybe someone will need it. Which is I doubt.
|
|
<p>
|
|
<em/WARNING:/ library destructors and functions registered with <tt/atexit()/ will not be called
|
|
so it is quite unsafe way to finish your program.
|
|
|
|
<sect2>Panic
|
|
<p>
|
|
<tt/void Panic (void)/
|
|
<p>
|
|
This calls system's <tt/Panic/ handler - it shows dialog box with message
|
|
<tscreen><verb>
|
|
System error at:xxxx
|
|
</verb></tscreen>
|
|
where <tt/xxxx/ is last known execution address (caller). By default this is bound to <tt/BRK/
|
|
instruction, but it might be usable in debugging as kind of <tt/assert/. (Note that <tt/assert/
|
|
is available as a separate function and will give you more information than that).
|
|
<p>
|
|
System is halted after call to <tt/Panic/ which means that library destructors will not be
|
|
called and some data may be lost (no wonder you're panicking).
|
|
|
|
<sect2>CallRoutine
|
|
<p>
|
|
<tt/void CallRoutine (void *myFunct)/
|
|
<p>
|
|
This is system caller routine. You need to provide pointer to a function and it will be immediately
|
|
called, unless the pointer is equal to <tt/NULL/. This is the main functionality of this function -
|
|
you don't need to check if the pointer is valid.
|
|
|
|
<sect2>GetSerialNumber
|
|
<p>
|
|
<tt/unsigned GetSerialNumber (void)/
|
|
<p>
|
|
This function returns the serial number of system. It might be used for copy-protection.
|
|
However, please remember that the Free Software is a true power and you are using it
|
|
right now.
|
|
|
|
<sect2>GetRandom
|
|
<p>
|
|
<tt/char GetRandom (void)/
|
|
<p>
|
|
This function returns a random number. It can be also read from <tt/random/ e.g.
|
|
<tscreen><verb>
|
|
a=random;
|
|
</verb></tscreen>
|
|
but by calling this function you are sure that the results will be always different.
|
|
<tt/random/ is updated once a frame (50Hz PAL) and on every call to <tt/GetRandom/.
|
|
<p>
|
|
Note that it is not the same as <tt/rand/ function from the standard library. <tt/GetRandom/
|
|
will give you unpredictable results (if IRQs would occur between calls to it) while
|
|
<tt/rand/ conforms to the standard and for given seed (<tt/srand/) it always returns with the
|
|
same sequence of values.
|
|
|
|
<sect2>SetDevice
|
|
<p>
|
|
<tt/void SetDevice (char device)/
|
|
<p>
|
|
This function sets current device to given. It might be used together with <tt/InitForIO/,
|
|
<tt/DoneWithIO/ and some Kernal routines. Unless new device is a disk drive this only sets
|
|
new value in <tt/curDevice/, in other case new disk driver is loaded from REU or internal RAM.
|
|
|
|
<sect2>get_ostype
|
|
<p>
|
|
<tt/char get_ostype (void)/
|
|
<p>
|
|
This function returns GEOS Kernal version combined (by logical OR) with machine type. Read
|
|
<tt/gsys.h/ for definitions of returned values.
|
|
|
|
<sect2>get_tv
|
|
<p>
|
|
<tt/char get_tv (void)/
|
|
<p>
|
|
This function returns PAL/NTSC flag combined (by logical OR) with 40/80 columns flag. This is
|
|
not the best way to check if screen has 40 or 80 columns since PAL/NTSC check is always
|
|
performed and it can take as long as full raster frame. If you just want to know if
|
|
screen has 40 or 80 columns use expression <tt/graphMode & 0x80/ which returns <tt/0/ for
|
|
40 columns and <tt/0x80/ for 80 columns. Remember that this parameter can be changed during
|
|
runtime. It is unclear if this will work for GEOS 64 so you probably do not want to test
|
|
anything if not running under GEOS128. Use <tt/get_ostype/ to check it. Read <tt/gsys.h/ for
|
|
definitions of returned values.
|
|
|
|
<sect>Library Structures
|
|
<p>
|
|
To simplify usage and optimize passing parameters to functions I have declared several structures
|
|
which describe most common objects. Some of these structures are bound to static addresses in
|
|
GEOS data space (<tt/$8000-$8fff/), so you can use their fields directly in optimized way.
|
|
Please see <tt/gsym.h/ and find them. All structures are defined in <tt/gstruct.h/ and you may
|
|
find also some comments there.
|
|
|
|
<sect1>Graphics Structures
|
|
|
|
<sect2>pixel
|
|
<p>
|
|
One simple structure describing a point on the screen.
|
|
|
|
<sect2>fontdesc
|
|
<p>
|
|
This structure describes a font in one pointsize. There is current font - <tt/struct fontdesc/
|
|
bound to <tt/curFontDesc/. You can also force GEOS to use your own fonts by calling
|
|
<tt/LoadCharSet/. You just need to open a VLIR font file and load one record - one pointsize -
|
|
somewhere. At the start of this area you already have all data for <tt/fontdesc/ so you can
|
|
pass a pointer to the load address of that pointsize to <tt/LoadCharSet/. (Note that although
|
|
it has 'Load' in the name, that function loads only GEOS internal data structures, not data
|
|
from disk).
|
|
|
|
<sect2>window
|
|
<p>
|
|
This widely used structure holds description of a region of the screen. It describes top-left and
|
|
bottom-right corners of a window.
|
|
|
|
<sect2>iconpic
|
|
<p>
|
|
Maybe the name isn't the best - it has nothing with <tt/DoIcons/ but with bitmap functions -
|
|
<tt/BitmapUp/ for example. This structure holds parameters needed to properly decode and show
|
|
a bitmap on the screen. Bitmap has to be encoded - if you have some non-GEOS bitmaps simply
|
|
convert them to Photo Scraps - this is the format used by all GEOS bitmap functions - <tt/DoIcons/
|
|
too.
|
|
|
|
<sect1>Icons
|
|
<p>
|
|
These structures describe click boxes (icons) that can be placed on screen or in a dialog box.
|
|
|
|
<sect2>icondef
|
|
<p>
|
|
This is the definition of a single click box. Please see <tt/gstruct.h/ for description of its fields.
|
|
|
|
<sect2>icontab
|
|
<p>
|
|
This is toplevel description of icons to be placed and enabled on the screen. This structure
|
|
has following fields:
|
|
<itemize>
|
|
<item><tt/char number/ - total number of icons declared here
|
|
<item><tt/struct pixel mousepos/ - after finishing <tt/DoIcons/ mouse pointer will be placed in
|
|
this point allowing you to have hint for user what is default action
|
|
<item><tt/struct icondef tab[&rsqb/ - this table of size equal to <tt/icontab.number/ contains
|
|
descriptions for all icons
|
|
</itemize>
|
|
|
|
<sect1>File and Disk
|
|
|
|
<sect2>tr_se
|
|
<p>
|
|
This simple structure holds track and sector number of something. Do not expect the track to be
|
|
in range 1-35, as GEOS can support many various and weird devices. For example my C128 256K
|
|
expansion is utilized as RAMDisk with layout of 4 tracks 128 sectors each. However assuming that
|
|
track number equal to 0 is illegal might be wise.
|
|
|
|
<sect2>f_date
|
|
<p>
|
|
This is placeholder for file datestamp. This structure is also present in <tt/struct filehandle/.
|
|
GEOS is not Y2K compliant, so if current file has in <tt/filehandle.date.year/ value less than 86
|
|
you can safely assume that it is e.g. 2004 and not 1904.
|
|
|
|
<sect2>filehandle
|
|
<p>
|
|
This is main file descriptor. It is either entry in the directory (returned from file functions)
|
|
or its copy in <tt/dirEntryBuf/. This is optimized so you can safely get to the file's year e.g.
|
|
by testing <tt/dirEntryBuf.date.year/ - it will be compiled to simple <tt/LDA, STA/.
|
|
|
|
<sect2>fileheader
|
|
<p>
|
|
This structure holds fileheader description. You can load file's header into <tt/fileHeader/
|
|
fixed area using <tt/GetFHdrInfo/. (note that <tt/fileHeader/ is a place in memory while
|
|
<tt/fileheader/ is a structure).
|
|
You will also need own fileheader for <tt/SaveFile/.
|
|
|
|
<sect1>System Structures
|
|
|
|
<sect2>s_date
|
|
<p>
|
|
This structure is defined only for <tt/system_date/. It is slightly different from <tt/f_date/
|
|
so I prepared this one. You can e.g. get or set current time using <tt/system_date.s_hour/ and
|
|
<tt/system_date.s_minute/. Accesses to these will be optimized to simple <tt/LDA/ and <tt/STA/
|
|
pair.
|
|
|
|
<sect2>process
|
|
<p>
|
|
You should declare a table of that type to prepare data for <tt/InitProcesses/. The maximum number
|
|
of processes is 20, and the last entry has to be equal to <tt/{NULL,NULL}/, so this table may hold
|
|
only 21 entries. The first member of this structure (<tt/pointer/) holds the pointer to called
|
|
function (void returning void), you will probably have to cast that pointer into <tt/unsigned int/.
|
|
The second field <tt/jiffies/ holds the amount of time between calls to that function.
|
|
On PAL systems there are 50 jiffies per second, while NTSC have 60 of them.
|
|
|
|
<sect1>Few thing in detail...
|
|
<p>
|
|
GEOSLib uses cc65 non-ANSI extensions to easily initialize data in memory. This is done with a
|
|
kind of array of unspecified length and unspecified type. Here is how it goes:
|
|
<tscreen><verb>
|
|
void example = {
|
|
(char)3, (unsigned)3, (char)0 };
|
|
</verb></tscreen>
|
|
Which will be compiled to following string of bytes:
|
|
<tscreen><verb>
|
|
_example:
|
|
.byte 3
|
|
.word 3
|
|
.byte 0
|
|
</verb></tscreen>
|
|
As you see this way it is possible to define data of any type in any order. You must remember to
|
|
cast each member to proper type.
|
|
|
|
<sect2>DoMenu structure
|
|
<p>
|
|
<tt/DoMenu/ is responsible for everything concerned with menu processing. Many, many GEOS programs
|
|
are just initializing screen and menu and exit to <tt/MainLoop/. In GEOSLib it is the same as
|
|
returning from <tt/main/ function without using <tt/exit(0)/.
|
|
<p>
|
|
Menu is described by two types of data - menu descriptors and menu items. Descriptor contains
|
|
information about following menu items, and items are containing names of entries and either
|
|
pointers to functions to execute or, in case of nested menus, pointers to submenu descriptors.
|
|
Note that submenu descriptor can be top-level descriptor, there's no difference in structure,
|
|
just in the content.
|
|
<p>
|
|
Here is how single descriptor looks like:
|
|
<tscreen><verb>
|
|
void myMenu = {
|
|
(char)top, (char)bottom, // this is the size of the menubox
|
|
(unsigned)left, (unsigned)right, // counting all items in current descriptor
|
|
(char)number_of_items | type_of_menu, // number of following items ORed with
|
|
// type of this menu, it can be either
|
|
// HORIZONTAL or VERTICAL if you will have also bit 6 set then menu won't be closed
|
|
// after moving mouse pointer outside the menubox. You can have at most 31 items.
|
|
</verb></tscreen>
|
|
This is followed by <tt/number_of_items/ of following item description.
|
|
<tscreen><verb>
|
|
...
|
|
"menuitemname", (char)item_type, (unsigned)pointer,
|
|
"nextitemname", (char)item_type, (unsigned)pointer,
|
|
...
|
|
"lastitemname", (char)item_type, (unsigned)pointer };
|
|
// Note that there isn't ending <tt/NULL/ or something like that.
|
|
</verb></tscreen>
|
|
<tt/pointer/ is a pointer to something, what it points for depends from <tt/item_type/. This one
|
|
can have following values:
|
|
<p>
|
|
<tt/MENU_ACTION/ - a function pointed by <tt/pointer/ will be called after clicking on menu item
|
|
<p>
|
|
<tt/SUB_MENU/ - <tt/pointer/ points to next menu descriptor - a submenu
|
|
<p>
|
|
Both of them can be ORed with <tt/DYN_SUB_MENU/ and then the <tt/pointer/ points to a function
|
|
which will return in <tt/r0/ needed pointer (to function to execute or a submenu).
|
|
<p>
|
|
For creating nested menus (you can have at most 8 levels of submenus) you need to declare such
|
|
structure for each submenu and top level menu.
|
|
|
|
<sect2>DoDlgBox command string
|
|
<p>
|
|
<tt/DoDlgBox/ is together with <tt/DoMenu/ one of the most powerful routines in GEOS. It is
|
|
responsible for creating dialog boxes, that is windows which task is to interact with user.
|
|
Format of the command string is following:
|
|
<tscreen><verb>
|
|
(window size and position)
|
|
(commands and parameters)
|
|
NULL
|
|
</verb></tscreen>
|
|
There is custom type defined for the command string: <tt/dlgBoxStr/.
|
|
|
|
<sect3>Size and position
|
|
<p>
|
|
The first element can be specified in two ways - by using default size and position or specifying
|
|
own. The first case results in
|
|
<tscreen><verb>
|
|
const dlgBoxStr example = {
|
|
DB_DEFPOS (pattern_of_shadow),
|
|
... // commands
|
|
DB_END };
|
|
</verb></tscreen>
|
|
And the own size and position would be:
|
|
<tscreen><verb>
|
|
const dlgBoxStr example = {
|
|
DB_SETPOS (pattern, top, bottom, left, right)
|
|
... // commands
|
|
DB_END };
|
|
</verb></tscreen>
|
|
|
|
<sect3>Commands
|
|
<p>
|
|
The next element of <tt/DoDlgBox/ command string are commands themselves. First six commands are
|
|
default icons and the number of selected icon will be returned from window processor. The icons are
|
|
<tt/OK, CANCEL, YES, NO, OPEN/, and <tt/DISK/. You can use predefined macros for use them, e.g.:
|
|
<tscreen><verb>
|
|
...
|
|
DB_ICON(OK, DBI_X_0, DBI_Y_0),
|
|
...
|
|
</verb></tscreen>
|
|
Note that the position is counted from top left corner of window, not entire screen and that the 'x'
|
|
position is counted in cards (8-pixel) and not in pixels. This is true also for all following commands.
|
|
<tt/DBI_X_0/ and <tt/DBI_Y_0/ are predefined (see <tt/gdlgbox.h/ for more), default positions
|
|
which will make icons to appear on default window exactly where you would expect them.
|
|
<p>
|
|
<tt/DB_TXTSTR (x, y, text)/ will cause to show given text in the window.
|
|
<p>
|
|
<tt/DB_VARSTR (x, y, ptr)/ works as above, but here you are passing a pointer to a zero page location
|
|
where the address of text is stored. This is useful for information windows where only text content
|
|
is variable. Consider following:
|
|
<tscreen><verb>
|
|
char text = "foo";
|
|
...
|
|
r15=(unsigned)text; // in code just before call to DoDlgBox
|
|
...
|
|
DB_VARSTR (TXT_LN_X, TXT_LN_1_Y, &r15),
|
|
...
|
|
</verb></tscreen>
|
|
will cause to appear the word ``foo'' in the window, but you may store the pointer to any text in
|
|
<tt/r15/ (in this case) before call to DoDlgBox.
|
|
<p>
|
|
<tt/DB_GETSTR(x, y, ptr, length)/ - will add input from keyboard feature. <tt/ptr/ works as in
|
|
previous example and points to place where text is to be stored. Note that the contents of this
|
|
place will be shown upon creating window. <tt/length/ is the maximum number of characters to input.
|
|
<p>
|
|
<tt/DB_SYSOPV(ptr)/ - this sets <tt/otherPressVec/ to given pointer. It is called on every keypress.
|
|
<p>
|
|
<tt/DB_GRPHSTR(ptr)/ - data for this command is the pointer for <tt/GraphicsString/ commands.
|
|
<p>
|
|
<tt/DB_GETFILES(x, y)/ - for standard window you should pass 4 for both x and y. This function
|
|
draws file selection box and searches current drive for files. Before call to <tt/DoDlgBox/ you
|
|
must load <tt/r7L/ with GEOS filetype of searched files and <tt/r10/ with class text. In <tt/r5/
|
|
you have to load pointer to a <tt/char[17]/ where selected filename will be copied. It works
|
|
like <tt/FindFTypes/ but is limited to first 16 files.
|
|
<p>
|
|
<tt/DB_OPVEC(ptr)/ - this sets the new pointer for button press function, if you pass
|
|
<tt/RstrFrmDialogue/ here you will cause the window to close after pressing mouse button.
|
|
<p>
|
|
<tt/DB_USRICON(x, y, ptr)/ - places single user icon (click box) on window, <tt/ptr/ points at a
|
|
<tt/struct icondef/ but fields <tt/x/ and <tt/y/ are not used here. You can have at most 8 click
|
|
boxes in a window, this is internal limit of GEOS Kernal.
|
|
<p>
|
|
<tt/DB_USRROUT(ptr)/ - this command causes to immediately call user routine pointed by <tt/ptr/.
|
|
|
|
<sect2>GraphicsString command string
|
|
<p>
|
|
<tt/GraphicsString/ is a very powerful routine to initialize whole screen at once. There are
|
|
predefined macros for all commands, names are self-explanatory, see them in <tt/ggraph.h/. Last
|
|
command have to be <tt/GSTR_END/. There is custom type defined for the command string: <tt/graphicStr/.
|
|
<p>
|
|
Here is an example for clearing the screen:
|
|
<tscreen><verb>
|
|
const graphicStr example = {
|
|
MOVEPENTO(0,0),
|
|
NEWPATTERN(0),
|
|
RECTANGLETO(319,199)
|
|
GSTR_END };
|
|
</verb></tscreen>
|
|
|
|
<sect2>InitRam table
|
|
<p>
|
|
This type of data is used to initialize one or more bytes in many places at once. The format is
|
|
as following:
|
|
<tscreen><verb>
|
|
void example = {
|
|
(unsigned)address_to_store_values_at,
|
|
(char)number_of_bytes_that_follow,
|
|
(char)data,(char)data (...)
|
|
// more such definitions
|
|
(unsigned)NULL // address of 0 ends the table
|
|
};
|
|
</verb></tscreen>
|
|
|
|
<sect2>Intercepting system vectors
|
|
<p>
|
|
It is possible to intercept and hook in the GEOS Kernal using vectors. Here is a little example:
|
|
<tscreen><verb>
|
|
void_func oldVector;
|
|
|
|
void NewVectorHandler(void) {
|
|
// do something and at the end call the old vector routine
|
|
oldVector();
|
|
}
|
|
|
|
void hook_into_system(void) {
|
|
oldVector = mouseVector;
|
|
mouseVector = NewVectorHandler;
|
|
}
|
|
|
|
void remove_hook(void) {
|
|
mouseVector = oldVector;
|
|
}
|
|
</verb></tscreen>
|
|
<p>
|
|
In your <tt/main/ function you should call <tt/hook_into_system()/ but <em/after/ all calls to GEOS
|
|
kernal (like <tt/DoMenu/, <tt/DoIcons/, etc.) - right before passing control to the <tt/MainLoop()/.
|
|
Be warned that vectors are most likely to be changed by GEOS kernal also by other functions (like
|
|
<tt/GotoFirstMenu/, <tt/DoDlgBox/ and its derivatives etc.). It depends on what kernal functions
|
|
you use and which vectors you altered. Unfortunately there is no exact list for GEOS 2.0, a complete
|
|
list for GEOS 1.x can be found in A. Boyce's Programmers' Reference Guide mentioned before. Most of
|
|
information contained there should be still valid for GEOS 2.0. When calling a function that restores
|
|
the vector you should add a <tt/hook_into_system()/ call right after it.
|
|
<p>
|
|
It is critical to restore old vector values before exiting the program. If you have more than one
|
|
place where you call <tt/exit()/ then it might be worth to register <tt/remove_hook/ function to
|
|
be called upon exiting with <tt/atexit(&remove_hook);/ call. This way you will ensure that
|
|
such destructor will be always called.
|
|
<p>
|
|
That little example above intercepts <tt/mouseVector/. The <tt/NewVectorHandler/ function will be
|
|
called every time the mouse button changes status. Other important vectors you should know about
|
|
are:
|
|
<itemize>
|
|
<item><tt/appMain/ - this is called from within <tt/MainLoop/ system loop
|
|
<item><tt/keyVector/ - called whenever a keypress occurs
|
|
<item><tt/intTopVector/ - called at the start of IRQ routine
|
|
<item><tt/intBotVector/ - called at the end of IRQ routine
|
|
</itemize>
|
|
|
|
</article>
|