[comp.sys.amiga.tech] Scrolling in 512K - Advice?

aman@xroads.UUCP (Chris Minshall) (11/03/90)

I need some advice on how to create a scrolling screen for a program that
will run in 512k.  I need to create a display that is roughly a 1280x1280
bitmap to scroll around in (the actual display will show 320x200 at a time).
Such a large bitmap cannot be created at all on a 512k machine and just
barely on a 1 meg.  Does anyone know of a technique that would allow one to
create a scrolling display using a small bitmap (emulating a larger one)???
Any help would be appreciated.

Chris
-- 
\  /  C r o s s r o a d s  C o m m u n i c a t i o n s
 /\   (602) 941-2005 300|1200 Baud 24 hrs/day
/  \  hplabs!hp-sdd!crash!xroads!aman

cmcmanis@stpeter.Eng.Sun.COM (Chuck McManis) (11/07/90)

In article <1149@xroads.UUCP> aman@xroads.UUCP (Chris Minshall) writes:
>I need some advice on how to create a scrolling screen for a program that
>will run in 512k.  I need to create a display that is roughly a 1280x1280
>bitmap to scroll around in (the actual display will show 320x200 at a time).
>Such a large bitmap cannot be created at all on a 512k machine and just
>barely on a 1 meg.  Does anyone know of a technique that would allow one to
>create a scrolling display using a small bitmap (emulating a larger one)???
>Any help would be appreciated.

There are a couple of ways you can do this. They revolve around using the
disk drive as a "backing store" for the image data. If your bitmap is
unique for each pixel, then you can store (n X m) sections of the bitmap
in a compressed format on the disk. Careful layout of the disk can 
insure a minimum of seeking. If you use the ROM based disk drivers
(ie Read() and Seek()) then you can also use the ram disk if it is available
on systems with more than .5K) You keep in memory the "view" bitmap and
bitmaps for the four edges of that bitmap. This allows you to scroll
on one of the edges when they are needed. When the edge bitmap is scrolled
on, you can then start another task to begin loading a new "edge" into 
the area vacated by this scrolled on portion. (ASCII image follows :)

		    +---------------+----------------+
		    |  Left Upper   | Right Upper    |
		    |     Panel     |     Panel      |
		    +---------------+----------------+
+---------------+   +--------------------------------+	 +----------------+
|  Left Panel   |   |                                |   |  Right Panel   |
|               |   |                                |   |                |
+---------------+   |                                |   +----------------+
|  Left Panel   |   |                                |   |  Right Panel   |
|               |   |     Viewing                    |   |                |
+---------------+   |                                |   +----------------+
|  Left Panel   |   |              Area              |   |  Right Panel   |
|               |   |                                |   |                |
+---------------+   |         320 X 200              |   +----------------+
|  Left Panel   |   |                                |   |  Right Panel   |
|               |   |                                |   |                |
+---------------+   +--------------------------------+	 +----------------+
		    +---------------+----------------+
		    | Left  Lower   | Right Lower    |
		    |     Panel     |     Panel      |
		    +---------------+----------------+

The panels in this ficticious example are 160 X 50 bitmaps that are
compressed on disk. The entire bitmap is then broken up into panels
and you need only make sure enough panels are in memory to scroll
smoothly onto the next panel. The size of the panels will be determined
by how fast you scroll across them. Because in this example the
panels are 1/8 the size of the bitmap, you will need 2.5 bitmaps
worth of space to store them in memory or 5000 bytes/panel or
20 * 5000 = 100,000 bytes. Roughly 1/4th of the available 400K
on a 512K machine. 

The other alternative is the "pattern space" bitmap where the bitmap
is actually a bunch of (n X m) squares that each contain 1 or 2
patterns. This allows you to store the patterns in memory an then 
just keep an array of patterns to represent your bitmap. This is 
what some of the adventure construction sets do. If you are really
clever, you can make your set of patterns a color font and use
the intuitext functions to build your bitmap. Then your bitmap
becomes a series of lines of text that you can use the system
blit routines to layout for you.



--
--Chuck McManis						    Sun Microsystems
uucp: {anywhere}!sun!cmcmanis   BIX: <none>   Internet: cmcmanis@Eng.Sun.COM
These opinions are my own and no one elses, but you knew that didn't you.
"I tell you this parrot is bleeding deceased!"

pochron@cat37.cs.wisc.edu (David Pochron) (11/17/90)

In article <2259@exodus.Eng.Sun.COM> cmcmanis@stpeter.Eng.Sun.COM (Chuck McManis) writes:

{stuff deleted}
>on systems with more than .5K) You keep in memory the "view" bitmap and
>bitmaps for the four edges of that bitmap. This allows you to scroll
>on one of the edges when they are needed. When the edge bitmap is scrolled
>on, you can then start another task to begin loading a new "edge" into 
>the area vacated by this scrolled on portion. (ASCII image follows :)

{more stuff deleted}

>smoothly onto the next panel. The size of the panels will be determined
>by how fast you scroll across them. Because in this example the
>on a 512K machine. 

{yet more stuff deleted}

I also have been experimenting with scrolling huge screens (with AMOS, of
course) and have a few additional comments I would like to add:

Both of these methods appear similar except the first one is just getting the
data from disk, and the second is assuming you have the data in memory, right?

Okay, this appears fine for coarse scrolling, but how does one go about doing
fine scrolling - using the hardware pointers, of course.  It seems you would
need to double buffer everything and redraw one buffer completely every time
an entire panel was uncovered.  (ie. redraw logical buffer in direction of
scroll, fine scroll physical buffer, switch to logical buffer when entire block
is revealed (now the physical buffer), go back to step 1 with the new logical
buffer)

Phew!  Sure wish they had just put multicolor text modes in the Amiga! :-)


If there is an easier way, please tell me - timing the redraw blits with the
hardware scroll pointers is a real pain.

>--
>--Chuck McManis					    Sun Microsystems


--
-------------------------------------------------------------------------------
David M. Pochron	    |  from Rescue Rangers, _A Fly in the Ointment_
pochron@garfield.cs.wisc.edu|  Gadget to Dale:  "Keep the hands off the body!"
-------------------------------------------------------------------------------

njluurin@cs.ruu.nl (Niek Luuring) (11/21/90)

In <1990Nov16.222133.23158@daffy.cs.wisc.edu> pochron@cat37.cs.wisc.edu (David Pochron) writes:

>{stuff deleted}
>
>I also have been experimenting with scrolling huge screens (with AMOS, of
>course) and have a few additional comments I would like to add:
>
>{remark reffering to other solutions deleted}
>
>Okay, this appears fine for coarse scrolling, but how does one go about doing
>fine scrolling - using the hardware pointers, of course.  It seems you would
>need to double buffer everything and redraw one buffer completely every time
>an entire panel was uncovered.  (ie. redraw logical buffer in direction of
>scroll, fine scroll physical buffer, switch to logical buffer when entire block
>is revealed (now the physical buffer), go back to step 1 with the new logical
>buffer)
>
>Phew!  Sure wish they had just put multicolor text modes in the Amiga! :-)
>
>
>If there is an easier way, please tell me - timing the redraw blits with the
>hardware scroll pointers is a real pain.
>
>-------------------------------------------------------------------------------
>David M. Pochron	    |  from Rescue Rangers, _A Fly in the Ointment_
>pochron@garfield.cs.wisc.edu|  Gadget to Dale:  "Keep the hands off the body!"
>-------------------------------------------------------------------------------

Ok, this thread has been up several times before. Since this was the first
problem I looked into when I got my Amiga, (and have been improving upon the
ideas for over three years now) I may have some helpfull comments:

When you are just scrolling in one direction (horizontal or vertical), there is
no need for two buffers!
Lets assume we are scrolling in a horizontal direction, and the field you want
to scroll is divided into blocks which can easily be blitted onto the screen.
We maintain the following bitmap:

-----------------------------------    Two screens wide with on both sides two
|  |             |             |  |    aditional blockwidths to put the new
|  |             |             |  |    blocks in.
|  |             |             |  |
|  |             |             |  |
-----------------------------------

The bitmap has the following purpose:

-----------------------------------    Somewhere in the bitmap is the visible
|       |ee|*************|ee|     |    portion, the window. (marked *)
|       |ee|*************|ee|     |    The first block of the expansion (next
|       |ee|*************|ee|     |    to the window) has a valid block
|       |ee|*************|ee|     |    Into the second block the new portion
-----------------------------------    of the screen can be blitted.
                                       On the left (resp. right) side you
----------------------------------     keep a copy of the right (left) side
|ghijklmnop*aBCDEFGHIJKLMNOp*abcd|     of the window plus its first expansion
----------------------------------     block.
|ghijklmnopq*bCDEFGHIJKLMNOPq*bcd|
----------------------------------     When scrolling to the left, (moving the
|ghijklmnopqr*cDEFGHIJKLMNOPQr*cd|     window to the right) the following
----------------------------------     has to be done:
|ghijklmnopqrs*dEFGHIJKLMNOPQRs*d|
----------------------------------     Blit the new portion of the screen on
|ghijklmnopqrst*eFGHIJKLMNOPQRSt*|     both the left and the right side of the
----------------------------------     window plus its first expanding blocks.
|ghijklmnopqrstu*fGHIJKLMNOPQRSTu|     This has the effect that when you
----------------------------------     encounter the right side of the bitmap,
|gHIJKLMNOPQRSTUv*ghijklmnopqrstu|     on the left side your copy is available
----------------------------------     (and vica versa).

Further improvement can be made when scrolling in the vertical direction:
By using a 'split screen' the copies on the upper and lower side of the bitmap
need not be used. But can be simulated by a "clever" copper list waiting for the
right moment and then swithing to another part of the bitmap (using modulo).

Hope this is of some help to whomever is wrestling with this problem too.

-------------------------------------------------------------------------------
Niek Luuring jr., student computer science, Utrecht University, The Netherlands
EMail:   njluurin@praxis.cs.ruu.nl
-------------------------------------------------------------------------------