home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / grap / util / 020 / tweak.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-23  |  10.2 KB  |  359 lines

  1. /*
  2.     TWEAK 1.0 - Mold your own VGA modes
  3.  
  4.     by Robert Schmidt of Ztiff Zox Softwear, 1992-93
  5.  
  6.     For documentation, see TWEAK.DOC.
  7.  
  8.  
  9.     This file is formatted with a tab-width of 4.
  10.     It's been compiled with Borland C++ 3.0 and 3.1, large model.
  11.     It might work with older Turbo versions, or even Microsoft C++, DJGPP,
  12.     Zortech and the lot.  What would I know, I can't afford more than
  13.     one compiler.
  14.  
  15.     Please send me any changes you do to enhance TWEAK or make it compatible
  16.     with other compilers, and I will start including conditional sections
  17.     for each supported compiler.  Do *not* re-release the changed source
  18.     without my permission.  Well, how can I stop ya...?
  19.  
  20.     TWEAK was based on information found in George Sutty & Steve Blair's
  21.     "Advanced Programmer's Guide to the EGA/VGA" (Brady).  While not a
  22.     magnificent book, it covers the basics and all registers.  No mention
  23.     of tweaking of any kind, but all register values for the standard
  24.     EGA/VGA modes are appendixed.
  25.  
  26.     Disclaimer:
  27.  
  28.     I don't think this is neccessary in PD stuff, but anyways:  This
  29.     product, TWEAK, referred to as THE WORK OF ART, is provided as is,
  30.     as they say.  From now on, I'll refer to myself as THE ARTIST, and
  31.     you as THE ART LOVER.  THE ARTIST doesn't know what 'as is' means to
  32.     THE ART LOVERS, but to THE ARTIST it means that THE ART LOVER ain't
  33.     got no friggin' right to hold THE ARTIST responsible for anything
  34.     mean, nice, cool, devastating, awesome or terrible happening to
  35.     THE ART LOVER, THE ART LOVER's computer or any part    within and
  36.     outside, THE ART LOVER's family, ex-family and their kin,
  37.     THE ART LOVER's sex life, THE ART LOVER's house, car, boat, in short:
  38.     THE ART LOVER's anything, as a consequence of using, not using, or
  39.     abusing THE WORK OF ART or any part contained within, including
  40.     executable, documentation, source, recommendations and references.
  41.     Phew.
  42.  
  43.     Some time ago, putting illegal or unsupported values or combinations
  44.     of such into the video card registers might prove hazardous to both
  45.     your monitor and your health.  I have *never* claimed that bad things
  46.     can't happen if you use TWEAK, although I'm pretty sure it won't.
  47.     I've never heard of any damage arising from trying out TWEAK, or from
  48.     fiddling with the VGA registers in general.
  49.  
  50.     History:
  51.  
  52.     0.9
  53.         First version available to the public.
  54.         Aw, what the heck, I'll admit this is the first version ever...
  55.         I know the usage of C++ classes may look a little stupid,
  56.             but it works.
  57.         Another stupid, *stupid* thing is the mixed use of conio and
  58.             iostream, but hey, it works too!
  59.         This version is not commented whatsoever.
  60.         Pretty lame interface - no help.
  61.         Test screens assume text start at segment 0xb800, and graphics
  62.         at 0xa000.
  63.     1.0
  64.         Changed from small to large memory model.  Not that I need it, it
  65.             just makes the code more readable.
  66.         Commented heavily, and beautified the code.
  67.         Nearly rewrote the program completely, by using another OO strategy.
  68.         Changed use of abort() to exit(1).
  69.         Text test pattern now fills entire text buffer from 0xb800:0x0000
  70.             to 0xb800:0xffff.
  71.         TWEAK now captures whatever screen mode is active at startup,
  72.             instead of defaulting to BIOS mode 3 (80x25).
  73.         The screen is reset to the startup BIOS mode at exit, too.
  74.         Added 'S' and 'L' as synonyms for F9 and F10.
  75.         Added Shift+TAB as a companion to TAB.
  76.         Editing screen now uses 80x50 instead of 80x25.
  77.         Added one text test screen which uses the 8x8 font.
  78.         Added online help, not context sensitive as promised.  Maybe later.
  79.         Edititing screen is cleared when a test is initiated, so that it
  80.             is easier to see that something happened if the wrong test
  81.             screen is selected.
  82.         Removed startup banner.
  83.         Removed use of cout and cin for screen/keyboard I/O, in favour of
  84.             the colors and windows provided by conio.h.
  85.         Instead, I use fstreams for *file* I/O... much more convenient than
  86.             FILEs.
  87.         Made the interface more cheerful by using lots of colors.
  88. */
  89.  
  90. #ifndef __LARGE__
  91. # ifndef __COMPACT__
  92. #  ifndef __HUGE__
  93. #   error A large data model is required!
  94. #  endif
  95. # endif
  96. #endif
  97.  
  98.  
  99. #include <stdio.h>
  100. #include <dos.h>
  101. #include <stdlib.h>
  102. #include <conio.h>
  103. #include <fstream.h>
  104.  
  105. #include "Screen.HPP"
  106. #include "Register.HPP"
  107. #include "RegTable.HPP"
  108. #include "TestPat.HPP"
  109.  
  110.  
  111. void helpWindow()
  112.     {
  113.     tempBuffer swap(textScr);
  114.     swap.save();
  115.     window(40,1,editWidth,21);
  116.     textattr(HELP_COLOR);
  117.     clrscr();
  118.     window(41,2,80,21);
  119.     gotoxy(1,1);
  120.     cprintf("TWEAK 1.0 by Robert Schmidt\n\r"
  121.             "Quick reference:\n\r"
  122.             "\n\r"
  123.             "Up/Down/Home/End: select register\n\r"
  124.             "Backspace: enable/disable register\n\r"
  125.             "2 hex digits: set register value\n\r"
  126.             "-/+: decrease/increase register value\n\r"
  127.             "F1-F8: toggle register bits 7-0\n\r"
  128.             "F9 or 'S': save register set to file\n\r"
  129.             "F10 or 'L': load set from file\n\r"
  130.             "'M': select BIOS mode to work from\n\r"
  131.             "TAB/Shift-TAB: select test screen\n\r"
  132.             "ENTER: test register set with pattern\n\r"
  133.             "'H': show this help window\n\r"
  134.             "ESC: Quit TWEAK immediately\n\r"
  135.             "\n\r"
  136.             "For more information, see the TWEAK.DOC\n\r"
  137.             "file.  Now press the 'any' key to\n\r"
  138.             "return!"
  139.             );
  140.     getch();
  141.     window(1,1,editWidth,editHeight);
  142.     swap.restore();
  143.     }
  144.  
  145.  
  146. main()
  147.     {
  148.     // Initialize the register table with descriptions and all.
  149.     RegisterTable regTable("TWEAK.DAT");
  150.     TestPatterns test;
  151.  
  152.     int parentBiosMode = getBiosMode();
  153.     // Set our default editing screen, and get its dimensions
  154.     setBiosMode(3);
  155.     textmode(C4350);
  156.     clrscr();
  157.     text_info *ti = new text_info;
  158.     gettextinfo(ti);
  159.     editMode = ti->currmode;
  160.     editHeight = ti->screenheight;
  161.     editWidth = ti->screenwidth;
  162.     editSize = editHeight * editWidth;
  163.     delete ti;
  164.  
  165.     tempBuffer swap(textScr);    // Establish the temporary screen buffer
  166.  
  167.     unsigned char quit = 0;            // Non-zero when a quit command is
  168.                                     //    initiated.
  169.     int key;                        // The last key pressed.
  170.  
  171.     // Build the editing screen:
  172.  
  173.     test.tellTest();
  174.     regTable.showBitMask();
  175.     regTable.printAllCon();
  176.     gotoxy(42, editHeight-7);
  177.     textattr(HELP_COLOR);
  178.     cprintf("(Press H if you need help)");
  179.  
  180.     // Start the main keyboard polling loop:
  181.  
  182.     while (!quit)
  183.         {
  184.         int key = getch();
  185.         if (!key)
  186.             key = getch() << 8;
  187.  
  188. keyentry:
  189.         switch (key)
  190.             {
  191.             case 0x4700:            //HOME
  192.                 regTable.setSelect(0);
  193.                 break;
  194.             case 0x4800:            //UP
  195.                 --regTable;
  196.                 break;
  197.             case 0x4F00:            //END
  198.                 regTable.setSelect(regTable.getMaxReg());
  199.                 break;
  200.             case 0x5000:            //DOWN
  201.                 ++regTable;
  202.                 break;
  203.  
  204.             // Function keys - toggle single bit in selected reg.
  205.             case 0x3B00:            //F1
  206.             case 0x3C00:
  207.             case 0x3D00:
  208.             case 0x3E00:
  209.             case 0x3F00:
  210.             case 0x4000:
  211.             case 0x4100:
  212.             case 0x4200:            //F8
  213.                 **regTable ^= (1<<7-((key>>8)-0x3B));
  214.                 break;
  215.             case 0x4300:            //F9
  216.             case 0x4400:            //F10
  217.  
  218.                 // Handle file operations (save/load):
  219.                 char *fname = new char[127];
  220.                 int r;
  221.                 int save=(key==0x4300);
  222.  
  223.                 // Prompt for filename.
  224.                 gotoxy(42,editHeight-1);
  225.                 textattr(PROMPT_COLOR);
  226.                 cprintf(save?"Save":"Load");
  227.                 cprintf(" file name: ");
  228.                 clreol();
  229.                 gets(fname);
  230.  
  231.                 gotoxy(42,editHeight-1);    // Get ready for error if bad
  232.                 textattr(ERROR_COLOR);        //    luck strikes
  233.                 if (save)
  234.                     {
  235.                     ofstream out(fname, ios::trunc|ios::binary|ios::out);
  236.                     if (out.bad())
  237.                         cprintf("Error opening %s", fname);
  238.                     else
  239.                         {
  240.                         out << regTable;
  241.                         if (out.bad())
  242.                             cprintf("Error writing ", fname);
  243.                         }
  244.                     }
  245.                 else
  246.                     {
  247.                     ifstream in(fname, ios::binary|ios::in|ios::nocreate);
  248.                     if (in.bad())
  249.                         cprintf("Error opening ", fname);
  250.                     else
  251.                         {
  252.                         in >> regTable;
  253.                         if (in.bad())
  254.                             cprintf("Error reading ", fname);
  255.                         }
  256.                     }
  257.  
  258.                 delete[] fname;
  259.                 // Update screen to reflect changes (if any).
  260.                 regTable.printAllCon();
  261.                 test.tellTest();
  262.                 break;
  263.             case '0': case '1': case '2': case '3': case '4': case '5':
  264.             case '6': case '7': case '8': case '9': case 'A': case 'B':
  265.             case 'C': case 'D': case 'E': case 'F':    case 'a': case 'b':
  266.             case 'c': case 'd': case 'e': case 'f':
  267.                 // Input hexadecimal number:
  268.                 gotoxy(40*(regTable.getSelect()/editHeight)+38,
  269.                     regTable.getSelect()%editHeight+1);
  270.                 ungetch(key);
  271.                 cprintf("%c \b", key);
  272.                 unsigned char newValue;
  273.                 cscanf("%2hx", &newValue);
  274.                 **regTable = newValue;
  275.                 break;
  276.  
  277.             case 'H':
  278.             case 'h':
  279.                 // Help:
  280.                 helpWindow();
  281.                 break;
  282.             // Alternate file I/O keys:
  283.             case 'S':
  284.             case 's':
  285.                 key = 0x4300;
  286.                 goto keyentry;
  287.             case 'L':
  288.             case 'l':
  289.                 key = 0x4400;
  290.                 goto keyentry;
  291.  
  292.             case 'M':
  293.             case 'm':
  294.  
  295.                 // Select a BIOS mode to work out from.
  296.                 int baseMode;
  297.                 gotoxy(42,editHeight-2);
  298.                 textattr(PROMPT_COLOR);
  299.                 cprintf("Base BIOS screen mode: 0x");
  300.                 clreol();
  301.                 cscanf("%2hx",&baseMode);
  302.                 swap.save();                //save edit buffer
  303.  
  304.                 // Set the selected mode, and grab register values.
  305.                 setBiosMode(baseMode);
  306.                 regTable.in();
  307.                 swap.restore();                //reset edit mode and buffer
  308.                 regTable.printAllCon();
  309.                 break;
  310.             case 8:
  311.                 (*regTable).toggleEnable();
  312.                 break;
  313.             case '-':
  314.                 // Decrease register value
  315.                 // Note that * (dereferencing) is overloaded for both
  316.                 //    RegisterTable and Register!  Pretty fancy :)
  317.                 (**regTable)--;
  318.                 break;
  319.             case '+':
  320.                 // Increase register value
  321.                 (**regTable)++;
  322.                 break;
  323.             case 13:    //ENTER
  324.                 // Test the screen mode.
  325.                 swap.save();
  326.                 // Clear the text screen, so the user can see something is
  327.                 //    happening.
  328.                 clrscr();
  329. //                memset(textScr, 0, sizeof(unsigned)*editSize);
  330.                 regTable.out();
  331.                 test.run();
  332.                 getch();
  333.                 swap.restore();
  334.                 break;
  335.             case 9:        //TAB
  336.                 // Select next test pattern:
  337.                 ++test;
  338.                 test.tellTest();
  339.                 break;
  340.             case 0x0F00: // shift-TAB
  341.                 // Select previous test pattern:
  342.                 --test;
  343.                 test.tellTest();
  344.                 break;
  345.             case 27:    //ESC
  346.                 // Quit TWEAK:
  347.                 quit = 1;
  348.                 break;
  349.             }
  350.         // Update the bit pattern display and register info:
  351.         regTable.showBitMask();
  352.         regTable.updateSelect();
  353.         }
  354.  
  355.     // Reset BIOS mode detected at startup.
  356.     setBiosMode(parentBiosMode);
  357.  
  358.     return 0;
  359.     }