Esempio n. 1
0
static void I_UploadNewPalette(int pal)
{
    // This is used to replace the current 256 colour cmap with a new one
    // Used by 256 colour PseudoColor modes

    // Array of SDL_Color structs used for setting the 256-colour palette
    static SDL_Color* colours;
    static int cachedgamma;
    static size_t num_pals;

    if ((colours == NULL) || (cachedgamma != usegamma)) {
        int pplump = W_GetNumForName("PLAYPAL");
        int gtlump = (W_CheckNumForName)("GAMMATBL",ns_prboom);
        register const byte * palette = W_CacheLumpNum(pplump);
        register const byte * const gtable = (const byte *)W_CacheLumpNum(gtlump) + 256*(cachedgamma = usegamma);
        register int i;

        num_pals = W_LumpLength(pplump) / (3*256);
        num_pals *= 256;

        if (!colours) {
            // First call - allocate and prepare colour array
            colours = malloc(sizeof(SDL_Color)*num_pals);
        }

        // set the colormap entries
        for (i=0 ; (size_t)i<num_pals ; i++) {
            colours[i].r = gtable[palette[0]];
            colours[i].g = gtable[palette[1]];
            colours[i].b = gtable[palette[2]];
            palette += 3;
        }

        W_UnlockLumpNum(pplump);
        W_UnlockLumpNum(gtlump);
        num_pals/=256;
    }
#ifdef RANGECHECK
    if ((size_t)pal >= num_pals) I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)", pal, num_pals);
#endif

    u32 i;
    for(i = 0; i < 256; i++)
    {
        u8 r, g, b;
        r = (u8)colours[i+256*pal].r;
        g = (u8)colours[i+256*pal].g;
        b = (u8)colours[i+256*pal].b;
        BG_PALETTE[i]=RGB8(r,g,b);
    }

}
Esempio n. 2
0
File: i_video.c Progetto: jezze/doom
static void setpalette(int pal)
{

    if (colours == NULL)
    {

        int pplump = W_GetNumForName("PLAYPAL");
        register const byte * palette = W_CacheLumpNum(pplump);
        register int i;

        num_pals = W_LumpLength(pplump) / (3*256);
        num_pals *= 256;

        if (!colours)
            colours = malloc(sizeof(*colours) * num_pals);

        for (i = 0; (size_t)i < num_pals; i++)
        {

            colours[i].r = palette[0];
            colours[i].g = palette[1];
            colours[i].b = palette[2];
            palette += 3;

        }

        W_UnlockLumpNum(pplump);

        num_pals /= 256;

    }

    SDL_SetPalette(surface, SDL_LOGPAL | SDL_PHYSPAL, colours + 256 * pal, 0, 256);

}
Esempio n. 3
0
static int R_DemoEx_GetVersion(void)
{
  int result = -1;

  int lump, ver;
  unsigned int size;
  const char *data;
  char str_ver[32];

  lump = W_CheckNumForName(DEMOEX_VERSION_LUMPNAME);
  if (lump != -1)
  {
    size = W_LumpLength(lump);
    if (size > 0)
    {
      data = W_CacheLumpNum(lump);
      strncpy(str_ver, data, MIN(size, sizeof(str_ver)));

      if (sscanf(str_ver, "%d", &ver) == 1)
      {
        result = ver;
      }
    }
    W_UnlockLumpNum(lump);
  }

  return result;
}
Esempio n. 4
0
//
// P_InitSwitchList()
//
// Only called at game initialization in order to list the set of switches
// and buttons known to the engine. This enables their texture to change
// when activated, and in the case of buttons, change back after a timeout.
//
// This routine modified to read its data from a predefined lump or
// PWAD lump called SWITCHES rather than a static table in this module to
// allow wad designers to insert or modify switches.
//
// Lump format is an array of byte packed switchlist_t structures, terminated
// by a structure with episode == -0. The lump can be generated from a
// text source file using SWANTBLS.EXE, distributed with the BOOM utils.
// The standard list of switches and animations is contained in the example
// source text file DEFSWANI.DAT also in the BOOM util distribution.
//
// Rewritten by Lee Killough to remove limit 2/8/98
//
void P_InitSwitchList(void)
{
  int i, index = 0;
  int episode = (gamemode == registered || gamemode==retail) ?
                 2 : gamemode == commercial ? 3 : 1;
  const switchlist_t *alphSwitchList;         //jff 3/23/98 pointer to switch table
  int lump = W_GetNumForName("SWITCHES"); // cph - new wad lump handling

  //jff 3/23/98 read the switch table from a predefined lump
  alphSwitchList = (const switchlist_t *)W_CacheLumpNum(lump);

  for (i=0;;i++)
  {
    if (index+1 >= max_numswitches)
      switchlist = realloc(switchlist, sizeof *switchlist *
          (max_numswitches = max_numswitches ? max_numswitches*2 : 8));
    if (SHORT(alphSwitchList[i].episode) <= episode) //jff 5/11/98 endianess
    {
      if (!SHORT(alphSwitchList[i].episode))
        break;
      switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name1);
      switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name2);
    }
  }

  numswitches = index/2;
  switchlist[index] = -1;
  W_UnlockLumpNum(lump);
}
Esempio n. 5
0
///////////////////////////////////////////////////////////
// Palette stuff.
//
static void I_UploadNewPalette(int pal)
{
  // This is used to replace the current 256 colour cmap with a new one
  // Used by 256 colour PseudoColor modes

  // Array of XColor structs used for setting the 256-colour palette 
  static XColor* colours;
  static int cachedgamma;
  static size_t num_pals;

  if ((colours == NULL) || (cachedgamma != usegamma)) {
    int            lump = W_GetNumForName("PLAYPAL");
    const byte *palette = W_CacheLumpNum(lump);
    register const byte *const gtable = gammatable[cachedgamma = usegamma];
    register int i;

    num_pals = W_LumpLength(lump) / (3*256);
    num_pals *= 256;

    if (!colours) {
      // First call - allocate and prepare colour array
      colours = malloc(sizeof(*colours)*num_pals);
      for (i=0 ; i<num_pals ; i++) {
	colours[i].pixel = i & 0xff;
	colours[i].flags = DoRed|DoGreen|DoBlue;
      }
    }

    // set the X colormap entries
    for (i=0 ; i<num_pals ; i++) {
      register int c;
      c = gtable[palette[0]];
      colours[i].red = (c<<8) + c;
      c = gtable[palette[1]];
      colours[i].green = (c<<8) + c;
      c = gtable[palette[2]];
      colours[i].blue = (c<<8) + c;
      palette += 3;
    }
  
    W_UnlockLumpNum(lump);
    num_pals/=256;
  }

#ifdef RANGECHECK
  if (pal >= num_pals) 
    I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)", 
	    pal, num_pals);
#endif
  
  // store the colors to the current colormap
  XStoreColors(X_display, X_cmap, colours + 256*pal, 256);

#ifdef HAVE_LIBXXF86DGA
  /* install DGA colormap */
  if(doDga)
     XF86DGAInstallColormap(X_display, X_screen, X_cmap);
#endif

}
Esempio n. 6
0
static void I_UploadNewPalette(int pal)
{
  // This is used to replace the current 256 colour cmap with a new one
  // Used by 256 colour PseudoColor modes

  static int cachedgamma;
  static size_t num_pals;

  if (V_GetMode() == VID_MODEGL)
    return;

  if ((palettes == NULL) || (cachedgamma != usegamma)) {
    int pplump = W_GetNumForName("PLAYPAL");
    int gtlump = (W_CheckNumForName)("GAMMATBL",ns_prboom);
    register const byte * palette = W_CacheLumpNum(pplump);
    register const byte * const gtable = (const byte *)W_CacheLumpNum(gtlump) + 256*(cachedgamma = usegamma);
    register int i;

    num_pals = W_LumpLength(pplump) / (3*256);
    num_pals *= 256;

    if (!palettes) {
      // First call - allocate and prepare colour array
      palettes = malloc(sizeof(*palettes)*num_pals);
    }

    // set the colormap entries
    for (i=0 ; (size_t)i<num_pals ; i++) {
      palettes[i] = (gtable[palette[0]] << 24) + (gtable[palette[1]] << 16) + (gtable[palette[2]] << 8) + 0xff;
      palette += 3;
    }

    W_UnlockLumpNum(pplump);
    W_UnlockLumpNum(gtlump);
    num_pals/=256;
  }

#ifdef RANGECHECK
  if ((size_t)pal >= num_pals)
    I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)",
      pal, num_pals);
#endif

  // store the colors to the current display
  currentPalette = 256 * pal;
}
Esempio n. 7
0
void gld_BindFlat(GLTexture *gltexture, unsigned int flags)
{
  const unsigned char *flat;
  unsigned char *buffer;
  int w, h;

  if (!gltexture || gltexture->textype != GLDT_FLAT)
  {
    qglBindTexture(GL_TEXTURE_2D, 0);
    last_glTexID = NULL;
    return;
  }

#ifdef HAVE_LIBSDL_IMAGE
  if (gld_LoadHiresTex(gltexture, CR_DEFAULT))
  {
    gld_SetTexClamp(gltexture, flags);
    last_glTexID = gltexture->texid_p;
    return;
  }
#endif

  gld_GetTextureTexID(gltexture, CR_DEFAULT); 

  if (last_glTexID == gltexture->texid_p)
  {
    gld_SetTexClamp(gltexture, flags);
    return;
  }

  last_glTexID = gltexture->texid_p;

  if (*gltexture->texid_p != 0)
  {
    qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);
    gld_SetTexClamp(gltexture, flags);
    return;
  }

  flat=W_CacheLumpNum(gltexture->index);
  buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
  if (!(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture)
    memset(buffer,transparent_pal_index,gltexture->buffer_size);
  else
    memset(buffer,0,gltexture->buffer_size);
  gld_AddFlatToTexture(gltexture, buffer, flat, !(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture);
  if (*gltexture->texid_p == 0)
    qglGenTextures(1, gltexture->texid_p);
  qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);

  buffer = gld_HQResize(gltexture, buffer, gltexture->buffer_width, gltexture->buffer_height, &w, &h);

  gld_BuildTexture(gltexture, buffer, false, w, h);

  gld_SetTexClamp(gltexture, flags);

  W_UnlockLumpNum(gltexture->index);
}
Esempio n. 8
0
void F_TextWrite (void)
{
  {
    // erase the entire screen to a tiled background
    const byte *src; // cph - const
    int         x,y;
    int         lump;
    
    // killough 4/17/98: 
    src = W_CacheLumpNum(lump = firstflat + R_FlatNumForName(finaleflat));
    
    V_DrawBlock(0, 0, 0, 64, 64, src, 0);
    
    for (y=0 ; y<SCREENHEIGHT ; y+=64)
      for (x=y ? 0 : 64; x<SCREENWIDTH ; x+=64)
	V_CopyRect(0, 0, 0, ((SCREENWIDTH-x) < 64) ? (SCREENWIDTH-x) : 64, 
		   ((SCREENHEIGHT-y) < 64) ? (SCREENHEIGHT-y) : 64, x, y, 0);
    W_UnlockLumpNum(lump);
  }
  V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  { // draw some of the text onto the screen
    int         cx = 10;
    int         cy = 10;
    const char* ch = finaletext; // CPhipps - const
    int         count = (finalecount - 10)/Get_TextSpeed();                 // phares
    int         w;
    
    if (count < 0)
      count = 0;
    
    for ( ; count ; count-- ) {
      int       c = *ch++;
      
      if (!c)
	break;
      if (c == '\n') {
	cx = 10;
	cy += 11;
	continue;
      }
              
      c = toupper(c) - HU_FONTSTART;
      if (c < 0 || c> HU_FONTSIZE) {
	cx += 4;
	continue;
      }
      
      w = SHORT (hu_font[c]->width);
      if (cx+w > SCREENWIDTH)
	break;
      // CPhipps - patch drawing updated
      V_DrawMemPatch(cx, cy, 0, hu_font[c], NULL, VPT_STRETCH);
      cx+=w;
    }
  }
}
Esempio n. 9
0
void R_DemoEx_ShowComment(void)
{
  extern patchnum_t hu_font[];

  int         lump;
  int         cx = 10;
  int         cy = 10;
  const char* ch;
  int         count;
  int         w;

  if (!use_demoex_info)
    return;

  lump = W_CheckNumForName(DEMOEX_COMMENT_LUMPNAME);
  if (lump == -1)
    return;

  count = W_LumpLength(lump);

  if (count <= 0)
    return;

  ch = W_CacheLumpNum(lump);

  for ( ; count ; count-- )
  {
    int c = *ch++;

    if (!c)
      break;
    if (c == '\n')
    {
      cx = 10;
      cy += 11;
      continue;
    }

    c = toupper(c) - HU_FONTSTART;
    if (c < 0 || c> HU_FONTSIZE)
    {
      cx += 4;
      continue;
    }

    w = hu_font[c].width;
    if (cx + w > SCREENWIDTH)
      break;

    V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH);
    cx += w;
  }

  W_UnlockLumpNum(lump);
}
Esempio n. 10
0
//
// I_SetPalette
//
void I_SetPalette (int pal)
{
  if (!INITIALISED) return;
  if (true_color) {
    int            lump = W_GetNumForName("PLAYPAL");
    const byte *palette = W_CacheLumpNum(lump);
    I_SetPaletteTranslation(palette + (3*256)*pal);
    W_UnlockLumpNum(lump);
  } else
    I_UploadNewPalette(pal);
}
Esempio n. 11
0
static int ReadLump(const char *filename, const char *lumpname, unsigned char **buffer)
{
  FILE *file = NULL;
  int size = 0;
  const unsigned char *data;
  int lump;

  file = fopen(filename, "r");
  if (file)
  {
    fseek(file, 0, SEEK_END);
    size = ftell(file);
    fseek(file, 0, SEEK_SET);
    *buffer = malloc(size + 1);
    size = fread(*buffer, 1, size, file);
    if (size > 0)
    {
      (*buffer)[size] = 0;
    }
    fclose(file);
  }
  else
  {
    char name[9];
    char* p;

    strncpy(name, lumpname, 9);
    name[8] = 0;
    for(p = name; *p; p++)
      *p = toupper(*p);

    lump = (W_CheckNumForName)(name, ns_prboom);

    if (lump != -1)
    {
      size = W_LumpLength(lump);
      data = W_CacheLumpNum(lump);
      *buffer = calloc(1, size + 1);
      memcpy (*buffer, data, size);
      (*buffer)[size] = 0;
      W_UnlockLumpNum(lump);
    }
  }

  return size;
}
Esempio n. 12
0
static dboolean CheckIfPatch(int lump)
{
  int size;
  int width, height;
  const patch_t * patch;
  dboolean result;

  size = W_LumpLength(lump);
  
  // minimum length of a valid Doom patch
  if (size < 13)
    return false;

  patch = (const patch_t *)W_CacheLumpNum(lump);

  width = LittleShort(patch->width);
  height = LittleShort(patch->height);

  result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < size / 4);

  if (result)
  {
    // The dimensions seem like they might be valid for a patch, so
    // check the column directory for extra security. All columns 
    // must begin after the column directory, and none of them must
    // point past the end of the patch.
    int x;

    for (x = 0; x < width; x++)
    {
      unsigned int ofs = LittleLong(patch->columnofs[x]);

      // Need one byte for an empty column (but there's patches that don't know that!)
      if (ofs < (unsigned int)width * 4 + 8 || ofs >= (unsigned int)size)
      {
        result = false;
        break;
      }
    }
  }

  W_UnlockLumpNum(lump);
  return result;
}
Esempio n. 13
0
//
// P_InitSwitchList()
//
// Only called at game initialization in order to list the set of switches
// and buttons known to the engine. This enables their texture to change
// when activated, and in the case of buttons, change back after a timeout.
//
// This routine modified to read its data from a predefined lump or
// PWAD lump called SWITCHES rather than a static table in this module to
// allow wad designers to insert or modify switches.
//
// Lump format is an array of byte packed switchlist_t structures, terminated
// by a structure with episode == -0. The lump can be generated from a
// text source file using SWANTBLS.EXE, distributed with the BOOM utils.
// The standard list of switches and animations is contained in the example
// source text file DEFSWANI.DAT also in the BOOM util distribution.
//
// Rewritten by Lee Killough to remove limit 2/8/98
//
void P_InitSwitchList(void)
{
  int i, index = 0;
  int episode = (gamemode == registered || gamemode==retail) ?
                 2 : gamemode == commercial ? 3 : 1;
  const switchlist_t *alphSwitchList;         //jff 3/23/98 pointer to switch table
  int lump = W_GetNumForName("SWITCHES"); // cph - new wad lump handling

  //jff 3/23/98 read the switch table from a predefined lump
  alphSwitchList = (const switchlist_t *)W_CacheLumpNum(lump);

  for (i=0;;i++)
  {
    if (index+1 >= max_numswitches)
      switchlist = realloc(switchlist, sizeof *switchlist *
          (max_numswitches = max_numswitches ? max_numswitches*2 : 8));
    if (SHORT(alphSwitchList[i].episode) <= episode) //jff 5/11/98 endianess
    {
      int texture1, texture2;

      if (!SHORT(alphSwitchList[i].episode))
        break;

      // Ignore switches referencing unknown texture names, instead of exiting.
      // Warn if either one is missing, but only add if both are valid.
      texture1 = R_CheckTextureNumForName(alphSwitchList[i].name1);
      if (texture1 == -1)
        lprintf(LO_WARN, "P_InitSwitchList: unknown texture %s\n",
            alphSwitchList[i].name1);
      texture2 = R_CheckTextureNumForName(alphSwitchList[i].name2);
      if (texture2 == -1)
        lprintf(LO_WARN, "P_InitSwitchList: unknown texture %s\n",
            alphSwitchList[i].name2);
      if (texture1 != -1 && texture2 != -1) {
        switchlist[index++] = texture1;
        switchlist[index++] = texture2;
      }
    }
  }

  numswitches = index/2;
  switchlist[index] = -1;
  W_UnlockLumpNum(lump);
}
Esempio n. 14
0
void S_StopMusic(void)
{
	//jff 1/22/98 return if music is not enabled
	if (!mus_card || nomusicparm)
		return;

	if (mus_playing)
	{
		//if (mus_paused)
		//	I_ResumeSong(mus_playing->handle);

		mus_stop_music();
		if (mus_playing->lumpnum >= 0)
			W_UnlockLumpNum(mus_playing->lumpnum); // cph - release the music data

		mus_playing->data = 0;
		mus_playing = 0;
	}
}
Esempio n. 15
0
File: g_save.c Progetto: AlexMax/d2k
static uint_64_t G_UpdateSignature(uint_64_t s, const char *name) {
  int i;
  int lump = W_CheckNumForName(name);

  if (lump != -1 && (i = lump + 10) < numlumps) {
    do {
      int size = W_LumpLength(i);
      const byte *p = W_CacheLumpNum(i);

      while (size--) {
        s <<= 1;
        s += *p++;
      }

      W_UnlockLumpNum(i);
    } while (--i > lump);
  }
  return s;
}
Esempio n. 16
0
//---------------------------------------------------------------------------
static void createTextureCompositePatch(int id) {
  rpatch_t *composite_patch;
  texture_t *texture;
  texpatch_t *texpatch;
  int patchNum;
  const patch_t *oldPatch;
  const column_t *oldColumn, *oldPrevColumn, *oldNextColumn;
  int i, x, y;
  int oy, count;
  int pixelDataSize;
  int columnsDataSize;
  int postsDataSize;
  int dataSize;
  int numPostsTotal;
  const unsigned char *oldColumnPixelData;
  int numPostsUsedSoFar;
  int edgeSlope;
  count_t *countsInColumn;

#ifdef RANGECHECK
  if (id >= numtextures)
    I_Error("createTextureCompositePatch: %i >= numtextures", id);
#endif

  composite_patch = &texture_composites[id];

  texture = textures[id];

  composite_patch->width = texture->width;
  composite_patch->height = texture->height;
  composite_patch->widthmask = texture->widthmask;
  composite_patch->leftoffset = 0;
  composite_patch->topoffset = 0;
  composite_patch->isNotTileable = 0;

  // work out how much memory we need to allocate for this patch's data
  pixelDataSize = (composite_patch->width * composite_patch->height + 4) & ~3;
  columnsDataSize = sizeof(rcolumn_t) * composite_patch->width;

  // count the number of posts in each column
  countsInColumn = (count_t *)calloc(sizeof(count_t), composite_patch->width);
  numPostsTotal = 0;

  for (i=0; i<texture->patchcount; i++) {
    texpatch = &texture->patches[i];
    patchNum = texpatch->patch;
    oldPatch = (const patch_t*)W_CacheLumpNum(patchNum);

    for (x=0; x<SHORT(oldPatch->width); x++) {
      int tx = texpatch->originx + x;

      if (tx < 0)
        continue;
      if (tx >= composite_patch->width)
        break;

      countsInColumn[tx].patches++;

      oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));
      while (oldColumn->topdelta != 0xff) {
        countsInColumn[tx].posts++;
        numPostsTotal++;
        oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
      }
    }

    W_UnlockLumpNum(patchNum);
  }

  postsDataSize = numPostsTotal * sizeof(rpost_t);

  // allocate our data chunk
  dataSize = pixelDataSize + columnsDataSize + postsDataSize;
  composite_patch->data = (unsigned char*)Z_Malloc(dataSize, PU_STATIC, (void **)&composite_patch->data);
  memset(composite_patch->data, 0, dataSize);

  // set out pixel, column, and post pointers into our data array
  composite_patch->pixels = composite_patch->data;
  composite_patch->columns = (rcolumn_t*)((unsigned char*)composite_patch->pixels + pixelDataSize);
  composite_patch->posts = (rpost_t*)((unsigned char*)composite_patch->columns + columnsDataSize);

  // sanity check that we've got all the memory allocated we need
  assert((((byte*)composite_patch->posts + numPostsTotal*sizeof(rpost_t)) - (byte*)composite_patch->data) == dataSize);

  memset(composite_patch->pixels, 0xff, (composite_patch->width*composite_patch->height));

  numPostsUsedSoFar = 0;

  for (x=0; x<texture->width; x++) {
      // setup the column's data
      composite_patch->columns[x].pixels = composite_patch->pixels + (x*composite_patch->height);
      composite_patch->columns[x].numPosts = countsInColumn[x].posts;
      composite_patch->columns[x].posts = composite_patch->posts + numPostsUsedSoFar;
      numPostsUsedSoFar += countsInColumn[x].posts;
  }

  // fill in the pixels, posts, and columns
  for (i=0; i<texture->patchcount; i++) {
    texpatch = &texture->patches[i];
    patchNum = texpatch->patch;
    oldPatch = (const patch_t*)W_CacheLumpNum(patchNum);

    for (x=0; x<SHORT(oldPatch->width); x++) {
      int tx = texpatch->originx + x;

      if (tx < 0)
        continue;
      if (tx >= composite_patch->width)
        break;

      oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));

      {
        // tiling
        int prevColumnIndex = x-1;
        int nextColumnIndex = x+1;
        while (prevColumnIndex < 0) prevColumnIndex += SHORT(oldPatch->width);
        while (nextColumnIndex >= SHORT(oldPatch->width)) nextColumnIndex -= SHORT(oldPatch->width);
        oldPrevColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[prevColumnIndex]));
        oldNextColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[nextColumnIndex]));
      }

      while (oldColumn->topdelta != 0xff) {
        rpost_t *post = &composite_patch->columns[tx].posts[countsInColumn[tx].posts_used];
        oldColumnPixelData = (const byte *)oldColumn + 3;
        oy = texpatch->originy;
        count = oldColumn->length;
        // the original renderer had several bugs which we reproduce here
        if (countsInColumn[tx].patches > 1) {
          // when there are multiple patches, then we need to handle the
          // column differently
          if (i == 0) {
            // draw first patch at original position, it will be partly
            // overdrawn below
            for (y=0; y<count; y++) {
              int ty = oy + oldColumn->topdelta + y;
              if (ty < 0)
                continue;
              if (ty >= composite_patch->height)
                break;
              composite_patch->pixels[tx * composite_patch->height + ty] = oldColumnPixelData[y];
            }
          }
          // do the buggy clipping
          if ((oy + oldColumn->topdelta) < 0) {
            count += oy;
            oy = 0;
          }
        } else {
          // with a single patch only negative y origins are wrong
          oy = 0;
        }
        // set up the post's data
        post->topdelta = oldColumn->topdelta + oy;
        post->length = count;
        if ((post->topdelta + post->length) > composite_patch->height) {
          if (post->topdelta > composite_patch->height)
            post->length = 0;
          else
            post->length = composite_patch->height - post->topdelta;
        }
        if (post->topdelta < 0) {
          if ((post->topdelta + post->length) <= 0)
            post->length = 0;
          else
            post->length -= post->topdelta;
          post->topdelta = 0;
        }
        post->slope = 0;

        edgeSlope = getColumnEdgeSlope(oldPrevColumn, oldNextColumn, oldColumn->topdelta);
        if (edgeSlope == 1) post->slope |= RDRAW_EDGESLOPE_TOP_UP;
        else if (edgeSlope == -1) post->slope |= RDRAW_EDGESLOPE_TOP_DOWN;

        edgeSlope = getColumnEdgeSlope(oldPrevColumn, oldNextColumn, oldColumn->topdelta+count);
        if (edgeSlope == 1) post->slope |= RDRAW_EDGESLOPE_BOT_UP;
        else if (edgeSlope == -1) post->slope |= RDRAW_EDGESLOPE_BOT_DOWN;

        // fill in the post's pixels
        for (y=0; y<count; y++) {
          int ty = oy + oldColumn->topdelta + y;
          if (ty < 0)
            continue;
          if (ty >= composite_patch->height)
            break;
          composite_patch->pixels[tx * composite_patch->height + ty] = oldColumnPixelData[y];
        }

        oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
        countsInColumn[tx].posts_used++;
        assert(countsInColumn[tx].posts_used <= countsInColumn[tx].posts);
      }
    }

    W_UnlockLumpNum(patchNum);
  }

  for (x=0; x<texture->width; x++) {
    rcolumn_t *column;

    if (countsInColumn[x].patches <= 1)
      continue;

    // cleanup posts on multipatch columns
    column = &composite_patch->columns[x];

    i = 0;
    while (i<(column->numPosts-1)) {
      rpost_t *post1 = &column->posts[i];
      rpost_t *post2 = &column->posts[i+1];
      int length;

      if ((post2->topdelta - post1->topdelta) < 0)
        switchPosts(post1, post2);

      if ((post1->topdelta + post1->length) >= post2->topdelta) {
        length = (post1->length + post2->length) - ((post1->topdelta + post1->length) - post2->topdelta);
        if (post1->length < length) {
          post1->slope = post2->slope;
          post1->length = length;
        }
        removePostFromColumn(column, i+1);
        i = 0;
        continue;
      }
      i++;
    }
  }

  if (1 || composite_patch->isNotTileable) {
    const rcolumn_t *column, *prevColumn;

    // copy the patch image down and to the right where there are
    // holes to eliminate the black halo from bilinear filtering
    for (x=0; x<composite_patch->width; x++) {
      //oldColumn = (const column_t *)((const byte *)oldPatch + oldPatch->columnofs[x]);

      column = R_GetPatchColumnClamped(composite_patch, x);
      prevColumn = R_GetPatchColumnClamped(composite_patch, x-1);

      if (column->pixels[0] == 0xff) {
        // force the first pixel (which is a hole), to use
        // the color from the next solid spot in the column
        for (y=0; y<composite_patch->height; y++) {
          if (column->pixels[y] != 0xff) {
            column->pixels[0] = column->pixels[y];
            break;
          }
        }
      }

      // copy from above or to the left
      for (y=1; y<composite_patch->height; y++) {
        //if (getIsSolidAtSpot(oldColumn, y)) continue;
        if (column->pixels[y] != 0xff) continue;

        // this pixel is a hole

        if (x && prevColumn->pixels[y-1] != 0xff) {
          // copy the color from the left
          column->pixels[y] = prevColumn->pixels[y];
        }
        else {
          // copy the color from above
          column->pixels[y] = column->pixels[y-1];
        }
      }
    }

    // verify that the patch truly is non-rectangular since
    // this determines tiling later on
  }

  free(countsInColumn);
}
Esempio n. 17
0
//---------------------------------------------------------------------------
static void createPatch(int id) {
  rpatch_t *patch;
  const int patchNum = id;
  const patch_t *oldPatch = (const patch_t*)W_CacheLumpNum(patchNum);
  const column_t *oldColumn, *oldPrevColumn, *oldNextColumn;
  int x, y;
  int pixelDataSize;
  int columnsDataSize;
  int postsDataSize;
  int dataSize;
  int *numPostsInColumn;
  int numPostsTotal;
  const unsigned char *oldColumnPixelData;
  int numPostsUsedSoFar;
  int edgeSlope;

#ifdef RANGECHECK
  if (id >= numlumps)
    I_Error("createPatch: %i >= numlumps", id);
#endif

  patch = &patches[id];
  // proff - 2003-02-16 What about endianess?
  patch->width = SHORT(oldPatch->width);
  patch->widthmask = 0;
  patch->height = SHORT(oldPatch->height);
  patch->leftoffset = SHORT(oldPatch->leftoffset);
  patch->topoffset = SHORT(oldPatch->topoffset);
  patch->isNotTileable = getPatchIsNotTileable(oldPatch);

  // work out how much memory we need to allocate for this patch's data
  pixelDataSize = (patch->width * patch->height + 4) & ~3;
  columnsDataSize = sizeof(rcolumn_t) * patch->width;

  // count the number of posts in each column
  numPostsInColumn = (int*)malloc(sizeof(int) * patch->width);
  numPostsTotal = 0;

  for (x=0; x<patch->width; x++) {
    oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));
    numPostsInColumn[x] = 0;
    while (oldColumn->topdelta != 0xff) {
      numPostsInColumn[x]++;
      numPostsTotal++;
      oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
    }
  }

  postsDataSize = numPostsTotal * sizeof(rpost_t);

  // allocate our data chunk
  dataSize = pixelDataSize + columnsDataSize + postsDataSize;
  patch->data = (unsigned char*)Z_Malloc(dataSize, PU_CACHE, (void **)&patch->data);
  memset(patch->data, 0, dataSize);

  // set out pixel, column, and post pointers into our data array
  patch->pixels = patch->data;
  patch->columns = (rcolumn_t*)((unsigned char*)patch->pixels + pixelDataSize);
  patch->posts = (rpost_t*)((unsigned char*)patch->columns + columnsDataSize);

  // sanity check that we've got all the memory allocated we need
  assert((((byte*)patch->posts  + numPostsTotal*sizeof(rpost_t)) - (byte*)patch->data) == dataSize);

  memset(patch->pixels, 0xff, (patch->width*patch->height));

  // fill in the pixels, posts, and columns
  numPostsUsedSoFar = 0;
  for (x=0; x<patch->width; x++) {

    oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));

    if (patch->isNotTileable) {
      // non-tiling
      if (x == 0) oldPrevColumn = 0;
      else oldPrevColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x-1]));
      if (x == patch->width-1) oldNextColumn = 0;
      else oldNextColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x+1]));
    }
    else {
      // tiling
      int prevColumnIndex = x-1;
      int nextColumnIndex = x+1;
      while (prevColumnIndex < 0) prevColumnIndex += patch->width;
      while (nextColumnIndex >= patch->width) nextColumnIndex -= patch->width;
      oldPrevColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[prevColumnIndex]));
      oldNextColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[nextColumnIndex]));
    }

    // setup the column's data
    patch->columns[x].pixels = patch->pixels + (x*patch->height) + 0;
    patch->columns[x].numPosts = numPostsInColumn[x];
    patch->columns[x].posts = patch->posts + numPostsUsedSoFar;

    while (oldColumn->topdelta != 0xff) {
      // set up the post's data
      patch->posts[numPostsUsedSoFar].topdelta = oldColumn->topdelta;
      patch->posts[numPostsUsedSoFar].length = oldColumn->length;
      patch->posts[numPostsUsedSoFar].slope = 0;

      edgeSlope = getColumnEdgeSlope(oldPrevColumn, oldNextColumn, oldColumn->topdelta);
      if (edgeSlope == 1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_TOP_UP;
      else if (edgeSlope == -1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_TOP_DOWN;

      edgeSlope = getColumnEdgeSlope(oldPrevColumn, oldNextColumn, oldColumn->topdelta+oldColumn->length);
      if (edgeSlope == 1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_BOT_UP;
      else if (edgeSlope == -1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_BOT_DOWN;

      // fill in the post's pixels
      oldColumnPixelData = (const byte *)oldColumn + 3;
      for (y=0; y<oldColumn->length; y++) {
        patch->pixels[x * patch->height + oldColumn->topdelta + y] = oldColumnPixelData[y];
      }

      oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
      numPostsUsedSoFar++;
    }
  }

  if (1 || patch->isNotTileable) {
    const rcolumn_t *column, *prevColumn;

    // copy the patch image down and to the right where there are
    // holes to eliminate the black halo from bilinear filtering
    for (x=0; x<patch->width; x++) {
      //oldColumn = (const column_t *)((const byte *)oldPatch + oldPatch->columnofs[x]);

      column = R_GetPatchColumnClamped(patch, x);
      prevColumn = R_GetPatchColumnClamped(patch, x-1);

      if (column->pixels[0] == 0xff) {
        // force the first pixel (which is a hole), to use
        // the color from the next solid spot in the column
        for (y=0; y<patch->height; y++) {
          if (column->pixels[y] != 0xff) {
            column->pixels[0] = column->pixels[y];
            break;
          }
        }
      }

      // copy from above or to the left
      for (y=1; y<patch->height; y++) {
        //if (getIsSolidAtSpot(oldColumn, y)) continue;
        if (column->pixels[y] != 0xff) continue;

        // this pixel is a hole

        if (x && prevColumn->pixels[y-1] != 0xff) {
          // copy the color from the left
          column->pixels[y] = prevColumn->pixels[y];
        }
        else {
          // copy the color from above
          column->pixels[y] = column->pixels[y-1];
        }
      }
    }

    // verify that the patch truly is non-rectangular since
    // this determines tiling later on
  }

  W_UnlockLumpNum(patchNum);
  free(numPostsInColumn);
}
Esempio n. 18
0
void D_Display (void)
{
   static boolean isborderstate        IDATA_ATTR= false;
   static boolean borderwillneedredraw IDATA_ATTR= false;
   static  gamestate_t  oldgamestate IDATA_ATTR= -1;
   boolean wipe;
   boolean viewactive = false, isborder = false;

   if (nodrawers)                   // for comparative timing / profiling
      return; 

   // save the current screen if about to wipe
   if ((wipe = gamestate != wipegamestate))
      wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);

   if (gamestate != GS_LEVEL) { // Not a level
      switch (oldgamestate) {
      case (gamestate_t)-1:
      case GS_LEVEL:
         V_SetPalette(0); // cph - use default (basic) palette
      default:
         break;
      }

      switch (gamestate) {
      case GS_INTERMISSION:
         WI_Drawer();
         break;
      case GS_FINALE:
         F_Drawer();
         break;
      case GS_DEMOSCREEN:
         D_PageDrawer();
         break;
      default:
         break;
      }
   } else if (gametic != basetic) { // In a level
      boolean redrawborderstuff;

      HU_Erase();

      if (setsizeneeded) {               // change the view size if needed
         R_ExecuteSetViewSize();
         oldgamestate = -1;            // force background redraw
      }

      // Work out if the player view is visible, and if there is a border
      viewactive = (!(automapmode & am_active) || (automapmode & am_overlay)) && !inhelpscreens;
      isborder = viewactive ? (viewheight != SCREENHEIGHT) : (!inhelpscreens && (automapmode & am_active));

      if (oldgamestate != GS_LEVEL) {
         R_FillBackScreen ();    // draw the pattern into the back screen
         redrawborderstuff = isborder;
      } else {
         // CPhipps -
         // If there is a border, and either there was no border last time,
         // or the border might need refreshing, then redraw it.
         redrawborderstuff = isborder && (!isborderstate || borderwillneedredraw);
         // The border may need redrawing next time if the border surrounds the screen,
         // and there is a menu being displayed
         borderwillneedredraw = menuactive && isborder && viewactive && (viewwidth != SCREENWIDTH);
      }

      if (redrawborderstuff)
         R_DrawViewBorder();

      // Now do the drawing
      if (viewactive)
         R_RenderPlayerView (&players[displayplayer]);
      if (automapmode & am_active)
         AM_Drawer();
      ST_Drawer((viewheight != SCREENHEIGHT) || ((automapmode & am_active) && !(automapmode & am_overlay)), redrawborderstuff);
      R_DrawViewBorder();

      HU_Drawer();
   }

   isborderstate      = isborder;
   oldgamestate = wipegamestate = gamestate;

   // draw pause pic
   if (paused) {
      static int x;

      if (!x) { // Cache results of x pos calc
         int lump = W_GetNumForName("M_PAUSE");
         const patch_t* p = W_CacheLumpNum(lump);
         x = (320 - SHORT(p->width))/2;
         W_UnlockLumpNum(lump);
      }

      // CPhipps - updated for new patch drawing
      V_DrawNamePatch(x, (!(automapmode & am_active) || (automapmode & am_overlay))
                      ? 4+(viewwindowy*200/SCREENHEIGHT) : 4, // cph - Must un-stretch viewwindowy
                      0, "M_PAUSE", CR_DEFAULT, VPT_STRETCH);
   }

   // menus go directly to the screen
   M_Drawer();          // menu is drawn even on top of everything
   D_BuildNewTiccmds();

   // normal update
   if (!wipe)
      I_FinishUpdate ();              // page flip or blit buffer
   else {
      // wipe update
      wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
      D_Wipe();
   }
}
Esempio n. 19
0
void gld_BindFlat(GLTexture *gltexture)
{
  const unsigned char *flat;
  int i;
  unsigned char *buffer;

  if (gltexture==last_gltexture)
    return;
  last_gltexture=gltexture;
  if (!gltexture)
    return;
  if (gltexture->textype!=GLDT_FLAT)
  {
    glBindTexture(GL_TEXTURE_2D, 0);
    last_gltexture = NULL;
    last_cm = -1;
    return;
  }
  if (gltexture->glTexID[CR_DEFAULT]!=0)
  {
    glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]);
    glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_RESIDENT,&i);
#ifdef _DEBUG
    if (i!=GL_TRUE)
      lprintf(LO_INFO, "glGetTexParam: %i\n", i);
#endif
    if (i==GL_TRUE)
      return;
  }
  flat=W_CacheLumpNum(gltexture->index);
  buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
  if (!(gltexture->mipmap & use_mipmapping) & gl_paletted_texture)
    memset(buffer,transparent_pal_index,gltexture->buffer_size);
  else
    memset(buffer,0,gltexture->buffer_size);
  gld_AddFlatToTexture(gltexture, buffer, flat, !(gltexture->mipmap & use_mipmapping) & gl_paletted_texture);

 if (gltexture->glTexID[CR_DEFAULT]==0)
   glGenTextures(1,&gltexture->glTexID[CR_DEFAULT]);

  glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]);
#ifdef USE_GLU_MIPMAP
  if (gltexture->mipmap & use_mipmapping)
  {
    gluBuild2DMipmaps(GL_TEXTURE_2D, gl_tex_format,
                      gltexture->buffer_width, gltexture->buffer_height,
                      GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_mipmap_filter);
    if (gl_texture_filter_anisotropic)
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0);
  }
  else
#endif /* USE_GLU_MIPMAP */
  {
#ifdef USE_GLU_IMAGESCALE
    if ((gltexture->buffer_width!=gltexture->tex_width) ||
        (gltexture->buffer_height!=gltexture->tex_height)
       )
    {
      unsigned char *scaledbuffer;

      scaledbuffer=(unsigned char*)Z_Malloc(gltexture->tex_width*gltexture->tex_height*4,PU_STATIC,0);
      if (scaledbuffer)
      {
        gluScaleImage(GL_RGBA,
                      gltexture->buffer_width, gltexture->buffer_height,
                      GL_UNSIGNED_BYTE,buffer,
                      gltexture->tex_width, gltexture->tex_height,
                      GL_UNSIGNED_BYTE,scaledbuffer);
        Z_Free(buffer);
        buffer=scaledbuffer;
        glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
                      gltexture->tex_width, gltexture->tex_height,
                      0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
      }
    }
    else
#endif /* USE_GLU_IMAGESCALE */
    {
      if (gl_paletted_texture) {
		I_Error("Paletted textures not supported");
		/*
        gld_SetTexturePalette(GL_TEXTURE_2D);
        glTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT,
                      gltexture->buffer_width, gltexture->buffer_height,
                      0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buffer); */
      } else {
        glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
                      gltexture->buffer_width, gltexture->buffer_height,
                      0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
      }
    }
	// Vladimir i -> x
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter);
  }
  Z_Free(buffer);
  W_UnlockLumpNum(gltexture->index);
}
Esempio n. 20
0
File: r_data.c Progetto: AlexMax/d2k
static void R_InitTextures (void)
{
  const maptexture_t *mtexture;
  texture_t    *texture;
  const mappatch_t   *mpatch;
  texpatch_t   *patch;
  int  i, j;
  int         maptex_lump[2] = {-1, -1};
  const int  *maptex;
  const int  *maptex1, *maptex2;
  char name[9];
  int names_lump; // cph - new wad lump handling
  const char *names; // cph -
  const char *name_p;// const*'s
  int  *patchlookup;
  int  nummappatches;
  int  offset;
  int  maxoff, maxoff2;
  int  numtextures1, numtextures2;
  const int *directory;
  int  errors = 0;

  // Load the patch names from pnames.lmp.
  name[8] = 0;
  names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES"));
  nummappatches = LittleLong(*((const int *)names));
  name_p = names+4;
  patchlookup = malloc(nummappatches*sizeof(*patchlookup));  // killough

  for (i=0 ; i<nummappatches ; i++)
    {
      strncpy (name,name_p+i*8, 8);
      patchlookup[i] = W_CheckNumForName(name);
      if (patchlookup[i] == -1)
        {
          // killough 4/17/98:
          // Some wads use sprites as wall patches, so repeat check and
          // look for sprites this time, but only if there were no wall
          // patches found. This is the same as allowing for both, except
          // that wall patches always win over sprites, even when they
          // appear first in a wad. This is a kludgy solution to the wad
          // lump namespace problem.

          patchlookup[i] = (W_CheckNumForName)(name, ns_sprites);

          if (patchlookup[i] == -1 && devparm)
            //jff 8/3/98 use logical output routine
            lprintf(LO_WARN,"\nWarning: patch %.8s, index %d does not exist",name,i);
        }
    }
  W_UnlockLumpNum(names_lump); // cph - release the lump

  // Load the map texture definitions from textures.lmp.
  // The data is contained in one or two lumps,
  //  TEXTURE1 for shareware, plus TEXTURE2 for commercial.

  maptex = maptex1 = W_CacheLumpNum(maptex_lump[0] = W_GetNumForName("TEXTURE1"));
  numtextures1 = LittleLong(*maptex);
  maxoff = W_LumpLength(maptex_lump[0]);
  directory = maptex+1;

  if (W_CheckNumForName("TEXTURE2") != -1)
    {
      maptex2 = W_CacheLumpNum(maptex_lump[1] = W_GetNumForName("TEXTURE2"));
      numtextures2 = LittleLong(*maptex2);
      maxoff2 = W_LumpLength(maptex_lump[1]);
    }
  else
    {
      maptex2 = NULL;
      numtextures2 = 0;
      maxoff2 = 0;
    }
  numtextures = numtextures1 + numtextures2;

  // killough 4/9/98: make column offsets 32-bit;
  // clean up malloc-ing to use sizeof

  textures = Z_Malloc(numtextures*sizeof*textures, PU_STATIC, 0);
  textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0);

  for (i=0 ; i<numtextures ; i++, directory++)
    {
      if (i == numtextures1)
        {
          // Start looking in second texture file.
          maptex = maptex2;
          maxoff = maxoff2;
          directory = maptex+1;
        }

      offset = LittleLong(*directory);

      if (offset > maxoff)
        I_Error("R_InitTextures: Bad texture directory");

      mtexture = (const maptexture_t *) ( (const byte *)maptex + offset);

      texture = textures[i] =
        Z_Malloc(sizeof(texture_t) +
                 sizeof(texpatch_t)*(LittleShort(mtexture->patchcount)-1),
                 PU_STATIC, 0);

      texture->width = LittleShort(mtexture->width);
      texture->height = LittleShort(mtexture->height);
      texture->patchcount = LittleShort(mtexture->patchcount);

        /* Mattias Engdegård emailed me of the following explenation of
         * why memcpy doesnt work on some systems:
         * "I suppose it is the mad unaligned allocation
         * going on (and which gcc in some way manages to cope with
         * through the __attribute__ ((packed))), and which it forgets
         * when optimizing memcpy (to a single word move) since it appears
         * to be aligned. Technically a gcc bug, but I can't blame it when
         * it's stressed with that amount of
         * non-standard nonsense."
   * So in short the unaligned struct confuses gcc's optimizer so
   * i took the memcpy out alltogether to avoid future problems-Jess
         */
      /* The above was #ifndef SPARC, but i got a mail from
       * Putera Joseph F NPRI <*****@*****.**> containing:
       *   I had to use the memcpy function on a sparc machine.  The
       *   other one would give me a core dump.
       * cph - I find it hard to believe that sparc memcpy is broken,
       * but I don't believe the pointers to memcpy have to be aligned
       * either. Use fast memcpy on other machines anyway.
       */
/*
  proff - I took this out, because Oli Kraus ([email protected]) told
  me the memcpy produced a buserror. Since this function isn't time-
  critical I'm using the for loop now.
*/
/*
#ifndef GCC
      memcpy(texture->name, mtexture->name, sizeof(texture->name));
#else
*/
      {
        size_t j;
        for(j=0;j<sizeof(texture->name);j++)
          texture->name[j]=mtexture->name[j];
      }
/* #endif */

      mpatch = mtexture->patches;
      patch = texture->patches;

      for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
        {
          patch->originx = LittleShort(mpatch->originx);
          patch->originy = LittleShort(mpatch->originy);
          patch->patch = patchlookup[LittleShort(mpatch->patch)];
          if (patch->patch == -1)
            {
              //jff 8/3/98 use logical output routine
              lprintf(LO_ERROR,"\nR_InitTextures: Missing patch %d in texture %.8s",
                     LittleShort(mpatch->patch), texture->name); // killough 4/17/98
              ++errors;
            }
        }

      for (j=1; j*2 <= texture->width; j<<=1)
        ;
      texture->widthmask = j-1;
      textureheight[i] = texture->height<<FRACBITS;
    }

  free(patchlookup);         // killough

  for (i=0; i<2; i++) // cph - release the TEXTUREx lumps
    if (maptex_lump[i] != -1)
      W_UnlockLumpNum(maptex_lump[i]);

  if (errors)
  {
    const lumpinfo_t* info = W_GetLumpInfoByNum(names_lump);
    wadfile_info_t *wf = M_CBufGet(&resource_files_buf, info->wadfile);

    if (wf == NULL) {
      I_Error(
        "R_InitTextures: Bad wadfile for %s (%d)\n", info->name, info->wadfile
      );
    }

    lprintf(LO_INFO,
      "\nR_InitTextures: The file %s seems to be incompatible with \"%s\".\n",
      wf->name,
      (doomverstr ? doomverstr : "DOOM"));
    I_Error("R_InitTextures: %d errors", errors);
  }

  // Precalculate whatever possible.
  if (devparm) // cph - If in development mode, generate now so all errors are found at once
  {
    R_InitPatches(); //e6y
    for (i=0 ; i<numtextures ; i++)
    {
      // proff - This is for the new renderer now
      R_CacheTextureCompositePatchNum(i);
      R_UnlockTextureCompositePatchNum(i);
    }
  }

  if (errors)
    I_Error("R_InitTextures: %d errors", errors);

  // Create translation table for global animation.
  // killough 4/9/98: make column offsets 32-bit;
  // clean up malloc-ing to use sizeof

  texturetranslation =
    Z_Malloc((numtextures+1)*sizeof*texturetranslation, PU_STATIC, 0);

  for (i=0 ; i<numtextures ; i++)
    texturetranslation[i] = i;

  // killough 1/31/98: Initialize texture hash table
  for (i = 0; i<numtextures; i++)
    textures[i]->index = -1;
  while (--i >= 0)
    {
      int j = W_LumpNameHash(textures[i]->name) % (unsigned) numtextures;
      textures[i]->next = textures[j]->index;   // Prepend to chain
      textures[j]->index = i;
    }
}
Esempio n. 21
0
File: r_data.c Progetto: AlexMax/d2k
static inline void precache_lump(int l)
{
  W_CacheLumpNum(l); W_UnlockLumpNum(l);
}
Esempio n. 22
0
///////////////////////////////////////////////////////////
// Palette stuff.
//
static void I_UploadNewPalette(int pal, int force)
{
  // This is used to replace the current 256 colour cmap with a new one
  // Used by 256 colour PseudoColor modes

  // Array of SDL_Color structs used for setting the 256-colour palette
  static SDL_Color* colours;
  static int cachedgamma;
  static size_t num_pals;

  if (V_GetMode() == VID_MODEGL)
    return;

  if ((colours == NULL) || (cachedgamma != usegamma) || force) {
    int pplump = W_GetNumForName("PLAYPAL");
    int gtlump = (W_CheckNumForName)("GAMMATBL",ns_prboom);
    register const byte * palette = W_CacheLumpNum(pplump);
    register const byte * const gtable = (const byte *)W_CacheLumpNum(gtlump) + 256*(cachedgamma = usegamma);
    register int i;

    num_pals = W_LumpLength(pplump) / (3*256);
    num_pals *= 256;

    if (!colours) {
      // First call - allocate and prepare colour array
      colours = malloc(sizeof(*colours)*num_pals);
#ifdef GL_DOOM
      vid_8ingl.colours = malloc(sizeof(vid_8ingl.colours[0]) * 4 * num_pals);
#endif
    }

    // set the colormap entries
    for (i=0 ; (size_t)i<num_pals ; i++) {
#ifdef GL_DOOM
      if (vid_8ingl.enabled)
      {
        if (V_GetMode() == VID_MODE8)
        {
          vid_8ingl.colours[i * 4 + 0] = gtable[palette[2]];
          vid_8ingl.colours[i * 4 + 1] = gtable[palette[1]];
          vid_8ingl.colours[i * 4 + 2] = gtable[palette[0]];
          vid_8ingl.colours[i * 4 + 3] = 255;
        }
      }
      else
#endif
      {
        colours[i].r = gtable[palette[0]];
        colours[i].g = gtable[palette[1]];
        colours[i].b = gtable[palette[2]];
      }

      palette += 3;
    }

    W_UnlockLumpNum(pplump);
    W_UnlockLumpNum(gtlump);
    num_pals/=256;
  }

#ifdef RANGECHECK
  if ((size_t)pal >= num_pals)
    I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)",
      pal, num_pals);
#endif

  // store the colors to the current display
  // SDL_SetColors(SDL_GetVideoSurface(), colours+256*pal, 0, 256);
#ifdef GL_DOOM
  if (vid_8ingl.enabled)
  {
    vid_8ingl.palette = pal;
  }
  else
#endif
  {
    SDL_SetPalette(SDL_GetVideoSurface(),SDL_LOGPAL|SDL_PHYSPAL,colours+256*pal, 0, 256);
  }
}
Esempio n. 23
0
static void R_DemoEx_GetParams(const byte *pwad_p, waddata_t *waddata)
{
  int lump;
  size_t size;
  char *str;
  const char *data;
  char **params;
  int i, p, paramscount;
  
  lump = W_CheckNumForName(DEMOEX_PARAMS_LUMPNAME);
  if (lump == -1)
    return;

  size = W_LumpLength(lump);
  if (size <= 0)
    return;

  str = calloc(size + 1, 1);
  if (!str)
    return;

  data = W_CacheLumpNum(lump);
  strncpy(str, data, size);

  M_ParseCmdLine(str, NULL, NULL, &paramscount, &i);

  params = malloc(paramscount * sizeof(char*) + i * sizeof(char) + 1);
  if (params)
  {
    struct {
      const char *param;
      wad_source_t source;
    } files[] = {
      {"-iwad" , source_iwad},
      {"-file" , source_pwad},
      {"-deh"  , source_deh},
      {NULL}
    };

    M_ParseCmdLine(str, params, ((char*)params) + sizeof(char*) * paramscount, &paramscount, &i);
  
    if (!M_CheckParm("-iwad") && !M_CheckParm("-file"))
    {
      i = 0;
      while (files[i].param)
      {
        p = M_CheckParmEx(files[i].param, params, paramscount);
        if (p >= 0)
        {
          while (++p != paramscount && *params[p] != '-')
          {
            char *filename;
            //something is wrong here
            filename = I_FindFile(params[p], ".wad");
            if (!filename)
            {
              filename = strdup(params[p]);
            }
            WadDataAddItem(waddata, filename, files[i].source, 0);
            free(filename);
          }
        }
        i++;
      }
    }

    if (!M_CheckParm("-complevel"))
    {
      p = M_CheckParmEx("-complevel", params, paramscount);
      if (p >= 0 && p < (int)paramscount - 1)
      {
        M_AddParam("-complevel");
        M_AddParam(strdup(params[p + 1]));
      }
    }

    //for recording or playback using "single-player coop" mode
    if (!M_CheckParm("-solo-net"))
    {
      p = M_CheckParmEx("-solo-net", params, paramscount);
      if (p >= 0)
      {
        M_AddParam("-solo-net");
      }
    }

    if (!M_CheckParm("-emulate"))
    {
      p = M_CheckParmEx("-emulate", params, paramscount);
      if (p >= 0 && p < (int)paramscount - 1)
      {
        M_AddParam("-emulate");
        M_AddParam(strdup(params[p + 1]));
      }
    }

    // for doom 1.2
    if (!M_CheckParm("-respawn"))
    {
      p = M_CheckParmEx("-respawn", params, paramscount);
      if (p >= 0)
      {
        M_AddParam("-respawn");
      }
    }

    // for doom 1.2
    if (!M_CheckParm("-fast"))
    {
      p = M_CheckParmEx("-fast", params, paramscount);
      if (p >= 0)
      {
        M_AddParam("-fast");
      }
    }

    // for doom 1.2
    if (!M_CheckParm("-nomonsters"))
    {
      p = M_CheckParmEx("-nomonsters", params, paramscount);
      if (p >= 0)
      {
        M_AddParam("-nomonsters");
      }
    }

    p = M_CheckParmEx("-spechit", params, paramscount);
    if (p >= 0 && p < (int)paramscount - 1)
    {
      spechit_baseaddr = atoi(params[p + 1]);
    }

    //overflows
    {
      overrun_list_t overflow;
      for (overflow = 0; overflow < OVERFLOW_MAX; overflow++)
      {
        int value;
        char *pstr, *mask;

        mask = malloc(strlen(overflow_cfgname[overflow]) + 16);
        if (mask)
        {
          sprintf(mask, "-set %s", overflow_cfgname[overflow]);
          pstr = strstr(str, mask);

          if (pstr)
          {
            strcat(mask, " = %d");
            if (sscanf(pstr, mask, &value) == 1)
            {
              overflows[overflow].tmp_emulate = value;
            }
          }
          free(mask);
        }
      }
    }

    free(params);
  }

  W_UnlockLumpNum(lump);
  free(str);
}
Esempio n. 24
0
//---------------------------------------------------------------------------
static void createPatch(int id) {
  rpatch_t *patch;
  const int patchNum = id;
  const patch_t *oldPatch;
  const column_t *oldColumn, *oldPrevColumn, *oldNextColumn;
  int x, y;
  int pixelDataSize;
  int columnsDataSize;
  int postsDataSize;
  int dataSize;
  int *numPostsInColumn;
  int numPostsTotal;
  const unsigned char *oldColumnPixelData;
  int numPostsUsedSoFar;
  int edgeSlope;

#ifdef RANGECHECK
  if (id >= numlumps)
    I_Error("createPatch: %i >= numlumps", id);
#endif

  if (!CheckIfPatch(patchNum))
  {
    I_Error("createPatch: Unknown patch format %s.",
      (patchNum < numlumps ? lumpinfo[patchNum].name : NULL));
  }

  oldPatch = (const patch_t*)W_CacheLumpNum(patchNum);

  patch = &patches[id];
  // proff - 2003-02-16 What about endianess?
  patch->width = LittleShort(oldPatch->width);
  patch->widthmask = 0;
  patch->height = LittleShort(oldPatch->height);
  patch->leftoffset = LittleShort(oldPatch->leftoffset);
  patch->topoffset = LittleShort(oldPatch->topoffset);
  patch->flags = 0;
  if (getPatchIsNotTileable(oldPatch))
    patch->flags |= PATCH_ISNOTTILEABLE;

#ifdef GL_DOOM
  // Width of M_THERMM patch is 9, but Doom interprets it as 8-columns lump
  // during drawing. It is not a problem for software mode and GL_NEAREST,
  // but looks wrong with filtering. So I need to patch it during loading.
  if (V_GetMode() == VID_MODEGL)
  {
    if (!strncasecmp(lumpinfo[id].name, "M_THERMM", 8) && patch->width > 8)
    {
      patch->width--;
    }
  }
#endif

  // work out how much memory we need to allocate for this patch's data
  pixelDataSize = (patch->width * patch->height + 4) & ~3;
  columnsDataSize = sizeof(rcolumn_t) * patch->width;

  // count the number of posts in each column
  numPostsInColumn = malloc(sizeof(int) * patch->width);
  numPostsTotal = 0;

  for (x=0; x<patch->width; x++) {
    oldColumn = (const column_t *)((const byte *)oldPatch + LittleLong(oldPatch->columnofs[x]));
    numPostsInColumn[x] = 0;
    while (oldColumn->topdelta != 0xff) {
      numPostsInColumn[x]++;
      numPostsTotal++;
      oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
    }
  }

  postsDataSize = numPostsTotal * sizeof(rpost_t);

  // allocate our data chunk
  dataSize = pixelDataSize + columnsDataSize + postsDataSize;
  patch->data = (unsigned char*)Z_Malloc(dataSize, PU_CACHE, (void **)&patch->data);
  memset(patch->data, 0, dataSize);

  // set out pixel, column, and post pointers into our data array
  patch->pixels = patch->data;
  patch->columns = (rcolumn_t*)((unsigned char*)patch->pixels + pixelDataSize);
  patch->posts = (rpost_t*)((unsigned char*)patch->columns + columnsDataSize);

  // sanity check that we've got all the memory allocated we need
  assert((((byte*)patch->posts  + numPostsTotal*sizeof(rpost_t)) - (byte*)patch->data) == dataSize);

  memset(patch->pixels, 0xff, (patch->width*patch->height));

  // fill in the pixels, posts, and columns
  numPostsUsedSoFar = 0;
  for (x=0; x<patch->width; x++) {
    int top = -1;

    oldColumn = (const column_t *)((const byte *)oldPatch + LittleLong(oldPatch->columnofs[x]));

    if (patch->flags&PATCH_ISNOTTILEABLE) {
      // non-tiling
      if (x == 0) oldPrevColumn = 0;
      else oldPrevColumn = (const column_t *)((const byte *)oldPatch + LittleLong(oldPatch->columnofs[x-1]));
      if (x == patch->width-1) oldNextColumn = 0;
      else oldNextColumn = (const column_t *)((const byte *)oldPatch + LittleLong(oldPatch->columnofs[x+1]));
    }
    else {
      // tiling
      int prevColumnIndex = x-1;
      int nextColumnIndex = x+1;
      while (prevColumnIndex < 0) prevColumnIndex += patch->width;
      while (nextColumnIndex >= patch->width) nextColumnIndex -= patch->width;
      oldPrevColumn = (const column_t *)((const byte *)oldPatch + LittleLong(oldPatch->columnofs[prevColumnIndex]));
      oldNextColumn = (const column_t *)((const byte *)oldPatch + LittleLong(oldPatch->columnofs[nextColumnIndex]));
    }

    // setup the column's data
    patch->columns[x].pixels = patch->pixels + (x*patch->height) + 0;
    patch->columns[x].numPosts = numPostsInColumn[x];
    patch->columns[x].posts = patch->posts + numPostsUsedSoFar;

    while (oldColumn->topdelta != 0xff) {
      int len = oldColumn->length;

      //e6y: support for DeePsea's true tall patches
      if (oldColumn->topdelta <= top)
      {
        top += oldColumn->topdelta;
      }
      else
      {
        top = oldColumn->topdelta;
      }

      // Clip posts that extend past the bottom
      if (top + oldColumn->length > patch->height)
      {
        len = patch->height - top;
      }

      if (len > 0)
      {
        // set up the post's data
        patch->posts[numPostsUsedSoFar].topdelta = top;
        patch->posts[numPostsUsedSoFar].length = len;
        patch->posts[numPostsUsedSoFar].slope = 0;

        edgeSlope = getColumnEdgeSlope(oldPrevColumn, oldNextColumn, top);
        if (edgeSlope == 1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_TOP_UP;
        else if (edgeSlope == -1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_TOP_DOWN;

        edgeSlope = getColumnEdgeSlope(oldPrevColumn, oldNextColumn, top+len);
        if (edgeSlope == 1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_BOT_UP;
        else if (edgeSlope == -1) patch->posts[numPostsUsedSoFar].slope |= RDRAW_EDGESLOPE_BOT_DOWN;

        // fill in the post's pixels
        oldColumnPixelData = (const byte *)oldColumn + 3;
        for (y=0; y<len; y++) {
          patch->pixels[x * patch->height + top + y] = oldColumnPixelData[y];
        }
      }
      oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
      numPostsUsedSoFar++;
    }
  }

  if (1 || (patch->flags&PATCH_ISNOTTILEABLE)) {
    const rcolumn_t *column, *prevColumn;

    // copy the patch image down and to the right where there are
    // holes to eliminate the black halo from bilinear filtering
    for (x=0; x<patch->width; x++) {
      //oldColumn = (const column_t *)((const byte *)oldPatch + oldPatch->columnofs[x]);

      column = R_GetPatchColumnClamped(patch, x);
      prevColumn = R_GetPatchColumnClamped(patch, x-1);

      if (column->pixels[0] == 0xff) {
        // e6y: marking of all patches with holes
        patch->flags |= PATCH_HASHOLES;

        // force the first pixel (which is a hole), to use
        // the color from the next solid spot in the column
        for (y=0; y<patch->height; y++) {
          if (column->pixels[y] != 0xff) {
            column->pixels[0] = column->pixels[y];
            break;
          }
        }
      }

      // copy from above or to the left
      for (y=1; y<patch->height; y++) {
        //if (getIsSolidAtSpot(oldColumn, y)) continue;
        if (column->pixels[y] != 0xff) continue;

        // this pixel is a hole

        // e6y: marking of all patches with holes
        patch->flags |= PATCH_HASHOLES;

        if (x && prevColumn->pixels[y-1] != 0xff) {
          // copy the color from the left
          column->pixels[y] = prevColumn->pixels[y];
        }
        else {
          // copy the color from above
          column->pixels[y] = column->pixels[y-1];
        }
      }
    }

    // verify that the patch truly is non-rectangular since
    // this determines tiling later on
  }

  W_UnlockLumpNum(patchNum);
  free(numPostsInColumn);
}