home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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
- };
-