View Single Post
Old 20 December 2020, 23:50   #1
Registered User

Join Date: Aug 2018
Location: Minneapolis, USA
Posts: 95
P96: What's the right way to do X?

Hi All,

I've got a non-game app I'm plugging away at for 68K amigas. I would like it to run on a 68000, or worst case 68020. I'd also like to support RTG Amigas. So don't want to give up one or the other, and am ok with having bifurcated code where necessary. Based on info from the experten, I'm going to be targeting the P96 API, as currently maintained by Jens and co. at Individual Computers. "Actively maintained" has such a nice ring.

I last used an RTG card in an Amiga about 25 years ago, and basically remember nothing about them. I've got a setup working in UAE now, and have started trying to adapt my program to work with it. I know I'm doing some stuff with the blitter and bitmaps that isn't going to work.

Boring background about app

The app is designed to let user run it in 1, 2, 3, or 8 bitplanes (more later?). The graphics are read off disk on an as-needed basis, using standard data types. If screen depth is <4, then it looks for an IFF file and loads it. If depth=8, it looks for PNGs, and uses them instead. (had some problem with GIFs, not sure why). For each graphic that is displayed, there is the main graphic, which is 1, 2, 3, or 8 bits (read from disk); there is a 1 bit mask (read from disk); and there is a "selected" mask which is just the regular mask with a checkerboard pattern applied.

The bitmaps are blitted onto the screen, with the regular or "selected" mask, as appropriate. The bitmaps are set up as interleaved, with goal of improving ECS/OCS performance.

The above all works with depths 1, 2, or 3 (non-RTG graphics). Screenshot shows the images blitted to the screen with the normal mask, and you can see the screened "selected" mask under the files I'm dragging.
Click image for larger version

Name:	Screen Shot 2020-12-20 at 4.42.05 PM.png
Views:	103
Size:	37.4 KB
ID:	70021

First problem: Copying a bitmap from file

When I load a graphic, I do this:
  1. AllocBitMap ->
  2. InitBitMap ->
  3. NewDTObject (to get the graphic from disk) ->
  4. BltBitMap to copy the bitmap contents from the DT object into the bitmap I prepared ->
  5. dispose of DT object.

unsigned long the_plane_count = BltBitMap(iff_bitmap, 0, 0, *the_dest_bitmap, 0, 0, pixel_width, pixel_height, 0xC0, 0xFF, NULL);

The P96 library does not care much for this line. What's the proper way to copy the bitmap out of the DT object?

Problem #2: Making the Masks

The masks are a little different. Here is the logic I was using:
  1. AllocBitMap ->
  2. InitBitMap ->
  3. NewDTObject (to get the graphic from disk) ->
  4. BltBitMap to copy the bitmap contents from the DT object into the bitmap I prepared ->
  5. dispose of DT object (SAME UP TO HERE) ->
  6. Get Planes[0] from the copied bitmap ->
  7. AllocVec the normal mask using pixel width/8 * pixel height * depth ->
  8. AllocVec the "selected" mask using same size formula ->
  9. iterate through plane 0 of the copied bitmap, row by row, copy/pasting each row once per bitplane, to interleave the masks (also, apply X0X0X0 pattern to the selected mask while doing this)

// if we have 2 or more bitplanes, we need to interleave the mask for the blitter to work.
// this means: 1st row of mask repeated once per bitplane, then 2nd row repeated once per bitplane, etc, etc,

unsigned char num_words_to_copy = pixel_width / 8 / sizeof(UWORD);

for (int row_num = 0; row_num < pixel_height; row_num++)
  for (int plane_num = 0; plane_num < the_depth; plane_num++)
    // write one row of one plane, either one column (if 16 pix) or 2 cols (if 32 px)
    for (int col_num = 0; col_num < num_words_to_copy; col_num++)
      *(mask_target_for_math+col_num) = *(mask_source_for_math+col_num);
      *(mask_target_for_math_selected+col_num) = (row_num % 2 == 0 ? *(mask_source_for_math+col_num) | 0x5555 : *(mask_source_for_math+col_num) | 0xAAAA);

    // advance the pointer for the destination, but not for the source, since we need to copy same source 1x per plane
    mask_target_for_math += num_words_to_copy;
    mask_target_for_math_selected += num_words_to_copy;

  // advance pointer for the source, in prep for move to next row
  mask_source_for_math += num_words_to_copy;
I'm sure this probably breaks a couple of rules when it comes to RTG: 1) interleaving probably has no value at all, and 2) I'm creating these masks in CHIP memory, which RTG doesn't need. Maybe 3) I'm reading bit map without locking it, but it's not clear to me if I need to do that.

I've switching to use P96AllocBitMap() and P96FreeBitMap for RTG mode.

Any advice here on how to set up the masks? Is p96ReadPixelArray() and p96WritePixelArray my friend here?
Warty is offline  
Page generated in 0.05238 seconds with 12 queries