Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "wl_def.h"
  2.  
  3.  
  4. pictabletype    *pictable;
  5. SDL_Surface     *latchpics[NUMLATCHPICS];
  6.  
  7. int         px,py;
  8. byte    fontcolor,backcolor;
  9. int         fontnumber;
  10.  
  11. //==========================================================================
  12.  
  13. void VWB_DrawPropString(const char* string)
  14. {
  15.         fontstruct  *font;
  16.         int                 width, step, height;
  17.         byte        *source, *dest;
  18.         byte        ch;
  19.         int i;
  20.         unsigned sx, sy;
  21.  
  22.         byte *vbuf = VL_LockSurface(curSurface);
  23.         if(vbuf == NULL) return;
  24.  
  25.         font = (fontstruct *) grsegs[STARTFONT+fontnumber];
  26.         height = font->height;
  27.         dest = vbuf + scaleFactor * (py * curPitch + px);
  28.  
  29.         while ((ch = (byte)*string++)!=0)
  30.         {
  31.                 width = step = font->width[ch];
  32.                 source = ((byte *)font)+font->location[ch];
  33.                 while (width--)
  34.                 {
  35.                         for(i=0; i<height; i++)
  36.                         {
  37.                                 if(source[i*step])
  38.                                 {
  39.                                         for(sy=0; sy<scaleFactor; sy++)
  40.                                                 for(sx=0; sx<scaleFactor; sx++)
  41.                                                         dest[(scaleFactor*i+sy)*curPitch+sx]=fontcolor;
  42.                                 }
  43.                         }
  44.  
  45.                         source++;
  46.                         px++;
  47.                         dest+=scaleFactor;
  48.                 }
  49.         }
  50.  
  51.         VL_UnlockSurface(curSurface);
  52. }
  53.  
  54. /*
  55. =================
  56. =
  57. = VL_MungePic
  58. =
  59. =================
  60. */
  61.  
  62. void VL_MungePic (byte *source, unsigned width, unsigned height)
  63. {
  64.         unsigned x,y,plane,size,pwidth;
  65.         byte *temp, *dest, *srcline;
  66.  
  67.         size = width*height;
  68.  
  69.         if (width&3)
  70.                 Quit ("VL_MungePic: Not divisable by 4!");
  71.  
  72. //
  73. // copy the pic to a temp buffer
  74. //
  75.         temp=(byte *) malloc(size);
  76.     CHECKMALLOCRESULT(temp);
  77.         memcpy (temp,source,size);
  78.  
  79. //
  80. // munge it back into the original buffer
  81. //
  82.         dest = source;
  83.         pwidth = width/4;
  84.  
  85.         for (plane=0;plane<4;plane++)
  86.         {
  87.                 srcline = temp;
  88.                 for (y=0;y<height;y++)
  89.                 {
  90.                         for (x=0;x<pwidth;x++)
  91.                                 *dest++ = *(srcline+x*4+plane);
  92.                         srcline+=width;
  93.                 }
  94.         }
  95.  
  96.         free(temp);
  97. }
  98.  
  99. void VWL_MeasureString (const char *string, word *width, word *height, fontstruct *font)
  100. {
  101.         *height = font->height;
  102.         for (*width = 0;*string;string++)
  103.                 *width += font->width[*((byte *)string)];       // proportional width
  104. }
  105.  
  106. void VW_MeasurePropString (const char *string, word *width, word *height)
  107. {
  108.         VWL_MeasureString(string,width,height,(fontstruct *)grsegs[STARTFONT+fontnumber]);
  109. }
  110.  
  111. /*
  112. =============================================================================
  113.  
  114.                                 Double buffer management routines
  115.  
  116. =============================================================================
  117. */
  118.  
  119. void VH_UpdateScreen()
  120. {
  121.         SDL_BlitSurface(screenBuffer, NULL, screen, NULL);
  122.         SDL_Flip(screen);
  123. }
  124.  
  125.  
  126. void VWB_DrawTile8 (int x, int y, int tile)
  127. {
  128.         LatchDrawChar(x,y,tile);
  129. }
  130.  
  131. void VWB_DrawTile8M (int x, int y, int tile)
  132. {
  133.         VL_MemToScreen (((byte *)grsegs[STARTTILE8M])+tile*64,8,8,x,y);
  134. }
  135.  
  136. void VWB_DrawPic (int x, int y, int chunknum)
  137. {
  138.         int     picnum = chunknum - STARTPICS;
  139.         unsigned width,height;
  140.  
  141.         x &= ~7;
  142.  
  143.         width = pictable[picnum].width;
  144.         height = pictable[picnum].height;
  145.  
  146.         VL_MemToScreen (grsegs[chunknum],width,height,x,y);
  147. }
  148.  
  149. void VWB_DrawPicScaledCoord (int scx, int scy, int chunknum)
  150. {
  151.         int     picnum = chunknum - STARTPICS;
  152.         unsigned width,height;
  153.  
  154.         width = pictable[picnum].width;
  155.         height = pictable[picnum].height;
  156.  
  157.     VL_MemToScreenScaledCoord (grsegs[chunknum],width,height,scx,scy);
  158. }
  159.  
  160.  
  161. void VWB_Bar (int x, int y, int width, int height, int color)
  162. {
  163.         VW_Bar (x,y,width,height,color);
  164. }
  165.  
  166. void VWB_Plot (int x, int y, int color)
  167. {
  168.     if(scaleFactor == 1)
  169.         VW_Plot(x,y,color);
  170.     else
  171.         VW_Bar(x, y, 1, 1, color);
  172. }
  173.  
  174. void VWB_Hlin (int x1, int x2, int y, int color)
  175. {
  176.     if(scaleFactor == 1)
  177.         VW_Hlin(x1,x2,y,color);
  178.     else
  179.         VW_Bar(x1, y, x2-x1+1, 1, color);
  180. }
  181.  
  182. void VWB_Vlin (int y1, int y2, int x, int color)
  183. {
  184.     if(scaleFactor == 1)
  185.                 VW_Vlin(y1,y2,x,color);
  186.     else
  187.         VW_Bar(x, y1, 1, y2-y1+1, color);
  188. }
  189.  
  190.  
  191. /*
  192. =============================================================================
  193.  
  194.                                                 WOLFENSTEIN STUFF
  195.  
  196. =============================================================================
  197. */
  198.  
  199. /*
  200. =====================
  201. =
  202. = LatchDrawPic
  203. =
  204. =====================
  205. */
  206.  
  207. void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)
  208. {
  209.         VL_LatchToScreen (latchpics[2+picnum-LATCHPICS_LUMP_START], x*8, y);
  210. }
  211.  
  212. void LatchDrawPicScaledCoord (unsigned scx, unsigned scy, unsigned picnum)
  213. {
  214.         VL_LatchToScreenScaledCoord (latchpics[2+picnum-LATCHPICS_LUMP_START], scx*8, scy);
  215. }
  216.  
  217.  
  218. //==========================================================================
  219.  
  220. void FreeLatchMem()
  221. {
  222.     int i;
  223.     for(i = 0; i < 2 + LATCHPICS_LUMP_END - LATCHPICS_LUMP_START; i++)
  224.     {
  225.         SDL_FreeSurface(latchpics[i]);
  226.         latchpics[i] = NULL;
  227.     }
  228. }
  229.  
  230. /*
  231. ===================
  232. =
  233. = LoadLatchMem
  234. =
  235. ===================
  236. */
  237.  
  238. void LoadLatchMem (void)
  239. {
  240.         int     i,width,height,start,end;
  241.         byte *src;
  242.         SDL_Surface *surf;
  243.  
  244. //
  245. // tile 8s
  246. //
  247.     surf = SDL_CreateRGBSurface(SDL_HWSURFACE, 8*8,
  248.         ((NUMTILE8 + 7) / 8) * 8, 8, 0, 0, 0, 0);
  249.     if(surf == NULL)
  250.     {
  251.         Quit("Unable to create surface for tiles!");
  252.     }
  253.     SDL_SetColors(surf, gamepal, 0, 256);
  254.  
  255.         latchpics[0] = surf;
  256.         CA_CacheGrChunk (STARTTILE8);
  257.         src = grsegs[STARTTILE8];
  258.  
  259.         for (i=0;i<NUMTILE8;i++)
  260.         {
  261.                 VL_MemToLatch (src, 8, 8, surf, (i & 7) * 8, (i >> 3) * 8);
  262.                 src += 64;
  263.         }
  264.         UNCACHEGRCHUNK (STARTTILE8);
  265.  
  266.         latchpics[1] = NULL;  // not used
  267.  
  268. //
  269. // pics
  270. //
  271.         start = LATCHPICS_LUMP_START;
  272.         end = LATCHPICS_LUMP_END;
  273.  
  274.         for (i=start;i<=end;i++)
  275.         {
  276.                 width = pictable[i-STARTPICS].width;
  277.                 height = pictable[i-STARTPICS].height;
  278.                 surf = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, 8, 0, 0, 0, 0);
  279.         if(surf == NULL)
  280.         {
  281.             Quit("Unable to create surface for picture!");
  282.         }
  283.         SDL_SetColors(surf, gamepal, 0, 256);
  284.  
  285.                 latchpics[2+i-start] = surf;
  286.                 CA_CacheGrChunk (i);
  287.                 VL_MemToLatch (grsegs[i], width, height, surf, 0, 0);
  288.                 UNCACHEGRCHUNK(i);
  289.         }
  290. }
  291.  
  292. //==========================================================================
  293.  
  294. /*
  295. ===================
  296. =
  297. = FizzleFade
  298. =
  299. = returns true if aborted
  300. =
  301. = It uses maximum-length Linear Feedback Shift Registers (LFSR) counters.
  302. = You can find a list of them with lengths from 3 to 168 at:
  303. = http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
  304. = Many thanks to Xilinx for this list!!!
  305. =
  306. ===================
  307. */
  308.  
  309. // XOR masks for the pseudo-random number sequence starting with n=17 bits
  310. static const uint32_t rndmasks[] = {
  311.                     // n    XNOR from (starting at 1, not 0 as usual)
  312.     0x00012000,     // 17   17,14
  313.     0x00020400,     // 18   18,11
  314.     0x00040023,     // 19   19,6,2,1
  315.     0x00090000,     // 20   20,17
  316.     0x00140000,     // 21   21,19
  317.     0x00300000,     // 22   22,21
  318.     0x00420000,     // 23   23,18
  319.     0x00e10000,     // 24   24,23,22,17
  320.     0x01200000,     // 25   25,22      (this is enough for 8191x4095)
  321. };
  322.  
  323. static unsigned int rndbits_y;
  324. static unsigned int rndmask;
  325.  
  326. extern SDL_Color curpal[256];
  327.  
  328. // Returns the number of bits needed to represent the given value
  329. static int log2_ceil(uint32_t x)
  330. {
  331.     int n = 0;
  332.     uint32_t v = 1;
  333.     while(v < x)
  334.     {
  335.         n++;
  336.         v <<= 1;
  337.     }
  338.     return n;
  339. }
  340.  
  341. void VH_Startup()
  342. {
  343.     int rndbits_x = log2_ceil(screenWidth);
  344.     rndbits_y = log2_ceil(screenHeight);
  345.  
  346.     int rndbits = rndbits_x + rndbits_y;
  347.     if(rndbits < 17)
  348.         rndbits = 17;       // no problem, just a bit slower
  349.     else if(rndbits > 25)
  350.         rndbits = 25;       // fizzle fade will not fill whole screen
  351.  
  352.     rndmask = rndmasks[rndbits - 17];
  353. }
  354.  
  355. boolean FizzleFade (SDL_Surface *source, int x1, int y1,
  356.     unsigned width, unsigned height, unsigned frames, boolean abortable)
  357. {
  358.     unsigned x, y, frame, pixperframe;
  359.     int32_t  rndval, lastrndval;
  360.     int      first = 1;
  361.  
  362.     lastrndval = 0;
  363.     pixperframe = width * height / frames;
  364.  
  365.     IN_StartAck ();
  366.  
  367.     frame = GetTimeCount();
  368.     byte *srcptr = VL_LockSurface(source);
  369.     if(srcptr == NULL) return false;
  370.  
  371.     do
  372.     {
  373.         IN_ProcessEvents();
  374.  
  375.         if(abortable && IN_CheckAck ())
  376.         {
  377.             VL_UnlockSurface(source);
  378.             SDL_BlitSurface(source, NULL, screen, NULL);
  379.             SDL_Flip(screen);
  380.             return true;
  381.         }
  382.  
  383.         byte *destptr = VL_LockSurface(screen);
  384.  
  385.         if(destptr != NULL)
  386.         {
  387.             rndval = lastrndval;
  388.  
  389.             // When using double buffering, we have to copy the pixels of the last AND the current frame.
  390.             // Only for the first frame, there is no "last frame"
  391.             for(int i = first; i < 2; i++)
  392.             {
  393.                 for(unsigned p = 0; p < pixperframe; p++)
  394.                 {
  395.                     //
  396.                     // seperate random value into x/y pair
  397.                     //
  398.  
  399.                     x = rndval >> rndbits_y;
  400.                     y = rndval & ((1 << rndbits_y) - 1);
  401.  
  402.                     //
  403.                     // advance to next random element
  404.                     //
  405.  
  406.                     rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask);
  407.  
  408.                     if(x >= width || y >= height)
  409.                     {
  410.                         if(rndval == 0)     // entire sequence has been completed
  411.                             goto finished;
  412.                         p--;
  413.                         continue;
  414.                     }
  415.  
  416.                     //
  417.                     // copy one pixel
  418.                     //
  419.  
  420.                     if(screenBits == 8)
  421.                     {
  422.                         *(destptr + (y1 + y) * screen->pitch + x1 + x)
  423.                             = *(srcptr + (y1 + y) * source->pitch + x1 + x);
  424.                     }
  425.                     else
  426.                     {
  427.                         byte col = *(srcptr + (y1 + y) * source->pitch + x1 + x);
  428.                         uint32_t fullcol = SDL_MapRGB(screen->format, curpal[col].r, curpal[col].g, curpal[col].b);
  429.                         memcpy(destptr + (y1 + y) * screen->pitch + (x1 + x) * screen->format->BytesPerPixel,
  430.                             &fullcol, screen->format->BytesPerPixel);
  431.                     }
  432.  
  433.                     if(rndval == 0)             // entire sequence has been completed
  434.                         goto finished;
  435.                 }
  436.  
  437.                 if(!i || first) lastrndval = rndval;
  438.             }
  439.  
  440.             // If there is no double buffering, we always use the "first frame" case
  441.             if(usedoublebuffering) first = 0;
  442.  
  443.             VL_UnlockSurface(screen);
  444.             SDL_Flip(screen);
  445.         }
  446.         else
  447.         {
  448.             // No surface, so only enhance rndval
  449.             for(int i = first; i < 2; i++)
  450.             {
  451.                 for(unsigned p = 0; p < pixperframe; p++)
  452.                 {
  453.                     rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask);
  454.                     if(rndval == 0)
  455.                         goto finished;
  456.                 }
  457.             }
  458.         }
  459.  
  460.         frame++;
  461.         Delay(frame - GetTimeCount());        // don't go too fast
  462.     } while (1);
  463.  
  464. finished:
  465.     VL_UnlockSurface(source);
  466.     VL_UnlockSurface(screen);
  467.     SDL_BlitSurface(source, NULL, screen, NULL);
  468.     SDL_Flip(screen);
  469.     return false;
  470. }
  471.