Article # 192, added by Geoworks, historical record
| first |
previous |
index |
next |
last |
Why does Swat "time out"?
; ; SaverVector abstraction ; ;============================================================================== A number of specific savers have needed to bounce things around the screen in a nice fashion, with different things when the point(s) being bounced encounter the edge of the drawing area. These actions are encapsulated in the SaverVector data type provided by the generic saver library. The vector is one-dimensional, meaning it has only half a coordinate, not the normal ordered pair, that it maintains. Two vectors will normally make up a point being moved around the screen. SaverVectorReflectTypes etype word SVRT_BOUNCE enum SaverVectorReflectTypes ; Elastic bounce (delta ; becomes -delta) SVRT_RANDOM enum SaverVectorReflectTypes ; Reflect in a random ; direction opposite the ; current one. This enumerated type tells the generic library what action is to be taken when the point crosses over one of the endpoints of its axis. It can reflect elasticly simply by negating the initial delta chosen for it, or it can reflect at a random velocity. SaverVector struc ; Data for current location SV_point word ; Current point SV_min word ; Minimum value for SV_point SV_max word ; Maximum value for SV_point SV_reflect SaverVectorReflectTypes ; Type of reflection to happen when ; SV_point reaches a boundary ; Data for delta value SV_delta sword ; Current delta SV_deltaBase byte ; Base value for delta. SV_deltaMax byte ; Maximum value for delta (above base) SaverVector ends This is the data structure to be stored in the specific saver's own data structure for each half of the ordered pair that makes up a single point. global SaverVectorInit:far ; ; Initialize a SaverVector structure ; ; Pass: es:di = SaverVector to initialize ; ax = SaverVectorReflectType ; cx = minimum value ; dx = maximum value ; bl = delta max ; bh = delta base ; Return: nothing ; global SaverVectorUpdate:far ; ; Update a SaverVector according to its delta, etc. ; ; Pass: ds:si = SaverVector to advance one step. ; Return: ax = the new coordinate. ; ;============================================================================== ; ; Document Control ; ;============================================================================== If a specific saver has documents it wishes to manipulate, it can do so using the SaverUIDocumentControl and SaverAppDocumentControl classes. As the names imply, the former is run by the UI thread and the latter by Saver's own thread, so the two objects must reside in separate blocks that the specific saver duplicates. The ugly work of supporting document control objects that can come and go is taken care of by the generic saver library, but a number of non-obvious actions must be performed by the specific saver. To wit: * In the SF_FETCH_UI procedure: * You must call ProcInfo with the handle of the generic library to obtain the handle of the saver's process thread. * Duplicate the application-run block as you duplicate the UI-run block. Note that the application-run block should be marked as ui-object in the .gp file to avoid confusing GeodeLoad. You will need to save this block handle for later. * Call MemModify on the resulting block, passing the saver's process thread in SI and MODIFY_OTHER in AH (NOTE: this is different for 2.0) * Invoke METHOD_APP_DOC_CONTROL_SET_OUTPUT on the app DC to point its output to the saver process. * Duplicate the UI-run block so you can get the OD of the ui DC. * Queue a METHOD_SADC_SET_UI_DC method for the app DC passing it the OD of the ui DC in ^lcx:dx. Note that this *must* be queued so the attaching of the ui DC, and subsequent opening of the default document, etc., will happen after the saver's UI is visibly built. * Invoke METHOD_UI_DOC_CONTROL_SET_PATH on the ui DC if the path wasn't set in the .ui file. * In the SF_SAVE_STATE procedure, flag that the application-run block must remain in existence. Message does this by setting the variable holding the block handle to 0. * In the library entry routine, when di==LCT_DETACH, if the SF_SAVE_STATE entry wasn't called, invoke METHOD_FREE_DUPLICATE on the app DC in the application-run block. * When restoring from state, you will need to call METHOD_SUIDC_GET_APP_DC on the ui DC to locate the application-run block. You will probably need to use the next mechanism, the specific saver process class, to properly interact with the document control, as far as updating the document at the right time, etc., so read on, MacDuff... For a real-life example of how this is used, consult Saver/Message/message.asm. ;============================================================================== ; ; Specific Saver Process Class ; ;============================================================================== The generic library allows a specific saver to have a process class via which it can receive messages from other parts of the system (such as clipboard- change notification) without a lot of messing around with application-run object blocks and the like (though this is sometimes necessary, as for using a document control object). To do this, declare your specific process class as a subclass of SaverClass, like so: MessageClass class SaverClass ; ; The state we save to our parent's state file on shutdown. ; MCI_fontID FontIDs FONT_URW_ROMAN ; Font to use MCI_size word 24*8 ; Pointsize of same MCI_angle sword 0 ; Angle at which to draw it. ; -1 => random MCI_color Colors -1 ; Color in which to draw it. ; -1 => random MCI_motion MessageMotionType MMT_BOUNCE MCI_speed word MESSAGE_MEDIUM_SPEED MCI_format MessageFormatType MFT_TEXT MessageClass endc Then call the function SaverSetSpecProcClass, passing the segment and offset of the class in cx:dx. That's all there is to it. You can then subclass any method available to SaverClass in your specific saver, including METHOD_SAVER_START and METHOD_SAVER_STOP. Message uses it to implement such document-control methods as METHOD_DC_FILE_OPEN, METHOD_DC_FILE_ATTACH_FAILED and others. ;============================================================================== ; ; Saver fades and other fun stuff ; ;============================================================================== SaverInitBlank() is provided to simplify things slightly for savers that wish to simply blank the screen to start with. The parameters match those of SF_START, so this routine can be called at the startof that. global SaverInitBlank:far ; ; Clear the window for initial blank. Designed to be called ; from SF_START for savers that want to start with a blank screen. ; ; Pass: di - GState handle ; si - window width ; dx - window height ; Return: none ; There are some utility routines provided for certain special effects. There a variety of fades and wipes (the Fades & Wipes saver uses these), as well as a routine to draw a background bitmap (Slide Show uses this). ; ; The different speeds supported for fades ; SaverFadeSpeeds etype word SAVER_FADE_SLOW_SPEED enum SaverFadeSpeeds SAVER_FADE_MEDIUM_SPEED enum SaverFadeSpeeds SAVER_FADE_FAST_SPEED enum SaverFadeSpeeds SaverWipeTypes record :12 SWT_LEFT:1 ;TRUE: wipe from left SWT_TOP:1 ;TRUE: wipe from top SWT_RIGHT:1 ;TRUE: wipe from right SWT_BOTTOM:1 ;TRUE: wipe from bottom SaverWipeTypes end global SaverFadePatternFade:far ; ; Fade a rectangle to a color, 0% -> 100% patterns ; ; Pass: (ax,bx,cx,dx) - rectangle to fade ; di - handle of GState ; si - SaverFadeSpeeds (very slow, slow, medium, fast) ; Return: none ; global SaverFadeWipe:far ; ; Fade a rectangle to a color by wiping from one or more directions ; ; Pass: (ax,bx,cx,dx) - rectangle to fade ; di - handle of GState ; si - SaverFadeSpeeds (very slow, slow, medium, fast) ; bp - SaverWipeTypes for sides to use ; Return: none ; SaverBitmapMode etype word SAVER_BITMAP_CENTER enum SaverBitmapMode SAVER_BITMAP_TILE enum SaverBitmapMode SAVER_BITMAP_UPPER_LEFT enum SaverBitmapMode SAVER_BITMAP_APPROPRIATE enum SaverBitmapMode global SaverDrawBGBitmap:far ; ; Draw a background bitmap to the window ; ; Pass: di - handle of GState ; (cx,dx) - width, height of window ; ax - SaverBitmapMode ; ds:si - ptr to NULL-terminated filename ; Return: carry - set if error ; ****************************************************************************** RANDOM NOTES ****************************************************************************** It is a good idea to save some sort of magic/protocol number before the state block you write out in SF_SAVE_STATE that you can check in SF_RESTORE_STATE, especially during development. Since you cannot use the normal geode protocol method of detecting old state files, this is the only way to safely change the format/size of the state block without wreaking havoc on unsuspecting people who are using your screen saver. Remember that a screen saver is intended to save the screen from wear, not just to be cool. This means the majority of the screen should be dark or should rapidly become so. ====================================================================== To get rid of the "timed out" error in Swat, do the following: 1. Make sure cable is correctly wired. See article "How the null modem lines should be connected." 2. Make sure any DOS windows that are/were running PCCOM are closed. Windows '95 DOS windows will keep a serial port open even after you exit PCCOM. 3. Make sure you're in the correct directory on the target machine. You'll see three strange characters (shaped like a house) followed by a "c" on the target machine if you are running in the wrong directory. The correct directory is the "root" directory where the geos.ini or geosec.ini file is located.