Mode 0 Screen Editor v2

By Robert Sprowson

Originally published in EUG #33

Brief Instructions

On running, enter a filename as requested, or choose NEW if you are starting from scratch. If you have to change disks to load the screen image, make sure to replace the program disk so that the core program is loaded. This will run the main section. Once there, the following keys help you to use EDIT's features:

M - Move area, the place where the area came from will be erased
C - Copy area
B - Box. Draw frame round an object
T - Enter text at the cursor. Use DELETE to backspace and RETURN for a new line
F - Fill area. A choice of B)lack; G)rey; W)hite has to be made
S - Save final image. The filename OUTPUT is reserved for this
P - Paste the contents of the Clipboard (COPY can also be used for this)
E - Edit the pixels by zooming in
COPY - Confirm
SPACE - Reveal cursor position
Arrow keys - Move around screen
SHIFT + Arrows - Move around the screen fast

If you choose to Edit pixels by zooming in ('E') then the selected area to enlarge must be smaller than 29 by 39 pixels, and when in the editor, TAB toggles the pixel status from white to black or vice versa. Press COPY to save the result back to the clipboard and zoom back out.

At all times, watch for the prompt in the bottom left of the screen for details on what to do next.

EDIT - Remarks on v2.00
History

EDITCORE

v1.00 Original BASIC version (September 1995)
v2.00 Version using new M/C features (Edit v2.00). Never finished due to problems with assembler. Keyboard entry no longer case sensitive: CAPS LOCK may be on or off (December 1996)
v3.00 Re-release version. Now uses PROCs for speed and makes full use of the new EDIT
v3.01 Uses integer variables with meaningful names throughout. This was not possible before as memory was tight due to masses of duplicated bulky BASIC code everywhere! If in text entry mode, the entered text may now be deleted without corrupting the image behind (March 1997) v3.05 Fixed bug in text entry part whereby OS would get confused as it was sent coordinates that were off the screen, since X% and Y% were out of range. Also "String too long" occured if you typed for ages without pressing RETURN (April 1997)

EDIT

v1.00 Original BASIC version (September 1995)
v2.00 Converted time-dependant routines to M/C, including box-drawing and scanning of keyboard. Boxes could only be dragged from top left to bottom right otherwise the assembler would go mad (November 1996)
v3.00 Realised keyboard scanning wasn't being slowed by BASIC; it was the line drawing that took all the time. Removed box drawing routine from M/C so now boxes are considered as a series of horizontal and vertical lines. Also, co-ordinates are size-ordered and range checked then clipped if appropriate so boxes can be dragged in any direction. The size ordering is reversed on exit so as not to confuse BASIC (March 1997)
v3.05 Reduced HIMEM to stop BASIC overwriting screen memory (March 1997)

EDITENLARGED

v1.00 Original BASIC version (September 1995)
v2.00 Tidied code and made it compatible with the new EDITCLP file format (uses integer variables for coordinates now). Speed improvements added for initial loading of file due to use of ! operator instead of several ? operators. Similarly for toggling of pixels (March 1997)
v2.05 Changed a FOR...NEXT loop so that one less calculation was required per itteration of the main loading loop. Saves time.
v2.10 Cursor used to be able to go outside the bounds of the area being edited. This didn't affect the result saved to the clipboard though (March 1997)

Variables

EDIT

key% holds the ASCII value of the last pressed button
X%,Y%,P%,Q% define the position of the cursor
addr% is the address at which to assemble (code length is approx half a KB)
exist% is the handle of the file requested by the user, if it exists
wait% is a dummy variable and is set to -1 if the INKEY times out
F$ holds the filename of the file requested by the user

EDITCRE

buffer% is a block of memory used to hold what was behind the message/prompt box, bottom left
row% is a block of memory used to buffer the clipboard file when loading back in snippets
key% holds the ASCII value of the last pressed button
step% is 2 if SHIFT wasn't pressed, 10 if SHIFT was pressed
X%,Y% are the current pixel coordinates
P%,Q% will be the other pair of coordinates. Eg when dragging a box, 2 points are required to define a rectangle
M$ is used by the message box generator, and holds the string to be shown
off% is a general offset pointer, used in lots of places
wait% is a dummy variable and is set to -1 if the INKEY times out
t%,b%,l%,r% are a copy of Y%,Q%,X%,P% when it is required that Y%,Q%,X%,P% need to be manipulated
tempX%,tempY% are backup copies of X% and Y% as X% and Y% are used as parameters to call the machine code
data% is used to hold a value read from screen memory
line$ is the string entered so far when text is being overlaid
F is a file handle

EDITENL

F is a file handle
width% holds the snippet width
height% holds the snipped depth
posx%,posy% is where the cursor is at the moment
bit% is a mask for isolating individual binary bits
offset% is the location currently being considered
data% is the byte got from a file
result% is data% after the bit being considered has been masked out
poke% is where in memory to put the value
X%,Y%,P%,Q% as before

Workings

EDIT

  • Ensure output is to screen only, shift screen down because of my monitor, speed up the repeat rate and make the cursors do ASCII values so that you can't get that white square appearing in MODE7
  • Menu chooses whether to go to PROCloadit or PROCnew
  • Assemble the code, turn off error handling and goto the main program
  • Assembler is commented as and when required, and integer variables (held even when CHAINing between programs) are set to important entry points. This means that if the code improved in the future, only "EDIT" would need to be updated and the other programs in the suite can make use of the new features
  • PROCload gives the opportunity to put in your "Screen Images" disk or whatever or just press a key to skip past that prompt. If the file can't be found then the program is rerun. Otherwise Mode is changed and the file is loaded, irrespective of whether it is the right length, etc...
  • PROCnew just changes MODE to black the screen and returns

EDITCRE

  • Reset keyboard repeat rate in case EditENL altered it, and DIM some memory
  • Enter main loop, poll the keyboard for some action. If it's a cursor key, then adjust the pointer's position accordingly. Depending on whether SHIFT was pressed the step rate is either *1 or *5 pixels at a time

    If the key pressed wasn't a cursor key, see if it was one of the keys that we're waiting for (by ANDing with &DF). CAPS can be on or off

  • PROCmssg
    Reads from the bottom of the screen memory, keeping this safe in the buffer, and then types over the area with M$. The user is given 1 second to read this before the former screen is restored
  • PROCcursor
    Draws a scaled-down box around the cursor. This routine is very simple as clipping is performed by the machine code, so no range checking needs to be done
  • PROCframe
    Draws a border defined by the entry parameters by considering a box to be a set of 2 horizontal and 2 vertical lines
  • PROCexpand
    Repeatedly calls PROCframe, keeping one set of coordinates constant and enlarging the other defined by which cursor key is pressed and the step defined by whether SHIFT was held down at the time. On receipt of a COPY, CHR$135, the values are ANDed with &FFFF so as only the bottom two bytes are ever checked by the M/C routines but BASIC allows four-byte integers. If the value has no depth or width, or none of either, then a message is flagged and you must give the box some size, at least 2*2 in size. Lastly, the coordinates are size ordered. This is essential because all other routines assume they are. This allows the box to be dragged from any corner and not just top-left down
  • PROCdragframe
    Move the whole box around the screen by adding offsets to both the start and finish coordinates. Note that the box may be dragged off the screen; this is used mainly when pasting areas back from the clipboard. They can be cropped by the limits of the monitor
  • PROCsaveselect
    This puts to a file only multiples of whole bytes to a file. This makes saving faster and easier
  • PROCloadselect
    As a tradeoff of PROCsaveselect being simple, the reloading becomes more complex as not all of the bits in the file are needed. On entry X,Y,P,Q are copied as this is to be the destination, then the source X,Y,P,Q are restored by looking at the file. The routine cycles through one line at a time, first reading each row into a memory buffer then interpreting these values. The destination co-ordinate is calculated in X% and Y% is already set by the loop. A test is made to see if the pixel is on the screen or not (USR(T%) - test range). If it isn't then that is skipped to save time, and to stop the clipboard being pasted in two different places on the screen! If it was on the screen then the byte is read that refers to X%. Lastly, a bit comparison is made to see if the bit in the byte from the screen (data% from USR(G%) - get byte) matches that from the file buffer (?row%+some offsets). If they match, no action is required. Otherwise toggle the pixel to the correct value (CALL C% - calculate and write pixel)
  • PROCclearselect
    Follows the same idea as PROCsaveselect but instead of filling the file with values read from the screen, it is filled with a pattern. 0 and 255 for black and white, or 170 for grey (binary 10101010). The renaming of the old clipboard file means that it is preserved, as the end user shouldn't know that when filling an area, they are in fact just loading a clipboard file in!
  • FNditherbw
    Chooses the fill "colour"
  • PROCtext
    Uses VDU5 and the OS's built-in character set to write text by Exclusive ORing. Delete function would not be possible unless the EOR option was used, as to delete the text you simply Exclusive OR a letter with itself
  • PROCedit
    Checks the selection size and warns if it is too big. Otherwise, saves the current screen to "OUTPUT" and goes onto EDITENL
  • FNscanclip
    Just tests the existance of a clipboard file, returning the handle

EDITENL

  • Turns the cursor off again, as a Mode change restores it.
  • Loads in the file by scanning through it serially and setting bytes in the screen to match the bit being scanned. The ! operator improves speed
  • Once loaded, the cursor keys are set to return ASCII and TAB toggles the screen bytes by EORing with &FFFFFFFF. Again the ! operator is used
  • Checks are made to ensure that the cursor hasn't moved beyond the bounds of the snippet. When done, the reverse process to loading is performed, i.e. the bit to put to file is determined by reading the screen memory
  • It is the responsibilty of EDITENL to reload the main picture, as EDITCRE doesn't do this; to make the snippet paste itself the keyboard is stuffed with "P" using FX138

Robert Sprowson, EUG #33