home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 October / Chip Ekim 2003.iso / prog / share / tod / setup.exe / rec.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-16  |  20.8 KB  |  804 lines

  1. #include <stdio.h>
  2. #include "tod.h"
  3. #include "hgrcos.h"
  4. #include "hiscore.h"
  5. #include <time.h>
  6.  
  7. #define FRAMERATE 60
  8.  
  9. int windowWid = 320;
  10. int windowHt  = 200;
  11.  
  12. #define NUM_RES 8
  13.  
  14. int xRes[NUM_RES] = {320, 320, 400, 512, 640, 640, 800,1024};
  15. int yRes[NUM_RES] = {200, 240, 300, 384, 400, 480, 600, 768};
  16. char lucidName[NUM_RES][NUM_RES] =
  17. {
  18.   "LUCID12", "LUCID12", "LUCID16", "LUCID20",
  19.   "LUCID24", "LUCID24", "LUCID32", "LUCID40"
  20. };
  21.  
  22. int playing_midi = 1;
  23.  
  24.  
  25. /* deformities:
  26.  
  27. So far we have eight degrees of freedom synchronized to the music.
  28. (Tetripz seems to have had about five.)
  29.  
  30. InitSidesPhi()
  31.         scaling (old)
  32.         x axis rotation (new)
  33. DisplaceScanlines()
  34.         ay^3 scanline displacement (new)
  35.         by^2 scanline displacement (old)
  36.         cy scanline displacement (new)
  37.         d scanline displacement (new)
  38.         sinusoidal x shift phase, amplitude, frequency (old)
  39. polynomial x shift: DisplaceScanlines()
  40. z axis rotation: RotateSides()
  41.  
  42. Currently unimplemented:
  43.  
  44. sinusoidal x scaling (new)
  45. polynomial x scaling (new)
  46. InitSidesPoly() : scaling + polynomial scanline displacement (new)
  47.  
  48. Degrees of freedom synchronized to the gameplay:
  49. DisplaceSides()
  50.         x shift (old)
  51.         y shift (old)
  52.  
  53. Game modes:
  54.         Classic (old)
  55.         Block Hole (new)
  56.  
  57. */
  58.  
  59. RGB *pal;
  60. volatile Timers timers;
  61. BITMAP *tetbits;
  62. FONT *lucid;
  63.  
  64.  
  65. void timerint(void)
  66. {
  67.   if(!timers.paused)
  68.   {
  69.     timers.odo++;
  70.     timers.trip++;
  71.   }
  72. } END_OF_FUNCTION(timerint);
  73.  
  74. void *GetResource(DATAFILE *dat, const char *name)
  75. {
  76.   DATAFILE *that = find_datafile_object(dat, (char *)name);
  77.   return that ? that->dat : NULL;
  78. }
  79.  
  80.  
  81. /* On some Windows 9x versions + video drivers + DirectX versions +
  82.  * Allegro versions, clear() and its workhorse clear_to_color()
  83.  * cause the program to dump core.  This doesn't.
  84.  */
  85. void clear2color(BITMAP *bmp, int color)
  86. {
  87.   rectfill(bmp, 0, 0, bmp->w - 1, bmp->h - 1, color);
  88. }
  89.  
  90.  
  91. static char *GetRes_List(int index, int *list_size)
  92. {
  93.   static char resname[16];
  94.   if(index < 0)
  95.   {
  96.     *list_size = NUM_RES;
  97.     return NULL;
  98.   }
  99.   else
  100.   {
  101.     sprintf(resname, "%4dx%3d", xRes[index], yRes[index]);
  102.     return resname;
  103.   }
  104. }
  105.  
  106. int GetRes(char *aimsn)
  107. {
  108.   int chosen;
  109.  
  110.   DIALOG dlg[] =
  111.   {
  112.    /* (dialog proc)     (x)   (y)   (w)   (h)   (fg)  (bg)  (key) (flags)  (d1)  (d2)  (dp) */
  113.    { d_box_proc,        0,    0,    288,  176,  0,    7,    0,    0,       0,    0,    NULL },
  114.    { d_button_proc,     208,  160,  48,   12,   0,    7,    13,   D_EXIT,  0,    0,    "Go"},
  115.    { d_button_proc,     144,  160,  64,   12,   0,    7,    27,   D_EXIT,  0,    0,    "Cancel"},
  116.    { d_list_proc,       96,   27,   80,   70,   0,    7,    'r',  D_EXIT,  0,    0,    GetRes_List },
  117.    { DY_check_proc,     24,   108,  144,  8,    0,    7,    'm',  D_SELECTED,0,  0,    "Play &MIDI"},
  118.    { DY_check_proc,     24,   120,  144,  8,    0,    7,    'j',  0,       0,    0,    "Use &joysticks"},
  119.    { d_text_proc,       24,   27,   88,   16,   0,    7,    0,    0,       0,    0,    "&Screen:"},
  120.    { d_text_proc,       24,   10,   136,  16,   0,    7,    0,    0,       0,    0,    "tetanus on drugs."},
  121.    { DY_idle_proc,      0,    0,    0,    0,    0,    0,    0,    0,       0,    0,    NULL },
  122.    { NULL,              0,    0,    0,    0,    0,    0,    0,    0,       0,    0,    NULL }
  123.   };
  124.  
  125.   /* Some VGAs garble 400x300 without returning error. */
  126.   if(set_gfx_mode(GFX_AUTODETECT, 320, 240, 0, 0) < 0)
  127.     if(set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) < 0)
  128.       return -1;
  129.  
  130.   centre_dialog(dlg);
  131.   install_keyboard();
  132.   install_joystick(JOY_TYPE_AUTODETECT);
  133.   if(num_joysticks == 0)
  134.     dlg[5].flags |= D_DISABLED;
  135.   else
  136.     dlg[5].flags |= D_SELECTED;
  137.  
  138.   if(popup_dialog(dlg, 3) == 2)
  139.   {
  140.     set_gfx_mode(GFX_TEXT, 80, 50, 0, 0);
  141.     return -1;
  142.   }
  143.  
  144.   chosen = dlg[3].d1;
  145.   playing_midi = (dlg[4].flags & D_SELECTED) != 0;
  146.   g.usingJoy = (dlg[5].flags & D_SELECTED) != 0;
  147.  
  148.   windowWid = xRes[chosen];
  149.   windowHt = yRes[chosen];
  150.  
  151.   if(set_gfx_mode(GFX_AUTODETECT, xRes[chosen], yRes[chosen], 0, 0) < 0)
  152.   {
  153.     set_gfx_mode(GFX_TEXT, 80, 50, 0, 0);
  154.     return -1;
  155.   }
  156.  
  157.   return chosen;
  158. }
  159.  
  160.  
  161. int GetOpts(char *aimsn, BITMAP *todlogo)
  162. {
  163.   DIALOG dlg[] =
  164.   {
  165.    /* (dialog proc)     (x)   (y)   (w)   (h)   (fg)  (bg)  (key) (flags)  (d1)  (d2)  (dp) */
  166.    { d_box_proc,        0,    0,    320,  200,  0,    0,    0,    0,       0,    0,    NULL },
  167.    { d_button_proc,     240,  184,  60,   12,   63,   0,    13,   D_EXIT,  0,    0,    "Play"},
  168.    { d_button_proc,     170,  184,  60,   12,   63,   0,    27,   D_EXIT,  0,    0,    "Cancel"},
  169.    { DY_check_proc,     24,   120,  144,  8,    63,   0,    't',  0,       0,    0,    "&The New Tetanus"},
  170.    { DY_check_proc,     24,   132,  144,  8,    63,   0,    '2',  0,       0,    0,    "&2-player (prealpha)"},
  171.    { DY_bitmap_proc,    0,    0,    320,  100,  63,   0,    0,    0,       0,    0,    todlogo },
  172.    { d_text_proc,       128,  104,  136,  8,    63,   0,    'n',  D_EXIT,  16,   0,    aimsn},
  173.    { DY_idle_proc,      0,    0,    0,    0,    0,    0,    0,    0,       0,    0,    NULL },
  174.    { NULL,              0,    0,    0,    0,    0,    0,    0,    0,       0,    0,    NULL }
  175.   };
  176.  
  177.   stop_midi();
  178.  
  179.   if(g.tntMode)
  180.     dlg[3].flags |= D_SELECTED;
  181.   if(nPlayers == 2)
  182.     dlg[4].flags |= D_SELECTED;
  183.  
  184.   centre_dialog(dlg);
  185.   install_keyboard();
  186.   install_joystick(JOY_TYPE_AUTODETECT);
  187.  
  188.   if(popup_dialog(dlg, 3) == 2)
  189.   {
  190.     return -1;
  191.   }
  192.  
  193.   g.tntMode = (dlg[3].flags & D_SELECTED) != 0;
  194.   nPlayers = (dlg[4].flags & D_SELECTED) ? 2 : 1;
  195.  
  196.   return 0;
  197. }
  198.  
  199.  
  200. void SetupLight1(void)
  201. {
  202.   int x, y;
  203.   int c1, c2;
  204.  
  205.   c1 = getpixel(g.backbits, 0, 0);
  206.   c2 = getpixel(g.backbits, 1, 0);
  207.   putpixel(g.backbits, 1, 0, c1);
  208.  
  209.   for(y = 0; y < 256; y++)
  210.   {
  211.     char *line = g.backbits->line[y];
  212.  
  213.     for(x = 0; x < 256; x++)
  214.     {
  215.       if(line[x] == c1)
  216.       {
  217.         fixed f = fsqrt((x - 128) * (x - 128) + (y - 128) * (y - 128)); /* between 0 and 2 */
  218.         fixed cosine = hgrcos(f << 10);
  219.         unsigned c = (cosine + 0x10000 + rand() % 0x1000) * 15 / 32768;
  220.         if(c > 63)
  221.           c = 63;
  222.         line[x] = c + 64;
  223.       }
  224.       else if(line[x] == c2)
  225.       {
  226.         fixed f = fsqrt((x - 128) * (x - 128) + (y - 128) * (y - 128)) +
  227.                   (fcos(x << 20) + fcos(y << 20)) / 64 + 0x10000;
  228.                   /* between 0 and 4 */
  229.         fixed cosine = hgrcos(f << 11);
  230.         unsigned c = (cosine + 0x10000 + rand() % 0x1000) * 15 / 32768;
  231.         if(c > 63)
  232.           c = 63;
  233.         line[x] = c + 128;
  234.       }
  235.     }
  236.   }
  237.  
  238.   for(y = 0; y < 64; y++)
  239.   {
  240.     pal[y + 64].r = pal[y + 64].g = 0;
  241.     pal[y + 64].b = 63;
  242.     pal[y + 128].r = 31;
  243.     pal[y + 128].g = pal[y + 128].b = 0;
  244.   }
  245. }
  246.  
  247.  
  248. #if 0
  249. /* No longer using ThetaLight(), as it added very little effect */
  250.  
  251. #define THETALIGHT_AMBIENT 15
  252. #define THETALIGHT_POWER (63 - THETALIGHT_AMBIENT)
  253.  
  254. void ThetaLight(fixed theta)
  255. {
  256.   unsigned r, g, b;
  257.   fixed s = (hgrsin(theta) >> 1) + 0x8000;
  258.   fixed c = (hgrcos(theta) >> 1) + 0x8000;
  259.   unsigned i = 192;
  260.   unsigned side;
  261.   unsigned char zpixel[8];
  262.  
  263.   /* 012
  264.    * 3 4
  265.    * 567
  266.    */
  267.   zpixel[1] = THETALIGHT_AMBIENT + fmul(THETALIGHT_POWER, s);
  268.   zpixel[3] = THETALIGHT_AMBIENT + fmul(THETALIGHT_POWER, 0x10000 - c);
  269.   zpixel[4] = THETALIGHT_AMBIENT + fmul(THETALIGHT_POWER, c);
  270.   zpixel[6] = THETALIGHT_AMBIENT + fmul(THETALIGHT_POWER, 0x10000 - s);
  271.  
  272.   zpixel[0] = (zpixel[1] + zpixel[3])/2;
  273.   zpixel[2] = (zpixel[1] + zpixel[4])/2;
  274.   zpixel[5] = (zpixel[6] + zpixel[3])/2;
  275.   zpixel[7] = (zpixel[6] + zpixel[4])/2;
  276.  
  277.   for(r = 0; r < 2; r++)
  278.     for(g = 0; g < 2; g++)
  279.       for(b = 0; b < 2; b++)
  280.         for(side = 0; side < 8; side++)
  281.         {
  282.           if(r)
  283.             pal[i].r = zpixel[side];
  284.           else
  285.             pal[i].r = 0;
  286.           if(g)
  287.             pal[i].g = zpixel[side];
  288.           else
  289.             pal[i].g = 0;
  290.           if(b)
  291.             pal[i].b = zpixel[side];
  292.           else
  293.             pal[i].b = 0;
  294.           i++;
  295.         }
  296. }
  297. #endif
  298.  
  299.  
  300. void InitSidesPhi(Seven *seven, fixed phi, fixed zBase)
  301. {
  302.   int i;
  303.   int wHt = seven->frontBuf->h;
  304.   fixed m, zCos;
  305.   int scanlineWidth = 160 / nPlayers;
  306.  
  307.   if(fcos(phi) == 0)
  308.   {
  309.     phi -= 0x8000;
  310.   }
  311.   zCos = fdiv(zBase, hgrcos(phi));
  312.   m = hgrtan(phi);
  313.  
  314.   for(i = 0; i < wHt; i++)
  315.   {
  316.     fixed scanline = fdiv(i - wHt / 2, wHt / 2);
  317.     fixed mline = fmul(m, scanline);
  318.     fixed zLine = fmul(zCos, scanline);
  319.     fixed y1 = fdiv(zLine, mline + 0x10000);
  320.     fixed x1 = fdiv(zBase, mline + 0x10000);
  321.  
  322.     if(x1 < 0)
  323.     {
  324.       seven->leftX[i] = seven->rightX[i] = 0;
  325.       seven->leftY[i] = seven->rightY[i] = 0;
  326.     }
  327.     else
  328.     {
  329.       seven->leftY[i] = seven->rightY[i] = 120 * y1;
  330.       seven->leftX[i] = -x1 * scanlineWidth;
  331.       seven->rightX[i] = x1 * scanlineWidth;
  332.     }
  333.   }
  334. }
  335.  
  336. void SevenRender(Seven *seven)
  337. {
  338.   unsigned char **back = seven->backBuf->line;
  339.   unsigned char **front = seven->frontBuf->line;
  340.   int x = 0, y = 0;
  341.   fixed xgap = 0, ygap = 0, sx, sy;
  342.   int width = seven->rightSide - seven->leftSide;
  343.   int height = seven->frontBuf->h;
  344.   unsigned char *dst;
  345.  
  346.   for(y = 0; y < height; y++)
  347.   {
  348.     sx = (seven->leftX[y] + seven->rightX[y]) / 2;
  349.     xgap = (seven->rightX[y] - seven->leftX[y]) /  width;
  350.     sx -= xgap * width / 2;
  351.     sy = (seven->leftY[y] + seven->rightY[y]) / 2;
  352.     ygap = (seven->rightY[y] - seven->leftY[y]) /  width;
  353.     sy -= ygap * width / 2;
  354.     dst = front[y] + seven->leftSide;
  355.     if(xgap || ygap)
  356.     {
  357.       x = width / 4;
  358.       do
  359.       {
  360.         *dst++ = back[(sy >> 16) & 0xff][(sx >> 16) & 0xff];
  361.         sy += ygap;
  362.         sx += xgap;
  363.         *dst++ = back[(sy >> 16) & 0xff][(sx >> 16) & 0xff];
  364.         sy += ygap;
  365.         sx += xgap;
  366.         *dst++ = back[(sy >> 16) & 0xff][(sx >> 16) & 0xff];
  367.         sy += ygap;
  368.         sx += xgap;
  369.         *dst++ = back[(sy >> 16) & 0xff][(sx >> 16) & 0xff];
  370.         sy += ygap;
  371.         sx += xgap;
  372.       } while(--x);
  373.     }
  374.     else
  375.       memset(dst, 15, width);
  376.   }
  377. }
  378.  
  379. void RotateSides(Seven *seven, int theta)
  380. {
  381.   fixed lx, ly, rx, ry;
  382.   fixed c = hgrcos(theta);
  383.   fixed s = hgrsin(theta);
  384.   int i;
  385.   int wHt = seven->frontBuf->h;
  386.  
  387.   for(i = 0; i < wHt; i++)
  388.   {
  389.     lx = seven->leftX[i];
  390.     rx = seven->rightX[i];
  391.     ly = seven->leftY[i];
  392.     ry = seven->rightY[i];
  393.  
  394.     seven->leftX[i]  = fmul(lx, c) - fmul(ly, s);
  395.     seven->rightX[i] = fmul(rx, c) - fmul(ry, s);
  396.     seven->leftY[i]  = fmul(ly, c) + fmul(lx, s);
  397.     seven->rightY[i] = fmul(ry, c) + fmul(rx, s);
  398.   }
  399. }
  400.  
  401. void ScaleSides(Seven *seven, int fac)
  402. {
  403.   int i;
  404.   int wHt = seven->frontBuf->h;
  405.  
  406.   for(i = 0; i < wHt; i++)
  407.   {
  408.     seven->leftX[i]  = fmul(seven->leftX[i],  fac);
  409.     seven->leftY[i]  = fmul(seven->leftY[i],  fac);
  410.     seven->rightX[i] = fmul(seven->rightX[i], fac);
  411.     seven->rightY[i] = fmul(seven->rightY[i], fac);
  412.   }
  413. }
  414.  
  415. void DisplaceSides(Seven *seven, fixed x, fixed y)
  416. {
  417.   int i;
  418.   int wHt = seven->frontBuf->h;
  419.  
  420.   for(i = 0; i < wHt; i++)
  421.   {
  422.     seven->leftX[i]  += x;
  423.     seven->leftY[i]  += y;
  424.     seven->rightX[i] += x;
  425.     seven->rightY[i] += y;
  426.   }
  427. }
  428.  
  429. void DisplaceScanlines(Seven *seven, int ticks,
  430.                        int a, int b, int c, int d,
  431.                        fixed dtheta, fixed amplitude,
  432.                        fixed noise, fixed heat)
  433. {
  434.   fixed lx, ly, rx, ry;
  435.   fixed xOff, yOff;
  436.   int i, y;
  437.  
  438.   int wHt = seven->frontBuf->h;
  439.   fixed dheat = 0x8000000 / wHt;
  440.   fixed theta = (ticks << 14) & 0x00ffffff;
  441.   fixed heatTheta = (ticks << 16) & 0x00ffffff;
  442.  
  443.   dtheta /= wHt;
  444.  
  445.   for(i = 0; i < wHt; i++)
  446.   {
  447.     y = i - wHt / 2;
  448.     xOff = ((a * y / wHt + b) * y / wHt + c) * y / wHt + d +
  449.            fmul(hgrcos(theta), amplitude);
  450.     xOff += fmul((rand() & 0x7ff) - 0x400, noise);
  451.     theta += dtheta;
  452.     heatTheta += dheat;
  453.  
  454.     yOff = fmul(hgrsin(heatTheta), heat);
  455.   
  456.     lx = seven->leftX[i];
  457.     rx = seven->rightX[i];
  458.     ly = seven->leftY[i];
  459.     ry = seven->rightY[i];
  460.  
  461.     seven->leftX[i]  = lx + fmul(rx - lx, xOff) - fmul(ry - ly, yOff);
  462.     seven->rightX[i] = rx + fmul(rx - lx, xOff) - fmul(ry - ly, yOff);
  463.     seven->leftY[i]  = ly + fmul(ry - ly, xOff) + fmul(rx - lx, yOff);
  464.     seven->rightY[i] = ry + fmul(ry - ly, xOff) + fmul(rx - lx, yOff);
  465.   }
  466. }
  467.  
  468. void textout_shadow(BITMAP *screen, const FONT *font, const char *str, int x, int y, int c1, int c2)
  469. {
  470.   textout(screen, (FONT *)font, (char *)str, x + 1, y + 1, c2);
  471.   textout(screen, (FONT *)font, (char *)str, x, y, c1);
  472. }
  473.  
  474.  
  475. static void wrapblit(BITMAP *a, BITMAP *b, int c, int d, int e, int f, int g, int h)
  476. {
  477.   blit(a, b, c, d, e, f, g, h);
  478. }
  479.  
  480. static void PlayGame(Seven *seven, ScreenPos *pos, const char *aimsn)
  481. {
  482.   int lastTimer = timers.odo;
  483.   int lastGameloop = timers.odo;
  484.   int lastFrame = timers.odo;
  485.   int done = 0;
  486.   unsigned framesDrawn = 0;
  487.   unsigned totalFrames = 0;
  488.   const int lead = SCREEN_H / 14;
  489.  
  490.   int i, j;
  491.  
  492.   while(!done)
  493.   {
  494.     while(timers.odo - lastFrame > 0)
  495.     {
  496.       unsigned int cw = 0;
  497.  
  498.       lastFrame++;
  499.  
  500.       for(i = 0; i < nPlayers; i++)
  501.       {
  502.         cw = Mana2CtlWord(&(pos[i]), midi_pos);
  503.         CtlWord2Screen(&(pos[i]), cw);
  504.         pos[i].scale += pos[i].dscale / VIRTUAL_FPS;
  505.         pos[i].theta += pos[i].dtheta / VIRTUAL_FPS;
  506.         pos[i].phi += pos[i].dphi / VIRTUAL_FPS;
  507.         pos[i].a += pos[i].da / VIRTUAL_FPS;
  508.         pos[i].b += pos[i].db / VIRTUAL_FPS;
  509.         pos[i].c += pos[i].dc / VIRTUAL_FPS;
  510.         pos[i].d += pos[i].dd / VIRTUAL_FPS;
  511.         pos[i].amp += pos[i].damp / VIRTUAL_FPS;
  512.  
  513.         pos[i].xc += (pos[i].xctarget - pos[i].xc) * 2 / VIRTUAL_FPS;
  514.         pos[i].yc += (pos[i].yctarget - pos[i].yc) * 2 / VIRTUAL_FPS;
  515.  
  516.         pos[i].fricCounter += 10;
  517.         while(pos[i].fricCounter > VIRTUAL_FPS)
  518.           Resonance(&(pos[i]));
  519.       }
  520.  
  521.     }
  522.  
  523.     if(timers.odo - lastTimer > 100)
  524.     {
  525.       pos->fps = framesDrawn;
  526.       framesDrawn = 0;
  527.       lastTimer += 100;
  528.     };
  529.  
  530.     if(timers.odo - lastGameloop > 0)
  531.     {
  532.       done |= GameLoop();
  533.       lastGameloop++;
  534.     }
  535.  
  536.     for(i = 0; i < nPlayers; i++)
  537.     {
  538.       InitSidesPhi(&(seven[i]), pos[i].phi, pos[i].scale);
  539.       RotateSides(&(seven[i]), pos[i].theta);
  540.  
  541.       if(timers.odo - lastGameloop > 0)
  542.       {
  543.         done |= GameLoop();
  544.         lastGameloop++;
  545.       }
  546.  
  547.       DisplaceScanlines(&(seven[i]), lastGameloop,
  548.                         pos[i].a, pos[i].b, pos[i].c, pos[i].d,
  549.                         pos[i].sinusFreq, pos[i].amp >> 8,
  550.                         pos[i].noise, pos[i].heat);
  551.       DisplaceSides(&(seven[i]), pos[i].xc, pos[i].yc);
  552.  
  553.       if(timers.odo - lastGameloop > 0)
  554.       {
  555.         done |= GameLoop();
  556.         lastGameloop++;
  557.       }
  558.  
  559.       if(midi_pos > 32)
  560.       {
  561.         pos[i].xctarget = (p[i].x + 13) * 0x80000; // centered on current block
  562.         pos[i].yctarget = (p[i].y + 21) * 0x50000; // centered below current blk
  563.       }
  564.       else
  565.       {
  566.         pos[i].xctarget = 0x800000;
  567.         pos[i].yctarget = 0x780000;
  568.       }
  569.  
  570.       SevenRender(&(seven[i]));
  571.       DrawNext(i);
  572.  
  573.       if(timers.odo - lastGameloop > 0)
  574.       {
  575.         done |= GameLoop();
  576.         lastGameloop++;
  577.       }
  578.     }
  579.  
  580.     if(timers.odo - lastGameloop > 25) /* if you fall too far behind */
  581.       lastGameloop += 15;
  582.  
  583.     totalFrames++;
  584.     framesDrawn++;
  585.     if(framesDrawn > pos->fps)
  586.       pos->fps++;
  587.  
  588.     text_mode(-1);
  589.     textprintf(seven->frontBuf, lucid, 0, lead * 13, 0,
  590.                "%4ufps %4lubeat %3udose %3umana",
  591.                pos->fps, midi_pos, pos[0].midiLoop, pos[0].mana);
  592.     textout(seven->frontBuf, lucid, aimsn, lead, lead, 0);
  593.     textprintf(seven->frontBuf, lucid, lead, lead * 2, 0, "sc%7u", p[0].score);
  594.     textprintf(seven->frontBuf, lucid, lead, lead * 3, 0, "line%5u", p[0].lines);
  595.  
  596.     if(nPlayers > 1)
  597.     {
  598.       textprintf(seven->frontBuf, lucid, lead*10, lead * 2, 0, "sc%7u", p[1].score);
  599.       textprintf(seven->frontBuf, lucid, lead*10, lead * 3, 0, "line%5u", p[1].lines);
  600.     }
  601.     wrapblit(seven->frontBuf, screen, 0, 0, 0, 0, seven->frontBuf->w, seven->frontBuf->h);
  602.  
  603. /*
  604.       if(key[KEY_Z])
  605.         pos->sinusFreq += 0x1000000 / pos->fps;
  606.       if(key[KEY_X])
  607.         pos->sinusFreq -= 0x1000000 / pos->fps;
  608. */
  609.  
  610.     /* animate the palette */
  611.     for(i = 0; i < 64; i++)
  612.     {
  613.       unsigned col;
  614.  
  615.       j = (i << 18) + (timers.odo << 16);
  616.       col = (hgrcos(j) + 0x10000) >> 11;
  617.       if(col > 63)
  618.         col = 63;
  619.  
  620.       pal[i + 64].g = col;
  621.       pal[i + 128].g = col / 2;
  622.     }
  623.     /* ThetaLight(0x600000 - pos->theta); */
  624.     set_palette(pal);
  625.  
  626.     while(keypressed())
  627.       switch(readkey() >> 8)
  628.       {
  629.       case KEY_ESC:
  630.         done = 1;
  631.         break;
  632.       case KEY_P:
  633.         save_pcx("todsnap.pcx", seven->frontBuf, pal);
  634.         break;
  635.       case KEY_INSERT:
  636.         pos->midiLoop++;
  637.         set_palette(black_palette);
  638.         break;
  639.       }
  640.   }
  641. }
  642.  
  643. int main(void)
  644. {
  645.   int y, i;
  646.   Seven seven[2];
  647.   DATAFILE *dat;
  648.   BITMAP *loadedBG;
  649.  
  650.   char aimsn[17] = "Anonymous Coward";
  651.  
  652.   allegro_init();
  653.   install_timer();
  654.   LOCK_VARIABLE(timers);
  655.   LOCK_FUNCTION(timerint);
  656.  
  657.   install_int(timerint, 10); /* 100 fps timer */
  658.   srand(time(0));
  659.  
  660.   y = GetRes(aimsn);
  661.   if(y < 0)
  662.   {
  663.     allegro_message("could not set graphics mode\n");
  664.     return 1;
  665.   }
  666.  
  667. /* FIXME: once I get digi in, change NONE to AUTODETECT */
  668.  
  669.   install_sound(DIGI_NONE,
  670.                 playing_midi ? MIDI_AUTODETECT : MIDI_NONE,
  671.                 NULL);
  672.  
  673.   dat = load_datafile("idltd.dat");
  674.   if(!dat)
  675.   {
  676.     alert("no idltd.dat", "", "", "OK", NULL, 13, 0);
  677.     return 1;
  678.   }
  679.  
  680.   loadedBG = GetResource(dat, "IDLTD_ELOI_BMP");
  681.   tetbits = GetResource(dat, "BLOX");
  682.   pal = GetResource(dat, "IDLTD_ELOI_PAL");
  683.   lucid = GetResource(dat, lucidName[y]);
  684.   if(!loadedBG)
  685.   {
  686.     alert("idltd.dat missing IDLTD_ELOI_PCX", "", "", "OK", NULL, 13, 0);
  687.     return 1;
  688.   }
  689.   if(!tetbits)
  690.   {
  691.     alert("idltd.dat missing BLOX", "", "", "OK", NULL, 13, 0);
  692.     return 1;
  693.   }
  694.   if(!pal)
  695.   {
  696.     alert("idltd.dat missing IDLTD_ELOI_PAL", "", "", "OK", NULL, 13, 0);
  697.     return 1;
  698.   }
  699.   if(!lucid)
  700.   {
  701.     alert("idltd.dat missing font", lucidName[y], "", "OK", NULL, 13, 0);
  702.     return 1;
  703.   }
  704.  
  705.   if(InitScore(dat) < 0)
  706.   {
  707.     alert("idltd.dat missing login graphics", "", "", "OK", NULL, 13, 0);
  708.     return 1;
  709.   }
  710.  
  711.   seven[0].frontBuf = create_bitmap(windowWid, windowHt);
  712.   if(!seven[0].frontBuf)
  713.   {
  714.     alert("no ram", "", "", "OK", NULL, 13, 0);
  715.     unload_datafile(dat);
  716.     return 1;
  717.   }
  718.   seven[1].frontBuf = seven[0].frontBuf;
  719.   clear(seven[0].frontBuf);
  720.   for(i = 0; i < 2; i++)
  721.   {
  722.     p[i].seven = &(seven[i]);
  723.  
  724.     seven[i].backBuf = create_bitmap(256, 256);
  725.     if(!seven[i].backBuf)
  726.     {
  727.       alert("no ram", "", "", "OK", NULL, 13, 0);
  728.       unload_datafile(dat);
  729.       return 1;
  730.     }
  731.   }
  732.  
  733.   g.backbits = create_bitmap(256, 256);
  734.   if(!g.backbits)
  735.   {
  736.     alert("no ram", "", "", "OK", NULL, 13, 0);
  737.     unload_datafile(dat);
  738.     return 1;
  739.   }
  740.  
  741.   set_palette(pal);
  742.   while(Login(aimsn) >= 0)
  743.   {
  744.     while(GetOpts(aimsn, GetResource(dat, "LOGIN_BMP")) >= 0)
  745.     {
  746.       ScreenPos pos[2] =
  747.       {
  748.         {
  749.           0, 0,  0, 0,  0, 0,  0, 0,  /* a b c d */
  750.           0, 0,  0x400000, 0,         /* phi */
  751.           0x13333, 0,                 /* scale */
  752.           0, 0, 0x8000000,            /* amp freq */
  753.           0x400000,                   /* noise */
  754.           0,                          /* heat */
  755.           0x800000, 0x800000,         /* center */
  756.           0x800000, 0x780000,         /* target for center */
  757.           0, FRAMERATE, 0,            /* fps */
  758.           0, 0,                       /* nEffects */
  759.           0, 1                        /* midi to mana */
  760.         }
  761.       };
  762.  
  763.       if(nPlayers == 2)
  764.       {
  765.         seven[0].nextX = SCREEN_W * 2/5;
  766.         seven[1].nextX = SCREEN_W / 2;
  767.         seven[0].leftSide = 0;
  768.         seven[0].rightSide = seven[1].leftSide = SCREEN_W / 2;
  769.         seven[1].rightSide = SCREEN_W;
  770.       }
  771.       else
  772.       {
  773.         seven[0].nextX = SCREEN_W * 1/5;
  774.         seven[0].leftSide = 0;
  775.         seven[0].rightSide = SCREEN_W;
  776.       }
  777.  
  778.       wrapblit(loadedBG, g.backbits, 0, 0, 0, 0, 256, 256);
  779.       SetupLight1();
  780.       set_palette(pal);
  781.  
  782.       for(i = 0; i < nPlayers; i++)
  783.       {
  784.         wrapblit(g.backbits, seven[i].backBuf, 0, 0, 0, 0, 256, 256);
  785.         NewGame(i);
  786.       }
  787.  
  788.       StartSong(1, dat, &(pos[0]));
  789.       pos[1] = pos[0];
  790.  
  791.       PlayGame(seven, pos, aimsn);
  792.     }
  793.   }
  794.  
  795.   destroy_bitmap(seven[0].frontBuf);
  796.   destroy_bitmap(seven[0].backBuf);
  797.   destroy_bitmap(seven[1].backBuf);
  798.   destroy_bitmap(g.backbits);
  799.   unload_datafile(dat);
  800.   remove_int(timerint);
  801.  
  802.   return 0;
  803. } END_OF_MAIN();
  804.