📄 graphics.cpp
字号:
{ &xcGreen, 0, 42 * 4, 0 },
{ &xcCyan, 0, 42 * 4, 42 * 4 },
{ &xcRed, 42 * 4, 0, 0 },
{ &xcMagenta, 42 * 4, 0, 42 * 4 },
{ &xcBrown, 42 * 4, 21 * 4, 0 },
{ &xcLightGrey, 42 * 4, 42 * 4, 42 * 4 },
{ &xcDarkGrey, 21 * 4, 21 * 4, 21 * 4 },
{ &xcLightBlue, 21 * 4, 21 * 4, 255 },
{ &xcLightGreen, 21 * 4, 255, 21 * 4 },
{ &xcLightCyan, 21 * 4, 255, 255 },
{ &xcLightRed, 255, 21 * 4, 21 * 4 },
{ &xcLightMagenta, 255, 21 * 4, 255 },
{ &xcYellow, 255, 255, 21 * 4 },
{ &xcWhite, 255, 255, 255 }
#else
{ &xcBlack, 0, 0, 0 },
{ &xcBlue, 0, 0, 0xA8 },
{ &xcGreen, 0, 0xA8, 0 },
{ &xcCyan, 0, 0xA8, 0xA8 },
{ &xcRed, 0xA8, 0, 0 },
{ &xcMagenta, 0xA8, 0, 0xA8 },
{ &xcBrown, 0xA8, 0x54, 0 },
{ &xcLightGrey, 0xA8, 0xA8, 0xA8 },
{ &xcDarkGrey, 0x54, 0x54, 0x54 },
{ &xcLightBlue, 0x54, 0x54, 0xFF },
{ &xcLightGreen, 0x54, 0xFF, 0x54 },
{ &xcLightCyan, 0x54, 0xFF, 0xFF },
{ &xcLightRed, 0xFF, 0x54, 0x54 },
{ &xcLightMagenta, 0xFF, 0x54, 0xFF },
{ &xcYellow, 0xFF, 0xFF, 0x54 },
{ &xcWhite, 0xFF, 0xFF, 0xFF }
#endif
};
std::for_each (table_colors,
table_colors + util::dim_array (table_colors),
assign_elem () );
}
#endif
#ifdef BLASSIC_USE_X
struct assign_color {
pcolor pxc;
const char * name;
};
class assign_elem {
public:
assign_elem (Colormap & cm) : cm (cm) { }
void operator () (const assign_color & elem)
{
XColor xc;
XAllocNamedColor (display, cm,
elem.name, elem.pxc, & xc);
}
private:
Colormap & cm;
};
void init_xcolors ()
{
static const assign_color table_colors []= {
#if 0
//{ &xcBlack, "black" },
{ &xcBlack, "#000000" },
{ &xcBlue, "darkblue" },
{ &xcGreen, "darkgreen" },
{ &xcCyan, "darkcyan" },
{ &xcRed, "darkred" },
{ &xcMagenta, "darkmagenta" },
//{ &xcBrown, "#7F7F00" },
{ &xcBrown, "brown" },
//{ &xcLightGrey, "#3F3F3F" },
//{ &xcLightGrey, "rgb:C0/C0/C0" },
{ &xcLightGrey, "grey" },
{ &xcDarkGrey, "darkgrey" },
//{ &xcLightBlue, "#0000FF" },
{ &xcLightBlue, "rgb:80/FF/FF" },
{ &xcLightGreen, "#00FF00" },
{ &xcLightCyan, "#00FFFF" },
{ &xcLightRed, "#FF0000" },
{ &xcLightMagenta, "#FF00FF" },
{ &xcYellow, "yellow" },
//{ &xcWhite, "white" }
{ &xcWhite, "#FFFFFF" }
#else
{ &xcBlack, "rgb:00/00/00" },
{ &xcBlue, "rgb:00/00/A8" },
{ &xcGreen, "rgb:00/A8/00" },
{ &xcCyan, "rgb:00/A8/A8" },
{ &xcRed, "rgb:A8/00/00" },
{ &xcMagenta, "rgb:A8/00/A8" },
{ &xcBrown, "rgb:A8/54/00" },
{ &xcLightGrey, "rgb:A8/A8/A8" },
{ &xcDarkGrey, "rgb:54/54/54" },
{ &xcLightBlue, "rgb:54/54/FF" },
{ &xcLightGreen, "rgb:54/FF/54" },
{ &xcLightCyan, "rgb:54/FF/FF" },
{ &xcLightRed, "rgb:FF/54/54" },
{ &xcLightMagenta, "rgb:FF/54/FF" },
{ &xcYellow, "rgb:FF/FF/54" },
{ &xcWhite, "rgb:FF/FF/FF" }
#endif
};
Colormap cm= DefaultColormap (display, screen);
std::for_each (table_colors,
table_colors + util::dim_array (table_colors),
assign_elem (cm) );
}
#endif
} // namespace
void graphics::initialize (const char * progname)
{
#ifdef BLASSIC_USE_SVGALIB
if (geteuid () == 0) {
std::string prog (progname);
std::string::size_type l= prog.size ();
if (l > 3 && prog.substr (l - 3) == "vga") {
vga_init ();
inited= true;
svgalib= true;
return;
}
else
if (getuid () != 0)
seteuid (getuid () );
}
#endif
#ifdef BLASSIC_USE_X
if (getenv ("DISPLAY") != NULL)
{
display= XOpenDisplay (0);
if (display)
{
inited= true;
screen= DefaultScreen (display);
init_xcolors ();
}
else
cerr << "Error al abrir display." << endl;
}
else
cerr << "Sin soporte de graficos." << endl;
#endif
#ifdef BLASSIC_USE_WINDOWS
WNDCLASS wndclass;
wndclass.style= CS_NOCLOSE | CS_OWNDC;
wndclass.lpfnWndProc= windowproc;
wndclass.cbClsExtra= 0;
wndclass.cbWndExtra= 0;
wndclass.hInstance= GetModuleHandle (0);
wndclass.hIcon= 0;
wndclass.hCursor= LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground= HBRUSH (GetStockObject (WHITE_BRUSH) );
wndclass.lpszMenuName= 0;
wndclass.lpszClassName= progname;
atomClass= RegisterClass (& wndclass);
if (atomClass == 0)
cerr << "Error al registrar clase" << endl;
else
{
inited= true;
init_wincolors ();
}
hEvent= CreateEvent (NULL, FALSE, FALSE, NULL);
// Event automatic, initial nonsignaled
//create_thread ();
#endif
}
void graphics::uninitialize ()
{
if (! inited) return;
if (actualmode != 0)
setmode (0);
#ifdef BLASSIC_USE_SVGA
#if 0
if (svgalib)
//vga_setmode (TEXT);
setmode (0);
#endif
#endif
#ifdef BLASSIC_USE_X
if (display)
{
//if (window_created)
// destroy_window ();
XCloseDisplay (display);
}
#endif
#ifdef BLASSIC_USE_WINDOWS
//destroy_thread ();
//if (window_created)
// destroy_window ();
if (atomClass)
UnregisterClass (LPCTSTR (atomClass),
GetModuleHandle (0) );
#endif
}
void graphics::idle ()
{
if (! window_created)
return;
#ifdef BLASSIC_USE_X
bool do_copy= false;
while (XCheckWindowEvent (display, window, eventusedmask, & x_event) )
switch (x_event.type)
{
case Expose:
do_copy= true;
break;
case KeyPress:
{
XKeyEvent & xk= x_event.xkey;
char buffer [10];
KeySym ks;
//XComposeStatus xcs;
int r= XLookupString (& xk, buffer, sizeof (buffer - 1),
& ks, /*& xcs*/ NULL);
if (r > 0)
{
buffer [r]= '\0';
queuekey.push (std::string (buffer) );
}
else
queuekey.push (string_from_key (ks) );
#if 0
buffer [r]= '\0';
cout << "State: " << xk.state <<
" Keycode: " << xk.keycode;
cout << " String: [";
for (int i= 0; i < r; ++i)
{
char c= buffer [i];
if (c < 32) cout << '^' << char (c + 'A' - 1);
else cout << c;
}
cout << "] Keysym: " << ks;
cout << endl;
#endif
}
break;
case ButtonPress:
{
XButtonEvent & xbpe= x_event.xbutton;
//cerr << "ButtonPress event, button=" <<
// xbpe.button <<
// endl;
switch (xbpe.button)
{
case 1:
queuekey.push (strCLICK);
break;
case 3:
queuekey.push (strSCLICK);
break;
default:
;
}
}
break;
case ButtonRelease:
{
XButtonEvent & xbpe= x_event.xbutton;
//cerr << "ButtonRelease event, button=" <<
// xbpe.button <<
// endl;
switch (xbpe.button)
{
case 1:
queuekey.push (strRELEASE);
break;
case 3:
queuekey.push (strSRELEASE);
break;
default:
;
}
}
break;
case MotionNotify:
{
XMotionEvent & xme= x_event.xmotion;
//cerr << "MotionNotify event " <<
// xme.x << ", " << xme.y <<
// endl;
xmousepos= xme.x;
ymousepos= xme.y;
}
break;
case EnterNotify:
{
XCrossingEvent & xce= x_event.xcrossing;
//cerr << "EnterNotify event" << endl;
xmousepos= xce.x;
ymousepos= xce.y;
}
break;
default:
//cerr << "Another event." << endl;
;
}
if (do_copy && pixmap_created)
{
#if 0
XCopyArea (display, pixmap, window, gc,
0, 0, screenwidth, screenheight, 0, 0);
XFlush (display);
#else
//XSetFunction (display, gc, drawmode_copy);
reinit_window ();
//XSetFunction (display, gc, drawmode);
#endif
//cerr << "Copied." << endl;
}
#endif
#ifdef BLASSIC_USE_WINDOWS
//Sleep (0);
#endif
}
#include "charset.h"
namespace {
void activecolor (pcolor pxc)
{
#ifdef BLASSIC_USE_X
XSetForeground (display, gcp, pxc->pixel);
XSetForeground (display, gc, pxc->pixel);
#endif
#ifdef BLASSIC_USE_WINDOWS
//HDC hdc= GetDC (window);
SelectObject (hdc, * pxc);
SelectObject (hdcPixmap, *pxc);
//ReleaseDC (window, hdc);
#endif
}
void textscroll ()
{
#ifdef BLASSIC_USE_SVGALIB
if (svgalib)
{
// PENDIENTE
return;
}
#endif
#ifdef BLASSIC_USE_X
int h= screenheight - 8;
//unsigned long white= WhitePixel (display, screen),
// black= BlackPixel (display, screen);
//XSetForeground (display, gcp, white);
XSetFunction (display, gcp, drawmode_copy);
XCopyArea (display, pixmap, pixmap, gcp,
0, 8, screenwidth, h, 0, 0);
activecolor (pbackground);
XFillRectangle (display, pixmap, gcp,
0, h, screenwidth, 8);
//XSetForeground (display, gcp, black);
activecolor (pforeground);
XSetFunction (display, gcp, drawmode);
#if 0
XSetForeground (display, gc, white);
XCopyArea (display, window, window, gc,
0, 8, screenwidth, h, 0, 0);
XFillRectangle (display, window, gc,
0, h, screenwidth, 8);
XSetForeground (display, gc, black);
#else
if (! fSynchro)
reinit_window ();
#endif
#endif
#ifdef BLASSIC_USE_WINDOWS
RECT r = { 0, screenheight - 8, screenwidth, screenheight };
int h= screenheight - 8;
BitBlt (hdcPixmap, 0, 0, screenwidth, h,
hdcPixmap, 0, 8, SRCCOPY);
//HBRUSH hbrush= (HBRUSH) GetStockObject (WHITE_BRUSH);
LOGPEN logpen;
GetObject (* pbackground, sizeof (LOGPEN), & logpen);
HBRUSH hbrush= CreateSolidBrush (logpen.lopnColor);
FillRect (hdcPixmap, & r, hbrush);
DeleteObject (hbrush);
#if 1
if (! fSynchro)
reinit_window ();
#else
//HDC hdc= GetDC (window);
BitBlt (hdc, 0, 0, screenwidth, h,
hdc, 0, 8, SRCCOPY);
FillRect (hdc, & r, hbrush);
//ReleaseDC (window, hdc);
#endif
#endif
}
#ifdef BLASSIC_USE_WINDOWS
#if 0
inline void do_plot_win (HDC hdc, int x, int y)
{
if (! fSynchro)
{
MoveToEx (hdc, x, y, 0);
LineTo (hdc, x + 1, y);
}
MoveToEx (hdcPixmap, x, y, 0);
LineTo (hdcPixmap, x + 1, y);
}
#endif
#endif
inline void do_plot (int x, int y)
{
#ifdef BLASSIC_USE_SVGALIB
if (svgalib)
{
vga_drawpixel (x, y);
return;
}
#endif
#ifdef BLASSIC_USE_X
if (! fSynchro)
XDrawPoint (display, window, gc, x, y);
XDrawPoint (display, pixmap, gcp, x, y);
#endif
#ifdef BLASSIC_USE_WINDOWS
//do_plot_win (hdc, x, y);
if (! fSynchro)
{
MoveToEx (hdc, x, y, 0);
LineTo (hdc, x + 1, y);
}
MoveToEx (hdcPixmap, x, y, 0);
LineTo (hdcPixmap, x + 1, y);
#endif
}
void print (int col, int row, unsigned char c)
{
static unsigned char mask [8]= { 128, 64, 32, 16, 8, 4, 2, 1 };
int x= col * 8;
int y= row * 8;
charset::chardata & data= charset::data [c];
#ifdef BLASSIC_USE_WINDOWS
//HDC hdc= GetDC (window);
//SetROP2 (hdc, drawmode);
//SetROP2 (hdcPixmap, drawmode);
#endif
for (int i= 0, yi= y; i < 8; ++i, ++yi)
{
unsigned char c= data [i];
for (int j= 0, xj= x; j < 8; ++j, ++xj)
{
bool f= (c & mask [j] ) != 0;
if (f || opaquemode)
{
pcolor pc= f ? pforeground : pbackground;
activecolor (pc);
//#ifdef BLASSIC_USE_WINDOWS
//do_plot_win (hdc, xj, yi);
//#else
do_plot (xj, yi);
//#endif
}
}
}
activecolor (pforeground);
#ifdef BLASSIC_USE_WINDOWS
//ReleaseDC (window, hdc);
#endif
}
int tcol, trow;
int maxtcol, maxtrow;
void setmaxtext ()
{
maxtcol= screenwidth / 8;
maxtrow= screenheight / 8;
}
enum TransformType { TransformIdentity, TransformInvertY };
TransformType activetransform= TransformIdentity;
void transform_y (int & y)
{
switch (activetransform)
{
case TransformIdentity:
break; // Nothing to do
case TransformInvertY:
y= screenheight - y;
break;
}
}
void recreate_windows ();
void setmode (int width, int height, int mode)
{
sysvar::set16 (sysvar::GraphicsWidth, short (width) );
sysvar::set16 (sysvar::GraphicsHeight, short (height) );
screenwidth= width;
screenheight= height;
activetransform= TransformIdentity;
#ifdef BLASSIC_USE_SVGALIB
if (svgalib) {
if (mode == user_mode)
throw ErrFunctionCall;
if (actualmode != text_mode)
{
free (font);
}
vga_setmode (mode);
if (mode != text_mode) {
setmaxtext ();
gl_setcontextvga (mode);
//font= new char [256 * 8 * 8 * BYTESPERPIXEL];
font= (char *) malloc (2 * 256 * 8 * 8 * BYTESPERPIXEL);
gl_expandfont (8, 8, 15, gl_font8x8, font);
gl_setfont (8, 8, font);
//cout << "Listo" << endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -