[comp.sys.atari.st] vro_cpyfmt

lsmichae@immd4.informatik.uni-erlangen.de (Lars Michael) (05/21/91)

I have some problems with the VDI function 'copy raster opaque'.

I tried to save ( and restore later) a rectangular area of the
hi rez screen.

I've used follwing routine:

VOID copy_block(dest_adr, src_adr, x, y, w, h)
 BYTE *dest_adr;
 BYTE *src_adr;
 WORD x, y, w, h;
 
{ WORD line;
  MFDB dest_mfdb;
  MFDB src_mfdb;
  WORD pxyarray[8];
  
  line = (Getrez()==2)?80:160;	/* get number  of Words in scanline */
  src_mfdb.fd_addr = src_adr;
  src_mfdb.fd_w = work_out[0]+1;
  src_mfdb.fd_h = work_out[1]+1;
  src_mfdb.fd_wdwidth = line;
  src_mfdb.fd_stand = 0;	/* use device specific format */
  src_mfdb.fd_nplanes = 4>>Getrez();
  pxyarray[0] = x;
  pxyarray[1] = y;
  pxyarray[2] = x+w+3;
  pxyarray[3] = y+h+3;

  dest_mfdb = src_mfdb;		/* dest_mfdb is identical .. */
  dest_mfdb.fd_addr = dest_adr;	/* except the address */
  pxyarray[4] = x;
  pxyarray[5] = y;
  pxyarray[6] = x+w+3;
  pxyarray[7] = y+h+3;

  (VOID) v_hide_c(VdiHandle);
  vro_cpyfm(VdiHandle, 3, pxyarray, &src_mfdb, &dest_mfdb);
  (VOID) v_show_c(VdiHandle, 0);
}

The routine will be entered by a call like

copy_block(Logbase(), temp, xdial, ydial, wdial, hdial);

Now, can someone tell me, what's wrong ?

---

								Lars

+----------------------------------------+----------------------------------+
|     lsmichae@faui43.uni-erlangen.de    |    | | |                         |
|             Lars Michael               |    | | |   "Down with ATARI,     |
|  Graduate Student of Computer Science  |   /  |  \  Long live the ST !"   |
|    at University of Erlangen/Germany   |  /   |   \                       |
+----------------------------------------+----------------------------------|
|  "May the Schwartz be with you!"                                          |
+---------------------------------------------------------------------------+

csbrod@immd4.informatik.uni-erlangen.de (Claus Brod) (05/21/91)

lsmichae@immd4.informatik.uni-erlangen.de (Lars Michael) writes:

>VOID copy_block(dest_adr, src_adr, x, y, w, h)
> BYTE *dest_adr;
> BYTE *src_adr;
> WORD x, y, w, h;
> 
>{ WORD line;
>  MFDB dest_mfdb;
>  MFDB src_mfdb;
>  WORD pxyarray[8];
>  
>  line = (Getrez()==2)?80:160;	/* get number  of Words in scanline */

Using Getrez() here is a major sin. You can calculate them from work_out[0],
and you can even forget about these parameters if you use the method
suggested below.

>  src_mfdb.fd_addr = src_adr;
>  src_mfdb.fd_w = work_out[0]+1;
>  src_mfdb.fd_h = work_out[1]+1;
>  src_mfdb.fd_wdwidth = line;
>  src_mfdb.fd_stand = 0;	/* use device specific format */
>  src_mfdb.fd_nplanes = 4>>Getrez();

Again, this is a SIN.

>  pxyarray[0] = x;
>  pxyarray[1] = y;
>  pxyarray[2] = x+w+3;
>  pxyarray[3] = y+h+3;

>  dest_mfdb = src_mfdb;		/* dest_mfdb is identical .. */
>  dest_mfdb.fd_addr = dest_adr;	/* except the address */
>  pxyarray[4] = x;
>  pxyarray[5] = y;
>  pxyarray[6] = x+w+3;
>  pxyarray[7] = y+h+3;

>  (VOID) v_hide_c(VdiHandle);
>  vro_cpyfm(VdiHandle, 3, pxyarray, &src_mfdb, &dest_mfdb);
>  (VOID) v_show_c(VdiHandle, 0);
>}

>The routine will be entered by a call like

>copy_block(Logbase(), temp, xdial, ydial, wdial, hdial);

Don't use Logbase() in a VDI context. Just use 0L as a pointer to
the current screen. VDI will automatically convert this to the
actual address needed and will even fill in the word width and plane
count parameters in the MFDB automatically!

----------------------------------------------------------------------
Claus Brod, Am Felsenkeller 2,			Things. Take. Time.
D-8772 Marktheidenfeld, Germany		 	(Piet Hein)
csbrod@medusa.informatik.uni-erlangen.de
Claus Brod@wue.maus.de
----------------------------------------------------------------------

ki@opal.cs.tu-berlin.de (Karsten Isakovic) (05/21/91)

In article <1991May21.104617.26475@informatik.uni-erlangen.de> lsmichae@immd4.informatik.uni-erlangen.de (Lars Michael) writes:
>I have some problems with the VDI function 'copy raster opaque'.

>  line = (Getrez()==2)?80:160;	/* get number  of Words in scanline */

Don't use Getrez(). This code will crash under nearly all graphics cards
(MATRIX, MGE, OverScan, Reflex) and even on the TT.
If you blit to / from the screen you must set fd_addr = NULL. In this
case all other values are filled in by the VDI. You can't know how many
BytesPerLine the actual graphics card has.
For the 'offscreen' MFDB, you must use w/16*planes. It does not matter if
the BPL in the offscreen area is different to the screen MFDB (As in
OverScan mode or with the Reflex card), the VDI handles this correctly.

>  src_mfdb.fd_nplanes = 4>>Getrez();

You get the plane count with the vq_extend call or in the AES global[10]
array but NOT with Getrez()!

>The routine will be entered by a call like
>copy_block(Logbase(), temp, xdial, ydial, wdial, hdial);

Don't intercept VDI and XBIOS calls. The Xbios calls are only for the
'main console' of the ST and not for a graphics card. (But most cards
have an emulation of the calls). If you use Getrez() with a Matrix card
installed, you will get the rez of the (probably not connected) ST-monitor.
With Physbase(), Setpallete, Setcolor there is the same problem.

>Now, can someone tell me, what's wrong ?

Your main 'bug' is in the pxy array. The '+3' copys more memory lines than 
possible, so you get an bus-error in the color resolution.

>  lsmichae@faui43.uni-erlangen.de  

Karsten, ki@opal.cs.tu-berlin.de    (Meet me in +Atari on IRC...) 

micro@imada.ou.dk (Klaus Pedersen) (05/22/91)

csbrod@immd4.informatik.uni-erlangen.de (Claus Brod) writes:

>Don't use Logbase() in a VDI context. Just use 0L as a pointer to
>the current screen. VDI will automatically convert this to the
>actual address needed and will even fill in the word width and plane
>count parameters in the MFDB automatically!

I might be wrong here, but it is my experince that you need to set the
fd_stand to device dependent format. Anyway it have helped me in my 
programs. I will go home and try it out now...

Klaus, micro@imada.ou.dk

>Claus Brod, Am Felsenkeller 2,			Things. Take. Time.

lsmichae@immd4.informatik.uni-erlangen.de (Lars Michael) (05/22/91)

I've eliminated all XBIOS calls in VDI context, got n_planes from
vq_extend() and instead of the screen address I'm using NULL.

Now it works yes fine.

Thanx to all guys who gave me some advice.
---

								Lars

+----------------------------------------+----------------------------------+
|     lsmichae@faui43.uni-erlangen.de    |    | | |                         |
|             Lars Michael               |    | | |   "Down with ATARI,     |
|  Graduate Student of Computer Science  |   /  |  \  Long live the ST !"   |
|    at University of Erlangen/Germany   |  /   |   \                       |
+----------------------------------------+----------------------------------|
|  "May the Schwartz be with you!"                                          |
+---------------------------------------------------------------------------+

ONM07@DMSWWU1A.BITNET (Julian F. Reschke) (05/24/91)

In article <1991May21.171701.2602@imada.ou.dk>, micro@imada.ou.dk (Klaus
Pedersen) says:
>I might be wrong here, but it is my experince that you need to set the
>fd_stand to device dependent format. Anyway it have helped me in my
>programs. I will go home and try it out now...
>
>Klaus, micro@imada.ou.dk

Shouldn't. Using a NULL pointer as raster adress means `I want the VDI
screen buffer and nothing else'. Clearly, the physical screen is ALWAYS
in device specific format.
___________________________ cut here _____________________________________
Julian F. Reschke, Hensenstr. 142, D-4400 Muenster, Phone: ++49 251 861241
fast eMail: ONM07@DMSWWU1A.BITNET,    slow: jr@ms.maus.de (++49 251 77216)
____________________ correct me if I'm wrong _____________________________