// window.cpp // // Implements a simple graphics interface around the Watcom graphics // library. Intended to make it easy to port programs with graphics, // since you'll only have to port this module. // // by Dave Hershberger #include #include #include // Watcom's graphics header #include "window.h" //////////////////////////////////////////////////////////// // Color functions. //////////////////////////////////////////////////////////// int Color::next_avail_index = 0; long Color::colors[NUM_COLORS]; Color::Color(long newcolor) { int i; // check to see if this color has already been set up. for(i = 0; i < next_avail_index; i++){ if(colors[i] == newcolor){ index = i; return; } } if(next_avail_index >= NUM_COLORS){ fprintf(stderr, "Warning: color allocation failed.\n"); fprintf(stderr, " Using closest existing color.\n"); index = closest(newcolor); } else{ // if not, set it up in the palette. index = next_avail_index; colors[index] = newcolor; next_avail_index++; _remappalette(index, newcolor); } } Color::Color(int red, int green, int blue) { int i; long newcolor = (blue << 16) | (green << 8) | red; // check to see if this color has already been set up. for(i = 0; i < next_avail_index; i++){ if(colors[i] == newcolor){ index = i; return; } } if(next_avail_index >= NUM_COLORS){ fprintf(stderr, "Warning: color allocation failed.\n"); fprintf(stderr, " Using closest existing color.\n"); index = closest(newcolor); } else{ // if not, set it up in the palette. index = next_avail_index; colors[index] = newcolor; next_avail_index++; _remappalette(index, newcolor); } } int Color::closest(long newcolor) { int red, green, blue; int ired, igreen, iblue; int i, mini; int dist, mindist = 10000; blue = newcolor >> 16; green = (newcolor >> 8) & 0xff; red = newcolor & 0xff; for(i = 0; i < next_avail_index; i++){ iblue = colors[i] >> 16; igreen = (colors[i] >> 8) & 0xff; ired = colors[i] & 0xff; dist = abs(red - ired) + abs(green - igreen) + abs(blue - iblue); if(dist < mindist){ mindist = dist; mini = i; } } return mini; } //////////////////////////////////////////////////////////// // Window functions. //////////////////////////////////////////////////////////// GraphMode Window::mode = UNKNOWN; Window::Window(int x1, int y1, int x2, int y2) { left = x1; top = y1; right = x2; bottom = y2; } void set_graphics_mode() { if(Window::mode != GRAPHICS){ // enter graphics mode (Watcom style) _setvideomode(_XRES256COLOR); Window::mode = GRAPHICS; } } void set_text_mode() { if(Window::mode != TEXT){ // set graphics mode to text (Watcom style) _setvideomode(_DEFAULTMODE); Window::mode = TEXT; } } void Window::set_color(Color color) { cur_color = color; } void Window::clear() { static Color black(0, 0, 0); _setcolor(black); _rectangle(_GFILLINTERIOR, left, top, right, bottom); } void Window::fill_ellipse(int x1, int y1, int x2, int y2) { _setcolor(cur_color); _setcliprgn(left, top, right, bottom); _ellipse(_GFILLINTERIOR, x1 + left, y1 + top, x2 + left, y2 + top); } void Window::fill_rectangle(int x1, int y1, int x2, int y2) { _setcolor(cur_color); _setcliprgn(left, top, right, bottom); _rectangle(_GFILLINTERIOR, x1 + left, y1 + top, x2 + left, y2 + top); } void Window::line(int x1, int y1, int x2, int y2) { _setcolor(cur_color); _setcliprgn(left, top, right, bottom); _moveto(x1 + left, y1 + top); _lineto(x2 + left, y2 + top); } void Window::set_pixel(int x, int y) { _setcolor(cur_color); _setcliprgn(left, top, right, bottom); _setpixel(left + x, top + y); } Color Window::get_pixel(int x, int y) { _setcliprgn(left, top, right, bottom); return Color(_getpixel(left + x, top + y)); } Image Window::get_image(int x1, int y1, int x2, int y2) { Image image = (Image) malloc(_imagesize(x1, y1, x2, y2)); _getimage(x1 + left, y1 + top, x2 + left, y2 + top, (char *) image); return image; } void Window::put_image(Image image, int x, int y) { _setcliprgn(left, top, right, bottom); _putimage(x + left, y + top, (char *)image, _GPSET); }