Exemple #1
0
void R_InitBuffer(int width, int height)
{
  int i=0;
  // Handle resize,
  //  e.g. smaller view windows
  //  with border and/or status bar.

  viewwindowx = (SCREENWIDTH-width) >> 1;

  // Same with base row offset.

  viewwindowy = width==SCREENWIDTH ? 0 : (SCREENHEIGHT-ST_SCALED_HEIGHT-height)>>1;

  drawvars.byte_topleft = screens[0].data + viewwindowy*screens[0].byte_pitch + viewwindowx;
  drawvars.short_topleft = (unsigned short *)(screens[0].data) + viewwindowy*screens[0].short_pitch + viewwindowx;
  drawvars.int_topleft = (unsigned int *)(screens[0].data) + viewwindowy*screens[0].int_pitch + viewwindowx;
  drawvars.byte_pitch = screens[0].byte_pitch;
  drawvars.short_pitch = screens[0].short_pitch;
  drawvars.int_pitch = screens[0].int_pitch;

  if (V_GetMode() == VID_MODE8) {
    for (i=0; i<FUZZTABLE; i++)
      fuzzoffset[i] = fuzzoffset_org[i]*screens[0].byte_pitch;
  } else if ((V_GetMode() == VID_MODE15) || (V_GetMode() == VID_MODE16)) {
    for (i=0; i<FUZZTABLE; i++)
      fuzzoffset[i] = fuzzoffset_org[i]*screens[0].short_pitch;
  } else if (V_GetMode() == VID_MODE32) {
    for (i=0; i<FUZZTABLE; i++)
      fuzzoffset[i] = fuzzoffset_org[i]*screens[0].int_pitch;
  }
}
Exemple #2
0
// CPhipps -
// I_CalculateRes
// Calculates the screen resolution, possibly using the supplied guide
void I_CalculateRes(int width, int height)
{
// e6y
// GLBoom will try to set the closest supported resolution 
// if the requested mode can't be set correctly.
// For example glboom.exe -geom 1025x768 -nowindow will set 1024x768.
// It affects only fullscreen modes.
  if (V_GetMode() == VID_MODEGL) {
    if ( desired_fullscreen )
    {
      I_ClosestResolution(&width, &height, SDL_OPENGL|SDL_FULLSCREEN);
    }
    SCREENWIDTH = width;
    SCREENHEIGHT = height;
    SCREENPITCH = SCREENWIDTH;
  } else {
    unsigned int count1, count2;
    int pitch1, pitch2;

    SCREENWIDTH = width;//(width+15) & ~15;
    SCREENHEIGHT = height;

    // e6y
    // Trying to optimise screen pitch for reducing of CPU cache misses.
    // It is extremally important for wiping in software.
    // I have ~20x improvement in speed with using 1056 instead of 1024 on Pentium4
    // and only ~10% for Core2Duo
    if (try_to_reduce_cpu_cache_misses)
    {
      unsigned int mintime = 100;
      int w = (width+15) & ~15;
      pitch1 = w * V_GetPixelDepth();
      pitch2 = w * V_GetPixelDepth() + 32;

      count1 = I_TestCPUCacheMisses(pitch1, SCREENHEIGHT, mintime);
      count2 = I_TestCPUCacheMisses(pitch2, SCREENHEIGHT, mintime);

      lprintf(LO_INFO, "I_CalculateRes: trying to optimize screen pitch\n");
      lprintf(LO_INFO, " test case for pitch=%d is processed %d times for %d msec\n", pitch1, count1, mintime);
      lprintf(LO_INFO, " test case for pitch=%d is processed %d times for %d msec\n", pitch2, count2, mintime);

      SCREENPITCH = (count2 > count1 ? pitch2 : pitch1);

      lprintf(LO_INFO, " optimized screen pitch is %d\n", SCREENPITCH);
    }
    else
    {
      SCREENPITCH = SCREENWIDTH * V_GetPixelDepth();
    }
  }

  // e6y: processing of screen_multiply
  {
    int factor = ((V_GetMode() == VID_MODEGL) ? 1 : render_screen_multiply);
    REAL_SCREENWIDTH = SCREENWIDTH * factor;
    REAL_SCREENHEIGHT = SCREENHEIGHT * factor;
    REAL_SCREENPITCH = SCREENPITCH * factor;
  }
}
Exemple #3
0
// CPhipps -
// I_CalculateRes
// Calculates the screen resolution, possibly using the supplied guide
void I_CalculateRes(unsigned int width, unsigned int height)
{
  // e6y: how about 1680x1050?
  /*
  SCREENWIDTH = (width+3) & ~3;
  SCREENHEIGHT = (height+3) & ~3;
  */

// e6y
// GLBoom will try to set the closest supported resolution 
// if the requested mode can't be set correctly.
// For example glboom.exe -geom 1025x768 -nowindow will set 1024x768.
// It affects only fullscreen modes.
  if (V_GetMode() == VID_MODEGL) {
    if ( desired_fullscreen )
    {
      I_ClosestResolution(&width, &height, SDL_OPENGL|SDL_FULLSCREEN);
    }
    SCREENWIDTH = width;
    SCREENHEIGHT = height;
    SCREENPITCH = SCREENWIDTH;
  } else {
    SCREENWIDTH = width;
    SCREENHEIGHT = height;
    SCREENPITCH = (width * V_GetPixelDepth() + 3) & ~3;
    if (!(SCREENPITCH % 1024))
      SCREENPITCH += 32;
  }
}
Exemple #4
0
void M_ChangeCompTranslucency(void)
{
  int i;
  int predefined_translucency[] = {
    MT_FIRE, MT_SMOKE, MT_FATSHOT, MT_BRUISERSHOT, MT_SPAWNFIRE,
    MT_TROOPSHOT, MT_HEADSHOT, MT_PLASMA, MT_BFG, MT_ARACHPLAZ, MT_PUFF, 
    MT_TFOG, MT_IFOG, MT_MISC12, MT_INV, MT_INS, MT_MEGA
  };
  
  for(i = 0; (size_t)i < sizeof(predefined_translucency)/sizeof(predefined_translucency[0]); i++)
  {
    if (!DEH_mobjinfo_bits[predefined_translucency[i]])
    {
      // Transparent sprites are not visible behind transparent walls in OpenGL.
      // It needs much work.
#ifdef GL_DOOM
      if (V_GetMode() == VID_MODEGL)
      {
        // Disabling transparency in OpenGL for original sprites
        // which are not changed by dehacked, because it's buggy for now.
        // Global sorting of transparent sprites and walls is needed
        mobjinfo[predefined_translucency[i]].flags &= ~MF_TRANSLUCENT;
      }
      else
#endif
      if (comp[comp_translucency]) 
        mobjinfo[predefined_translucency[i]].flags &= ~MF_TRANSLUCENT;
      else 
        mobjinfo[predefined_translucency[i]].flags |= MF_TRANSLUCENT;
    }
  }
}
Exemple #5
0
void G_SkipDemoStop(void)
{
  fastdemo = saved_fastdemo;
  nodrawers = saved_nodrawers;
  nosfxparm = saved_nosfxparm;
  nomusicparm = saved_nomusicparm;
  
  render_precise = saved_render_precise;
  M_ChangeRenderPrecise();

  demo_stoponnext = false;
  demo_stoponend = false;
  demo_warp = false;
  doSkip = false;
  demo_skiptics = 0;
  startmap = 0;

  I_Init2();
  if (!sound_inited_once && !(nomusicparm && nosfxparm))
  {
    I_InitSound();
  }
  S_Init(snd_SfxVolume, snd_MusicVolume);
  S_Stop();
  S_RestartMusic();

#ifdef GL_DOOM
  if (V_GetMode() == VID_MODEGL) {
    gld_PreprocessLevel();
  }
#endif
}
Exemple #6
0
void R_VideoErase(int x, int y, int count)
{
  if (V_GetMode() != VID_MODEGL)
    memcpy(screens[0].data+y*screens[0].byte_pitch+x*V_GetPixelDepth(),
           screens[1].data+y*screens[1].byte_pitch+x*V_GetPixelDepth(),
           count*V_GetPixelDepth());   // LFB copy.
}
Exemple #7
0
void M_ChangeRenderPrecise(void)
{
#ifdef GL_DOOM
  if (V_GetMode() != VID_MODEGL)
  {
    gl_seamless = false;
    return;
  }
  else
  {
    if (render_precise)
    {
      gl_seamless = true;
      gld_InitVertexData();
    }
    else
    {
      gl_seamless = false;
      gld_CleanVertexData();
    }
  }
#endif // GL_DOOM

  AM_SetRenderPrecise();
}
Exemple #8
0
int I_ScreenShot (const char *fname)
{
#ifdef GL_DOOM
  if (V_GetMode() == VID_MODEGL)
  {
    int result = -1;
    unsigned char *pixel_data = gld_ReadScreen();

    if (pixel_data)
    {
      SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(
          pixel_data, SCREENWIDTH, SCREENHEIGHT, 24, SCREENWIDTH*3,
          0x000000ff, 0x0000ff00, 0x00ff0000, 0);

      if (surface)
      {
        result = SAVE_PNG_OR_BMP(surface, fname);
        SDL_FreeSurface(surface);
      }
      free(pixel_data);
    }
    return result;
  }
  else
#endif
  return SAVE_PNG_OR_BMP(SDL_GetVideoSurface(), fname);
}
Exemple #9
0
R_DrawSpan_f R_GetDrawSpanFunc(enum draw_filter_type_e filter,
                               enum draw_filter_type_e filterz) {
  R_DrawSpan_f result = drawspanfuncs[V_GetMode()][filterz][filter];
  if (result == NULL)
    I_Error("R_GetDrawSpanFunc: undefined function (%d, %d)",
            filter, filterz);
  return result;
}
Exemple #10
0
R_DrawColumn_f R_GetDrawColumnFunc(enum column_pipeline_e type,
                                   enum draw_filter_type_e filter,
                                   enum draw_filter_type_e filterz) {
  R_DrawColumn_f result = drawcolumnfuncs[V_GetMode()][filterz][filter][type];
  if (result == NULL)
    I_Error("R_GetDrawColumnFunc: undefined function (%d, %d, %d)",
            type, filter, filterz);
  return result;
}
Exemple #11
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 (V_GetMode() == VID_MODEGL)
    return;

  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(*colours)*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

  // store the colors to the current display
  // SDL_SetColors(SDL_GetVideoSurface(), colours+256*pal, 0, 256);
  //SDL_SetColors(screen, colours+256*pal, 0, 256);
  
  /* Vladimir
  SDL_SetPalette(
      SDL_GetVideoSurface(),
      SDL_LOGPAL | SDL_PHYSPAL,
      colours+256*pal, 0, 256); */
}
Exemple #12
0
//
// I_TranslateFrameBuffer
//
// TODO: allow copying partial screens (for top screen borders)
void I_TranslateFrameBuffer(unsigned scrn, gfxScreen_t scrndest, gfx3dSide_t side, int xoff, int yoff) {
	
	if (scrn >= NUM_SCREENS)
		I_Error("I_TranslateFrameBuffer: invalid screen number %u", scrn);
	
	// this is really hacky and obviously doesn't account for the possibility of
	// different color depths, etc.
	uint16_t width, height;
	char *fb = gfxGetFramebuffer(scrndest, side, &width, &height);
	
	// center screen horizontally
	if (xoff < 0) {
		xoff = (height - screens[scrn].width) / 2;
	}
	if (xoff > height - screens[scrn].width)
		I_Error("I_TranslateFrameBuffer: bad x-offset (%d > %u)", xoff, height - screens[scrn].width);

	// center screen vertically	
	if (yoff < 0) {
		yoff = (width - screens[scrn].height) / 2;
	}
	if (yoff > width - screens[scrn].height)
		I_Error("I_TranslateFrameBuffer: bad y-offset (%d > %u)", yoff, width - screens[scrn].height);
		
	uint16_t x, y;
	// do palette lookups and rotate image 90' into the framebuffer here
	char *src = screens[scrn].data;
	
	for (x = yoff; x < screens[scrn].height + yoff; x++) {
		for (y = xoff; y < screens[scrn].width + xoff; y++) {
			char *dest = fb + ((y * width + (width - x - 1)) * 3);
			char px;
			
			switch (V_GetMode()) {
			case VID_MODE8:
				px = *src++;
				
				*dest++ = current_pal[px].b;
				*dest++ = current_pal[px].g;
				*dest++ = current_pal[px].r;
				break;
				
			case VID_MODE32:
				*dest++ = *src++;
				*dest++ = *src++;
				*dest++ = *src++;
				src++;
				
				break;
				
			default:
				I_Error("I_TranslateFrameBuffer: unsupported video mode");
			}
		}
	}
}
Exemple #13
0
void CheckPitch(signed int *pitch)
{
  if (V_GetMode() == VID_MODEGL)
  {
    if(*pitch > maxViewPitch)
      *pitch = maxViewPitch;
    if(*pitch < minViewPitch)
      *pitch = minViewPitch;

    (*pitch) >>= 16;
    (*pitch) <<= 16;
  }
}
Exemple #14
0
void I_FinishUpdate (void)
{
  if (I_SkipFrame()) return;

#ifdef MONITOR_VISIBILITY
  if (!(SDL_GetAppState()&SDL_APPACTIVE)) {
    return;
  }
#endif

#ifdef GL_DOOM
  if (V_GetMode() == VID_MODEGL) {
    // proff 04/05/2000: swap OpenGL buffers
    gld_Finish();
    return;
  }
#endif
/* Vladimir
  if (SDL_MUSTLOCK(screen)) {
      int h;
      byte *src;
      byte *dest;

      if (SDL_LockSurface(screen) < 0) {
        lprintf(LO_INFO,"I_FinishUpdate: %s\n", SDL_GetError());
        return;
      }
      dest=screen->pixels;
      src=screens[0].data;
      h=screen->h;
      for (; h>0; h--)
      {
        memcpy(dest,src,SCREENWIDTH*V_GetPixelDepth());
        dest+=screen->pitch;
        src+=screens[0].byte_pitch;
      }
      SDL_UnlockSurface(screen);
  }
  */
  /* Update the display buffer (flipping video pages if supported)
   * If we need to change palette, that implicitely does a flip */
  if (newpal != NO_PALETTE_CHANGE) {
    I_UploadNewPalette(newpal);
    newpal = NO_PALETTE_CHANGE;
  }
  
  // Vladimir SDL_Flip(screen);
  //JNI_UpdateRect(screen);
  JNI_Flip(screens[0].data, SCREENWIDTH, SCREENHEIGHT, colours);
}
Exemple #15
0
angle_t R_PointToAngle(fixed_t x, fixed_t y, int usePlayer)
{
  static fixed_t oldx, oldy;
  static angle_t oldresult;

  if (usePlayer == 0)
  {
    x -= viewx; y -= viewy;
  }
  else
  {
    //SB- use player position rather than view position (as these will have stereo offset included
    //and can mean different sprites for each eye!)
    x -= viewplayer->mo->x;
    y -= viewplayer->mo->y;
  }

  if ( /* !render_precise && */
      // e6y: here is where "slime trails" can SOMETIMES occur
#ifdef GL_DOOM
      (V_GetMode() != VID_MODEGL) &&
#endif
      (x < INT_MAX/4 && x > -INT_MAX/4 && y < INT_MAX/4 && y > -INT_MAX/4)
     )
  {
    // old R_PointToAngle
    return (x || y) ?
    x >= 0 ?
      y >= 0 ?
        (x > y) ? tantoangle[SlopeDiv(y,x)] :                      // octant 0
                ANG90-1-tantoangle[SlopeDiv(x,y)] :                // octant 1
        x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] :                // octant 8
                       ANG270+tantoangle[SlopeDiv(x,y)] :          // octant 7
      y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3
                            ANG90 + tantoangle[SlopeDiv(x,y)] :    // octant 2
        (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] :  // octant 4
                              ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
    0;
  }

  // R_PointToAngleEx merged into R_PointToAngle
  // e6y: The precision of the code above is abysmal so use the CRT atan2 function instead!
  if (oldx != x || oldy != y)
  {
    oldx = x;
    oldy = y;
    oldresult = (int)(atan2(y, x) * ANG180/M_PI);
  }
  return oldresult;
}
Exemple #16
0
static void R_ShowStats(void)
{
//e6y
#if 1
    static unsigned int FPS_SavedTick = 0, FPS_FrameCount = 0;
    unsigned int tick = SDL_GetTicks();
    FPS_FrameCount++;
    if(tick >= FPS_SavedTick + 1000)
    {
        doom_printf((V_GetMode() == VID_MODEGL)
                    ?"Frame rate %d fps\nWalls %d, Flats %d, Sprites %d"
                    :"Frame rate %d fps\nSegs %d, Visplanes %d, Sprites %d",
                    1000 * FPS_FrameCount / (tick - FPS_SavedTick), rendered_segs,
                    rendered_visplanes, rendered_vissprites);
        FPS_SavedTick = tick;
        FPS_FrameCount = 0;
    }
#else

#define KEEPTIMES 10
    static int keeptime[KEEPTIMES], showtime;
    int now = I_GetTime();

    if (now - showtime > 35) {
        doom_printf((V_GetMode() == VID_MODEGL)
                    ?"Frame rate %d fps\nWalls %d, Flats %d, Sprites %d"
                    :"Frame rate %d fps\nSegs %d, Visplanes %d, Sprites %d",
                    (35*KEEPTIMES)/(now - keeptime[0]), rendered_segs,
                    rendered_visplanes, rendered_vissprites);
        showtime = now;
    }
    memmove(keeptime, keeptime+1, sizeof(keeptime[0]) * (KEEPTIMES-1));
    keeptime[KEEPTIMES-1] = now;

#endif //e6y
}
Exemple #17
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;
}
Exemple #18
0
static void D_DoomLoop(void)
{
  for (;;)
    {
      WasRenderedInTryRunTics = false;
      // frame syncronous IO operations
      I_StartFrame ();

      if (ffmap == gamemap) ffmap = 0;

      // process one or more tics
      if (singletics)
        {
          I_StartTic ();
          G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]);
          if (advancedemo)
            D_DoAdvanceDemo ();
          M_Ticker ();
          G_Ticker ();
          P_Checksum(gametic);
          gametic++;
          maketic++;
        }
      else
        TryRunTics (); // will run at least one tic

      // killough 3/16/98: change consoleplayer to displayplayer
      if (players[displayplayer].mo) // cph 2002/08/10
	S_UpdateSounds(players[displayplayer].mo);// move positional sounds

      if (V_GetMode() == VID_MODEGL ? 
        !movement_smooth || !WasRenderedInTryRunTics :
        !movement_smooth || !WasRenderedInTryRunTics || gamestate != wipegamestate
      )
        {
        // Update display, next frame, with current state.
        D_Display();
      }

      // CPhipps - auto screenshot
      if (auto_shot_fname && !--auto_shot_count) {
  auto_shot_count = auto_shot_time;
  M_DoScreenShot(auto_shot_fname);
      }
    }
}
Exemple #19
0
angle_t R_PointToAngle(fixed_t x, fixed_t y)
{
#if 0
	// JDC: the oldresult case only hit 10%, making it a net loss.
	// JDC: added parenthesis to force constant evaluation
    return (int)(atan2(y-viewy, x-viewx) * (ANG180/M_PI) );	
#else
  static fixed_t oldx, oldy;
  static angle_t oldresult;

  x -= viewx; y -= viewy;

  if ( /* !render_precise && */
      // e6y: here is where "slime trails" can SOMETIMES occur
#ifdef GL_DOOM
      (V_GetMode() != VID_MODEGL) &&
#endif
      (x < INT_MAX/4 && x > -INT_MAX/4 && y < INT_MAX/4 && y > -INT_MAX/4)
     )
  {
    // old R_PointToAngle
    return (x || y) ?
    x >= 0 ?
      y >= 0 ?
        (x > y) ? tantoangle[SlopeDiv(y,x)] :                      // octant 0
                ANG90-1-tantoangle[SlopeDiv(x,y)] :                // octant 1
        x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] :                // octant 8
                       ANG270+tantoangle[SlopeDiv(x,y)] :          // octant 7
      y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3
                            ANG90 + tantoangle[SlopeDiv(x,y)] :    // octant 2
        (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] :  // octant 4
                              ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
    0;
  }

  // R_PointToAngleEx merged into R_PointToAngle
  // e6y: The precision of the code above is abysmal so use the CRT atan2 function instead!
  if (oldx != x || oldy != y)
  {
    oldx = x;
    oldy = y;
    oldresult = (int)(atan2(y, x) * ANG180/M_PI );
  }
   return oldresult;
#endif	
}
Exemple #20
0
// Update the value of window_focused when we get a focus event
//
// We try to make ourselves be well-behaved: the grab on the mouse
// is removed if we lose focus (such as a popup window appearing),
// and we dont move the mouse around if we aren't focused either.
static void UpdateFocus(void)
{
  Uint8 state;

  state = SDL_GetAppState();

  // We should have input (keyboard) focus and be visible 
  // (not minimised)
  window_focused = (state & SDL_APPINPUTFOCUS) && (state & SDL_APPACTIVE);

  // e6y
  // Reuse of a current palette to avoid black screen at software fullscreen modes
  // after switching to OS and back
  if (desired_fullscreen && window_focused)
  {
    // currentPaletteIndex?
    if (st_palette < 0)
      st_palette = 0;

    V_SetPalette(st_palette);
  }

#ifdef GL_DOOM
  if (V_GetMode() == VID_MODEGL)
  {
    if (gl_hardware_gamma)
    {
      if (!window_focused)
      {
        // e6y: Restore of startup gamma if window loses focus
        gld_SetGammaRamp(-1);
      }
      else
      {
        gld_SetGammaRamp(useglgamma);
      }
    }
  }
#endif

  // Should the screen be grabbed?
  //    screenvisible = (state & SDL_APPACTIVE) != 0;
}
Exemple #21
0
void R_DrawViewBorder(void)
{
  int top, side, i;

  if (V_GetMode() == VID_MODEGL) {
    // proff 11/99: we don't have a backscreen in OpenGL from where we can copy this
    R_FillBackScreen();
    return;
  }

  // e6y: wide-res
  if ((wide_ratio || wide_offsety) &&
     ((SCREENHEIGHT != viewheight) ||
     ((automapmode & am_active) && ! (automapmode & am_overlay))))
  {
    for (i = (SCREENHEIGHT - ST_SCALED_HEIGHT); i < SCREENHEIGHT; i++)
    {
      R_VideoErase (0, i, wide_offsetx);
      R_VideoErase (SCREENWIDTH - wide_offsetx, i, wide_offsetx);
    }
  }

  if ( viewheight >= ( SCREENHEIGHT - ST_SCALED_HEIGHT ))
    return; // if high-res, don´t go any further!

  top = ((SCREENHEIGHT-ST_SCALED_HEIGHT)-viewheight)/2;
  side = (SCREENWIDTH-scaledviewwidth)/2;

  // copy top
  for (i = 0; i < top; i++)
    R_VideoErase (0, i, SCREENWIDTH);

  // copy sides
  for (i = top; i < (top+viewheight); i++) {
    R_VideoErase (0, i, side);
    R_VideoErase (viewwidth+side, i, side);
  }

  // copy bottom
  for (i = top+viewheight; i < (SCREENHEIGHT - ST_SCALED_HEIGHT); i++)
    R_VideoErase (0, i, SCREENWIDTH);
}
Exemple #22
0
void M_ChangeMaxViewPitch(void)
{
  int max_up, max_dn, angle_up, angle_dn;
  
  if (V_GetMode() == VID_MODEGL)
  {
    max_up = movement_maxviewpitch;
    max_dn = movement_maxviewpitch;
  }
  else
  {
    max_up = MIN(movement_maxviewpitch, 61);
    max_dn = MIN(movement_maxviewpitch, 36);
  }

  angle_up = (int)((float)max_up / 45.0f * ANG45);
  angle_dn = (int)((float)max_dn / 45.0f * ANG45);

  maxViewPitch = (+angle_up - (1<<ANGLETOFINESHIFT));
  minViewPitch = (-angle_dn + (1<<ANGLETOFINESHIFT));

  viewpitch = 0;
}
Exemple #23
0
void D_Display (void)
{
  static boolean inhelpscreensstate   = false;
  static boolean isborderstate        = false;
  static boolean borderwillneedredraw = false;
  static gamestate_t oldgamestate = -1;
  boolean wipe;
  boolean viewactive = false, isborder = false;

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

  if (!I_StartDisplay())
    return;

  // save the current screen if about to wipe
  if ((wipe = gamestate != wipegamestate) && (V_GetMode() != VID_MODEGL))
    wipe_StartScreen();

  if (gamestate != GS_LEVEL) { // Not a level
    switch (oldgamestate) {
    case -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 || (V_GetMode() == VID_MODEGL))
      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);
    if (V_GetMode() != VID_MODEGL)
      R_DrawViewBorder();
    HU_Drawer();
  }

  inhelpscreensstate = inhelpscreens;
  isborderstate      = isborder;
  oldgamestate = wipegamestate = gamestate;

  // draw pause pic
  if (paused) {
    // Simplified the "logic" here and no need for x-coord caching - POPE
    V_DrawNamePatch((320 - V_NamePatchWidth("M_PAUSE"))/2, 4,
                    0, "M_PAUSE", CR_DEFAULT, VPT_STRETCH);
  }

  // menus go directly to the screen
  M_Drawer();          // menu is drawn even on top of everything
#ifdef HAVE_NET
  NetUpdate();         // send out any new accumulation
#else
  D_BuildNewTiccmds();
#endif

  // normal update
  if (!wipe || (V_GetMode() == VID_MODEGL))
    I_FinishUpdate ();              // page flip or blit buffer
  else {
    // wipe update
    wipe_EndScreen();
    D_Wipe();
  }

  I_EndDisplay();

  //e6y: don't thrash cpu during pausing
  if (paused) {
    I_uSleep(1000);
  }
}
Exemple #24
0
void I_PreInitGraphics(void)
{
  int p;
  char *video_driver = strdup(sdl_videodriver);

  // Initialize SDL
  unsigned int flags = 0;
  if (!(M_CheckParm("-nodraw") && M_CheckParm("-nosound")))
    flags = SDL_INIT_VIDEO;
#ifdef PRBOOM_DEBUG
  flags |= SDL_INIT_NOPARACHUTE;
#endif

  // e6y: Forcing "directx" video driver for Win9x.
  // The "windib" video driver is the default for SDL > 1.2.9, 
  // to prevent problems with certain laptops, 64-bit Windows, and Windows Vista.  
  // The DirectX driver is still available, and can be selected by setting 
  // the environment variable SDL_VIDEODRIVER to "directx".

  if ((p = M_CheckParm("-videodriver")) && (p < myargc - 1))
  {
    free(video_driver);
    video_driver = strdup(myargv[p + 1]);
  }

  if (strcasecmp(video_driver, "default"))
  {
    // videodriver != default
    char buf[80];
    strcpy(buf, "SDL_VIDEODRIVER=");
    strncat(buf, video_driver, sizeof(buf) - sizeof(buf[0]) - strlen(buf));
    putenv(buf);
  }
  else
  {
    // videodriver == default
#ifdef _WIN32
    if ((int)GetVersion() < 0 && V_GetMode() != VID_MODEGL ) // win9x
    {
      free(video_driver);
      video_driver = strdup("directx");
      putenv("SDL_VIDEODRIVER=directx");
    }
#endif
  }

  p = SDL_Init(flags);

  if (p < 0 && strcasecmp(video_driver, "default"))
  {
    static const union {
      const char *c;
      char *s;
    } u = { "SDL_VIDEODRIVER=" };

    //e6y: wrong videodriver?
    lprintf(LO_ERROR, "Could not initialize SDL with SDL_VIDEODRIVER=%s [%s]\n", video_driver, SDL_GetError());

    putenv(u.s);

    p = SDL_Init(flags);
  }

  free(video_driver);

  if (p < 0)
  {
    I_Error("Could not initialize SDL [%s]", SDL_GetError());
  }

  atexit(I_ShutdownSDL);
}
Exemple #25
0
void TryRunTics ()
{
  int runtics;
  int entertime = I_GetTime();

  // Wait for tics to run
  while (1) {
#ifdef HAVE_NET
    NetUpdate();
#else

    D_BuildNewTiccmds();

#endif
    runtics = (server ? remotetic : maketic) - gametic;

    if (!runtics) {
      if (!movement_smooth) {
#ifdef HAVE_NET
        if (server)
          I_WaitForPacket(ms_to_next_tick);
        else
#endif
          I_uSleep(ms_to_next_tick*1000);
      }

      if (I_GetTime() - entertime > 10) {
#ifdef HAVE_NET
        if (server) {
          char buf[sizeof(packet_header_t)+1];
          remotesend--;
          packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic);
          buf[sizeof(buf)-1] = consoleplayer;
          I_SendPacket((packet_header_t *)buf, sizeof buf);
        }
#endif

        M_Ticker(); return;
      }
      //if ((displaytime) < (tic_vars.next-SDL_GetTicks()))
      {
        WasRenderedInTryRunTics = true;
        if (V_GetMode() == VID_MODEGL ? 
            movement_smooth : 
            movement_smooth && gamestate==wipegamestate)
        {
          isExtraDDisplay = true;
          D_Display(0);
          D_Display(1);
          isExtraDDisplay = false;
        }
      }
    } else break;
  }

  while (runtics--) {
#ifdef HAVE_NET
    if (server) CheckQueuedPackets();
#endif


    if (advancedemo)
      D_DoAdvanceDemo ();


    M_Ticker ();
    I_GetTime_SaveMS();
    G_Ticker ();
    P_Checksum(gametic);
    gametic++;
#ifdef HAVE_NET
    NetUpdate(); // Keep sending our tics to avoid stalling remote nodes
#endif
  }
}
Exemple #26
0
void I_UpdateVideoMode(void)
{
  int init_flags;
  int i;
  video_mode_t mode;

  lprintf(LO_INFO, "I_UpdateVideoMode: %dx%d (%s)\n", SCREENWIDTH, SCREENHEIGHT, desired_fullscreen ? "fullscreen" : "nofullscreen");

  mode = I_GetModeFromString(default_videomode);
  if ((i=M_CheckParm("-vidmode")) && i<myargc-1) {
    mode = I_GetModeFromString(myargv[i+1]);
  }

  V_InitMode(mode);
  V_DestroyUnusedTrueColorPalettes();
  V_FreeScreens();

  I_SetRes();

  // Initialize SDL with this graphics mode
  if (V_GetMode() == VID_MODEGL) {
    init_flags = SDL_OPENGL;
  } else {
    if (use_doublebuffer)
      init_flags = SDL_DOUBLEBUF;
    else
      init_flags = SDL_SWSURFACE;
#ifndef _DEBUG
    init_flags |= SDL_HWPALETTE;
#endif
  }

  if ( desired_fullscreen )
    init_flags |= SDL_FULLSCREEN;

  if (V_GetMode() == VID_MODEGL) {
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, gl_colorbuffer_bits );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, gl_depthbuffer_bits );
    screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, gl_colorbuffer_bits, init_flags);
  } else {
    screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, V_GetNumPixelBits(), init_flags);
  }

  if(screen == NULL) {
    I_Error("Couldn't set %dx%d video mode [%s]", SCREENWIDTH, SCREENHEIGHT, SDL_GetError());
  }

  lprintf(LO_INFO, "I_UpdateVideoMode: 0x%x, %s, %s\n", init_flags, screen->pixels ? "SDL buffer" : "own buffer", SDL_MUSTLOCK(screen) ? "lock-and-copy": "direct access");

  // Get the info needed to render to the display
  if (!SDL_MUSTLOCK(screen))
  {
    screens[0].not_on_heap = true;
    screens[0].data = (unsigned char *) (screen->pixels);
    screens[0].byte_pitch = screen->pitch;
    screens[0].short_pitch = screen->pitch / V_GetModePixelDepth(VID_MODE16);
    screens[0].int_pitch = screen->pitch / V_GetModePixelDepth(VID_MODE32);
  }
  else
  {
    screens[0].not_on_heap = false;
  }

  V_AllocScreens();

  // Hide pointer while over this window
  SDL_ShowCursor(0);

  I_PrepareMouse(1);

  R_InitBuffer(SCREENWIDTH, SCREENHEIGHT);

  if (V_GetMode() == VID_MODEGL) {
    int temp;
    lprintf(LO_INFO,"SDL OpenGL PixelFormat:\n");
    SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_RED_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_GREEN_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_BLUE_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_STENCIL_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_STENCIL_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_ACCUM_RED_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_ACCUM_RED_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_ACCUM_GREEN_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_ACCUM_GREEN_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_ACCUM_BLUE_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_ACCUM_BLUE_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_ACCUM_ALPHA_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &temp );
    lprintf(LO_INFO,"    SDL_GL_DOUBLEBUFFER: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_BUFFER_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_BUFFER_SIZE: %i\n",temp);
    SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &temp );
    lprintf(LO_INFO,"    SDL_GL_DEPTH_SIZE: %i\n",temp);
#ifdef GL_DOOM
    gld_Init(SCREENWIDTH, SCREENHEIGHT);
#endif
  }
}
Exemple #27
0
static void R_AddLine (seg_t *line)
{
  int      x1;
  int      x2;
  angle_t  angle1;
  angle_t  angle2;
  angle_t  span;
  angle_t  tspan;
  static sector_t tempsec;     // killough 3/8/98: ceiling/water hack

  curline = line;

  angle1 = R_PointToAngle (line->v1->x, line->v1->y);
  angle2 = R_PointToAngle (line->v2->x, line->v2->y);

  // Clip to view edges.
  span = angle1 - angle2;

  // Back side, i.e. backface culling
  if (span >= ANG180)
    return;

  // Global angle needed by segcalc.
  rw_angle1 = angle1;
  angle1 -= viewangle;
  angle2 -= viewangle;

  tspan = angle1 + clipangle;
  if (tspan > 2*clipangle)
    {
      tspan -= 2*clipangle;

      // Totally off the left edge?
      if (tspan >= span)
        return;

      angle1 = clipangle;
    }

  tspan = clipangle - angle2;
  if (tspan > 2*clipangle)
    {
      tspan -= 2*clipangle;

      // Totally off the left edge?
      if (tspan >= span)
        return;
      angle2 = 0-clipangle;
    }

  // The seg is in the view range,
  // but not necessarily visible.

  angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
  angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;

  // killough 1/31/98: Here is where "slime trails" can SOMETIMES occur:
  x1 = viewangletox[angle1];
  x2 = viewangletox[angle2];

#ifdef GL_DOOM
  // proff 11/99: we have to add these segs to avoid gaps in OpenGL
  if (x1 >= x2)       // killough 1/31/98 -- change == to >= for robustness
  {
    if (V_GetMode() == VID_MODEGL)
    {
      if (ds_p == drawsegs+maxdrawsegs)   // killough 1/98 -- fix 2s line HOM
      {
        unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a
        unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough
        drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs));
        //ds_p = drawsegs+maxdrawsegs;
        ds_p = drawsegs + pos;          // jff 8/9/98 fix from ZDOOM1.14a
        maxdrawsegs = newmax;
      }
      ds_p->curline = curline;
      ds_p++;
      gld_AddWall(curline);
      return;
    }
    else
      return;
  }
#else
  // Does not cross a pixel?
  if (x1 >= x2)       // killough 1/31/98 -- change == to >= for robustness
    return;
#endif

  backsector = line->backsector;

  // Single sided line?
  if (backsector)
    // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
    backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

  /* cph - roll up linedef properties in flags */
  if ((linedef = curline->linedef)->r_validcount != gametic)
    R_RecalcLineFlags();

  if (linedef->r_flags & RF_IGNORE)
  {
    return;
  }
  else
    R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED);
}
Exemple #28
0
//
// R_RenderView
//
void R_RenderPlayerView (player_t* player)
{
    R_SetupFrame (player);

    // Clear buffers.
    R_ClearClipSegs ();
    R_ClearDrawSegs ();
    R_ClearPlanes ();
    R_ClearSprites ();

    rendered_segs = rendered_visplanes = 0;
    if (V_GetMode() == VID_MODEGL)
    {
#ifdef GL_DOOM
        // proff 11/99: clear buffers
        gld_InitDrawScene();
        // proff 11/99: switch to perspective mode
        gld_StartDrawScene();
#endif
    } else {
        if (autodetect_hom)
        {   // killough 2/10/98: add flashing red HOM indicators
            int color=(gametic % 20) < 9 ? 0xb0 : 0;
            int h=viewheight;
            for (; h>0; h--)
                memset(screens[0].data+(viewwindowy+h)*screens[0].pitch,color,SCREENWIDTH);
            R_DrawViewBorder();
        }
    }

    // check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    // The head node is the last node output.
    R_RenderBSPNode (numnodes-1);

    // Check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    if (V_GetMode() != VID_MODEGL)
        R_DrawPlanes ();

    // Check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    if (V_GetMode() != VID_MODEGL) {
        R_DrawMasked ();
        R_ResetColumnBuffer();
    }

    // Check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    if (V_GetMode() == VID_MODEGL) {
#ifdef GL_DOOM
        // proff 11/99: draw the scene
        gld_DrawScene(player);
        // proff 11/99: finishing off
        gld_EndDrawScene();
#endif
    }

    if (rendering_stats) R_ShowStats();

    R_RestoreInterpolations();
}
Exemple #29
0
static void R_Subsector(int num)
{
  int         count;
  seg_t       *line;
  subsector_t *sub;
  sector_t    tempsec;              // killough 3/7/98: deep water hack
  int         floorlightlevel;      // killough 3/16/98: set floor lightlevel
  int         ceilinglightlevel;    // killough 4/11/98
#ifdef GL_DOOM
  visplane_t dummyfloorplane;
  visplane_t dummyceilingplane;
#endif

#ifdef RANGECHECK
  if (num>=numsubsectors)
    I_Error ("R_Subsector: ss %i with numss = %i", num, numsubsectors);
#endif

  sub = &subsectors[num];
  frontsector = sub->sector;
  count = sub->numlines;
  line = &segs[sub->firstline];

  // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
  frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
                           &ceilinglightlevel, false);   // killough 4/11/98

  // killough 3/7/98: Add (x,y) offsets to flats, add deep water check
  // killough 3/16/98: add floorlightlevel
  // killough 10/98: add support for skies transferred from sidedefs

  floorplane = frontsector->floorheight < viewz || // killough 3/7/98
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
    R_FindPlane(frontsector->floorheight,
                frontsector->floorpic == skyflatnum &&  // kilough 10/98
                frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->floorpic,
                floorlightlevel,                // killough 3/16/98
                frontsector->floor_xoffs,       // killough 3/7/98
                frontsector->floor_yoffs
                ) : NULL;

  ceilingplane = frontsector->ceilingheight > viewz ||
    frontsector->ceilingpic == skyflatnum ||
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].floorpic == skyflatnum) ?
    R_FindPlane(frontsector->ceilingheight,     // killough 3/8/98
                frontsector->ceilingpic == skyflatnum &&  // kilough 10/98
                frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->ceilingpic,
                ceilinglightlevel,              // killough 4/11/98
                frontsector->ceiling_xoffs,     // killough 3/7/98
                frontsector->ceiling_yoffs
                ) : NULL;
#ifdef GL_DOOM
  // check if the sector is faked
  if ((frontsector==sub->sector)  && (V_GetMode() == VID_MODEGL))
  {
    // if the sector has bottomtextures, then the floorheight will be set to the
    // highest surounding floorheight
    if ((frontsector->no_bottomtextures) || (!floorplane))
    {
      int i=frontsector->linecount;

      dummyfloorplane.height=INT_MIN;
      while (i--)
      {
        line_t *tmpline=frontsector->lines[i];
        if (tmpline->backsector)
          if (tmpline->backsector != frontsector)
            if (tmpline->backsector->floorheight>dummyfloorplane.height)
            {
              dummyfloorplane.height=tmpline->backsector->floorheight;
              dummyfloorplane.lightlevel=tmpline->backsector->lightlevel;
            }
        if (tmpline->frontsector)
          if (tmpline->frontsector != frontsector)
            if (tmpline->frontsector->floorheight>dummyfloorplane.height)
            {
              dummyfloorplane.height=tmpline->frontsector->floorheight;
              dummyfloorplane.lightlevel=tmpline->frontsector->lightlevel;
            }
      }
      if (dummyfloorplane.height!=INT_MIN)
        floorplane=&dummyfloorplane;
    }
    // the same for ceilings. they will be set to the lowest ceilingheight
    if ((frontsector->no_toptextures) || (!ceilingplane))
    {
      int i=frontsector->linecount;

      dummyceilingplane.height=INT_MAX;
      while (i--)
      {
        line_t *tmpline=frontsector->lines[i];
        if (tmpline->backsector)
          if (tmpline->backsector != frontsector)
            if (tmpline->backsector->ceilingheight<dummyceilingplane.height)
            {
              dummyceilingplane.height=tmpline->backsector->ceilingheight;
              dummyceilingplane.lightlevel=tmpline->backsector->lightlevel;
            }
        if (tmpline->frontsector)
          if (tmpline->frontsector != frontsector)
            if (tmpline->frontsector->ceilingheight<dummyceilingplane.height)
            {
              dummyceilingplane.height=tmpline->frontsector->ceilingheight;
              dummyceilingplane.lightlevel=tmpline->frontsector->lightlevel;
            }
      }
      if (dummyceilingplane.height!=INT_MAX)
        ceilingplane=&dummyceilingplane;
    }
  }
#endif

  // killough 9/18/98: Fix underwater slowdown, by passing real sector
  // instead of fake one. Improve sprite lighting by basing sprite
  // lightlevels on floor & ceiling lightlevels in the surrounding area.
  //
  // 10/98 killough:
  //
  // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
  // That is part of the 242 effect!!!  If you simply pass sub->sector to
  // the old code you will not get correct lighting for underwater sprites!!!
  // Either you must pass the fake sector and handle validcount here, on the
  // real sector, or you must account for the lighting in some other way,
  // like passing it as an argument.

  R_AddSprites(sub, (floorlightlevel+ceilinglightlevel)/2);
  while (count--)
  {
    if (line->miniseg == false)
      R_AddLine (line);
    line++;
    curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so R_ColourMap doesn't try using it for other things */
  }
#ifdef GL_DOOM
  if (V_GetMode() == VID_MODEGL)
    gld_AddPlane(num, floorplane, ceilingplane);
#endif
}
Exemple #30
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);
}