home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d494
/
vscreen
/
source
/
vscreen-handler.c
next >
Wrap
C/C++ Source or Header
|
1991-06-06
|
25KB
|
745 lines
/*
* VSCREEN-HANDLER.C
*
* Creates virtual screens that can be larger than
* the actual display area of your monitor. The virtual
* screen scrolls when the mouse moves off the edge of
* the display.
*
* Copyright 1988 by Davide P. Cervone, all rights reserved.
*
* You may may distibute this code as is, for non-commercial
* purposes, provided that this notice remains intact and the
* documentation file is distributed with it.
*
* You may not modify this code or incorporate it into your
* own programs without the permission of the author.
*/
/*
* WARNING: This code uses and even modifies the INTUITIONPRIVATE
* area of the IntuitionBase structure. Use it at your own risk. It is
* likely to break under a future release of Intuition.
*/
#include "vScreen.h"
static char program[] = "vScreen-Handler"; /* the program name */
static char author[] = COPYRIGHT; /* the copyright notice */
#define MAJVER 1 /* major version number */
#define MINVER 0 /* minor version number */
/*
* Macros for normalizing screen Y coordinates to absolute display
* corrdinates (using the LaceShift and LaceScreen variables).
*/
#define TWICE_Y(y) ((y)<<LaceShift)
#define NTWICE_Y(y) ((LaceScreen)?(y)<<1:(y))
#define HALF_Y(y) ((y)>>LaceShift)
#define NHALF_Y(y) ((LaceScreen)?(y)>>1:(y))
/*
* Macros for normalizing screen X coordinates to absolute display
* corrdinates (using the HiResShift and HiResScreen variables).
*/
#define TWICE_X(x) ((x)<<HiResShift)
#define NTWICE_X(x) ((HiResScreen)?(x)<<1:(x))
#define HALF_X(x) ((x)>>HiResShift)
#define NHALF_X(x) ((HiResScreen)?(x)>>1:(x))
/*
* The qualifiers used to check whether the left command key is pressed
*/
#define SHIFTQUALS (~IEQUALIFIER_RELATIVEMOUSE)
static struct Screen *VScreen; /* pointer to the virtual screen */
static SHORT ScreenWidth,ScreenHeight; /* the new width and height */
static SHORT OldWidth,OldHeight; /* the old width and height */
static SHORT *RxOffset,*RyOffset; /* pointers to the RasInfo offsets */
static SHORT RxOffset2,RyOffset2; /* normalized RxOffset and RyOffset */
static LONG LaceScreen,LaceShift; /* used to normalize Y positions */
static LONG HiResScreen,HiResShift; /* used to normalize X positions */
static WORD OldMaxDH,OldMaxDR,OldMaxDW; /* Old MaxDisplay values */
static WORD MinXMouse,MaxXMouse,MinYMouse,MaxYMouse;
/* the Display min and max values (as opposed to the Intuition values) */
static WORD Xshift = 0; /* how far to shift VScreen */
static WORD Yshift = 0; /* how far to shift VScreen */
static struct Screen *OldScreen = NULL; /* pointer to last active screen */
static WORD ScreenTop,ScreenBottom; /* Y position of vScreen borders */
static short NotVScreen = FALSE; /* TRUE when mouse not over VScreen */
#define BOTTOMSCREEN 1 /* Mouse over screen below VScreen */
#define TOPSCREEN -1 /* mouse over screen behind VScreen */
#define OVERVSCREEN (NotVScreen == FALSE)
extern struct vScreenInfo vScreenData; /* the data neede by vScreen */
/*
* Setup()
*
* This routine gets called by vScreen after vScreen-Handler gets LoadSeged.
* Setup must return the pointer to the data structure that vScreen uses
* to initialize vScreen-Handler's variables.
*
* vScreen passes its version number to Setup(). If Setup() detects a
* version mismatch, it should return NULL.
*/
struct vScreenInfo *Setup(version)
int version;
{
return(&vScreenData);
}
/*
* SetScreenMinMax()
*
* Set the OldScreen to the current ActiveScreen. If it is VScreen,
* the set the Min and Max Mouse values to the virtual screen sizes,
* otherwise, set them to the current display edges (in the coordinate
* system of the virtual screen; i.e., origin is offset by RxOffset and
* RyOffset).
*/
static void SetScreenMinMax()
{
if ((OldScreen = IntuitionBase->ActiveScreen) == VScreen)
{
IntuitionBase->MinXMouse = 0;
IntuitionBase->MaxXMouse = TWICE_X(ScreenWidth) - 1;
IntuitionBase->MinYMouse = IntuitionBase->MouseYMinimum;
IntuitionBase->MaxYMouse = TWICE_Y(ScreenHeight) - 1;
} else {
IntuitionBase->MinXMouse = RxOffset2;
IntuitionBase->MaxXMouse = OldMaxDW + RxOffset2 - 1;
IntuitionBase->MinYMouse = IntuitionBase->MouseYMinimum + RyOffset2;
IntuitionBase->MaxYMouse = OldMaxDR + RyOffset2;
}
}
/*
* ResetVScreen()
*
* When the mouse moves over a screen other than the virtual screen, we need
* to reset the modified Intuition fields to their normal values so that if
* the mouse is pressed over the other screen, it hits the right position.
*
* Set OldScreen to the ActiveScreen.
* Set the Min and Max Mouse values where scrolling will occur to the
* display edges (relative to the non-virtual screen).
* Set the Intuition MaxDisplay values to their original dimensions.
* Subtract the RxOffset and RyOffsets from the Intuition mouse coordinates
* (they are now relative to the screen the mouse is moving over).
*/
static void ResetVScreen()
{
OldScreen = IntuitionBase->ActiveScreen;
MinXMouse = IntuitionBase->MinXMouse = 0;
MaxXMouse = IntuitionBase->MaxXMouse = OldMaxDW - 1;
MinYMouse = IntuitionBase->MinYMouse = IntuitionBase->MouseYMinimum;
MaxYMouse = IntuitionBase->MaxYMouse = OldMaxDR;
IntuitionBase->MaxDisplayHeight = OldMaxDH;
IntuitionBase->MaxDisplayRow = OldMaxDR;
IntuitionBase->MaxDisplayWidth = OldMaxDW;
IntuitionBase->MouseX -= RxOffset2;
IntuitionBase->MouseY -= RyOffset2;
}
/*
* SetVScreen()
*
* When the mouse moves back over the virtual screen, we need to change to
* Intuition Mouse corrdinates to be relative to the virtual screen again,
* so that if the mouse is pressed, it will hit the right spot.
*
* Set the Min and Max values for the Intuition Mouse.
* Set the Min and Max values where scrolling will occur (relative to
* the virtual screen origin).
* Set the Intuition MaxDisplay values to the full screen size (so that
* Intuition will allow the mouse to move to the edge of the virtual
* screen).
* Add the RxOffset and RyOffset to the Intuition Mouse position so that
* Intuition thinks the mouse is positioned relative correctly on the
* virtual screen (we compensate for this in MoveSprite).
*/
static void SetVScreen()
{
SetScreenMinMax();
MinXMouse = RxOffset2;
MaxXMouse = OldMaxDW + RxOffset2 - 1;
MinYMouse = IntuitionBase->MouseYMinimum + RyOffset2;
MaxYMouse = OldMaxDR + RyOffset2;
IntuitionBase->MaxDisplayHeight = TWICE_Y(ScreenHeight);
IntuitionBase->MaxDisplayRow = TWICE_Y(ScreenHeight) - 1;
IntuitionBase->MaxDisplayWidth = TWICE_X(ScreenWidth);
IntuitionBase->MouseX += RxOffset2;
IntuitionBase->MouseY += RyOffset2;
}
/*
* FindBounds()
*
* Locate the absolute display position of the top of the virtual screen
* and of the top of the highest screen that is on top of the virtual
* screen. That is, if the mouse is between the TopScreen and BottomScreen
* Y values, then it is positioned over top pf the visible portion of the
* virtual screen. If the screen is not showing, then BottomScreen will
* be less that TopScreen.
*
* Note that TopScreen and BottomScreen are relative to a 320 x 200 screen,
* since they are compared to the mouse pointer coordinates (since the pointer
* is a sprite, its coordinates always are LoRes and Non-Interlaced).
*/
static void FindBounds()
{
struct Screen *theScreen = IntuitionBase->FirstScreen;
WORD Top;
ScreenTop = NHALF_Y(VScreen->TopEdge) - 1;
ScreenBottom = IntuitionBase->MaxDisplayRow;
while (theScreen && theScreen != VScreen)
{
Top = theScreen->TopEdge;
if (theScreen->ViewPort.Modes & LACE) Top >>= 1;
if (Top < ScreenBottom) ScreenBottom = Top;
theScreen = theScreen->NextScreen;
}
}
/*
* FixView()
*
* When the virtual Screen is the first screen, its viewport will try to
* display ALL of the vertical length of the screen. This might cause an
* overscan display when there is not supposed to be one, so when this
* occurs, we set the ViewPort height manually, remake the Screen, and
* merge the copper list into the rest of the display. This routine gets
* called whenever the intuition View is loaded. Since this happens
* whenever a screen changes position, this is a good place to check the
* screen top and bottom bounds.
*/
static void FixView(ForceUpdate)
int ForceUpdate;
{
short TooBig = (VScreen->ViewPort.DHeight > OldHeight);
if (TooBig || ForceUpdate)
{
if (TooBig) VScreen->ViewPort.DHeight = OldHeight;
MakeScreen(VScreen);
MrgCop(&(IntuitionBase->ViewLord));
}
FindBounds();
}
/*
* CheckShift()
*
* Check that a forced screen shoft will not go too far. If it does, then
* clear the InputEvent mouse movement so that the mouse doesn't move
* when the screen can't scroll any more.
*
* If the mouse is not over the virtual screen, then we don't want the
* mouse to move at all, so clear the InputEvent mouse movement.
*/
static void CheckShift(Xshift,Yshift,theEvent)
WORD *Xshift,*Yshift;
struct InputEvent *theEvent;
{
if (*Xshift < -RxOffset2 ||
*Xshift > TWICE_X(ScreenWidth-OldWidth)-RxOffset2)
{
*Xshift -= theEvent->ie_X;
theEvent->ie_X = 0;
}
if (*Yshift < -RyOffset2 ||
*Yshift > TWICE_Y(ScreenHeight-OldHeight)-RyOffset2)
{
*Yshift -= theEvent->ie_Y;
theEvent->ie_Y = 0;
}
if (NotVScreen) theEvent->ie_X = theEvent->ie_Y = 0;
}
/*
* ShiftVScreen()
*
* Shift the virtual screen by the specified amount.
*
* If there is movement in the X direction,
* Check that the screen does not scroll too far to the left or right.
* If it does, then reduce the move so that the screen scrolls to the edge.
* If the mouse is over the virtual screen, then
* Adjust the Min and Max values for when scrolling occurs.
* Increment the Screen's ViewPort RasInfo RxOffset by the amount of
* the scroll, and record the normalized value for later use.
* The RxOffset is what tells the graphics library which part of the
* larger bitmap should actually be displayed.
*
* Similarly for the Y shift.
*
* Finally, if there was actually movement in either direction,
* Fix the View (FixView calls MakeScreen() and MrgCop()) and
* Load the new View.
*/
static void ShiftVScreen(Xmove,Ymove)
WORD Xmove,Ymove;
{
WORD xOffset, yOffset;
if (Xmove)
{
xOffset = *RxOffset + Xmove;
if (xOffset < 0) Xmove -= xOffset;
if (xOffset > ScreenWidth-OldWidth)
Xmove += (ScreenWidth-OldWidth - xOffset);
if (OVERVSCREEN)
{
MinXMouse += TWICE_X(Xmove);
MaxXMouse += TWICE_X(Xmove);
}
*RxOffset += Xmove;
RxOffset2 = TWICE_X(*RxOffset);
}
if (Ymove)
{
yOffset = *RyOffset + Ymove;
if (yOffset < 0) Ymove -= yOffset;
if (yOffset > ScreenHeight-OldHeight)
Ymove += (ScreenHeight-OldHeight - yOffset);
if (OVERVSCREEN)
{
MinYMouse += TWICE_Y(Ymove);
MaxYMouse += TWICE_Y(Ymove);
}
*RyOffset += Ymove;
RyOffset2 = TWICE_Y(*RyOffset);
}
if (Xmove || Ymove)
{
FixView(TRUE);
LoadView(&(IntuitionBase->ViewLord));
}
}
/*
* cLoadView()
*
* Replaces the LoadView function in the graphics library (the stub calls
* the old LoadView() after cLoadView() runs).
*
* If the virtual screen is still open, and the view is the Intuition View,
* the Fix the view (make sure that the height is no larger than the
* old MaxDisplayHeight).
*
* Note: when you drag a screen up and down, Intuition calls RemakeDisplay()
* which in turn calls MakeScreen() on each screen, MrgCop() and finally
* LoadView(). cLoadView() gets called in place of LoadView(), and it will
* call FixView(), which calls MakeScreen() and MrgCop() again. This are high
* overhead calls, so when the virtual screen is the FirstScreen and there is
* another screen showing behind it, this can nearly double the overhead of
* dragging a screen.
*/
void cLoadView(view)
struct View *view;
{
if (VScreen && view == &(IntuitionBase->ViewLord)) FixView(FALSE);
}
/*
* cMoveSprite();
*
* Repaces MoveSprite() in the graphics library (the stub calls the old
* MoveSprive() after cMoveSprite() runs).
*
* If the sprite being moved is sprite zero (the pointer sprite), and
* the virtual screen is still open, then
* If the pointer is over the virtual screen
* Subtract the offsets (relative to a 320 x 200 screen, since this
* is a sprite). We must do this, since we added RxOffset and RyOffset
* to the Intuition MouseX and MouseY values. Since Intuition does not
* take the RxOffset and RyOffset into account, we have to subtract
* the values here in order to keep the pointer on the display area.
*
* If the Min and Max X Mouse values are equal, a screen is being dragged.
* If the LayerInfo Lock has a NestCount, then the layers are locked.
*
* If the mouse is not over the virtual screen then
* Set the MinY for scrolling to the top of the view.
* If we used to be over the virtual screen and
* we're not currently dragging a screen, then
* If the virtual screen is not locked, then
* Reset the coordinate system to fit the screen we are over.
* Save which type of screen we're over.
* otherwise (the screen is locked; e.g., the user has the
* menu button down, or is dragging a window),
* so scroll the screen if we move off the top.
* Otherwise (the mouse IS over the virtual screen)
* Set the MinY for scrolling to the top of the view relative to the
* virtual screen origin.
* If we used to be over some other screen, and we're not dragging
* a screen, and the current screen is not locked, then
* (we need to change coordinates to the virtual screen coordinates)
* If we are going from a bottom screen onto the virtual screen
* then activate the cirtual screen (I couldn't find a way to do
* the coordinate transfer without this).
* Set the coordinates relative to the virtual screen.
* Record that we are over the virtual screen.
*
* If a new screen has become active then
* If we were over the virtual screen, check that we still are
* Record the active screen
*
* If the user is dragging the screen, don't let him drag it off
* the bottom of the display area (where he won;t be able to reach it).
*
* If the MouseY has gone past the top of the screen (i.e., if a screen
* has closed and the pointer was above it), put the pointer at the
* top of the display.
*/
void cMoveSprite(ss,x,y)
struct SimpleSprite *ss;
long x,y;
{
short NotDrag;
short NotLocked;
if (ss->num == 0 && VScreen)
{
if (OVERVSCREEN)
{
x -= NHALF_X(*RxOffset);
y -= NHALF_Y(*RyOffset);
}
NotDrag = (IntuitionBase->MinXMouse != IntuitionBase->MaxXMouse);
NotLocked =
(IntuitionBase->ActiveScreen->LayerInfo.Lock.ss_NestCount == 0);
if (y < ScreenTop || y >= ScreenBottom)
{
MinYMouse = IntuitionBase->MouseYMinimum;
if (OVERVSCREEN && NotDrag)
{
if (NotLocked)
{
ResetVScreen();
NotVScreen = (y < ScreenTop)? TOPSCREEN: BOTTOMSCREEN;
} else {
if (y < ScreenTop) ShiftVScreen(0,NTWICE_Y(y-ScreenTop));
}
}
} else {
MinYMouse = IntuitionBase->MouseYMinimum + RyOffset2;
if (NotVScreen && NotDrag && NotLocked)
{
if (NotVScreen == BOTTOMSCREEN &&
IntuitionBase->ActiveScreen != VScreen &&
VScreen->FirstWindow) ActivateWindow(VScreen->FirstWindow);
SetVScreen();
NotVScreen = FALSE;
}
}
if (OldScreen != IntuitionBase->ActiveScreen)
{
if (OVERVSCREEN) SetScreenMinMax();
OldScreen = IntuitionBase->ActiveScreen;
}
if (NotDrag == FALSE &&
IntuitionBase->MaxYMouse > OldMaxDR + RyOffset2)
IntuitionBase->MaxYMouse = OldMaxDR + RyOffset2;
if (IntuitionBase->MouseY < IntuitionBase->MinYMouse)
IntuitionBase->MouseY = IntuitionBase->MinYMouse;
}
}
/*
* cAutoRequest()
*
* Replaces AutoRequest() in the Intuition Library (the stub calls
* AutoRequest() after cAutoRequest() runs).
*
* If the AutoRequest is to appear on the virtual screen, then shift
* the virtual screen so that the System Request window will be showing.
* Note that this could change the screen position even while the user is
* doing critical work (e.g., dragging a window, pulling menus, etc).
* It would be better to trap this through BuildSysRequest(), but since
* Intuition does not use its own vector table, I can not trap all the
* calls to BuildSysRequest, specifically, the ones called by AutoRequest().
*/
void cAutoRequest(theWindow)
struct Window *theWindow;
{
if (theWindow == NULL || theWindow->WScreen == VScreen)
{
IntuitionBase->MouseX -= RxOffset2;
IntuitionBase->MouseY -= RyOffset2;
ShiftVScreen(-(*RxOffset),-(*RyOffset));
}
}
/*
* cBuildSysRequest()
*
* Replaces BuildSysRequest() in the Intuition Libaray (the stub routine
* calls BuildSysRequest() before calling cBuildSysReques()).
*
* If the window (returned by BuildSysRequest) exists, then
* If it is on the virtual screen, and it is not completely showing, then
* Move the window so that it is in the upper left corner of the
* displayed section of the screen.
*
* Note that this is better than what we do with AutoRequest, since the
* screen itself does not scroll.
*/
void cBuildSysRequest(theWindow)
struct Window *theWindow;
{
if (theWindow && theWindow != (struct Window *)TRUE)
{
if (theWindow->WScreen == VScreen &&
(theWindow->LeftEdge < *RxOffset ||
theWindow->TopEdge < *RyOffset))
MoveWindow(theWindow,*RxOffset-theWindow->LeftEdge,
*RyOffset-theWindow->TopEdge);
}
}
/*
* cCloseScreen()
*
* Replaces CloseScreen() in the IntuitionLibrary (the stub routine calls
* CloseScreen() after cCloseScreen() runs).
*
* If the virtual screen is still open, and it is the one being closed,
* reset the coordinate system, and mark the virtual screen as closed.
*/
void cCloseScreen(theScreen)
struct Screen *theScreen;
{
if (theScreen == VScreen && VScreen != NULL)
{
ResetVScreen();
VScreen = NULL;
}
}
/*
* myHandler()
*
* This is the input handler that gets added to the Input.Device input
* chain. It is at priority 51, so it is ahead of Intuition.
*
* If a screen is not being dragged, and the virtual screen is still open,
* then for each event in the event list,
* If the event is a RAWMOUSE event,
* If the left Amiga key is held down then
* Add it into the forced shift count and
* Check that the shift is valid.
* Add the movement into the total movement so far.
*
* Find the new MouseX and MouseY positions.
* Shift the screen by the forced shift amounts, checking that the
* coordinates are shifted when needed, and retaining any un-used
* shift amount (due to LoRes or Non-Interlaced screens).
*
* If the active screen is the virtual screen, then
* if the mouse has moved off the left or right edge of the display,
* or if the mouse has moved past the Intuition Min or Max values,
* then shift the screen by the appropriate amount. Do this for
* both the X and Y directions.
*
* Finally, return the original event list.
*/
struct InputEvent *myHandler(EventList,data)
struct InputEvent *EventList;
APTR data;
{
struct InputEvent *theEvent = EventList;
WORD MouseX,MouseY;
WORD Xmove = 0;
WORD Ymove = 0;
WORD Ychange = 0;
WORD Xchange = 0;
WORD dx,dy;
if (IntuitionBase->MinXMouse != IntuitionBase->MaxXMouse && VScreen)
{
Forbid();
while (theEvent)
{
if (theEvent->ie_Class == IECLASS_RAWMOUSE)
{
if ((theEvent->ie_Qualifier & SHIFTQUALS) == IEQUALIFIER_LCOMMAND)
{
Xshift += theEvent->ie_X;
Yshift += theEvent->ie_Y;
CheckShift(&Xshift,&Yshift,theEvent);
}
Xchange += theEvent->ie_X;
Ychange += theEvent->ie_Y;
}
theEvent = theEvent->ie_NextEvent;
}
Permit();
MouseX = IntuitionBase->MouseX + HALF_X(Xchange);
MouseY = IntuitionBase->MouseY + HALF_Y(Ychange);
if (Xshift < 0) dx = -HALF_X(-Xshift); else dx = HALF_X(Xshift);
if (Yshift < 0) dy = -HALF_Y(-Yshift); else dy = HALF_Y(Yshift);
if (dx || dy)
{
ShiftVScreen(dx,dy);
if (IntuitionBase->ActiveScreen != VScreen && OVERVSCREEN)
SetScreenMinMax();
if (HiResScreen) Xshift = 0; else Xshift %= 2;
if (LaceScreen) Yshift = 0; else Yshift %= 2;
}
if (IntuitionBase->ActiveScreen == VScreen)
{
if (MouseX < MinXMouse) Xmove = MouseX - MinXMouse;
if (MouseX > MaxXMouse) Xmove = MouseX - MaxXMouse;
if (Xmove == 0)
{
if (MouseX < IntuitionBase->MinXMouse)
Xmove = MouseX - IntuitionBase->MinXMouse;
if (MouseX > IntuitionBase->MaxXMouse)
Xmove = MouseX - IntuitionBase->MaxXMouse;
}
if (MouseY < MinYMouse) Ymove = MouseY - MinYMouse;
if (MouseY > MaxYMouse) Ymove = MouseY - MaxYMouse;
if (Ymove == 0)
{
if (MouseY < IntuitionBase->MinYMouse)
Ymove = MouseY - IntuitionBase->MinYMouse;
if (MouseY > IntuitionBase->MaxYMouse)
Ymove = MouseY - IntuitionBase->MaxYMouse;
}
if (Xmove || Ymove) ShiftVScreen(Xmove,Ymove);
}
}
return(EventList);
}
/*
* These are the assembler stubs needed in order to SetFunction some
* of the Intuiton and graphics library functions.
*/
extern void myHandlerStub();
extern void aCloseScreen();
extern void aBuildSysRequest();
extern void aAutoRequest();
extern void aLoadView();
extern void aMoveSprite();
/*
* These are the jump addresses in the assembler routines that need to
* be filled in by vScreen once the old SetFunction vectors are known.
* This is a kludge, and is a form od self-modifying code, but I can't figure
* out a better way that works. The JSR (Ax) form is only good if there is
* a free A register to use, which is not always the case.
*/
extern unsigned char *CloseScreenJmpAddress;
extern unsigned char *BuildSysRequestJmpAddress;
extern unsigned char *AutoRequestJmpAddress;
extern unsigned char *LoadViewJmpAddress;
extern unsigned char *MoveSpriteJmpAddress;
static char PortName[] = PORTNAME; /* the name of the named port */
static struct Interrupt HandlerInfo = /* the Interrupt needed to add an */
{ /* input handler to the input chain */
{NULL, NULL, 0, 51, NULL}, /* ln_Pri = 51 (before Intuition) */
NULL,
&myHandlerStub /* the handler to add */
};
/*
* This is the structure passed from the Setup() routine to vScreen.
* It includes pointers to the variables that vSCreen needs to initialize,
* plus pointers to the routines that vScreen will SetFunction into the
* appropriate libraries.
*/
struct vScreenInfo vScreenData =
{
MAJVER,MINVER,0,
&program[0],
&PortName[0],
NULL,
&HandlerInfo,
&IntuitionBase, &GfxBase,
&VScreen,
&ScreenWidth,&ScreenHeight,
&OldWidth,&OldHeight,
&RxOffset,&RyOffset,
&RxOffset2,&RyOffset2,
&LaceScreen,&LaceShift,
&HiResScreen,&HiResShift,
&OldMaxDH,&OldMaxDR,&OldMaxDW,
&SetVScreen, &ResetVScreen, &FixView,
&aCloseScreen, &aBuildSysRequest, &aAutoRequest, &aLoadView, &aMoveSprite,
(long *) &CloseScreenJmpAddress,
(long *) &BuildSysRequestJmpAddress,
(long *) &AutoRequestJmpAddress,
(long *) &LoadViewJmpAddress,
(long *) &MoveSpriteJmpAddress,
0,0,0,0,0
};