]> 4ch.mooo.com Git - 16.git/blobdiff - 16/graph.h
modified: 16/Project 16.bfproject
[16.git] / 16 / graph.h
diff --git a/16/graph.h b/16/graph.h
deleted file mode 100644 (file)
index cabc296..0000000
+++ /dev/null
@@ -1,951 +0,0 @@
-////////////////////////////////////////\r
-//  Graph.h\r
-//      Coded by Denn Man\r
-//\r
-//  Licensed under the Academic Free License version 1.2\r
-//\r
-//  *Special thanks to Micheal Abrash\r
-//   and his columns in Dr. Dobbs Journal\r
-//   (Jul91 and Aug91) documenting\r
-//   ModeX\r
-//\r
-//      For use with Turbo-C\r
-//  Uses as much assembly as possible\r
-//   in order to optimize drawing speed\r
-//      Self-sufficient: Nothing else needed\r
-////////////////////////////////////////\r
-\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include <math.h>\r
-#include <stdio.h>\r
-\r
-\r
-// Start of video memory (SEGMENT)\r
-#define MCGA_MEM               0xA000\r
-// Video Digital-Analog-Converter Port\r
-#define VIDEO_DAC              0x03C8\r
-// Video DAC Read Port\r
-#define DAC_READ               0x03C7\r
-// Video Data Port\r
-#define VIDEO_DATA     0x03C9\r
-// VGA Sequence Controller\r
-#define SC_INDEX               0x03C4\r
-// CRT Control Register\r
-#define CRTC_INDEX     0x03D4\r
-// Miscellaneous Output Register\r
-#define MISC_OUTPUT    0x03C2\r
-// VGA Map Mask Register\r
-#define MAP_MASK               0x02\r
-// Screen Width\r
-#define SCR_WIDTH              80\r
-// VGA Graphics Controller Register\r
-#define GC_INDEX               0x03CE\r
-// VGA Read Map Register\r
-#define READ_MAP               0x04\r
-// PI\r
-#define PI 3.14159265358\r
-\r
-// Datatypes\r
-typedef unsigned char byte;\r
-typedef unsigned int word;\r
-typedef unsigned long dword;\r
-\r
-typedef struct tagTILE {\r
-       word height;\r
-       word width;\r
-       byte *data;\r
-} TILE;\r
-\r
-// FOR BITMAP FILES!!!\r
-typedef struct tagBITMAPFILEHEADER {\r
-       word    bfType;\r
-       dword   bfSize;\r
-       word    bfReserved1;\r
-       word    bfReserved2;\r
-       dword   bfOffBits;\r
-} BITMAPFILEHEADER;\r
-\r
-typedef struct tagBITMAPINFOHEADER {\r
-       dword   biSize;\r
-       dword biWidth;\r
-       dword   biHeight;\r
-       word    biPlanes;\r
-       word    biBitCount;\r
-       dword   biCompression;\r
-       dword   biSizeImage;\r
-       dword   biXPelsPerMeter;\r
-       dword   biYPelsPerMeter;\r
-       dword   biClrUsed;\r
-       dword   biClrImportant;\r
-} BITMAPINFOHEADER;\r
-\r
-typedef struct tagRGBQUAD {\r
-       byte    rgbBlue;\r
-       byte    rgbGreen;\r
-       byte    rgbRed;\r
-       byte    rgbReserved;\r
-} RGBQUAD;\r
-\r
-typedef struct tagBITMAPINFO {\r
-       BITMAPINFOHEADER        bmiHeader;\r
-       RGBQUAD                         bmiColors[256];\r
-} BITMAPINFO;\r
-\r
-typedef struct tagBITMAP {\r
-       BITMAPFILEHEADER        bmFileHeader;\r
-       BITMAPINFO                      bmInfo;\r
-       byte                                    *bmData;\r
-} BITMAP;\r
-// DONE WITH BITMAP FILE INFO\r
-\r
-// Monitor settings for ModeX\r
-struct tagCRTParms {\r
-       word V_Total;                   // Vertical Total\r
-       word OverFlow;                  // Overflow\r
-       word CellHeight;                // Cell Height\r
-       word V_Sync_Start;      // Vertical Sync Start\r
-       word V_Sync_End;                // Vertical Sync End\r
-       word V_Disp;                    // Vertical Displayed\r
-       word D_Off;                             // Turn off dword mode\r
-       word V_Blank_Start;     // Vertical Blank Start\r
-       word V_Blank_End;               // Vertical Blank End\r
-       word B_On;                              // Turn byte mode on\r
-} CRTParms;\r
-\r
-byte VIDEO_MODE;       // The current video mode\r
-word MAX_X;                    // Last available X\r
-word MAX_Y;                    // Last available Y\r
-word SCREEN_WIDTH;\r
-word SCREEN_HEIGHT;\r
-byte MAX_COLORS;       // Last available color\r
-byte FG_COLOR;         // For text and mono stuff\r
-byte BG_COLOR;\r
-word CUR_X;                    // Current X\r
-word CUR_Y;                    // Current Y\r
-word visibleStart;// Start offset in video memory of screen\r
-word activeStart; // Start offset in video memory to write to\r
-\r
-// For rectangle filling (ModeX)\r
-byte LeftClipPlaneMask[] = { 0x0F, 0x0E, 0x0C, 0x08 };\r
-byte RightClipPlaneMask[] = { 0x0F, 0x01, 0x03, 0x07 };\r
-\r
-// In case things go awry\r
-char msg_error[81];\r
-\r
-void exit_error(void)\r
-{\r
-       printf("%s\a\n", msg_error);\r
-}\r
-\r
-////////////////////////////////////////\r
-// init_modeX\r
-//\r
-// -Initialized modeX 320x240x256 graphics\r
-// -Clears video memory\r
-// -Sets page 1 active at offset 0\r
-////////////////////////////////////////\r
-void init_modeX(void)\r
-{\r
-       // Fill the CRT Parameters\r
-       CRTParms.V_Total = 0x0D06;\r
-       CRTParms.OverFlow = 0x3E07;\r
-       CRTParms.CellHeight = 0x4109;\r
-       CRTParms.V_Sync_Start = 0xEA10;\r
-       CRTParms.V_Sync_End = 0xAC11;\r
-       CRTParms.V_Disp = 0xDF12;\r
-       CRTParms.D_Off = 0x0014;\r
-       CRTParms.V_Blank_Start = 0xE715;\r
-       CRTParms.V_Blank_End = 0x0616;\r
-       CRTParms.B_On = 0xE317;\r
-\r
-       asm {\r
-               mov ax, 0x0013       // Start in mode 13h\r
-               int 0x10                                        // Call interrupt\r
-\r
-               mov dx, SC_INDEX                // Disable Chain-4 Memory model\r
-               mov ax, 0x0604\r
-               out dx, ax\r
-               mov ax, 0x0100                  // Synchronous reset while switching clocks\r
-               out dx, ax\r
-\r
-               mov dx, MISC_OUTPUT     // Select 28MHz dot clock, 60 Hz scan rate\r
-               mov al, 0xE3\r
-               out dx, al\r
-\r
-               mov dx, SC_INDEX                // Restart Sequencer\r
-               mov ax, 0x0300\r
-               out dx, ax\r
-\r
-               mov dx, CRTC_INDEX      // Reprogram the CRT Controller\r
-               mov al, 0x11                    // Select Write-Protect bit\r
-               out dx, al\r
-               inc dx                                  // CRT-Data register into DX now\r
-               in al, dx                               // Get current VSync End Register setting\r
-               and al, 0x7F         // Remove write-protect on various registers\r
-               out dx, al\r
-               dec dx                                  // CRT-Controller\r
-               cld                                             // Clear the direction\r
-               mov si, OFFSET CRTParms // Load settings\r
-               mov cx, 20                              // 20 Entries\r
-       }\r
-       SetCRTParmsLoop:asm {\r
-               lodsw                                           // Load the addr:data pair\r
-               out dx, ax                              // Send them out\r
-               loop SetCRTParmsLoop    // Do it for each one\r
-\r
-               mov dx, SC_INDEX                // Enable write to all bitplanes\r
-               mov ax, 0x0F02\r
-               out dx, ax\r
-               mov ax, MCGA_MEM                // Load video memory\r
-               mov es, ax\r
-               mov di, 0            // Start at the top\r
-               mov ax, 0                               // Store 0's\r
-               mov cx, 0x8000                  // Do it 8000h times\r
-               rep stosw                               // Store them\r
-       }\r
-\r
-       // Fill globals\r
-       VIDEO_MODE = 0xFF;\r
-       MAX_X = 319;\r
-       MAX_Y = 239;\r
-       SCREEN_WIDTH = 320;\r
-       SCREEN_HEIGHT = 240;\r
-       MAX_COLORS = 255;\r
-       FG_COLOR = 15;\r
-       BG_COLOR = 0;\r
-       CUR_X = 0;\r
-       CUR_Y = 0;\r
-\r
-       activeStart = 0;                        // Write to Page 0\r
-       visibleStart = 0;                       // Read from Page 0\r
-}\r
-\r
-////////////////////////////////////////\r
-//     close_graph\r
-//\r
-//     -Shuts down graphics, sets text mode,\r
-//  and fills appropriate variables\r
-// -Frees memory taken by video buffers\r
-////////////////////////////////////////\r
-void close_graph(void)\r
-{\r
-       asm {\r
-               mov ax, 0x0003\r
-               int 0x10\r
-       }\r
-\r
-       VIDEO_MODE = 0x03;\r
-       MAX_X = 80;\r
-       MAX_Y = 25;\r
-       SCREEN_WIDTH = 80;\r
-       SCREEN_HEIGHT = 25;\r
-       MAX_COLORS = 15;\r
-       FG_COLOR = 7;\r
-       BG_COLOR = 0;\r
-       CUR_X = 1;\r
-       CUR_Y = 1;\r
-}\r
-\r
-void cleargraph(void)\r
-{\r
-       asm {\r
-               pusha\r
-               push es\r
-               push di\r
-\r
-               mov ax, MCGA_MEM\r
-               mov es, ax\r
-               mov di, 0\r
-\r
-               mov dx, SC_INDEX                // Enable write to all bitplanes\r
-               mov ax, 0x0F02\r
-               out dx, ax\r
-\r
-               mov cx, 0x8000\r
-               mov ax, 0x0000\r
-               rep stosw\r
-\r
-               pop di\r
-               pop es\r
-               popa\r
-       }\r
-}\r
-\r
-////////////////////////////////////////\r
-// setActiveStart\r
-//\r
-// -Sets the starting memory address\r
-//  at which graphics are written to\r
-////////////////////////////////////////\r
-void setActiveStart(word PageBase)\r
-{\r
-       activeStart = PageBase;\r
-}\r
-\r
-////////////////////////////////////////\r
-// setVisibleStart\r
-//\r
-// -Sets the starting memory address\r
-//  at which graphics are displayed from\r
-////////////////////////////////////////\r
-void setVisibleStart(word PageBase)\r
-{\r
-       visibleStart = PageBase;\r
-\r
-       asm {\r
-               pusha                                           // Dont touch!\r
-\r
-               mov bx, PageBase                // Load the offset into BX\r
-               mov dx, CRTC_INDEX      // Load the CRT Index Port into DX\r
-               mov al, 0x0C                    // Function 0Ch, High Byte of addres\r
-               mov ah, bh                              // Load the high byte\r
-               out dx, ax                              // Send it\r
-               inc al                                  // Function 0Dh, Low Byte of address\r
-               mov ah, bl                              // Load the low byte\r
-               out dx, ax                              // Send it\r
-\r
-               popa                                            // We were never here\r
-       }\r
-}\r
-\r
-////////////////////////////////////////\r
-// setActivePage\r
-//\r
-// -Sets page in which graphics are\r
-//  written\r
-////////////////////////////////////////\r
-void setActivePage(byte Page)\r
-{\r
-       // Page = (Page Offset * Width of Screen (Bytes) * Screen Height (Rows))\r
-       setActiveStart(Page * SCR_WIDTH * SCREEN_HEIGHT);\r
-}\r
-\r
-////////////////////////////////////////\r
-// setVisiblePage\r
-//\r
-// -Sets page from which graphics are\r
-//  drawn\r
-////////////////////////////////////////\r
-void setVisiblePage(byte Page)\r
-{\r
-       // Page = (Page Offset * Width of Screen (Bytes) * Screen Height (Rows))\r
-       setVisibleStart(Page * SCR_WIDTH * SCREEN_HEIGHT);\r
-}\r
-\r
-void vScroll(int rows)\r
-{\r
-       // Scrolling = current start + (rows * bytes in a row)\r
-       setVisibleStart(visibleStart + (rows * SCR_WIDTH));\r
-}\r
-\r
-void read_palette(byte *pal)\r
-{\r
-       int i;\r
-\r
-       for (i = 0; i < 256; i++)\r
-       {\r
-               asm cli\r
-               outportb(DAC_READ, i);\r
-               pal[(i * 3) + 0] = inportb(VIDEO_DATA);\r
-               pal[(i * 3) + 1] = inportb(VIDEO_DATA);\r
-               pal[(i * 3) + 2] = inportb(VIDEO_DATA);\r
-               asm sti\r
-       }\r
-}\r
-\r
-void load_palette(byte *pal)\r
-{\r
-       int i;\r
-\r
-       for (i = 0; i < 256; i++)\r
-       {\r
-               asm cli\r
-               outportb(VIDEO_DAC, i);\r
-               outportb(VIDEO_DATA, pal[(i * 3) + 0]);\r
-               outportb(VIDEO_DATA, pal[(i * 3) + 1]);\r
-               outportb(VIDEO_DATA, pal[(i * 3) + 2]);\r
-               asm sti\r
-       }\r
-}\r
-\r
-////////////////////////////////////////\r
-// setpalette\r
-//\r
-// -Self explanatory, sets the color\r
-//  of a given index in 256 MCGA mode\r
-////////////////////////////////////////\r
-void setpalette(byte index, byte red, byte green, byte blue)\r
-{\r
-       outportb(VIDEO_DAC, index);\r
-       outportb(VIDEO_DATA, red);\r
-       outportb(VIDEO_DATA, green);\r
-       outportb(VIDEO_DATA, blue);\r
-}\r
-\r
-////////////////////////////////////////\r
-// putpixel\r
-//\r
-// -Puts a pixel (in modeX) at (X, Y)\r
-//  in active page\r
-////////////////////////////////////////\r
-void putpixel(word x, word y, byte Color)\r
-{\r
-       asm {\r
-               pusha\r
-               push es\r
-               push di\r
-\r
-               mov ax, SCR_WIDTH          // Load screen width, in bytes\r
-               mul y                      // Multiply it by Y to get row\r
-               mov di, x                  // Load X into BX\r
-               shr di, 2                                               // Divide X by 4 to get plane\r
-               add di, ax                                              // Add to col offset, row offset\r
-               add di, activeStart                     // Add the page offset\r
-               mov ax, MCGA_MEM                                // Load video memory into AX\r
-               mov es, ax                                              // Then ES\r
-\r
-               mov cx, x                                // Get X pos\r
-               and cl, 0x03                                    // Get X plane\r
-               mov ax, 0x0100 + MAP_MASK       // Load Map-Mask register\r
-               shl ah, cl                                              // Write to only the desired plane\r
-               mov dx, SC_INDEX                                // Tell the Map-Mask to do the same\r
-               out dx, ax                                              // Do it\r
-\r
-               mov al, Color                                   // Load the color\r
-               stosb                                                           // Store it\r
-\r
-               pop di\r
-               pop es\r
-               popa\r
-       }\r
-}\r
-\r
-////////////////////////////////////////\r
-// getpixel\r
-//\r
-// -Returns color of pixel (in ModeX)\r
-//  at (x, y)\r
-////////////////////////////////////////\r
-byte getpixel(word x, word y)\r
-{\r
-       byte returnvalue;       // To hold color\r
-\r
-       asm {\r
-               pusha                                           // Dont touch anything\r
-               push es\r
-               push di\r
-               mov ax, SCR_WIDTH               // Move screen width (in bytes) into AX\r
-               mul y                                           // Multiply by y to get row\r
-               mov bx, x                               // Move x into BX\r
-               shr bx, 2                               // Divide by 4 to get plane\r
-               add bx, ax                              // Add the two offsets together\r
-               add bx, activeStart     // Add the PageBase\r
-               mov ax, MCGA_MEM                // Video Memory into AX\r
-               mov es, ax                              // Now into ES\r
-\r
-               mov ah, byte ptr x      // X into AH\r
-               and ah, 0x03                    // Get Plane\r
-               mov al, READ_MAP                // Tell the Video Card\r
-               mov dx, GC_INDEX\r
-               out dx, ax                              // Do it\r
-\r
-               mov al, es:[bx]         // Get the color\r
-               sub ah, ah                              // Clear AH\r
-               mov returnvalue, al     //      Store the color into returnvalue\r
-               pop di\r
-               pop es\r
-               popa                                            // Put everything back\r
-       }\r
-\r
-       return returnvalue;             // Return color\r
-}\r
-\r
-////////////////////////////////////////\r
-// vline\r
-//\r
-// -Draws a vertical line from (x,y1)-(x,y2)\r
-//  of color in activePage\r
-////////////////////////////////////////\r
-void vline(word y1, word y2, word x, byte color)\r
-{\r
-       asm {\r
-               pusha                // Dont touch anything here\r
-               push es\r
-               push di\r
-               push si                                 // For lowY\r
-\r
-               mov si, y1                              // Move y1 into SI\r
-               mov bx, y2                              // y2 into BX\r
-               cmp si, bx                              // Compare the two\r
-               jle vline_ordered               // IF y1 <= y2, skip the next lines\r
-\r
-               xchg si, bx                             // ELSE switch them\r
-       }\r
-       vline_ordered:asm {\r
-               mov ax, MCGA_MEM                // Load the video memory into AX\r
-               mov es, ax                              // then into ES\r
-               mov ax, SCR_WIDTH               // Load screen width (bytes) into AX\r
-               mul si                                  // and Multiply by the y1 value\r
-               mov di, ax                              // Move it into DI\r
-               mov ax, x                               // x into AX\r
-               shr ax, 2                               // Divided by 4\r
-               add di, ax                              // and added to get first point offset\r
-\r
-               mov dx, SC_INDEX                // Point to Sequence Controller\r
-               mov al, MAP_MASK                // Select Map Mask Register (0x02)\r
-               out dx, al                              // Do it\r
-               inc dx                                  // Next Register (SC Data)\r
-               mov cl, byte ptr x      // x into CL\r
-               and cl, 0x03                    // x & 0011b to get plane\r
-               mov al, 0x01         // Only one plane, so load 0001b\r
-               shl ax, cl                              // Shift it left by the plane number\r
-               out dx, al                              // Send it\r
-\r
-               mov cx, bx                              // Load highY into CX\r
-               sub cx, si                              // Subtract lowY to get ydelta\r
-               inc cx                                  // Add one\r
-\r
-               mov al, color                   // Load the color into AL\r
-       }\r
-       vline_row_top:asm {\r
-               stosb                                           // Store the color\r
-               add di, SCR_WIDTH               // Add a row\r
-               dec di                                  // Subtract one, because STO incs DI\r
-               loop vline_row_top      // Loop until done\r
-\r
-               pop si\r
-               pop di\r
-               pop es\r
-               popa                 // Put everything back\r
-       }\r
-}\r
-\r
-////////////////////////////////////////\r
-// hline\r
-//\r
-// -Draws a horizontal line from\r
-//  (x1, y)-(x2, y) of color in activePage\r
-// -Faster than a speeding bullet! (Draws\r
-//  four pixels at a time by turning on\r
-//  all bitplanes for read at once.\r
-// -This function is ALL MINE!!! Not one\r
-//  bit of a copy. :)\r
-////////////////////////////////////////\r
-void hline(word x1, word x2, word y, byte color)\r
-{\r
-       asm {\r
-               pusha                      // Dont touch anything\r
-               push es\r
-               push di\r
-               push si                                                 // For lowX\r
-\r
-               mov ax, MCGA_MEM                                // Load the graphics memory\r
-               mov es, ax\r
-\r
-               mov ax, SCR_WIDTH                               // Screen width (bytes) into AX\r
-               mul y                                                           // Multiply by y to get row offset\r
-               mov di, ax                                              // Move row offset into DI\r
-\r
-               mov si, x1                                              // This was a pain to order the variables\r
-               mov cx, x2                                              // Load x1 into SI, x2 into CX\r
-               cmp si, cx                                              // Compare them\r
-               jle hline_ordered                               // If x1 is <= x2, skip the next stuff\r
-\r
-               xchg si, cx                                             // ELSE switch them\r
-       }\r
-       hline_ordered:asm {\r
-               mov ax, si                                      // lowX into AX\r
-               shr ax, 2                                               // Divided by 4\r
-               add di, ax                                              // Add the lowX offset to DI\r
-\r
-               mov ax, si                                              // lowX back into AX\r
-               and ax, 0x0003                                  // lowX AND 0011b to get left bit planes\r
-       }\r
-       _BH = LeftClipPlaneMask[_AX];   //      Load the left mask into BH\r
-       asm {\r
-               mov dx, SC_INDEX                                // Sequence Controller into DX\r
-               mov al, MAP_MASK                                // Map Mask (Function 0Ch) into AL\r
-               out dx, al                                              // Send it\r
-               inc dx                                                  // SC Data Register\r
-               mov al, bh                                              // Load the mask into AL\r
-               out dx, al                                              // Send it\r
-\r
-               mov al, color                                   // Load color into AL\r
-               stosb                                                           // Store the first byte of line\r
-\r
-               mov dx, SC_INDEX           // Loading a mask again\r
-               mov al, MAP_MASK                                // ...\r
-               out dx, al                                              // ...\r
-               inc dx                                                  // ... as before\r
-               mov al, 0x0F                                    // Turn all bits on, we want MAX SPEED!\r
-               out dx, al                                              // Send it\r
-\r
-               push cx                                                 // Store the highX\r
-               sub cx, si                                              // Subtract the lowX from highX\r
-               shr cx, 2                                               // Divide it by 4\r
-               dec cx                                                  // Minus the last byte\r
-\r
-               mov al, color                                   // Load the color into AL\r
-               rep stosb                                               // Repeat the storing of color\r
-\r
-               pop cx                                                  // Get out highX back\r
-               inc cl                                                  // Increment, BUG FIX : Not sure why\r
-               and cl, 0x03                                    // AND 0011b to get bit planes\r
-       }\r
-       _BL = RightClipPlaneMask[_CL];// Load the right mask into BL\r
-       asm {\r
-               mov dx, SC_INDEX                                // Again, we send the mask to the\r
-               mov al, MAP_MASK                                // VGA card\r
-               out dx, al                                              // ...\r
-               inc dx                                                  // ...\r
-               mov al, bl                                              // ...\r
-               out dx, al                                              // ... We have seen this already...\r
-\r
-               mov al, color                                   // Load the color into AL\r
-               stosb                                                           // Store the last byte\r
-\r
-               pop si\r
-               pop di\r
-               pop es\r
-               popa                                                            // Put everything back, we're done!\r
-       }\r
-}\r
-\r
-////////////////////////////////////////\r
-// line\r
-//\r
-// -Draws a line from (x1, y1)-(x2, y2)\r
-//  of color in the active page\r
-// -Uses Bresenhem's Line routine\r
-////////////////////////////////////////\r
-void line(word x1, word y1, word x2, word y2, byte color)\r
-{\r
-       int dx, dy;\r
-       int xinc, yinc;\r
-       int P_right;\r
-       int P_right_up;\r
-       int P;\r
-\r
-       if (x1 == x2)\r
-               vline(y1, y2, x1, color);\r
-//     if (y1 == y2)\r
-//             hline(x1, x1, y1, 0, color);\r
-\r
-       dx = abs(x2 - x1);\r
-       dy = abs(y2 - y1);\r
-\r
-       xinc = (x1 > x2) ? -1 : 1;\r
-       yinc = (y1 > y2) ? -1 : 1;\r
-\r
-       if (dx > dy)\r
-       {\r
-               P_right = (2 * dy);\r
-               P_right_up = P_right - (2 * dx);\r
-               P = P_right - dx;\r
-\r
-               for (; dx >= 0; dx--)\r
-               {\r
-                       putpixel(x1, y1, color);\r
-                       if (P > 0)\r
-                       {\r
-                               x1 += xinc;\r
-                               y1 += yinc;\r
-                               P += P_right_up;\r
-                       }\r
-                       else\r
-                       {\r
-                               x1 += xinc;\r
-                               P += P_right;\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               P_right = (2 * dx);\r
-               P_right_up = P_right - (2 * dy);\r
-               P = P_right - dy;\r
-\r
-               for (; dy >= 0; dy--)\r
-               {\r
-                       putpixel(x1, y1, color);\r
-                       if (P > 0)\r
-                       {\r
-                               x1 += xinc;\r
-                               y1 += yinc;\r
-                               P += P_right_up;\r
-                       }\r
-                       else\r
-                       {\r
-                               y1 += yinc;\r
-                               P += P_right;\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void rect(word x1, word y1, word x2, word y2, byte color)\r
-{\r
-       // Just draw the four lines, x is longer because hline is a\r
-       // faster routine than vline.\r
-       hline(x1, x2, y1, color);\r
-       hline(x1, x2, y2, color);\r
-       vline(y1 + 1, y2 - 1, x1, color);\r
-       vline(y1 + 1, y2 - 1, x2, color);\r
-}\r
-\r
-////////////////////////////////////////\r
-// fillrect\r
-//\r
-// -Fills a rectangle (in ModeX) of color\r
-//  from (x1, y1) to (x2, y2)\r
-//\r
-// *Adopted from Dr. Dobbs Journal Sep 91\r
-////////////////////////////////////////\r
-void fillrect(word x1, word y1, word x2, word y2, byte color)\r
-{\r
-       asm {\r
-               pusha                         // Dont touch anything\r
-               push ds\r
-               push si\r
-               push es\r
-               push di\r
-               push bp\r
-\r
-               cld                                                                     // Clear direction flag (left to right)\r
-               mov ax, SCR_WIDTH                                       // Screen Width (bytes) into AX\r
-               mul y1                                                          // Times y1 value\r
-               mov di, x1                                                      // x1 into DI\r
-               shr di, 2                                                       // Divided by four to get plane\r
-               add di, ax                                                      // Add the y offset\r
-               add di, activeStart                             // Add the PageBase\r
-               mov ax, MCGA_MEM                                        // Now set up the video memory\r
-               mov es, ax                                                      // into ES\r
-               mov dx, SC_INDEX                                        // Point to Sequence Controller\r
-               mov al, MAP_MASK                                        // Select Map Mask Register (0x02)\r
-               out dx, al                                                      // Do it\r
-               inc dx                                                          // Next Register (SC Data)\r
-               mov si, x1                                                      // x1 into SI\r
-               and si, 0x0003                                          // x1 & 0011b to get plane\r
-       }\r
-       _BH = LeftClipPlaneMask[_SI];           // Select appropriate mask\r
-       asm {\r
-               mov si, x2                                                      // Do the same for x2\r
-               and si, 0x0003                                          // x2 & 0011b\r
-       }\r
-       _BL = RightClipPlaneMask[_SI];  // Mask select\r
-       asm {\r
-               mov cx, x2                    // x2 into CX\r
-               mov si, x1                                                      // x1 into SI\r
-               cmp cx, si                                                      // Compare them\r
-               jle FillDone                                            // IF CX <= SI jump to FillDone\r
-               dec cx                        // Decrement CX\r
-               and si, 0xFFFC                // x1 & 1111111111111100\r
-               sub cx, si                    // Subtract x1 from x2\r
-               shr cx, 2                     // Divide CX by 4\r
-               jnz MasksSet                                            // Jump if not zero to MasksSet\r
-               and bh, bl                                                      // BH = BH and BL\r
-       }\r
-       MasksSet:asm {\r
-               mov si, y2                                                      // y2 into SI\r
-               sub si, y1                    // Subtract y1\r
-               jle FillDone                  // IF SI <= 0 jump to FillDone\r
-               mov ah, byte ptr color                  // Load color\r
-               mov bp, SCR_WIDTH                                       // Load screen width (bytes)\r
-               sub bp, cx                                                      // Subtract xdelta from width\r
-               dec bp                                                          // Minus 1\r
-       }\r
-       FillRowsLoop:asm {\r
-               push cx                       // Dont hurt CX\r
-               mov al, bh                                                      // Left Clip Mask into AL\r
-               out dx, al                                                      // Send it out\r
-               mov al, ah                                                      // Color to AL\r
-               stosb                                                                   // Send it out\r
-               dec cx                                                          // Minus left edge byte\r
-               js FillLoopBottom                                       // Jump if SIGNAL flag NOT set\r
-               jz DoRightEdge                                          // If that's it, do the right.\r
-               mov al, 0x0F                                            // Turn all bit planes on\r
-               out dx, al                                                      // Do it\r
-               mov al, ah                                                      // Load color into AL\r
-               rep stosb                                                       // Store it over and over\r
-       }\r
-       DoRightEdge:asm {\r
-               mov al, bl                                                      // Right Clip Mask into AL\r
-               out dx, al                                                      // Do it\r
-               mov al, ah                                                      // Load color into AL\r
-               stosb                                                                   // Store it\r
-       }\r
-       FillLoopBottom:asm {\r
-               add di, bp                                                      // Next scan line\r
-               pop cx                                                          // What row?\r
-               dec si                                                          // One less row\r
-               jnz FillRowsLoop                                        // If not zero, go again\r
-       }\r
-       FillDone:asm {\r
-               pop bp\r
-               pop di\r
-               pop es\r
-               pop si\r
-               pop ds\r
-               popa                                                            // All done, put everything back\r
-       }\r
-}\r
-\r
-void circle(word x, word y, word radius, byte color)\r
-{\r
-       float angle;\r
-       float ainc = 1;\r
-       word xc, yc;\r
-\r
-       if (radius > 119)                       // IF the radius is greater than 119, make the\r
-               ainc = 0.25;                    // increment smaller\r
-       if (radius > 61)                        // IF it's bigger than 61\r
-               ainc = 0.5;                             // do the same\r
-\r
-\r
-       // Only calculate 1/8th of the circle\r
-       // Four quadrants = (x, y), (-x, y), (-x, -y), (x, -y)\r
-       // Eight octants are made by switching x's and y's.\r
-       // Draw eight pixels per iteration and make the circle\r
-       // eight times faster than conventional routines.\r
-       for (angle = 0; angle <= 45; angle += ainc)\r
-       {\r
-               xc = (word)floor(cos((angle * PI) / 180) * radius);\r
-               yc = (word)floor(sin((angle * PI) / 180) * radius);\r
-\r
-               putpixel(x + xc, y + yc, color);\r
-               putpixel(x + xc, y - yc, color);\r
-               putpixel(x - xc, y + yc, color);\r
-               putpixel(x - xc, y - yc, color);\r
-\r
-               putpixel(x + yc, y + xc, color);\r
-               putpixel(x + yc, y - xc, color);\r
-               putpixel(x - yc, y + xc, color);\r
-               putpixel(x - yc, y - xc, color);\r
-       }\r
-}\r
-\r
-void load_BMP_palette(BITMAP *s)\r
-{\r
-       int i;\r
-\r
-       for (i = 0; i < 256; i++)\r
-               setpalette(i, (byte)floor((s->bmInfo.bmiColors[i].rgbRed / 63) * 255),\r
-                                                 (byte)floor((s->bmInfo.bmiColors[i].rgbGreen / 63) * 255),\r
-                                                 (byte)floor((s->bmInfo.bmiColors[i].rgbBlue / 63) * 255));\r
-}\r
-\r
-////////////////////////////////////////\r
-// load_BMP\r
-//\r
-// -Opens a bitmap (Non-Compressed) and\r
-//  stores the data into a given BITMAP\r
-//  variable\r
-// -Allocate memory BEFORE calling this\r
-//  function for the BITMAP structure\r
-// -Must be 256 Color, Columns divisible\r
-//  by four\r
-////////////////////////////////////////\r
-void load_BMP(char *filename, TILE *target)\r
-{\r
-       FILE *inBMP;                                                                                    // Create file handle\r
-       BITMAP *tempBMP;\r
-       int color;\r
-\r
-       if ((inBMP = fopen(filename, "r+b")) == NULL)// Open it\r
-       {\r
-               sprintf(msg_error, "Cannot open %s", filename);\r
-               atexit(exit_error);                                                             // IF error, exit and\r
-               exit(1);                                                                                                // tell user.\r
-       }\r
-\r
-       tempBMP = (BITMAP *)malloc(sizeof(BITMAP) - 1);\r
-\r
-       fseek(inBMP, 0, 0);                          // Goto the beginning\r
-       fread(tempBMP, sizeof(BITMAP) - 1, 1, inBMP);           // And load it all into\r
-                                                                                                                               // the given variable\r
-\r
-       fseek(inBMP, 54, 0);                         // Goto color offset\r
-       for (color = 0; color < 256; color++)        // and read 'em in.\r
-       {\r
-               tempBMP->bmInfo.bmiColors[color].rgbBlue = fgetc(inBMP);\r
-               tempBMP->bmInfo.bmiColors[color].rgbGreen = fgetc(inBMP);\r
-               tempBMP->bmInfo.bmiColors[color].rgbRed = fgetc(inBMP);\r
-               tempBMP->bmInfo.bmiColors[color].rgbReserved = fgetc(inBMP);\r
-       }\r
-\r
-       load_BMP_palette(tempBMP);\r
-\r
-       // Allocate space for the data to hold the pixels\r
-       // Goto the pixel offset in the file\r
-       // Read in the pixels\r
-       target->data = (byte *)calloc((tempBMP->bmFileHeader.bfSize - tempBMP->bmFileHeader.bfOffBits), 1);\r
-       target->height = tempBMP->bmInfo.bmiHeader.biHeight;\r
-       target->width = tempBMP->bmInfo.bmiHeader.biWidth;\r
-       fseek(inBMP, tempBMP->bmFileHeader.bfOffBits, 0);\r
-       fread(target->data, target->height * target->width, 1, inBMP);\r
-\r
-       free(tempBMP);\r
-       fclose(inBMP);                               // Dont forget to close\r
-}\r
-\r
-void show_BMP(TILE *source, word x, word y)\r
-{\r
-       word row, col, offset = 0;\r
-\r
-       for (row = source->height; row > 0; row--)\r
-       {\r
-               for (col = 0; col < source->height; col++)\r
-               {\r
-                       if (source->data[offset] != 255)\r
-                               putpixel(x + col, y + row, source->data[offset]);\r
-                       offset++;\r
-               }\r
-       }\r
-}\r
-\r
-void show_tile(TILE *tile, word x, word y)\r
-{\r
-       word cx, cy;\r
-\r
-       for (cy = 1; cy <= tile->height; cy++)\r
-               for (cx = 0; cx < tile->width; cx++)\r
-                       if (tile->data[cx + (cy * tile->width)] != 255)\r
-                               putpixel(x + cx, y + cy, tile->data[cx + (cy * tile->width)]);\r
-}\r
-\r
-void make_tile(TILE *target, TILE *source)\r
-{\r
-       int row, col, offset = 0;\r
-\r
-       target->data = (byte *)malloc(source->height * source->width + source->width);\r
-\r
-       target->height = source->height;\r
-       target->width = source->width;\r
-\r
-       for (row = source->height * source->width; row >= 0; row -= source->width)\r
-       {\r
-               for (col = 0; col < source->width; col++)\r
-               {\r
-                       target->data[offset] = source->data[col + row];\r
-                       offset++;\r
-               }\r
-       }\r
-}\r
-\r
-void get_tile(word x1, word y1, word x2, word y2, TILE *target)\r
-{\r
-       int cx, cy, offset = 0;\r
-\r
-       target->height = abs(y2 - y1);\r
-       target->width = abs(x2 - x1);\r
-\r
-       target->data = (byte *)malloc(target->height * target->width + target->width);\r
-\r
-       for (cy = 0; cy <= target->height; cy++)\r
-               for (cx = 0; cx < target->width; cx++)\r
-               {\r
-                       target->data[offset] = getpixel(x1 + cx, y1 + cy);\r
-                       offset++;\r
-               }\r
-}\r