Pixel-doubling blitter

From GDWiki

Jump to: navigation, search
Image:40px-notepad.png To comply with our quality standards, this article may need to be rewritten.
Please help improve this article. The discussion page may contain suggestions.

Here is C-code for pixel-doubling blitter using SDL. Code has been tested with gcc-4.0.3, with flags -Wall -pedantic -ansi -g

void
  pixel_doubling_blit(SDL_Surface* surface)
  {
    register int i, j;
 
    SDL_Surface* screen = SDL_GetVideoSurface();
 
    int bpp = surface->format->BytesPerPixel;
 
    assert(bpp == screen->format->BytesPerPixel);
 
    if (SDL_MUSTLOCK(screen) != 0)
    {
      if (SDL_LockSurface(screen) < 0)
      {
        fprintf(stderr, "screen locking failed\n");
        return;
      }
    }
 
    switch (bpp)
    {
      case 2:
      {
        int tpitch = screen->pitch / 2;
        int spitch = surface->pitch / 2;
         /* :COMMENT: 051223.15: pitch is always in bytes
          * However, incrementing is done in sizeof(Uint16)
          * and sizeof(Uint16) is two bytes. */
 
        Uint16* tp = (Uint16*) screen->pixels;
        Uint16* sp = (Uint16*) surface->pixels;
 
        const int wd = ((screen->w / 2) < (surface->w))
            ? (screen->w / 2) : (surface->w);
 
        const int hg = ((screen->h) < (surface->w))
            ? (screen->h) : (surface->w);
 
        for (j = 0; j < hg; ++j)
        {
          for (i = 0; i < wd; ++i)
          {
            tp[i*2] = sp[i];
            tp[i*2 + 1] = sp[i];
          }
          tp += tpitch;
          if (j % 2 != 0)  sp += spitch;
        }
 
        break;
      }
      case 3:
      {
         /* :COMMENT: 051223.18: This case has only been tested on
          *                      little-endian machine. */
 
        int tpitch = screen->pitch;
        int spitch = surface->pitch;
 
        const int wd = ((screen->w / 2) < (surface->w))
            ? (screen->w / 2) : (surface->w);
 
        const int hg = ((screen->h) < (surface->w))
            ? (screen->h) : (surface->w);
 
        Uint8* tp = (Uint8*) screen->pixels;
        Uint8* sp = (Uint8*) surface->pixels;
 
        for (j = 0; j < hg; ++j)
        {
          for (i = 0; i < 3 * wd; i += 3)
          {
            int i2 = i * 2;
            tp[i2 + 0] = sp[i];
            tp[i2 + 1] = sp[i + 1];
            tp[i2 + 2] = sp[i + 2];
            tp[i2 + 3] = sp[i];
            tp[i2 + 4] = sp[i + 1];
            tp[i2 + 5] = sp[i + 2];
          }
          tp += tpitch;
          if (j % 2 != 0)  sp += spitch;
        }
 
        break;
      }
      case 4:
      {
        int tpitch = screen->pitch / 4;
        int spitch = surface->pitch / 4;
         /* :COMMENT: 051223.15: pitch is always in bytes
          * However, incrementing is done in sizeof(Uint32)
          * and sizeof(Uint32) is four bytes. */
 
        Uint32* tp = (Uint32*) screen->pixels;
        Uint32* sp = (Uint32*) surface->pixels;
 
        const int wd = ((screen->w / 2) < (surface->w))
            ? (screen->w / 2) : (surface->w);
 
        const int hg = ((screen->h) < (surface->w))
            ? (screen->h) : (surface->w);
 
        for (j = 0; j < hg; ++j)
        {
          for (i = 0; i < wd; ++i)
          {
            tp[i*2] = sp[i];
            tp[i*2 + 1] = sp[i];
          }
          tp += tpitch;
          if (j % 2 != 0)  sp += spitch;
        }
 
        break;
      }
      default:
        /* :COMMENT: 051223.17: This should never happen. */
        fprintf(stderr, "Unknown bitdepth.\n");
        break;
    }
 
 
    if (SDL_MUSTLOCK(screen) != 0)
    {
      SDL_UnlockSurface(screen);
    }
  }
Categories