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

📄 draw.c

📁 Microwindows genesis was with the NanoGUI project, and is now the primary distribution for both th
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * NanoBreaker, a Nano-X Breakout clone by Alex Holden. * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. *  * The Original Code is NanoBreaker. *  * The Initial Developer of the Original Code is Alex Holden. * Portions created by Alex Holden are Copyright (C) 2002 * Alex Holden <alex@alexholden.net>. All Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the terms * of the GNU General Public license (the  "[GNU] License"), in which case the * provisions of [GNU] License are applicable instead of those * above.  If you wish to allow use of your version of this file only * under the terms of the [GNU] License and not to allow others to use * your version of this file under the MPL, indicate your decision by * deleting  the provisions above and replace  them with the notice and * other provisions required by the [GNU] License.  If you do not delete * the provisions above, a recipient may use your version of this file * under either the MPL or the [GNU] License. *//* draw.c contains functions for drawing the various game objects. */#include <stdio.h>#include <stdlib.h>#include <nano-X.h>#include <nxcolors.h>#include "nbreaker.h"/* Tiles the background image onto the canvas over the rectangle specified by * x, y, w, and h. This could probably be done more efficiently, but it works * and doesn't seem to use a lot of CPU time. */static void draw_tiled_background(nbstate *state, int x, int y, int w, int h){	int tilex = 0, tiley = 0, fromx, fromy, cx, cy;	int destwidth, destheight, srcwidth, srcheight, cwidth, cheight;	int dwidth = state->canvaswidth;	int dheight = state->canvasheight;	int swidth = state->background->w;	int sheight = state->background->h;	/* Clip the width of the background image to the size of the canvas	 * if necessary. */	if(swidth > dwidth) srcwidth = dwidth;	else srcwidth = swidth;	if(sheight > dheight) srcheight = dheight;	else srcheight = sheight;	/* For each row of tiles: */	for(;tiley < dheight; tiley += srcheight, tilex = 0) {		/* If we've gone past the rectangle, return. */		if(tiley > (y + h)) return;		/* If we haven't reached the rectangle, go to the next row. */		if(y > (tiley + srcheight)) continue;		/* Clip the output to the bottom of the output window. */		if((tiley + srcheight) > dheight) destheight = dheight - tiley;		else destheight = srcheight;		/* For each tile in the row: */		for(;tilex < dwidth; tilex += srcwidth) {			/* If we've gone past the rectangle, skip to the next			 * row. */			if(tilex > (x + w)) break;			/* If we haven't reached the rectangle, skip to the			 * next tile in the row. */			if(x > (tilex + srcwidth)) continue;			/* Clip the output size to the right side of the			 * output window. */			if((tilex + srcwidth) > dwidth)				destwidth = dwidth - tilex;			else destwidth = srcwidth;			/* If the tile X dimension is completely within the			 * output rectangle, set the clipping to the full			 * size of the background image. */			if((tilex >= x) && ((tilex + destwidth) <= (x + w))) {				fromx = 0;				cx = tilex;				cwidth = destwidth;			} else { /* Not completely in the output rectangle. */				/* If necessary, clip off the left part of				 * the rectangle. */				if(x > tilex) {					fromx = x - tilex;					cwidth = destwidth - fromx;				} else {					/* Otherwise clip off the right part					 * of the rectangle. */					fromx = 0;					cwidth = x + w - tilex;				}				/* Clip it to the size of the output area. */				if(cwidth > w) cwidth = w;				/* Clip it to the size of the output window? */				if(cwidth > destwidth) cwidth = destwidth;				/* Calculate the start of the area to copy				 * from. */				cx = tilex + fromx;			}			/* As above but for the Y dimension. */			if((tiley >= y) && ((tiley + destheight) <= (y + h))) {				fromy = 0;				cy = tiley;				cheight = destheight;			} else {				if(y > tiley) {					fromy = y - tiley;					cheight = destheight - fromy;				} else {					fromy = 0;					cheight = y + h - tiley;				}				if(cheight > h) cheight = h;				if(cheight > destheight) cheight = destheight;				cy = tiley + fromy;			}			/* If the output size is non-zero after clipping, copy			 * it to the canvas. */			if((cwidth > 0) && (cheight > 0)) {				GrCopyArea(state->canvas, state->gc, cx, cy,						cwidth, cheight,						state->background->p,						fromx, fromy, 0);			}		}	}}/* Fill in the intersection of the two specified rectangles: */static void fill_in_rectangle(nbstate *state, int x, int y, int w, int h,		int xx, int yy, int ww, int hh){	int xxx, yyy;	/* Calculate the bottom right extents of the second rectangle: */	xxx = xx + ww;	yyy = yy + hh;	/* Intersect with the requested area: */	if(x > xx) xx = x;	if(y > yy) yy = y;	if(x + w < xxx) xxx = x + w;	if(y + h < yyy) yyy = y + h;	/* Calculate the size of the resulting area: */	ww = xxx - xx;	hh = yyy - yy;	/* If the result is greater than zero in size, draw it: */	if(ww > 0 && hh > 0)		GrFillRect(state->canvas, state->gc, xx, yy, ww, hh);}/* Draw the background image in the middle of the canvas over the rectangle * specified by x, y, w, and h. */static void draw_centred_background(nbstate *state, int x, int y, int w, int h){	int bgx, bgy, xx, yy, ww, hh;	/* Work out where to place the background image: */	if(state->background->w >= state->canvaswidth) bgx = 0;	else bgx = (state->canvaswidth / 2) - (state->background->w / 2);	if(state->background->h >= state->canvasheight) bgy = 0;	else bgy = (state->canvasheight / 2) - (state->background->h / 2);	/* If the area to copy intersects the area of the image: */	if(x < bgx + state->background->w && y < bgx + state->background->h &&						x + w > bgx && y + h > bgy) {		/* Clip the start of the region: */		xx = (x > bgx) ? x : bgx;		yy = (y > bgy) ? y : bgy;		/* Clip the end of the region: */		ww = (x + w < bgx + state->background->w) ? x + w - xx :		       bgx + state->background->w - xx;			hh = (y + h < bgy + state->background->h) ? y + h - yy :		       bgy + state->background->h - yy;			/* Copy the background image. */		if(ww > 0 && hh > 0)			GrCopyArea(state->canvas, state->gc, xx, yy, ww, hh,				state->background->p, xx - bgx, yy - bgy, 0);	}		/* We fill in the rest of the canvas area black: */	GrSetGCForeground(state->gc, GR_COLOR_BLACK);	/* Fill in the top rectangle: */	fill_in_rectangle(state, x, y, w, h, 0, 0, state->canvaswidth, bgy);	/* Fill in the left rectangle: */	fill_in_rectangle(state, x, y, w, h, 0, bgy, bgx, state->background->h);	/* Fill in the right rectangle: */	fill_in_rectangle(state, x, y, w, h, bgx + state->background->w, bgy,				state->canvaswidth - bgx + state->background->w,							state->background->h);	/* Fill in the bottom rectangle: */	fill_in_rectangle(state, x, y, w, h, 0, bgy + state->background->h,				state->canvaswidth, state->canvasheight - bgy +							state->background->h);}/* Draw the background image onto the canvas over the rectangle specified by * x, y, w, and h. */void draw_background(nbstate *state, int x, int y, int w, int h){	if(state->backgroundtiled) draw_tiled_background(state, x, y, w, h);	else draw_centred_background(state, x, y, w, h);}/* Draw the splash sprite (if there is one) in the centre of the canvas. */void draw_splash(nbstate *state){	if(!state->splash) return;	GrCopyAreaAlpha(state->canvas, state->gc, state->splash->a,			(state->canvaswidth / 2) - (state->splash->w / 2),			(state->canvasheight / 2) - (state->splash->h / 2),

⌨️ 快捷键说明

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