0,0 → 1,470 |
#include "wl_def.h" |
|
|
pictabletype *pictable; |
SDL_Surface *latchpics[NUMLATCHPICS]; |
|
int px,py; |
byte fontcolor,backcolor; |
int fontnumber; |
|
//========================================================================== |
|
void VWB_DrawPropString(const char* string) |
{ |
fontstruct *font; |
int width, step, height; |
byte *source, *dest; |
byte ch; |
int i; |
unsigned sx, sy; |
|
byte *vbuf = VL_LockSurface(curSurface); |
if(vbuf == NULL) return; |
|
font = (fontstruct *) grsegs[STARTFONT+fontnumber]; |
height = font->height; |
dest = vbuf + scaleFactor * (py * curPitch + px); |
|
while ((ch = (byte)*string++)!=0) |
{ |
width = step = font->width[ch]; |
source = ((byte *)font)+font->location[ch]; |
while (width--) |
{ |
for(i=0; i<height; i++) |
{ |
if(source[i*step]) |
{ |
for(sy=0; sy<scaleFactor; sy++) |
for(sx=0; sx<scaleFactor; sx++) |
dest[(scaleFactor*i+sy)*curPitch+sx]=fontcolor; |
} |
} |
|
source++; |
px++; |
dest+=scaleFactor; |
} |
} |
|
VL_UnlockSurface(curSurface); |
} |
|
/* |
================= |
= |
= VL_MungePic |
= |
================= |
*/ |
|
void VL_MungePic (byte *source, unsigned width, unsigned height) |
{ |
unsigned x,y,plane,size,pwidth; |
byte *temp, *dest, *srcline; |
|
size = width*height; |
|
if (width&3) |
Quit ("VL_MungePic: Not divisable by 4!"); |
|
// |
// copy the pic to a temp buffer |
// |
temp=(byte *) malloc(size); |
CHECKMALLOCRESULT(temp); |
memcpy (temp,source,size); |
|
// |
// munge it back into the original buffer |
// |
dest = source; |
pwidth = width/4; |
|
for (plane=0;plane<4;plane++) |
{ |
srcline = temp; |
for (y=0;y<height;y++) |
{ |
for (x=0;x<pwidth;x++) |
*dest++ = *(srcline+x*4+plane); |
srcline+=width; |
} |
} |
|
free(temp); |
} |
|
void VWL_MeasureString (const char *string, word *width, word *height, fontstruct *font) |
{ |
*height = font->height; |
for (*width = 0;*string;string++) |
*width += font->width[*((byte *)string)]; // proportional width |
} |
|
void VW_MeasurePropString (const char *string, word *width, word *height) |
{ |
VWL_MeasureString(string,width,height,(fontstruct *)grsegs[STARTFONT+fontnumber]); |
} |
|
/* |
============================================================================= |
|
Double buffer management routines |
|
============================================================================= |
*/ |
|
void VH_UpdateScreen() |
{ |
SDL_BlitSurface(screenBuffer, NULL, screen, NULL); |
SDL_Flip(screen); |
} |
|
|
void VWB_DrawTile8 (int x, int y, int tile) |
{ |
LatchDrawChar(x,y,tile); |
} |
|
void VWB_DrawTile8M (int x, int y, int tile) |
{ |
VL_MemToScreen (((byte *)grsegs[STARTTILE8M])+tile*64,8,8,x,y); |
} |
|
void VWB_DrawPic (int x, int y, int chunknum) |
{ |
int picnum = chunknum - STARTPICS; |
unsigned width,height; |
|
x &= ~7; |
|
width = pictable[picnum].width; |
height = pictable[picnum].height; |
|
VL_MemToScreen (grsegs[chunknum],width,height,x,y); |
} |
|
void VWB_DrawPicScaledCoord (int scx, int scy, int chunknum) |
{ |
int picnum = chunknum - STARTPICS; |
unsigned width,height; |
|
width = pictable[picnum].width; |
height = pictable[picnum].height; |
|
VL_MemToScreenScaledCoord (grsegs[chunknum],width,height,scx,scy); |
} |
|
|
void VWB_Bar (int x, int y, int width, int height, int color) |
{ |
VW_Bar (x,y,width,height,color); |
} |
|
void VWB_Plot (int x, int y, int color) |
{ |
if(scaleFactor == 1) |
VW_Plot(x,y,color); |
else |
VW_Bar(x, y, 1, 1, color); |
} |
|
void VWB_Hlin (int x1, int x2, int y, int color) |
{ |
if(scaleFactor == 1) |
VW_Hlin(x1,x2,y,color); |
else |
VW_Bar(x1, y, x2-x1+1, 1, color); |
} |
|
void VWB_Vlin (int y1, int y2, int x, int color) |
{ |
if(scaleFactor == 1) |
VW_Vlin(y1,y2,x,color); |
else |
VW_Bar(x, y1, 1, y2-y1+1, color); |
} |
|
|
/* |
============================================================================= |
|
WOLFENSTEIN STUFF |
|
============================================================================= |
*/ |
|
/* |
===================== |
= |
= LatchDrawPic |
= |
===================== |
*/ |
|
void LatchDrawPic (unsigned x, unsigned y, unsigned picnum) |
{ |
VL_LatchToScreen (latchpics[2+picnum-LATCHPICS_LUMP_START], x*8, y); |
} |
|
void LatchDrawPicScaledCoord (unsigned scx, unsigned scy, unsigned picnum) |
{ |
VL_LatchToScreenScaledCoord (latchpics[2+picnum-LATCHPICS_LUMP_START], scx*8, scy); |
} |
|
|
//========================================================================== |
|
void FreeLatchMem() |
{ |
int i; |
for(i = 0; i < 2 + LATCHPICS_LUMP_END - LATCHPICS_LUMP_START; i++) |
{ |
SDL_FreeSurface(latchpics[i]); |
latchpics[i] = NULL; |
} |
} |
|
/* |
=================== |
= |
= LoadLatchMem |
= |
=================== |
*/ |
|
void LoadLatchMem (void) |
{ |
int i,width,height,start,end; |
byte *src; |
SDL_Surface *surf; |
|
// |
// tile 8s |
// |
surf = SDL_CreateRGBSurface(SDL_HWSURFACE, 8*8, |
((NUMTILE8 + 7) / 8) * 8, 8, 0, 0, 0, 0); |
if(surf == NULL) |
{ |
Quit("Unable to create surface for tiles!"); |
} |
SDL_SetColors(surf, gamepal, 0, 256); |
|
latchpics[0] = surf; |
CA_CacheGrChunk (STARTTILE8); |
src = grsegs[STARTTILE8]; |
|
for (i=0;i<NUMTILE8;i++) |
{ |
VL_MemToLatch (src, 8, 8, surf, (i & 7) * 8, (i >> 3) * 8); |
src += 64; |
} |
UNCACHEGRCHUNK (STARTTILE8); |
|
latchpics[1] = NULL; // not used |
|
// |
// pics |
// |
start = LATCHPICS_LUMP_START; |
end = LATCHPICS_LUMP_END; |
|
for (i=start;i<=end;i++) |
{ |
width = pictable[i-STARTPICS].width; |
height = pictable[i-STARTPICS].height; |
surf = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, 8, 0, 0, 0, 0); |
if(surf == NULL) |
{ |
Quit("Unable to create surface for picture!"); |
} |
SDL_SetColors(surf, gamepal, 0, 256); |
|
latchpics[2+i-start] = surf; |
CA_CacheGrChunk (i); |
VL_MemToLatch (grsegs[i], width, height, surf, 0, 0); |
UNCACHEGRCHUNK(i); |
} |
} |
|
//========================================================================== |
|
/* |
=================== |
= |
= FizzleFade |
= |
= returns true if aborted |
= |
= It uses maximum-length Linear Feedback Shift Registers (LFSR) counters. |
= You can find a list of them with lengths from 3 to 168 at: |
= http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf |
= Many thanks to Xilinx for this list!!! |
= |
=================== |
*/ |
|
// XOR masks for the pseudo-random number sequence starting with n=17 bits |
static const uint32_t rndmasks[] = { |
// n XNOR from (starting at 1, not 0 as usual) |
0x00012000, // 17 17,14 |
0x00020400, // 18 18,11 |
0x00040023, // 19 19,6,2,1 |
0x00090000, // 20 20,17 |
0x00140000, // 21 21,19 |
0x00300000, // 22 22,21 |
0x00420000, // 23 23,18 |
0x00e10000, // 24 24,23,22,17 |
0x01200000, // 25 25,22 (this is enough for 8191x4095) |
}; |
|
static unsigned int rndbits_y; |
static unsigned int rndmask; |
|
extern SDL_Color curpal[256]; |
|
// Returns the number of bits needed to represent the given value |
static int log2_ceil(uint32_t x) |
{ |
int n = 0; |
uint32_t v = 1; |
while(v < x) |
{ |
n++; |
v <<= 1; |
} |
return n; |
} |
|
void VH_Startup() |
{ |
int rndbits_x = log2_ceil(screenWidth); |
rndbits_y = log2_ceil(screenHeight); |
|
int rndbits = rndbits_x + rndbits_y; |
if(rndbits < 17) |
rndbits = 17; // no problem, just a bit slower |
else if(rndbits > 25) |
rndbits = 25; // fizzle fade will not fill whole screen |
|
rndmask = rndmasks[rndbits - 17]; |
} |
|
boolean FizzleFade (SDL_Surface *source, int x1, int y1, |
unsigned width, unsigned height, unsigned frames, boolean abortable) |
{ |
unsigned x, y, frame, pixperframe; |
int32_t rndval, lastrndval; |
int first = 1; |
|
lastrndval = 0; |
pixperframe = width * height / frames; |
|
IN_StartAck (); |
|
frame = GetTimeCount(); |
byte *srcptr = VL_LockSurface(source); |
if(srcptr == NULL) return false; |
|
do |
{ |
IN_ProcessEvents(); |
|
if(abortable && IN_CheckAck ()) |
{ |
VL_UnlockSurface(source); |
SDL_BlitSurface(source, NULL, screen, NULL); |
SDL_Flip(screen); |
return true; |
} |
|
byte *destptr = VL_LockSurface(screen); |
|
if(destptr != NULL) |
{ |
rndval = lastrndval; |
|
// When using double buffering, we have to copy the pixels of the last AND the current frame. |
// Only for the first frame, there is no "last frame" |
for(int i = first; i < 2; i++) |
{ |
for(unsigned p = 0; p < pixperframe; p++) |
{ |
// |
// seperate random value into x/y pair |
// |
|
x = rndval >> rndbits_y; |
y = rndval & ((1 << rndbits_y) - 1); |
|
// |
// advance to next random element |
// |
|
rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask); |
|
if(x >= width || y >= height) |
{ |
if(rndval == 0) // entire sequence has been completed |
goto finished; |
p--; |
continue; |
} |
|
// |
// copy one pixel |
// |
|
if(screenBits == 8) |
{ |
*(destptr + (y1 + y) * screen->pitch + x1 + x) |
= *(srcptr + (y1 + y) * source->pitch + x1 + x); |
} |
else |
{ |
byte col = *(srcptr + (y1 + y) * source->pitch + x1 + x); |
uint32_t fullcol = SDL_MapRGB(screen->format, curpal[col].r, curpal[col].g, curpal[col].b); |
memcpy(destptr + (y1 + y) * screen->pitch + (x1 + x) * screen->format->BytesPerPixel, |
&fullcol, screen->format->BytesPerPixel); |
} |
|
if(rndval == 0) // entire sequence has been completed |
goto finished; |
} |
|
if(!i || first) lastrndval = rndval; |
} |
|
// If there is no double buffering, we always use the "first frame" case |
if(usedoublebuffering) first = 0; |
|
VL_UnlockSurface(screen); |
SDL_Flip(screen); |
} |
else |
{ |
// No surface, so only enhance rndval |
for(int i = first; i < 2; i++) |
{ |
for(unsigned p = 0; p < pixperframe; p++) |
{ |
rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask); |
if(rndval == 0) |
goto finished; |
} |
} |
} |
|
frame++; |
Delay(frame - GetTimeCount()); // don't go too fast |
} while (1); |
|
finished: |
VL_UnlockSurface(source); |
VL_UnlockSurface(screen); |
SDL_BlitSurface(source, NULL, screen, NULL); |
SDL_Flip(screen); |
return false; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |