home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff253.lzh / Elements / Source / elements.c next >
C/C++ Source or Header  |  1989-10-19  |  23KB  |  866 lines

  1. /***************************************************************************
  2.  * elements.c - CAMM v2.0 Periodic Table of the Elements module. This set  *
  3.  * 11-8-88      of routines draws and gives information about the periodic *
  4.  * Paul Miller  table of the elements. (Info provided by Sargent-Welch)    *
  5.  ***************************************************************************/
  6.  
  7. #include "elements.h"
  8. #include <libraries/dos.h>
  9.  
  10. struct Window *ewindow;
  11. struct Screen *escreen;
  12.  
  13. struct TextFont *TextFont;
  14. struct TextFont *ElementFont;
  15. struct TextFont *CAMMFont;
  16. struct TextAttr TextAttr = {(STRPTR)"CAMMtopaz.font", 8, 0, FPF_DISKFONT};
  17. struct TextAttr ElementAttr = {(STRPTR)"element.font", 12, 0, FPF_DISKFONT};
  18. struct TextAttr CAMMAttr = {(STRPTR)"CAMM.font", 5, 0, FPF_DISKFONT};
  19.  
  20. struct IntuiText TextText = {
  21.    1,0,JAM1,0,0,&TextAttr, (UBYTE *)"", NULL
  22. };
  23. struct IntuiText ElementText = {
  24.    1,0,JAM1,0,0,&ElementAttr, (UBYTE *)"", NULL
  25. };
  26. struct IntuiText CAMMText = {
  27.    1,0,JAM1,0,0,&CAMMAttr, (UBYTE *)"", NULL
  28. };
  29.  
  30. char *columntext[] = {"IA","IIA","IIA","IVA","VA","VIA","VIIA","VIIIA",
  31.                       "IB","IIB","IIIB","IVB","VB","VIB","VIIB","VIII"};
  32. char *rowtext[] = {"I","II","III","IV","V","VI","VII"};
  33. USHORT table_x[] = {0,1,2,3,4,5,6,8,10,11,12,13,14,15,16,17};
  34. USHORT table_y[] = {0,1,3,3,3,3,3,3,3,3,1,1,1,1,1,0};
  35.  
  36. USHORT info_x[]={126,197,150,126,126,205,174,157,205,230,253,
  37.                  157,254,205,286,246};
  38.  
  39. int tabledata[] = {249,106, 249,103, 265,103,
  40.                      -298,103, 315,103, 315,106, -1};
  41. int CubicFCData[] = {0,0, 26,0, 38,12, 38,35, 12,35, 0,23, 0,0,
  42.        12,12, 38,12, -12,12, 12,35, -25,23, 26,23, 26,24, 25,24, -1};
  43. int CubicBCData[] = {0,0, 26,0, 26,23, 0,23, 0,0, 12,12, 12,35, 0,23,
  44.        -12,12, 38,12, 38,35, 12,35, -26,23, 38,35, -26,0, 38,12,
  45.        -38,35, 0,0, -26,0, 12,35, -38,12, 0,23, -12,12, 20,23, -1};
  46. int CubicData[] = {0,0, 26,0, 38,12, 38,35, 12,35, 0,23, 0,0,
  47.        12,12, 38,12, -12,12, 12,35, -1};
  48. int HexData[] = {0,10, 19,0, 38,10, 38,31, 19,41, 0,31, 0,10, 38,31,
  49.        -19,0, 19,41, -38,10, 0,31, -1};
  50. int RhombData[] = {0,35, 5,12, 13,4, 8,27, 0,35, 25,31, 30,8, 5,12,
  51.        -13,4, 38,0, 33,23, 8,27, -33,23, 25,31, -38,0, 30,8, -1};
  52. int TetraData[] = {11,39, 11,5, 22,5, 22,39, 11,39, -11,5, 18,0, 29,0, 22,5,
  53.        -29,0, 29,34, 22,39, -1};
  54. int OrthoData[] = {0,41, 0,11, 27,11, 27,41, 0,41, -27,11, 38,0, 11,0, 0,11,
  55.        -38,0, 38,30, 27,41, -1};
  56. int MonoData[] = {0,20, 10,0, 28,0, 38,20, 28,40, 10,40, 0,20, -1};
  57. int *structuredata[] = {&CubicFCData[0], &CubicBCData[0], &CubicData[0],
  58.    &HexData[0], &RhombData[0], &TetraData[0], &OrthoData[0], &MonoData[0]};
  59.  
  60. char *structuretext[] = {"Cubic, FC", "Cubic, BC", "Cubic", "Hexagonal",
  61.    "Rhombohedral","Tetragonal","Orthorhombic","Monoclinic", "Unknown"};
  62.  
  63. char *elem_type[] = {"SOLID","LIQUID","GAS","SYNTHETIC"};
  64.  
  65. char *infotext[] = {"Atomic Weight:","Electron Configuration:",
  66.    "Oxidation States:","Boiling Point:","Melting Point:",
  67.    "Density at 300K (g/cm3):","Covalent Radius (A):","Atomic Radius (A):",
  68.    "Atomic Volume (cm3/mol):","First Ionization Potential:",
  69.    "Specific Heat Capacity (J/gK):","Electronegativity:",
  70.    "Heat of Vaporization (kJ/mol):","Heat of Fusion (kJ/mol):",
  71.    "Electrical Conductivity (106/Ocm):","Thermal Conductivity (W/cmK):"};
  72.  
  73. UWORD color_map[4] = {0x0020, 0x00A0, 0x007F, 0x0E44};
  74. UWORD shadow_map[8] = {0x0333, 0x00A0, 0x000F, 0x0E00,
  75.                        0x0000, 0x0000, 0x0000, 0x0000};
  76.  
  77. struct IntuitionBase *IntuitionBase;
  78. struct GfxBase *GfxBase;
  79. struct DiskfontBase *DiskfontBase;
  80.  
  81. extern struct Menu infomenu_strip[];
  82.  
  83. struct Element element[ELEMENTS];
  84. struct Info info[ELEMENTS];
  85.  
  86. long Xoff = EOFF_X, Yoff = EOFF_Y;
  87. BOOL shadow = FALSE;
  88.  
  89. void elements(), handle_infomenu(), draw_table(), outline(), PrintBText();
  90. void superscript(), convert_superscript(), draw_text(), draw_box();
  91. void draw_data(), draw_infotext(), draw_info(), open_libraries(), abort();
  92. void highlight_box();
  93.  
  94. main(argc,argv)
  95. int argc;
  96. char *argv[];
  97. {
  98.    struct NewScreen ns;
  99.  
  100.    if (argc > 1)
  101.       shadow = TRUE;
  102.  
  103.    open_libraries();
  104.    if (!load_elements())
  105.       abort("Cannot find `Elements.DAT' file.");
  106.    if (!load_info())
  107.       abort("Cannot find `Info.DAT' file.");
  108.  
  109.    setmem(&ns, sizeof(ns), 0L);
  110.  
  111.    ns.LeftEdge = 0;
  112.    ns.TopEdge = 0;
  113.    ns.Width = SCREEN_WIDTH;
  114.    ns.Height = SCREEN_HEIGHT;
  115.    ns.Depth = DEPTH;
  116.    ns.DetailPen = 0;
  117.    ns.BlockPen = 1;
  118.    ns.ViewModes = HIRES | LACE;
  119.    ns.Type = CUSTOMSCREEN;
  120.    ns.DefaultTitle = (UBYTE *)SCREEN_TITLE;
  121.  
  122.    if (shadow)
  123.       ns.Depth = SHADOWDEPTH;
  124.  
  125.    if (!(escreen = (struct Screen *)OpenScreen(&ns)))
  126.       abort("Cannot open main screen.");
  127.  
  128.    if (!shadow)
  129.       LoadRGB4(&escreen->ViewPort, color_map, 4L);
  130.    else
  131.       LoadRGB4(&escreen->ViewPort, shadow_map, 8L);
  132.  
  133.    elements(escreen);
  134. }
  135.  
  136. void elements(screen)
  137. struct Screen *screen;
  138. {
  139.    struct NewWindow nw;
  140.    struct Window *w;
  141.    struct IntuiMessage *message;
  142.    ULONG class;
  143.    USHORT code;
  144.    int mx, my, info;
  145.  
  146.    setmem(&nw, sizeof(nw), 0L);
  147.  
  148.    nw.LeftEdge = 0;
  149.    nw.TopEdge = EWIN_TOP;
  150.    nw.Width = EWIN_WIDTH;
  151.    nw.Height = EWIN_HEIGHT;
  152.    nw.DetailPen = -1;
  153.    nw.BlockPen = -1;
  154.    nw.IDCMPFlags = MOUSEBUTTONS | MENUPICK;
  155.    nw.Flags = WINDOWDEPTH | GIMMEZEROZERO | SMART_REFRESH | REPORTMOUSE |
  156.               ACTIVATE;
  157.    nw.Title = (UBYTE *)E_TITLE;
  158.    nw.Screen = screen;
  159.    nw.Type = CUSTOMSCREEN;
  160.  
  161.    if (!(ewindow = (struct Window *)OpenWindow(&nw)))
  162.       abort("Cannot open elements window.");
  163.  
  164.    SetMenuStrip(ewindow, infomenu_strip);
  165.  
  166.    if (shadow)
  167.       draw_table(ewindow, shadow);
  168.  
  169.    draw_table(ewindow, FALSE);
  170.  
  171.    while(1)
  172.    {
  173.       Wait(1L<<ewindow->UserPort->mp_SigBit);
  174.  
  175.       while(message = (struct IntuiMessage *)GetMsg(ewindow->UserPort))
  176.       {
  177.          class = message->Class;
  178.          code = message->Code;
  179.          mx = message->MouseX;
  180.          my = message->MouseY;
  181.          w = message->IDCMPWindow;
  182.          ReplyMsg(message);
  183.          switch (class)
  184.          {
  185.             case CLOSEWINDOW:
  186.                close_window(w);
  187.             case MOUSEBUTTONS:
  188.                switch (code)
  189.                {
  190.                   case SELECTDOWN:
  191.                      if (info = get_element(mx, my))
  192.                         info_window(info-1);
  193.                      break;
  194.                }
  195.                break;
  196.             case MENUPICK:
  197.                ClearMenuStrip(w);
  198.                handle_infomenu(code);
  199.                SetMenuStrip(w, infomenu_strip);
  200.                break;
  201.          }
  202.       }
  203.    }
  204. }
  205.  
  206. void handle_infomenu(menu)
  207. int menu;
  208. {
  209.    if (menu != MENUNULL)
  210.    {
  211.       switch (ITEMNUM(menu))
  212.       {
  213.          case 0:
  214.             display_subpart();
  215.             break;
  216.          case 1:
  217.             display_radioiso();
  218.             break;
  219.          case 2:
  220.             display_ionichar();
  221.             break;
  222.          case 3:
  223.             display_notes();
  224.             break;
  225.          case 4:
  226.             display_info();
  227.             break;
  228.          case 5:
  229.             close_all();
  230.             abort("");
  231.             break;
  232.       }
  233.    }
  234. }
  235.  
  236. get_element(x, y)
  237. int x, y;
  238. {
  239.    register int i;
  240.  
  241.    if (y <= EWIN_TOP)
  242.       return(NULL);
  243.  
  244.    y -= EWIN_TOP;
  245.  
  246.    if (y > (EOFF_Y + 7 * BOX_H))
  247.       y -= (.25 * BOX_H);
  248.  
  249.    x = (x - EOFF_X - 4) / BOX_W;
  250.    y = (y - EOFF_Y) / BOX_H;
  251.  
  252.    for (i = 0; i < ELEMENTS; i++)
  253.       if ((x == element[i].column) && (y == element[i].row))
  254.       {
  255.          highlight_box(i);
  256.          return(i+1);
  257.       }
  258.    return(NULL);
  259. }
  260.  
  261. void draw_table(window, shad)
  262. struct Window *window;
  263. BOOL shad;
  264. {
  265.    struct RastPort *rp = window->RPort;
  266.    long x, y, i, num;
  267.    char number[3];
  268.  
  269.    if (!shad)
  270.    {
  271.       SetAPen(rp, (long)BOX_COLOR);
  272.       Xoff = EOFF_X;
  273.       Yoff = EOFF_Y;
  274.    }
  275.    else
  276.    {
  277.       SetAPen(rp, (long)SHADOWBLACK);
  278.       ElementText.FrontPen = SHADOWBLACK;
  279.       Xoff = EOFF_SHADX;
  280.       Yoff = EOFF_SHADY;
  281.    }
  282.  
  283.    for (i = 0; i < ELEMENTS; i++)
  284.    {
  285.       num = element[i].number;
  286.       x = Xoff + (element[i].column * BOX_W);
  287.       y = Yoff + (element[i].row * BOX_H);
  288.  
  289.       if ((num>57 && num<72) || (num>89 && num<104))
  290.          y += (.25 * BOX_H);
  291.  
  292.       draw_box(rp, x, y, BOX_W, BOX_H);
  293.  
  294.       sprintf(number, "%d", element[i].number);
  295.       superscript(number);
  296.       if (!shad)
  297.          ElementText.FrontPen = BOX_COLOR;
  298.       else
  299.          ElementText.FrontPen = SHADOWBLACK;
  300.       ElementText.IText = (UBYTE *)number;
  301.       PrintIText(rp, &ElementText, (long)(x+ENUM_X), (long)(y+ENUM_Y));
  302.  
  303.       if (num > 103) x -= 6;
  304.  
  305.       if (!shad)
  306.          ElementText.FrontPen = element[i].type;
  307.  
  308.       ElementText.IText = (UBYTE *)element[i].symbol;
  309.       if (element[i].type == SYNTHETIC_E)
  310.       {
  311.          if (!shad)
  312.             outline(rp, &ElementText, x+ESYM_X-2L, y+ESYM_Y-2L, BOX_COLOR);
  313.          else
  314.             outline(rp, &ElementText, x+ESYM_X-2L, y+ESYM_Y-2L, SHADOWBLACK);
  315.       }
  316.       else
  317.          PrintIText(rp, &ElementText, (long)(x+ESYM_X), (long)(y+ESYM_Y));
  318.    }
  319.    Move(rp, (long)(Xoff+(12*BOX_W)-1), (long)(Yoff+(1*BOX_H)));
  320.    Draw(rp, (long)(Xoff+(12*BOX_W)-1), (long)(Yoff+(2*BOX_H)-1));
  321.    Draw(rp, (long)(Xoff+(13*BOX_W)-1), (long)(Yoff+(2*BOX_H)-1));
  322.    Draw(rp, (long)(Xoff+(13*BOX_W)-1), (long)(Yoff+(3*BOX_H)-1));
  323.    Draw(rp, (long)(Xoff+(14*BOX_W)-1), (long)(Yoff+(3*BOX_H)-1));
  324.    Draw(rp, (long)(Xoff+(14*BOX_W)-1), (long)(Yoff+(4*BOX_H)-1));
  325.    Draw(rp, (long)(Xoff+(15*BOX_W)-1), (long)(Yoff+(4*BOX_H)-1));
  326.    Draw(rp, (long)(Xoff+(15*BOX_W)-1), (long)(Yoff+(5*BOX_H)-1));
  327.    Draw(rp, (long)(Xoff+(16*BOX_W)-1), (long)(Yoff+(5*BOX_H)-1));
  328.    Draw(rp, (long)(Xoff+(16*BOX_W)-1), (long)(Yoff+(6*BOX_H)-1));
  329.  
  330.    draw_text(window, shad);
  331. }
  332.  
  333. void outline(rp, text, x, y, color)
  334. struct RastPort *rp;
  335. struct IntuiText *text;
  336. long x, y, color;
  337. {
  338.    long xx, yy;
  339.  
  340.    text->FrontPen = color;
  341.    for (yy = y-1; yy <= y+1; yy++)
  342.       for (xx = x-1; xx <= x+1; xx++)
  343.          PrintIText(rp, text, xx, yy);
  344.    text->FrontPen = BACKGROUND;
  345.    PrintIText(rp, text, x, y);
  346. }
  347.  
  348. void superscript(text)
  349. char text[];
  350. {
  351.    register USHORT i;
  352.  
  353.    for (i = 0; text[i] != '\0'; i++)
  354.       text[i] += 0x50;
  355. }
  356.  
  357. void convert_super(in, out)
  358. char in[], out[];
  359. {
  360.    register USHORT i, n;
  361.  
  362.    for (i = 0, n = 0; in[i] != '\0'; i++)
  363.    {
  364.       if (in[i] == '+')
  365.          out[n] = in[++i] + 0x50;
  366.       else
  367.          out[n] = in[i];
  368.       n++;
  369.    }
  370.    out[n] = '\0';
  371. }
  372.  
  373. void draw_text(w, shad)
  374. struct Window *w;
  375. BOOL shad;
  376. {
  377.    struct RastPort *rp = w->RPort;
  378.    long i, x, y;
  379.  
  380.    if (!shad)
  381.       CAMMText.FrontPen = BOX_COLOR;
  382.    else
  383.       CAMMText.FrontPen = SHADOWBLACK;
  384.  
  385.    CAMMText.IText = (UBYTE *)"GROUP";
  386.    PrintIText(rp, &CAMMText, (long)(Xoff+3), (long)(Yoff-14));
  387.  
  388.    for (i = 0; i < 16; i++)
  389.    {
  390.       CAMMText.IText = (UBYTE *)columntext[i];
  391.       x = Xoff+(table_x[i]*BOX_W)+2;
  392.       x += (.5 * (BOX_W - IntuiTextLength(&CAMMText)));
  393.       y = Yoff + (table_y[i]*BOX_H) - 7;
  394.       PrintIText(rp, &CAMMText, x, y);
  395.    }
  396.    for (i = 0; i < 7; i++)
  397.    {
  398.       CAMMText.IText = (UBYTE *)rowtext[i];
  399.       x = (Xoff - IntuiTextLength(&CAMMText))/2;
  400.       y = Yoff+(i*BOX_H)+ROWNUM_Y;
  401.       PrintIText(rp, &CAMMText, x, y);
  402.    }
  403.  
  404.    draw_data(rp, &tabledata[0], Xoff, Yoff);
  405. }
  406.  
  407. void draw_box(rp, x, y, width, height)
  408. struct RastPort *rp;
  409. long x, y, width, height;
  410. {
  411.    Move(rp, x, y);
  412.    Draw(rp, x+width, y);
  413.    Draw(rp, x+width, y+height);
  414.    Draw(rp, x, y+height);
  415.    Draw(rp, x, y);
  416. }
  417.  
  418. void draw_data(rp, data, x, y)
  419. struct RastPort *rp;
  420. int data[];
  421. long x, y;
  422. {
  423.    long i;
  424.  
  425.    Move(rp, (long)(data[0]+x), (long)(data[1]+y));
  426.  
  427.    for (i = 2; data[i] != -1; i += 2)
  428.    {
  429.       if (data[i] < 0)
  430.          Move(rp, (long)((-data[i])+x), (long)(data[i+1]+y));
  431.       else
  432.          Draw(rp, (long)(data[i]+x), (long)(data[i+1]+y));
  433.    }
  434. }
  435.  
  436. info_window(num)
  437. int num;
  438. {
  439.    struct Window *iwindow;
  440.    LONG pro, neu;
  441.    char title[80];
  442.  
  443.    pro = element[num].number;
  444.    neu = (long)info[num].AWeight;
  445.    if (neu < 0)
  446.       neu = -neu;
  447.    neu -= pro;
  448.    sprintf(title,"%s: %s (P:%d N:%d E:%d)", element[num].symbol,
  449.       element[num].name, pro, neu, pro);
  450.  
  451.    pro = Xoff + (element[num].column * BOX_W) - (.5 * IWIN_WIDTH);
  452.    neu = Yoff + (element[num].row * BOX_H) - (.5 * IWIN_HEIGHT);
  453.    if (pro < 0) pro = 0;
  454.    if (pro > SCREEN_WIDTH-IWIN_WIDTH) pro = SCREEN_WIDTH-IWIN_WIDTH;
  455.    if (neu < EWIN_TOP) neu = EWIN_TOP;
  456.    if (neu > SCREEN_HEIGHT-IWIN_HEIGHT) neu = SCREEN_HEIGHT-IWIN_HEIGHT;
  457.  
  458.    iwindow = get_window(pro,neu,IWIN_WIDTH,IWIN_HEIGHT,title);
  459.    if (iwindow == NULL)
  460.       return(NULL);
  461.  
  462.    draw_infotext(iwindow);
  463.    draw_info(iwindow, num);
  464.  
  465.    return(TRUE);
  466. }
  467.  
  468. void draw_infotext(window)
  469. struct Window *window;
  470. {
  471.    struct RastPort *rp = window->RPort;
  472.    register USHORT i;
  473.  
  474.    TextText.FrontPen = GREENTEXT;
  475.  
  476.    for (i = 0; i < INFOTEXT; i++)
  477.    {
  478.       TextText.IText = (UBYTE *)infotext[i];
  479.       PrintIText(rp, &TextText, (long)INFOTEXTX, (long)(((i+1)*10)+3));
  480.    }
  481.    TextText.IText = (UBYTE *)"Stable Form:";
  482.    PrintIText(rp, &TextText, 214L, 13L);
  483.    TextText.IText = (UBYTE *)"Crystal";
  484.    PrintIText(rp, &TextText, 312L, 63L);
  485.    TextText.IText = (UBYTE *)"Structure:";
  486.    PrintIText(rp, &TextText, 304L, 73L);
  487. }
  488.  
  489. void draw_info(window, num)
  490. struct Window *window;
  491. int num;
  492. {
  493.    struct RastPort *rp = window->RPort;
  494.    register USHORT i;
  495.    char info_t[INFOTEXT][25];
  496.    char floattext[25], modtext[25];
  497.  
  498.    TextText.FrontPen = REDTEXT;
  499.    TextText.IText = (UBYTE *)elem_type[element[num].type-1];
  500.    PrintIText(rp, &TextText, 318L, 13L);
  501.  
  502.    if (info[num].OxiStates[0] == '*')
  503.       info[num].OxiStates[0] = 0xB1;
  504.  
  505.    TextText.IText = (UBYTE *)structuretext[info[num].Structure];
  506.    i = 343 - (.5 * IntuiTextLength(&TextText));
  507.    PrintIText(rp, &TextText, (long)i, 83L);
  508.  
  509.    if (info[num].Structure < 8)
  510.       draw_data(rp, structuredata[info[num].Structure], 324L, 93L);
  511.  
  512.    sprintf(info_t[0], "%f", info[num].AWeight);
  513.    convert_super(info[num].Config, info_t[1]);
  514.    sprintf(info_t[2], "%s", info[num].OxiStates);
  515.    sprintf(info_t[5], "%f", info[num].Density);
  516.    sprintf(info_t[6], "%f", info[num].CRadius);
  517.    sprintf(info_t[7], "%f", info[num].ARadius);
  518.    sprintf(info_t[8], "%f", info[num].AVolume);
  519.    sprintf(info_t[9], "%f", info[num].IonPot);
  520.    sprintf(info_t[10], "%f", info[num].SpecHeat);
  521.    sprintf(info_t[11], "%f", info[num].Electroneg);
  522.    sprintf(info_t[12], "%f", info[num].HeatVap);
  523.    sprintf(info_t[13], "%f", info[num].HeatFus);
  524.    convert_super(info[num].ElecCond, info_t[14]);
  525.    sprintf(info_t[15], "%f", info[num].ThermalCond);
  526.  
  527.    shfloat(info_t[0]);
  528.    for (i = 5; i < 14; i++)
  529.       shfloat(info_t[i]);
  530.    shfloat(info_t[15]);
  531.  
  532.    if (info[num].AWeight < 0)
  533.    {
  534.       info_t[0][0] = '(';
  535.       info_t[0][4] = ')';
  536.       info_t[0][5] = '\0';
  537.    }
  538.    if (info[num].BoilingP == 0.0)
  539.       sprintf(info_t[3], "-");
  540.    else
  541.    {
  542.       sprintf(floattext, "%.3f", info[num].BoilingP);
  543.       sprintf(modtext, "%.3f", (info[num].BoilingP-273.0));
  544.       shfloat(floattext);
  545.       shfloat(modtext);
  546.       sprintf(info_t[3], "%s°K (%s°C)", floattext,modtext);
  547.    }
  548.    if (info[num].MeltingP == 0.0)
  549.       sprintf(info_t[4], "-");
  550.    else
  551.    {
  552.       sprintf(floattext, "%.3f", info[num].MeltingP);
  553.       sprintf(modtext, "%.3f", (info[num].MeltingP-273.0));
  554.       shfloat(floattext);
  555.       shfloat(modtext);
  556.       sprintf(info_t[4], "%s°K (%s°C)", floattext,modtext);
  557.    }
  558.    for (i = 1; info_t[14][i] != '\0'; i++)
  559.       if (info_t[14][i] == '-')
  560.          info_t[14][i] = 0x8E;
  561.  
  562.    for (i = 0; i < INFOTEXT; i++)
  563.    {
  564.       if (i == 2)
  565.       {
  566.          PrintBText(rp, info_t[i], (long)info_x[i], (long)(((i+1)*10)+3));
  567.          continue;
  568.       }
  569.       TextText.IText = (UBYTE *)info_t[i];
  570.       PrintIText(rp, &TextText, (long)info_x[i], (long)(((i+1)*10)+3));
  571.    }
  572. }
  573.  
  574. void PrintBText(rp, text, x, y)
  575. struct RastPort *rp;
  576. char *text;
  577. long x, y;
  578. {
  579.    register USHORT i;
  580.    char letter[2];
  581.  
  582.    for (i = 0; text[i] != '\0'; i++)
  583.    {
  584.       if (text[i] == 'B')
  585.       {
  586.          sprintf(letter,"%c",text[++i]);
  587.          TextText.IText = (UBYTE *)letter;
  588.          PrintIText(rp, &TextText, x, y);
  589.          PrintIText(rp, &TextText, x+1, y);
  590.       }
  591.       else
  592.       {
  593.          sprintf(letter,"%c",text[i]);
  594.          TextText.IText = (UBYTE *)letter;
  595.          PrintIText(rp, &TextText, x, y);
  596.       }
  597.       x += 8;
  598.    }
  599. }
  600.  
  601. shfloat(text)
  602. char *text;
  603. {
  604.    register USHORT i;
  605.    USHORT decimal = NULL;
  606.  
  607.    if (text[0] == '0' && text[1] == '\0')
  608.    {
  609.       text[0] = '-';
  610.       return(NULL);
  611.    }
  612.    for (i = 0; text[i] != '\0'; i++)
  613.    {
  614.       if (text[i] == '.')
  615.          decimal = 1;
  616.    }
  617.    if (!decimal)
  618.       return(NULL);
  619.  
  620.    while (--i > 0)
  621.    {
  622.       if ((text[i] != '0') || (text[i-1] == '.'))
  623.          break;
  624.       text[i] = '\0';
  625.    }
  626.    if (text[0] == '0' && text[3] == '\0')
  627.    {
  628.       text[0] = '-';
  629.       text[1] = '\0';
  630.    }
  631. }
  632.  
  633. load_info()
  634. {
  635.    register LONG fd;
  636.    register USHORT i;
  637.  
  638.    fd = (LONG)Open(INFO_FILE, MODE_OLDFILE);
  639.    if (!fd)
  640.       return(NULL);
  641.  
  642.    for (i = 0; i < ELEMENTS; i++)
  643.    {
  644.       Read(fd, &info[i].Structure, 2L);
  645.       Read(fd, &info[i].AWeight, 4L);
  646.       Read(fd, &info[i].Config, 25L);
  647.       Read(fd, &info[i].OxiStates, 11L);
  648.       Read(fd, &info[i].BoilingP, 4L);
  649.       Read(fd, &info[i].MeltingP, 4L);
  650.       Read(fd, &info[i].Density, 4L);
  651.       Read(fd, &info[i].CRadius, 4L);
  652.       Read(fd, &info[i].ARadius, 4L);
  653.       Read(fd, &info[i].AVolume, 4L);
  654.       Read(fd, &info[i].IonPot, 4L);
  655.       Read(fd, &info[i].SpecHeat, 4L);
  656.       Read(fd, &info[i].Electroneg, 4L);
  657.       Read(fd, &info[i].HeatVap, 4L);
  658.       Read(fd, &info[i].HeatFus, 4L);
  659.       Read(fd, &info[i].ElecCond, 13L);
  660.       Read(fd, &info[i].ThermalCond, 4L);
  661.    }
  662.    Close(fd);
  663.    return(TRUE);
  664. }
  665.  
  666. void open_libraries()
  667. {
  668.    if ((DiskfontBase = (struct DiskfontBase *)
  669.       OpenLibrary("diskfont.library",0L)) == NULL)
  670.       abort("Couldn't open diskfont.library!");
  671.    if ((IntuitionBase = (struct IntuitionBase *)
  672.       OpenLibrary("intuition.library",0L)) == NULL)
  673.       abort("Could't open intuition.library!");
  674.    if ((GfxBase = (struct GfxBase *)
  675.       OpenLibrary("graphics.library",0L)) == NULL)
  676.       abort("Couldn't open graphics.library!");
  677.  
  678.    if ((TextFont = (struct TextFont *)OpenDiskFont(&TextAttr)) == NULL)
  679.       abort("Couldn't find CAMMtopaz.font.");
  680.    if ((ElementFont = (struct TextFont *)OpenDiskFont(&ElementAttr)) == NULL)
  681.       abort("Couldn't find element.font.");
  682.    if ((CAMMFont = (struct TextFont *)OpenDiskFont(&CAMMAttr)) == NULL)
  683.       abort("Couldn't find CAMM.font.");
  684. }
  685.  
  686. void abort(txt)
  687. char *txt;
  688. {
  689.    puts(txt);
  690.    if (infomenu_strip) ClearMenuStrip(ewindow);
  691.    if (ewindow) CloseWindow(ewindow);
  692.    if (escreen) CloseScreen(escreen);
  693.    if (TextFont) CloseFont(TextFont);
  694.    if (CAMMFont) CloseFont(CAMMFont);
  695.    if (ElementFont) CloseFont(ElementFont);
  696.    if (GfxBase) CloseLibrary(GfxBase);
  697.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  698.    if (DiskfontBase) CloseLibrary(DiskfontBase);
  699.    exit(NULL);
  700. }
  701.  
  702. load_elements()
  703. {
  704.    register LONG fd;
  705.    USHORT num, col, row;
  706.    char symbol[4], name[13], type[7];
  707.    register USHORT i;
  708.  
  709.    fd = (LONG)Open(ELEMENTS_FILE, MODE_OLDFILE);
  710.    if (!fd)
  711.       abort("Cannot find elements file.");
  712.  
  713.    for (i = 0; i < ELEMENTS; i++)
  714.    {
  715.       Read(fd, &num, 2L);
  716.       Read(fd, &col, 2L);
  717.       Read(fd, &row, 2L);
  718.       Read(fd, &symbol, 4L);
  719.       Read(fd, &name, 13L);
  720.       Read(fd, &type, 7L);
  721.  
  722.       element[i].number = num;
  723.       element[i].column = col-1;
  724.       element[i].row = row-1;
  725.       switch(type[1])
  726.       {
  727.          case 'O':
  728.             element[i].type = SOLID_E;
  729.             break;
  730.          case 'I':
  731.             element[i].type = LIQUID_E;
  732.             break;
  733.          case 'A':
  734.             element[i].type = GAS_E;
  735.             break;
  736.          case 'Y':
  737.             element[i].type = SYNTHETIC_E;
  738.             break;
  739.       }
  740.       strcpy(element[i].symbol, symbol);
  741.       strcpy(element[i].name, name);
  742.    }
  743.    Close(fd);
  744.  
  745.    *(infotext[5]+21) += 0x50;
  746.    *(infotext[6]+17) = 0xC2;
  747.    *(infotext[7]+15) = 0xC2;
  748.    *(infotext[8]+17) += 0x50;
  749.    *(infotext[14]+27) += 0x50;
  750.    *(infotext[14]+29) = 0x95;
  751.  
  752.    return(TRUE);
  753. }
  754.  
  755. struct Window *get_window(left,top,width,height,title)
  756. int left, top, width, height;
  757. UBYTE *title;
  758. {
  759.    struct NewWindow nw;
  760.    struct Window *window;
  761.    UBYTE *text;
  762.  
  763.    if (left+width > SCREEN_WIDTH)
  764.       left = SCREEN_WIDTH-width-1;
  765.    if (top+height > SCREEN_HEIGHT)
  766.       top = SCREEN_HEIGHT-height-1;
  767.  
  768.    if (left < 0) left = 0;
  769.    if (top < 0) top = EWIN_TOP;
  770.  
  771.    text = (UBYTE *)AllocMem(80L, MEMF_PUBLIC|MEMF_CLEAR);
  772.    if (!text) return(NULL);
  773.    strcpy(text, title);
  774.  
  775.    setmem(&nw, sizeof(nw), 0L);
  776.    nw.TopEdge = top;
  777.    nw.LeftEdge = left;
  778.    nw.Width = width;
  779.    nw.Height = height;
  780.    nw.DetailPen = -1;
  781.    nw.BlockPen = -1;
  782.    nw.IDCMPFlags = NULL;
  783.    nw.Flags = WINDOWDEPTH|WINDOWDRAG|WINDOWCLOSE|SMART_REFRESH|ACTIVATE;
  784.    nw.Title = text;
  785.    nw.Screen = escreen;
  786.    nw.Type = CUSTOMSCREEN;
  787.  
  788.    window = (struct Window *)OpenWindow(&nw);
  789.    if (window == NULL)
  790.    {
  791.       if (text) FreeMem(text, 80);
  792.       return(NULL);
  793.    }
  794.  
  795.    window->UserPort = ewindow->UserPort;
  796.    ModifyIDCMP(window, CLOSEWINDOW | MENUPICK);
  797.  
  798.    SetMenuStrip(window, infomenu_strip);
  799.    window->UserData = text;
  800.  
  801.    return(window);
  802. }
  803.  
  804. close_window(window)
  805. struct Window *window;
  806. {
  807.    struct IntuiMessage *message;
  808.  
  809.    if (window == NULL)
  810.       return(NULL);
  811.  
  812.    while (message = (struct IntuiMessage *)GetMsg(window->UserPort))
  813.    {
  814.       if (message->IDCMPWindow == window)
  815.          Remove(&message->ExecMessage.mn_Node);
  816.       ReplyMsg(message);
  817.    }
  818.    if (window->MenuStrip)
  819.       ClearMenuStrip(window);
  820.    window->UserPort = NULL;
  821.    ModifyIDCMP(window, NULL);
  822.  
  823.    if (window->UserData)
  824.    {
  825.       FreeMem(window->UserData, 80L);
  826.       window->Title = NULL;
  827.       window->UserData = NULL;
  828.    }
  829.    CloseWindow(window);
  830.  
  831.    return(TRUE);
  832. }
  833.  
  834. close_all()
  835. {
  836.    struct Window *window = ewindow;
  837.  
  838.    while (window = ewindow->NextWindow)
  839.    {
  840.       ewindow->NextWindow = window->NextWindow;
  841.       close_window(window);
  842.    }
  843.    ewindow->NextWindow = NULL;
  844.    return(NULL);
  845. }
  846.  
  847. void highlight_box(num)
  848. int num;
  849. {
  850.    register int x, y;
  851.    struct RastPort *rp = ewindow->RPort;
  852.  
  853.    x = EOFF_X + (element[num].column * BOX_W);
  854.    y = EOFF_Y + (element[num].row * BOX_H);
  855.  
  856.    if (y > (Yoff + 6*BOX_H))
  857.       y += .25 * BOX_H;
  858.  
  859.    SetAPen(rp, GREENTEXT);
  860.    SetDrMd(rp, COMPLEMENT);
  861.    RectFill(rp, x, y, x+BOX_W, y+BOX_H);
  862.    Delay(2);
  863.    RectFill(rp, x, y, x+BOX_W, y+BOX_H);
  864.    SetDrMd(rp, JAM1);
  865. }
  866.