SCREEN1 = SYSVAR @ JSROM

Anything QL Software or Programming Related.
User avatar
tofro
QL Wafer Drive
Posts: 1596
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: SCREEN1 = SYSVAR @ JSROM

Postby tofro » Sun Jun 16, 2019 12:11 pm

I sometimes mix up the various Adventure Creation Tools for the QL - It actually was ACT, as you say.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Ralf R.
Over Heated PSU
Posts: 131
Joined: Fri Jun 15, 2018 8:58 pm

Re: SCREEN1 = SYSVAR @ JSROM

Postby Ralf R. » Sun Jun 16, 2019 1:37 pm

tofro wrote:I sometimes mix up the various Adventure Creation Tools for the QL - It actually was ACT, as you say.

Tobias


;) Doesn't matter.


tcat
Super Gold Card
Posts: 553
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: SCREEN1 = SYSVAR @ JSROM

Postby tcat » Sun Jun 16, 2019 6:05 pm

Hi,

Most interesting. While I have looked up some titles made in `Quill', I was not able to do so for `ACT'?

Comparing some ZX game graphics to QL mode 8 pictures, ZX seems to me as more catchy. Cannot give exact reasoning, perhaps is a matter of personal opinion?

Tomas


Ralf R.
Over Heated PSU
Posts: 131
Joined: Fri Jun 15, 2018 8:58 pm

Re: SCREEN1 = SYSVAR @ JSROM

Postby Ralf R. » Sun Jun 16, 2019 6:21 pm

It seems, ACT came (unfortunately) too late. I do not know a game, which was produced with it (but there seem to be a few). Steve had done it (as usual) all in machine code and also the finished games were EXd. A bit like a compiler.

Would be very good, if this program would be freeware, unfortuntely noone is able to contact Steve.


tcat
Super Gold Card
Posts: 553
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: SCREEN1 = SYSVAR @ JSROM

Postby tcat » Tue Jun 18, 2019 8:04 am

The most simple way to actually implement character printing would be, IMHO, the following:
Restrict yourself to available print positions that are word-aligned in screen memory (i.e. 8 pixels in mode 4, 4 in mode 8).
Don't stick with the QL font format, but rather prepare the font like you would see it on-screen (i.e. pre-defined foreground and background color). You don't need to stick with QL character sizes as well - 8 x 8 is easily possible then.

Hi,
Based on the above, this handles fonts on 8x8 raster, mode 4, word aligned.
Should therefore print ZX system font. Locals not needed, all fits in regs.

Code: Select all

char     link     a4,#-$0c          ;locals ch
ch_x     equ     -$02               ;d1
ch_y     equ     -$04               ;d2
ch_col   equ     -$06               ;d3
ch_ch    equ     -$08               ;d4
ch_wd    equ     -$0a               ;word
ch_wm    equ     -$0c               ;mask

         lea      dctl,a2           ;display ctrl copy
         move.w   d1,ch_x(a4)       ;x, save locals
         move.w   d2,ch_y(a4)       ;y
         move.w   d3,ch_col(a4)     ;col
         move.w   d4,ch_ch(a4)      ;ch

*        lea      dbg,a5            ;debug
*        lea      out,a1            ;debug
*        move.l   a5,(a1)           ;debug

         lea      ch_fnt,a3         ;font raster
         lsl.w    #3,d4             ;d4=ch*8, index to fnt
         lea      0(a3,d4.w),a3     ;a3=fnt[ch*8]

         bsr      acalc             ;a0=address x,y
         moveq    #7,d7             ;8 scan lines, -1 for DBF
ch_ln    move.b   (a3)+,d0          ;scan line

         clr.b    d4                ;   076543210
         clr.w    d5                ;d3=......GR.
ch_tg    btst     #2,d3             ;test G bit
         beq.s    ch_tr
         move.b   d0,d4
ch_tr    btst     #1,d3             ;test R bit
         beq.s    ch_w
         move.b   d0,d5

ch_w     lsl.w    #8,d4             ;word
         or.w     d5,d4
*        move.w   d4,(a5)+          ;debug

ch_m     clr.w    d1                ;mask
         move.b   d0,d1
         lsl.w    #8,d0
         or.w     d1,d0
         not.w    d0
*        move.w   d0,(a5)+          ;debug

         and.w    d0,(a0)           ;mask
         or.w     d4,(a0)           ;word
         lea      128(a0),a0        ;next line
         dbf.w    d7,ch_ln

ch_exit  unlk     a4
         clr.l    d0                ;No error code
         rts                      ;Return to BASIC


         ; Font raster 8x8 pixels
ch_fnt   ; 0       76543210
         dc.b     %11111111
         dc.b     %10000001
         dc.b     %10000001
         dc.b     %10000001
         dc.b     %10000001
         dc.b     %10000001
         dc.b     %10000001
         dc.b     %11111111

         ; 1       76543210
         dc.b     %11111111
         dc.b     %11000011
         dc.b     %10100101
         dc.b     %10011001
         dc.b     %10011001
         dc.b     %10100101
         dc.b     %11000011
         dc.b     %11111111

dbg      dc.w     1                 ;Debug buffer RESPRed
         end


Dealing with 5x9 raster on any x,y, is not simple and would probably need some shift rotate magic.
Tomas


tcat
Super Gold Card
Posts: 553
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: SCREEN1 = SYSVAR @ JSROM

Postby tcat » Tue Jun 18, 2019 10:23 am

Hi,
Can do this with ZX font, x aligned, y can skew by single pixel.
Tomas

zxfont.png
ZX Font @ QL
zxfont.png (2.41 KiB) Viewed 702 times


tcat
Super Gold Card
Posts: 553
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: SCREEN1 = SYSVAR @ JSROM

Postby tcat » Fri Jun 21, 2019 8:44 am

Hi,

I am further thinking about fill. I do scan line fill for circle, and ellipse using BLOCK, that I now have optimised. Filled rectangle really is BLOCK on its own.
I cannot do arcs, or ellipse rotate so far.

But how about irregular shapes, polygons etc? How does QL handle it?
I have coded flood fill for Oberon system as a recursive algo, while simple didactic, exhausts stack for larger areas.

Code: Select all

  PROCEDURE Fill*(tgc, rpc, x, y: INTEGER);
    VAR c: INTEGER; (*tgc, rpc - target, replacement colour*)
  BEGIN
    (*c = pick colour at x,y coord *)
    IF c = tgc THEN
      Display.Dot(rpc, x, y, Display.replace); (*no clip*)
      Fill(tgc, rpc, x, y-1); (*south*)
      Fill(tgc, rpc, x, y+1); (*north*)
      Fill(tgc, rpc, x-1, y); (*west*)
      Fill(tgc, rpc, x+1, y); (*east*)
    END
  END Fill;

On the QL, each short return address may take a single word, plus four procedure params word each, i.e. 5x2 =10bytes per call. Small area of 100 pixels would then take 1000 stack bytes to fill? If I am right.

Looking for a solution.
Tom
Last edited by tcat on Sat Jun 29, 2019 6:34 pm, edited 1 time in total.


User avatar
tofro
QL Wafer Drive
Posts: 1596
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: SCREEN1 = SYSVAR @ JSROM

Postby tofro » Fri Jun 21, 2019 9:25 am

Tomas,

the QL's native FILL works with a simple scanline algorithm that simply remembers a start and an endpoint per scanline while FILL is active. This can work with a static size buffer of max. 256 (max # of scanlines) x 2 (number of points) x 2 (word x coordinates) - And has the advantage that it knows the max size of the buffer beforehand (the other advantage is: It is very fast). The disadvantage is: It cannot fill some shapes without the programmer splitting concave shapes into convex ones (concave shapes can have more than one single start and endpoint per scanline).

The classic recursive shape fill algorithm that you showed can use lots of stack space very fast - Some implementations like on the Commodore 128 or the BBC Micro simply abort with "Out of memory" or unfilled spaces on more complex patterns to fill. This is definitively not recommended. A slightly modified version of the recursive algorithm is to use a self-allocated list of coordinates instead of the stack which gives more control over the memory situation.

Another (better) option is to mix the original QL approach of scanlines with a stack of areas to re-visit.

Instead of trying to explain all these algorithms, it is probably better to refer to Wikipedia, which has an extensive discussion of various flood-fill algorithms.

The first design decision you have to make is: How do you define the border of the area to be filled - you can either fill everything that is the same pixel color as the initial pixel (that is a sort of "repaint" algorithm) or you can fill until you hit a specific border colour (that is what I call "real flood fill").

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
tcat
Super Gold Card
Posts: 553
Joined: Fri Jan 18, 2013 5:27 pm
Location: Prague, Czech Republic

Re: SCREEN1 = SYSVAR @ JSROM

Postby tcat » Fri Jun 21, 2019 6:20 pm

Hi,

This can work with a static size buffer of max. 256 (max # of scanlines) x 2 (number of points) x 2 (word x coordinates)

I could think of two arrays x1[y=0..255], x2[y=0..255], that I can get populated each time I call a routine to plot a pixel, where x1<=x2. First I draw shape outline, second step I walk through the arrays and for each x1,x2>0 I draw a line for a given y. I will call BLOCK for faster fill.
In assembly the arrays would really be a buffer of 256 longs.

Am I Close?
Tomas


User avatar
tofro
QL Wafer Drive
Posts: 1596
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: SCREEN1 = SYSVAR @ JSROM

Postby tofro » Sat Jun 22, 2019 10:36 am

tcat wrote:Hi,

Am I Close?
Tomas


Yep. Pseudo code for a SD.FILL operation in QDOS looks like that:

On FILL 1:

Code: Select all

Allocate a yRes * 2 * WORD array.
Initialize all the min and max X values in that array to an invalid x coordinate


While FILL is active, in all drawing operations that set a pixel at x, y, do the following:

Code: Select all

consult the pair of x coordinates for this y in the allocated array
  if both coordinates are the invalid value (scanline has not been visited yet)
    set both x coordinates to the one you're setting a pixel at
  else if the x value is smaller than the current min x in the pair
    replace min x in the pair with the current x
  else if current x is larger than the current max x in the pair
    replace max x in the pair with the current x
  else if it's in-between (which is a sure sign you're handling a concave form)
    do nothing


On FILL 0 after a FILL 1 do the following

Code: Select all

run through the fill buffer,
   for each y coordinate in that buffer
      draw a horizontal line between min x and max x
       


Obviously, while being the fastest possible FILL, this method has two downsides:
  • Can't fill complex concave areas
  • Slows down drawing the circumference

On the other hand, this fill is really fast and has a very limited memory footprint.

Hope this helps.
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO

Who is online

Users browsing this forum: No registered users and 5 guests