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

📄 graphics.cpp

📁 由一个古老的BASIC解释器改进而成, 保留了ANSI C固有的艺术美感.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				charout (' ');
			} while (x > 0);
		}
		if (col >= width)
			throw ErrFunctionCall;
		do {
			charout (' ');
		} while (x < col);
	}
	void setcolor (int color)
	{
		foreground= mapcolor (color);
	}
	void setbackground (int color)
	{
		background= mapcolor (color);
	}
	void movecharforward (size_t n)
	{
		for (size_t i= 0; i < n; ++i)
		{
			if (++x >= width)
			{
				x= 0;
				if (++y >= height)
				{
					textscroll ();
					y= height - 1;
				}
			}
		}
	}
	void movecharback (size_t n)
	{
		for (size_t i= 0; i < n; ++i)
		{
			if (x > 0)
				--x;
			else
			{
				if (y > 0)
				{
					x= width - 1;
					--y;
				}
			}
		}
	}
	void movecharup (size_t n)
	{
		y-= n;
	}
	void movechardown (size_t n)
	{
		y+= n;
	}
	void cls ()
	{
		x= y= 0;

		int x1= orgx * 8, x2= width * 8;
		int y1= orgy * 8, y2= height * 8;

		#ifdef BLASSIC_USE_WINDOWS
		RECT r= { x1, y1, x1 + x2, y1 + y2 };
	        LOGPEN logpen;
        	GetObject (* background, sizeof (LOGPEN), & logpen);
		HBRUSH hbrush= CreateSolidBrush (logpen.lopnColor);
		if (! fSynchro)
			FillRect (hdc, & r, hbrush);
		FillRect (hdcPixmap, & r, hbrush);
		DeleteObject (hbrush);
		#endif

		#ifdef BLASSIC_USE_X
		activecolor (background);
		XSetFunction (display, gcp, drawmode_copy);
		XFillRectangle (display, pixmap, gcp,
			x1, y1, x2, y2);
		XSetFunction (display, gcp, drawmode);
		if (! fSynchro)
		{
			XSetFunction (display, gc, drawmode_copy);
			XFillRectangle (display, window, gc,
				x1, y1, x2, y2);
			XSetFunction (display, gc, drawmode);
		}
		activecolor (pforeground);
		#endif
	}
	void textscroll ()
	{
		int x1= orgx * 8, y1= orgy * 8;
		int w= width * 8; int h= height * 8;
		#ifdef BLASSIC_USE_X
		//int h= screenheight - 8;
		XSetFunction (display, gcp, drawmode_copy);
		XCopyArea (display, pixmap, pixmap, gcp,
			x1, y1 + 8, w, h - 8, x1, y1);
		activecolor (background);
		XFillRectangle (display, pixmap, gcp,
			x1, y1 + h - 8, w, 8);
		XSetFunction (display, gcp, drawmode);
		//XSetForeground (display, gcp, black);

		if (! fSynchro)
		{
			//XSetForeground (display, gc, white);
			XSetFunction (display, gc, drawmode_copy);
			XCopyArea (display, window, window, gc,
				x1, y1 + 8, w, h, x1, y1);
			XFillRectangle (display, window, gc,
				x1, y1 + h - 8, w, 8);
			//XSetForeground (display, gc, black);
			XSetFunction (display, gc, drawmode);
		}
		activecolor (foreground);
		#endif

		#ifdef BLASSIC_USE_WINDOWS
		RECT r = { x1, y1 + h - 8, x1 + w, y1 + h};

		BitBlt (hdcPixmap, x1, y1, w, h - 8,
			hdcPixmap, x1, y1 + 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

	}
	void charout (char c)
	{
		pcolor foresave= pforeground;
		pforeground= foreground;
		pcolor backsave= pbackground;
		pbackground= background;
		switch (c)
		{
		case '\n':
                	x= 0;
        	        if (++y >= height)
			{
				textscroll ();
				y= height - 1;
			}
			break;
		case '\r':
			x= 0;
			break;
		case '\t':
			if (x >= (width / zone) * zone)
			{
				//cerr << "Fin de linea" << endl;
				for ( ; x < width; ++x)
					print (orgx + x, orgy + y, ' ');
				x= 0;
				if (++y >= height)
				{
					textscroll ();
					y= height - 1;
				}
			}
			else
			{
				do {
					print (orgx + x, orgy + y, ' ');
					++x;
				} while (x % zone);
			}
			break;
		default:
			print (orgx + x, orgy + y, c);
			if (++x >= width)
			{
				x= 0;
				if (++y >= height)
				{
					textscroll ();
					y= height - 1;
				}
			}
		}
		pforeground= foresave;
		pbackground= backsave;
	}
	void invertcursor ()
	{
		int x1= (orgx + x) * 8;
		int y1= (orgy + y) * 8;

		#ifdef BLASSIC_USE_X
		XSetFunction (display, gc, drawmode_invert);
		XSetFunction (display, gcp, drawmode_invert);
		XFillRectangle (display, window, gc, x1, y1 + 6, 8, 2);
		XFillRectangle (display, pixmap, gcp, x1, y1 + 6, 8, 2);
		XSetFunction (display, gc, drawmode);
		XSetFunction (display, gcp, drawmode);
		#endif

		#ifdef BLASSIC_USE_WINDOWS
		HBRUSH hbrush= (HBRUSH) GetStockObject (BLACK_BRUSH);
		HDC ahdc [2]= { hdc, hdcPixmap };
		for (size_t i= 0; i < 2; ++i)
		{
			HDC hdc= ahdc [i];
			SetROP2 (hdc, drawmode_invert);
			HBRUSH hold= (HBRUSH) SelectObject (hdc, hbrush);
			Rectangle (hdc, x1, y1 + 6, x1 + 8, y1 + 8);
			SelectObject (hdc, hold);
			SetROP2 (hdc, drawmode);
		}
		#endif
	}
private:
	int orgx, orgy, width, height;
	pcolor foreground;
	pcolor background;
	int x, y;
};

BlWindow windowzero;

typedef std::map <BlChannel, BlWindow *> MapWindow;
MapWindow mapwindow;

void killwindowifnotzero (MapWindow::value_type & mw)
{
	if (mw.first != BlChannel (0) )
		delete mw.second;
}

void recreate_windows ()
{
	windowzero.setdefault ();
	windowzero.defaultcolors ();
	windowzero.cls ();
	for_each (mapwindow.begin (), mapwindow.end (), killwindowifnotzero);
	mapwindow.clear ();
	mapwindow [0]= & windowzero;
}

inline void do_charout (char c)
{
	switch (c)
	{
	case '\n':
                tcol= 0;
                if (++trow >= maxtrow)
		{
			textscroll ();
			trow= maxtrow - 1;
		}
		return;
	case '\r':
		tcol= 0;
		return;
	case '\t':
		if (tcol >= (maxtcol / zone) * zone)
		{
			//cerr << "Fin de linea" << endl;
			for ( ; tcol < maxtcol; ++tcol)
				print (tcol, trow, ' ');
			tcol= 0;
			if (++trow >= maxtrow)
			{
				textscroll ();
				trow= maxtrow - 1;
			}
		}
		else
		{
			do {
				print (tcol, trow, ' ');
				++tcol;
			} while (tcol % zone);
		}
		return;
	}
        print (tcol, trow, c);
        if (++tcol >= maxtcol)
        {
                tcol= 0;
                if (++trow >= maxtrow)
		{
			textscroll ();
			trow= maxtrow - 1;
		}
        }
}

} // namespace

void graphics::setcolor (BlChannel ch, int color)
{
	mapwindow [ch]->setcolor (color);
}

void graphics::setbackground (BlChannel ch, int color)
{
	mapwindow [ch]->setbackground (color);
}

void graphics::cls (BlChannel n)
{
	mapwindow [n]->cls ();
}

void graphics::definewindow (BlChannel n, int x1, int x2, int y1, int y2)
{
	requiregraphics ();
	--x1; --x2; --y1; --y2;
	MapWindow::iterator it= mapwindow.find (n);
	if (it != mapwindow.end () )
		it->second->set (x1, x2, y1, y2);
	else
		mapwindow [n]= new BlWindow (x1, x2, y1, y2);
}

void graphics::undefinewindow (BlChannel n)
{
	if (n == 0)
		return;
	MapWindow::iterator it= mapwindow.find (n);
	if (it != mapwindow.end () )
	{
		delete it->second;
		mapwindow.erase (it);
	}
}

size_t graphics::getlinewidth ()
{
	#if 0
	return maxtcol;
	#else
	return windowzero.getwidth ();
	#endif
}

void graphics::charout (char c)
{
	//do_charout (c);
	windowzero.charout (c);
	//idle ();
}

void graphics::stringout (const std::string & str)
{
	//bool fSynchroNormal= fSynchro;
	//fSynchro= true;

	//std::for_each (str.begin (), str.end (), do_charout);
	for (std::string::size_type i= 0, l= str.size (); i < l; ++i)
		windowzero.charout (str [i]);

	//fSynchro= fSynchroNormal;
	//if (! fSynchro)
	//	reinit_window ();

	//idle ();
}

void graphics::charout (BlChannel ch, char c)
{
	mapwindow [ch]->charout (c);
}

void graphics::stringout (BlChannel ch, const std::string & str)
{
	BlWindow * pwin= mapwindow [ch];
	for (std::string::size_type i= 0, l= str.size (); i < l; ++i)
		pwin->charout (str [i]);
}

#if 0
void graphics::locate (int row, int col)
{
        trow= row - 1;
        tcol= col - 1;
}
#endif

void graphics::gotoxy (int x, int y)
{
	trow= y;
	tcol= x;
}

void graphics::gotoxy (BlChannel ch, int x, int y)
{
	mapwindow [ch]->gotoxy (x, y);
}

void graphics::tab (size_t n)
{
	int col (n - 1);
	if (tcol >= col)
	{
		do {
			do_charout (' ');
		} while (tcol > 0);
	}
        if (col >= maxtcol)
                throw ErrFunctionCall;
	do {
		do_charout (' ');
	} while (tcol < col);
}

void graphics::tab (BlChannel ch, size_t n)
{
	mapwindow [ch]->tab (n);
}

void graphics::movecharforward (size_t n)
{
	#if 0
	for (size_t i= 0; i < n; ++i)
	{
		if (++tcol >= maxtcol)
		{
			tcol= 0;
			if (++trow >= maxtrow)
			{
				textscroll ();
				trow= maxtrow - 1;
			}
		}
	}
	#else
	windowzero.movecharforward (n);
	#endif
}

void graphics::movecharback (size_t n)
{
	#if 0
	for (size_t i=0; i < n; ++i)
	{
		if (tcol > 0)
			--tcol;
		else
		{
			if (trow > 0)
			{
				tcol= maxtcol - 1;
				--trow;
			}
		}
	}
	#else
	windowzero.movecharback (n);
	#endif
}

void graphics::movecharup (size_t n)
{
	#if 0
	trow-= n;
	#else
	windowzero.movecharup (n);
	#endif
}

void graphics::movechardown (size_t n)
{
	#if 0
	trow+= n;
	#else
	windowzero.movechardown (n);
	#endif
}

void graphics::definesymbol (int symbol, const unsigned char (& byte) [8] )
{
	if (symbol < 0 || symbol > 255)
		throw ErrFunctionCall;
	memcpy (charset::data + symbol, byte, sizeof (byte) );
}

void graphics::synchronize (bool mode)
{
	fSynchro= mode;
}

void graphics::synchronize ()
{
	reinit_window ();
}

namespace {

bool fSynchroSaved= false;

}

void graphics::synchronize_suspend ()
{
        fSynchroSaved= fSynchro;
        if (fSynchro)
                reinit_window ();
        fSynchro= false;
}

void graphics::synchronize_restart ()
{
        fSynchro= fSynchroSaved;
}

int graphics::xmouse () { return xmousepos; }
int graphics::ymouse () { return ymousepos; }

int graphics::xpos () { return lastx; }
int graphics::ypos () { return lasty; }

namespace {

void invertcursor ()
{
	int x1= tcol * 8;
	int y1= trow * 8;

	#ifdef BLASSIC_USE_X
	XSetFunction (display, gc, drawmode_invert);
	XSetFunction (display, gcp, drawmode_invert);
	XFillRectangle (display, window, gc, x1, y1 + 6, 8, 2);
	XFillRectangle (display, pixmap, gcp, x1, y1 + 6, 8, 2);
	XSetFunction (display, gc, drawmode);
	XSetFunction (display, gcp, drawmode);
	#endif

	#ifdef BLASSIC_USE_WINDOWS
	HBRUSH hbrush= (HBRUSH) GetStockObject (BLACK_BRUSH);
        HDC ahdc [2]= { hdc, hdcPixmap };
        for (size_t i= 0; i < 2; ++i)
        {
                HDC hdc= ahdc [i];
	        SetROP2 (hdc, drawmode_invert);
                HBRUSH hold= (HBRUSH) SelectObject (hdc, hbrush);
                Rectangle (hdc, x1, y1 + 6, x1 + 8, y1 + 8);
                SelectObject (hdc, hold);
	        SetROP2 (hdc, drawmode);
        }
	#endif
}

}

void graphics::showcursor ()
{
	//invertcursor ();
	windowzero.invertcursor ();
}

void graphics::hidecursor ()
{
	//invertcursor ();
	windowzero.invertcursor ();
}

// Fin de graphics.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -