示例#1
0
//Perform frame by frame updates and blits. Set the stream
//state to STOP if there are no more frames to update.
void RenderToSurface(BITMAP *vscreen) {
    //update each frame
    if (g_pSample->Update(0, NULL, NULL, 0) != S_OK) {
        g_bAppactive = FALSE;
        g_pMMStream->SetState(STREAMSTATE_STOP);
    }
    else {
        g_bAppactive = TRUE;
        acquire_screen();
        // Because vscreen is a DX Video Bitmap, it can be stretched
        // onto the screen (also a Video Bmp) but not onto a memory
        // bitmap (which is what "screen" is when using gfx filters)
        if (is_video_bitmap(screen))
        {
            stretch_blit(vscreen, screen, 0, 0, vscreen->w, vscreen->h,
                         screen->w / 2 - newWidth / 2,
                         screen->h / 2 - newHeight / 2,
                         newWidth, newHeight);
        }
        else
        {
            blit(vscreen, vsMemory, 0, 0, 0, 0, vscreen->w, vscreen->h);
            stretch_blit(vsMemory, screen, 0, 0, vscreen->w, vscreen->h,
                         screen->w / 2 - newWidth / 2,
                         screen->h / 2 - newHeight / 2,
                         newWidth, newHeight);
        }
        release_screen();

        render_to_screen(screen, 0, 0);
        // if we're not playing AVI sound, poll the game MP3
        if (!useSound)
            update_polled_stuff_and_crossfade();
    }
}
示例#2
0
/* ddraw_do_stretch_blit:
 *   Accelerated stretch_blit, stretch_sprite, stretch_masked_blit
 */
static void ddraw_do_stretch_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height, int masked)
{
   RECT dest_rect, source_rect;
   DDCOLORKEY src_key;
   HRESULT hr;
   BITMAP *dest_parent;
   BITMAP *source_parent;

   dest_rect.left = dest_x + dest->x_ofs;
   dest_rect.top = dest_y + dest->y_ofs;
   dest_rect.right = dest_x + dest->x_ofs + dest_width;
   dest_rect.bottom = dest_y + dest->y_ofs + dest_height;

   source_rect.left = source_x + source->x_ofs;
   source_rect.top = source_y + source->y_ofs;
   source_rect.right = source_x + source->x_ofs + source_width;
   source_rect.bottom = source_y + source->y_ofs + source_height;

   src_key.dwColorSpaceLowValue = source->vtable->mask_color;
   src_key.dwColorSpaceHighValue = source->vtable->mask_color;

   if ( ( (masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT_MASKED)) ||
          (!masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT)) 
        ) && ( is_video_bitmap(source) || is_system_bitmap(source) ) ) {

      /* find parents */
      dest_parent = dest;
      while (dest_parent->id & BMP_ID_SUB)
         dest_parent = (BITMAP *)dest_parent->extra;

      source_parent = source;
      while (source_parent->id & BMP_ID_SUB)
         source_parent = (BITMAP *)source_parent->extra;

      _enter_gfx_critical();
      gfx_directx_release_lock(dest);
      gfx_directx_release_lock(source);

      IDirectDrawSurface2_SetColorKey(DDRAW_SURFACE_OF(source_parent)->id,
                                      DDCKEY_SRCBLT, &src_key);

      hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(dest_parent)->id, &dest_rect,
                                   DDRAW_SURFACE_OF(source_parent)->id, &source_rect,
                                   (masked ? DDBLT_KEYSRC : 0) | DDBLT_WAIT, NULL);
      _exit_gfx_critical();

      if (FAILED(hr))
	 _TRACE(PREFIX_E "Blt failed (%x)\n", hr);

      /* only for windowed mode */
      if ((gfx_driver->id == GFX_DIRECTX_WIN) && (dest_parent == gfx_directx_forefront_bitmap))
         win_gfx_driver->paint(&dest_rect);
   }
   else {
      /* have to use the original software version */
      _orig_stretch_blit(source, dest, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, masked);
   }
}
示例#3
0
/* request_video_bitmap:
 *  Triple buffering function: triggers a swap to display the specified 
 *  video memory bitmap object, which will take place on the next retrace.
 */
int request_video_bitmap(BITMAP *bitmap)
{
   if ((!is_video_bitmap(bitmap)) || 
       (bitmap->w != SCREEN_W) || (bitmap->h != SCREEN_H) ||
       (_dispsw_status))
      return -1;

   if (gfx_driver->request_video_bitmap)
      return gfx_driver->request_video_bitmap(bitmap);

   return request_scroll(bitmap->x_ofs, bitmap->y_ofs);
}
示例#4
0
/* show_video_bitmap:
 *  Page flipping function: swaps to display the specified video memory 
 *  bitmap object (this must be the same size as the physical screen).
 */
int show_video_bitmap(BITMAP *bitmap)
{
   if ((!is_video_bitmap(bitmap)) || 
       (bitmap->w != SCREEN_W) || (bitmap->h != SCREEN_H) ||
       (_dispsw_status))
      return -1;

   if (gfx_driver->show_video_bitmap)
      return gfx_driver->show_video_bitmap(bitmap);

   return scroll_screen(bitmap->x_ofs, bitmap->y_ofs);
}
示例#5
0
/* _xaccel_draw_sprite:
 *  Accelerated draw_sprite.
 */
static void _xaccel_draw_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y)
{
   int sx, sy, w, h;

   if (is_video_bitmap(sprite)) {
      sx = 0;
      sy = 0;
      w = sprite->w;
      h = sprite->h;

      if (bmp->clip) {
         if (x < bmp->cl) {
            sx += bmp->cl - x;
            w -= bmp->cl - x;
            x = bmp->cl;
         }

         if (y < bmp->ct) {
            sy += bmp->ct - y;
            h -= bmp->ct - y;
            y = bmp->ct;
         }

         if (x + w > bmp->cr)
            w = bmp->cr - x;

         if (w <= 0)
            return;

         if (y + h > bmp->cb)
            h = bmp->cb - y;

         if (h <= 0)
            return;
      }

      sx += sprite->x_ofs;
      sy += sprite->y_ofs;
      x += bmp->x_ofs;
      y += bmp->y_ofs;

      XLOCK();
      XDGACopyTransparentArea(_xwin.display, _xwin.screen, sx, sy, w, h, x, y, sprite->vtable->mask_color);
      XUNLOCK();
      bmp->id &= ~BMP_ID_LOCKED;
   }
   else
      _orig_draw_sprite(bmp, sprite, x, y);
}
示例#6
0
/* _xaccel_masked_blit:
 *  Accelerated masked_blit.
 */
static void _xaccel_masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)
{
   if (is_video_bitmap(source)) {
      source_x += source->x_ofs;
      source_y += source->y_ofs;
      dest_x += dest->x_ofs;
      dest_y += dest->y_ofs;

      XLOCK();
      XDGACopyTransparentArea(_xwin.display, _xwin.screen, source_x, source_y, width, height, dest_x, dest_y, source->vtable->mask_color);
      XUNLOCK();
      dest->id &= ~BMP_ID_LOCKED;
   }
   else
      _orig_masked_blit(source, dest, source_x, source_y, dest_x, dest_y, width, height);
}
示例#7
0
/* ddraw_masked_blit:
 *  Accelerated masked blitting routine.
 */
static void photon_masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)
{
   struct Ph_rect source_rect = {
      { source_x + source->x_ofs,
        source_y + source->y_ofs },
      { source_x + source->x_ofs + width - 1,
        source_y + source->y_ofs + height - 1 }
   };
   
   struct Ph_rect dest_rect = {
      { dest_x + dest->x_ofs,
        dest_y + dest->y_ofs },
      { dest_x + dest->x_ofs + width - 1,
        dest_y + dest->y_ofs + height - 1 }
   };
   
   struct BITMAP *dest_parent, *source_parent;

   if (is_video_bitmap(source)) {
      if (!chroma_on) {
         PgChromaOn();
         chroma_on = TRUE;
      }
      
      /* find parents */
      source_parent = source;
      while (source_parent->id & BMP_ID_SUB)
         source_parent = (BITMAP *)source_parent->extra;
         
      dest_parent = dest;
      while (dest_parent->id & BMP_ID_SUB)
         dest_parent = (BITMAP *)dest_parent->extra;

      PgContextBlit(BMP_EXTRA(source_parent)->context, &source_rect,
                    BMP_EXTRA(dest_parent)->context, &dest_rect);

      /* only for windowed mode */
      if (dest_parent == pseudo_screen)
         ph_update_window(&dest_rect);
   }
   else {
      /* have to use the original software version */
      _orig_masked_blit(source, dest, source_x, source_y, dest_x, dest_y, width, height);
   }
}
示例#8
0
/* photon_draw_sprite:
 *  Accelerated sprite drawing routine.
 */
static void photon_draw_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y)
{
   int sx, sy, w, h;

   if (is_video_bitmap(sprite)) {
      sx = sprite->x_ofs;
      sy = sprite->y_ofs;
      w = sprite->w;
      h = sprite->h;

      if (bmp->clip) {
	 if (x < bmp->cl) {
	    sx += bmp->cl - x;
	    w -= bmp->cl - x;
	    x = bmp->cl;
	 }

	 if (y < bmp->ct) {
	    sy += bmp->ct - y;
	    h -= bmp->ct - y;
	    y = bmp->ct;
	 }

	 if (x + w > bmp->cr)
	    w = bmp->cr - x;

	 if (w <= 0)
	    return;

	 if (y + h > bmp->cb)
	    h = bmp->cb - y;

	 if (h <= 0)
	    return;
      }

      photon_masked_blit(sprite, bmp, sx, sy, x, y, w, h);
   }
   else {
      /* have to use the original software version */
      _orig_draw_sprite(bmp, sprite, x, y);
   }
}
示例#9
0
/* ddraw_draw_sprite:
 *  Accelerated sprite drawing routine.
 */
static void ddraw_draw_sprite(BITMAP * bmp, BITMAP * sprite, int x, int y)
{
   int sx, sy, w, h;

   if (is_video_bitmap(sprite) || is_system_bitmap(sprite)) {
      sx = 0;  /* sprite->x_ofs & sprite->y_ofs will be accounted for in ddraw_masked_blit */
      sy = 0;
      w = sprite->w;
      h = sprite->h;

      if (bmp->clip) {
	 if (x < bmp->cl) {
	    sx += bmp->cl - x;
	    w -= bmp->cl - x;
	    x = bmp->cl;
	 }

	 if (y < bmp->ct) {
	    sy += bmp->ct - y;
	    h -= bmp->ct - y;
	    y = bmp->ct;
	 }

	 if (x + w > bmp->cr)
	    w = bmp->cr - x;

	 if (w <= 0)
	    return;

	 if (y + h > bmp->cb)
	    h = bmp->cb - y;

	 if (h <= 0)
	    return;
      }

      ddraw_masked_blit(sprite, bmp, sx, sy, x, y, w, h);
   }
   else {
      /* have to use the original software version */
      _orig_draw_sprite(bmp, sprite, x, y);
   }
}
示例#10
0
int uip_vgamode(void)
{
  int depth, rate;
  unsigned long screenbase;

  for (rate = 60; rate <= 70; rate += 10) {
    for (depth = 15; depth <= 16; depth++) {
      LOG_VERBOSE(("Trying mode 640x480 depth %d rate %d", depth, rate));
      set_color_depth(depth);
      request_refresh_rate(rate);
      if ((set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 480 * 2) < 0)) {
        LOG_VERBOSE(("Mode not supported"));
        continue;
      }
      if (SCREEN_W != 640 || SCREEN_H != 480) {
        LOG_CRITICAL(("Screen not approriate for depth %d rate %d",
                      depth, rate));
        continue;
      }
      goto WHEE;
    }
  }
  LOG_CRITICAL(("Failed to find suitable mode"));
  return 1;
WHEE:
  uip_vga = 1;
  if (uip_forceredshift != -1 && uip_forcegreenshift != -1 &&
      uip_forceblueshift != -1) {
    uip_uipinfo->redshift = uip_forceredshift;
    uip_uipinfo->greenshift = uip_forcegreenshift;
    uip_uipinfo->blueshift = uip_forceblueshift;
  } else {
    uip_uipinfo->redshift = ui_topbit(makecol(255, 0, 0)) - 4;
    uip_uipinfo->greenshift = ui_topbit(makecol(0, 255, 0)) - 4;
    uip_uipinfo->blueshift = ui_topbit(makecol(0, 0, 255)) - 4;
  }
  if ((uip_bank0 = create_video_bitmap(640, 480)) == NULL ||
      (uip_bank1 = create_video_bitmap(640, 480)) == NULL) {
    uip_textmode();
    LOG_CRITICAL(("Failed to allocate memory pages"));
    return 1;
  }
  if (is_linear_bitmap(uip_bank0) == 0 ||
      is_linear_bitmap(uip_bank1) == 0 ||
      is_video_bitmap(uip_bank0) == 0 || is_video_bitmap(uip_bank1) == 0) {
    uip_textmode();
    LOG_CRITICAL(("Allocated bitmaps not suitable or linear addressing mode "
                  "not supported by hardware"));
    return 1;
  }
  /* don't you just hate MS platforms? */
  __djgpp_nearptr_enable();
  __dpmi_get_segment_base_address(uip_bank0->seg, &screenbase);
  uip_uipinfo->screenmem0 = (uint8 *)(screenbase + uip_bank0->line[0] -
                                      __djgpp_base_address);
  __dpmi_get_segment_base_address(uip_bank1->seg, &screenbase);
  uip_uipinfo->screenmem1 = (uint8 *)(screenbase + uip_bank1->line[0] -
                                      __djgpp_base_address);
  uip_uipinfo->linewidth = 2 * VIRTUAL_W;       /* 16 bit */
  uip_displaybank(0);           /* set current to 0th bank */
  uip_clearscreen();            /* clear bank */
  ui_setupscreen();             /* setup bank */
  uip_displaybank(-1);          /* toggle bank */
  uip_clearscreen();            /* clear bank */
  ui_setupscreen();             /* setup bank */
  if (install_keyboard() == -1) {
    uip_textmode();
    LOG_CRITICAL(("Unable to initialise keyboard"));
    return 1;
  }
  if (uip_bank0->y_ofs != 0 || uip_bank1->y_ofs != 480) {
    uip_textmode();
    LOG_CRITICAL(("sorry, I don't understand this video layout"));
    return 1;
  }
  keyboard_lowlevel_callback = uip_keyboardhandler;
  uip_keypoll = keyboard_needs_poll()? 1 : 0;
  return 0;
}
示例#11
0
/* destroy_bitmap:
 *  Destroys a memory bitmap.
 */
void destroy_bitmap(BITMAP *bitmap)
{
   VRAM_BITMAP *prev, *pos;

   if (bitmap) {
      if (is_video_bitmap(bitmap)) {
	 /* special case for getting rid of video memory bitmaps */
	 ASSERT(!_dispsw_status);

	 prev = NULL;
	 pos = vram_bitmap_list;

	 while (pos) {
	    if (pos->bmp == bitmap) {
	       if (prev)
		  prev->next_y = pos->next_y;
	       else
		  vram_bitmap_list = pos->next_y;

	       if (pos->x < 0) {
		  /* the driver is in charge of this object */
		  gfx_driver->destroy_video_bitmap(bitmap);
		  _AL_FREE(pos);
		  return;
	       } 

	       /* Update cached bitmap size using worst case scenario:
		* the bitmap lies between two holes whose size is the cached
		* size on each axis respectively.
		*/
	       failed_bitmap_w = failed_bitmap_w * 2 + ((bitmap->w + 15) & ~15);
	       if (failed_bitmap_w > BMP_MAX_SIZE)
		  failed_bitmap_w = BMP_MAX_SIZE;

	       failed_bitmap_h = failed_bitmap_h * 2 + bitmap->h;
	       if (failed_bitmap_h > BMP_MAX_SIZE)
		  failed_bitmap_h = BMP_MAX_SIZE;

	       _AL_FREE(pos);
	       break;
	    }

	    prev = pos;
	    pos = pos->next_y;
	 }

	 _unregister_switch_bitmap(bitmap);
      }
      else if (is_system_bitmap(bitmap)) {
	 /* special case for getting rid of system memory bitmaps */
	 ASSERT(gfx_driver != NULL);

	 if (gfx_driver->destroy_system_bitmap) {
	    gfx_driver->destroy_system_bitmap(bitmap);
	    return;
	 }
      }

      /* normal memory or sub-bitmap destruction */
      if (system_driver->destroy_bitmap) {
	 if (system_driver->destroy_bitmap(bitmap))
	    return;
      }

      if (bitmap->dat)
	 _AL_FREE(bitmap->dat);

      _AL_FREE(bitmap);
   }
}
示例#12
0
void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, ALLEGRO_BITMAP *dest, uint32 width, uint32 height) {

	int j, v;
	unsigned int x, y;
	int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest));
	unsigned long color[12];
	unsigned char **src_line = new unsigned char*[4];
	unsigned char **dst_line = new unsigned char*[2];

	/* Point to the first 3 lines. */
	src_line[0] = src;
	src_line[1] = src;
	src_line[2] = src + src_pitch;
	src_line[3] = src + src_pitch * 2;
	
	/* Can we write the results directly? */
	if (is_video_bitmap(dest) || is_planar_bitmap(dest)) {
		//dst_line[0] = malloc(sizeof(char) * sbpp * width);
		//dst_line[1] = malloc(sizeof(char) * sbpp * width);
		dst_line[0] = new unsigned char[sbpp*width];
		dst_line[1] = new unsigned char[sbpp*width];
		v = 1;
	}
	else {
		dst_line[0] = dest->line[0];
		dst_line[1] = dest->line[1];
		v = 0;
	}
	
	/* Set destination */
	bmp_select(dest);

	x = 0, y = 0;
	
	if (PixelsPerMask == 2) {
		unsigned short *sbp;
		sbp = (unsigned short*)src_line[0];
		color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = *(sbp + 1); color[5] = *(sbp + 2);
		sbp = (unsigned short*)src_line[2];
		color[6] = *sbp;     color[7] = color[6];     color[8] = *(sbp + 1); color[9] = *(sbp + 2);
		sbp = (unsigned short*)src_line[3];
		color[10] = *sbp;    color[11] = *(sbp + 1); 
	}
	else {
		unsigned long *lbp;
		lbp = (unsigned long*)src_line[0];
		color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
		color[4] = *(lbp + 1); color[5] = *(lbp + 2);
		lbp = (unsigned long*)src_line[2];
		color[6] = *lbp;     color[7] = color[6];     color[8] = *(lbp + 1); color[9] = *(lbp + 2);
		lbp = (unsigned long*)src_line[3];
		color[10] = *lbp;    color[11] = *(lbp + 1);
	}

	for (y = 0; y < height; y++) {
	
		/* Todo: x = width - 2, x = width - 1 */
		
		for (x = 0; x < width; x++) {
			unsigned long product1a, product1b, product2a, product2b;

//---------------------------------------     B1 B2           0  1
//                                         4  5  6  S2 ->  2  3  4  5
//                                         1  2  3  S1     6  7  8  9
//                                            A1 A2          10 11

			if (color[7] == color[4] && color[3] != color[8]) {
				product1b = product2a = color[7];

				if ((color[6] == color[7]) || (color[4] == color[1]))
					product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3]));
				else
					product1a = INTERPOLATE(color[3], color[4]);

				if ((color[4] == color[5]) || (color[7] == color[10]))
					product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8]));
				else
					product2b = INTERPOLATE(color[7], color[8]);
			}
			else if (color[3] == color[8] && color[7] != color[4]) {
				product2b = product1a = color[3];

				if ((color[0] == color[3]) || (color[5] == color[9]))
					product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4]));
				else
					product1b = INTERPOLATE(color[3], color[1]);

				if ((color[8] == color[11]) || (color[2] == color[3]))
					product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2]));
				else
					product2a = INTERPOLATE(color[7], color[8]);

			}
			else if (color[3] == color[8] && color[7] == color[4]) {
				register int r = 0;

				r += GET_RESULT(color[4], color[3], color[6], color[10]);
				r += GET_RESULT(color[4], color[3], color[2], color[0]);
				r += GET_RESULT(color[4], color[3], color[11], color[9]);
				r += GET_RESULT(color[4], color[3], color[1], color[5]);

				if (r > 0) {
					product1b = product2a = color[7];
					product1a = product2b = INTERPOLATE(color[3], color[4]);
				}
				else if (r < 0) {
					product2b = product1a = color[3];
					product1b = product2a = INTERPOLATE(color[3], color[4]);
				}
				else {
					product2b = product1a = color[3];
					product1b = product2a = color[7];
				}
			}
			else {
				product2b = product1a = INTERPOLATE(color[7], color[4]);
				product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b);
				product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a);

				product2a = product1b = INTERPOLATE(color[3], color[8]);
				product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a);
				product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b);
			}

			if (PixelsPerMask == 2) {
				*((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
				*((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
			}
			else {
				*((unsigned long *) (&dst_line[0][x * 8])) = product1a;
				*((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
				*((unsigned long *) (&dst_line[1][x * 8])) = product2a;
				*((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
			}
			
			/* Move color matrix forward */
			color[0] = color[1]; 
			color[2] = color[3]; color[3] = color[4]; color[4] = color[5];
			color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; 
			color[10] = color[11];
			
			if (x < width - 2) {
				x += 2;
				if (PixelsPerMask == 2) {
					color[1] = *(((unsigned short*)src_line[0]) + x);
					if (x < width) {
						color[5] = *(((unsigned short*)src_line[1]) + x + 1);
						color[9] = *(((unsigned short*)src_line[2]) + x + 1);
					}
					color[11] = *(((unsigned short*)src_line[3]) + x);
				}
				else {
					color[1] = *(((unsigned long*)src_line[0]) + x);
					if (x < width) {
						color[5] = *(((unsigned long*)src_line[1]) + x + 1);
						color[9] = *(((unsigned long*)src_line[2]) + x + 1);
					}
					color[11] = *(((unsigned long*)src_line[3]) + x);
				}
				x -= 2;
			}
		}

		/* We're done with one line, so we shift the source lines up */
		src_line[0] = src_line[1];
		src_line[1] = src_line[2];
		src_line[2] = src_line[3];		

		/* Read next line */
		if (y + 3 >= height)
			src_line[3] = src_line[2];
		else
			src_line[3] = src_line[2] + src_pitch;
			
		/* Then shift the color matrix up */
		if (PixelsPerMask == 2) {
			unsigned short *sbp;
			sbp = (unsigned short*)src_line[0];
			color[0] = *sbp;     color[1] = *(sbp + 1);
			sbp = (unsigned short*)src_line[1];
			color[2] = *sbp;     color[3] = color[2];    color[4] = *(sbp + 1);  color[5] = *(sbp + 2);
			sbp = (unsigned short*)src_line[2];
			color[6] = *sbp;     color[7] = color[6];    color[8] = *(sbp + 1);  color[9] = *(sbp + 2);
			sbp = (unsigned short*)src_line[3];
			color[10] = *sbp;    color[11] = *(sbp + 1);
		}
		else {
			unsigned long *lbp;
			lbp = (unsigned long*)src_line[0];
			color[0] = *lbp;     color[1] = *(lbp + 1);
			lbp = (unsigned long*)src_line[1];
			color[2] = *lbp;     color[3] = color[2];    color[4] = *(lbp + 1);  color[5] = *(lbp + 2);
			lbp = (unsigned long*)src_line[2];
			color[6] = *lbp;     color[7] = color[6];    color[8] = *(lbp + 1);  color[9] = *(lbp + 2);
			lbp = (unsigned long*)src_line[3];
			color[10] = *lbp;    color[11] = *(lbp + 1);
		}


		/* Write the 2 lines, if not already done so */
		if (v) {
			unsigned long dst_addr;
		
			dst_addr = bmp_write_line(dest, y * 2);
			for (j = 0; j < dest->w * sbpp; j += sizeof(long))
				bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j)));
				
			dst_addr = bmp_write_line(dest, y * 2 + 1);
			for (j = 0; j < dest->w * sbpp; j += sizeof(long))
				bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j)));
		}
		else {
			if (y < height - 1) {
				dst_line[0] = dest->line[y * 2 + 2];
				dst_line[1] = dest->line[y * 2 + 3];
			}
		}
	}
	bmp_unwrite_line(dest);
	
	if (v) {
		delete dst_line[0];
		delete dst_line[1];
	}
	delete[] src_line;
	delete[] dst_line;

}