⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.cpp

📁 由一个古老的BASIC解释器改进而成, 保留了ANSI C固有的艺术美感.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	        { &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 + -