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

📄 nxsnake.c

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                                                                        * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.      *                                                                        * This file is part of the PIXIL Operating Environment                  *                                                                        * The use, copying and distribution of this file is governed by one     * of two licenses, the PIXIL Commercial License, or the GNU General     * Public License, version 2.                                            *                                                                        * Licensees holding a valid PIXIL Commercial License may use this file  * in accordance with the PIXIL Commercial License Agreement provided    * with the Software. Others are governed under the terms of the GNU    * General Public License version 2.                                     *                                                                        * This file may be distributed and/or modified under the terms of the   * GNU General Public License version 2 as published by the Free         * Software Foundation and appearing in the file LICENSE.GPL included    * in the packaging of this file.                                       *                                                                        * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING   * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A             * PARTICULAR PURPOSE.                                                   *                                                                        * RESTRICTED RIGHTS LEGEND                                              *                                                                      * Use, duplication, or disclosure by the government is subject to       * restriction as set forth in paragraph (b)(3)(b) of the Rights in      * Technical Data and Computer Software clause in DAR 7-104.9(a).        *                                                                       * See http://www.pixil.org/gpl/ for GPL licensing        * information.                                                          *                                                                       * See http://www.pixil.org/license.html or               * email cetsales@centurysoftware.com for information about the PIXIL    * Commercial License Agreement, or if any conditions of this licensing  * are not clear to you.                                                 */#include <pixil_config.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <time.h>#include <getopt.h>#ifdef CONFIG_PAR#include <par/par.h>#endif#define MWINCLUDECOLORS#include "nano-X.h"#include "nxsnake.h"#include "text.h"#include "levels.h"#define BGCOLOR WHITE#define FGCOLOR (GR_RGB(0x00, 0x66, 0xCC))#define TXTCOLOR BLACKstatic GR_WINDOW_ID tileset_pixmap = 0;static GR_REGION_ID level_clipmask = 0;static int draw_fullscreen = 1;/* This matrix indicates where the snake, border and nibbles are *//* This is how the engine determines where the snake, nibbles and *//* borders are */unsigned char playground[YUNITS][XUNITS];snake_t global_snake;GR_WINDOW_ID swindow, offscreen;static int game_state = 0;static int current_level = 0;#define SNAKE_START_SPEED 110static unsigned long game_speed;static unsigned long start_speed = SNAKE_START_SPEED;struct{    int active;    int x;    int y;}nibble;int skipped = 0;#define MOVE_ILLEGAL 0#define MOVE_LEGAL   1#define MOVE_NIBBLE  2inline voidSET_SNAKE_DIRECTION(unsigned short *value, unsigned char dir){    *value &= 0x0FFF;    *value |= ((dir & 0xF) << 12);}inline voidSET_SNAKE_OFFSET(unsigned short *value, unsigned short off){    *value &= 0xF000;    *value |= (off & 0xFFF);}voidload_tileset(char *file){    char path[256];    GR_GC_ID gc = GrNewGC();#ifdef CONFIG_PAR    db_handle *par_db = db_openDB(db_getDefaultDB(), PAR_DB_MODE_RDONLY);    if (par_db) {	par_getScreentopDir(par_db, "icondir", path, sizeof(path) - 1);	db_closeDB(par_db);	strcat(path, "/");	strcat(path, file);    } else#endif    {	getcwd(path, 128);	strcat(path, "/");	strcat(path, file);    }    tileset_pixmap = GrNewPixmap(XUNITSIZE * TILE_COUNT, YUNITSIZE, 0);    GrDrawImageFromFile(tileset_pixmap, gc, 0, 0,			XUNITSIZE * TILE_COUNT, YUNITSIZE, path, 0);    GrDestroyGC(gc);}voiddraw_tile(int tile, int x, int y){    GR_GC_ID gc = GrNewGC();    GrCopyArea(offscreen, gc, x, y, XUNITSIZE, YUNITSIZE,	       tileset_pixmap, tile * XUNITSIZE, 0, MWROP_SRCCOPY);    GrDestroyGC(gc);}voidinit_level(int l){    global_snake.speed = 1;    global_snake.headx = level[l].startx;    global_snake.heady = level[l].starty;    global_snake.tailpointer = 0;    global_snake.length = 5;    global_snake.growth = 0;    bzero(global_snake.body, 256 * sizeof(unsigned short));    SET_SNAKE_DIRECTION(&global_snake.body[0], level[l].dir);    SET_SNAKE_OFFSET(&global_snake.body[0], global_snake.length);}intadvance_snake(void){    unsigned short netoff = 0;    int pos = 0;    unsigned char dir;    unsigned short off;    short newx;    short newy;    int ret;    if (!global_snake.body[0])	return (MOVE_LEGAL);    dir = GET_SNAKE_DIRECTION(global_snake.body[0]);    newx = global_snake.headx;    newy = global_snake.heady;    switch (dir) {    case SNAKE_DIR_LEFT:	newx = global_snake.headx - 1;	if (newx < 0)	    newx = XUNITS - 1;	break;    case SNAKE_DIR_RIGHT:	newx = global_snake.headx + 1;	if (newx >= XUNITS)	    newx = 0;	break;    case SNAKE_DIR_UP:	newy = global_snake.heady - 1;	if (newy < 0)	    newy = YUNITS - 1;	break;    case SNAKE_DIR_DOWN:	newy = global_snake.heady + 1;	if (newy >= YUNITS)	    newy = 0;	break;    }    /* Now check the new position */    switch (playground[newy][newx]) {    case PLAYGROUND_EMPTY:    case PLAYGROUND_TAIL:	ret = MOVE_LEGAL;	break;    case PLAYGROUND_BORDER:    case PLAYGROUND_SNAKE:	return (MOVE_ILLEGAL);    case PLAYGROUND_NIBBLE:	/* Yummy... */	global_snake.growth += 5;	global_snake.score++;	game_speed--;	nibble.active = 0;	ret = MOVE_NIBBLE;	break;    }    /* Now advance the head.  That means advancing the absolute x and y */    /* and adding one to the current offset */    global_snake.headx = newx;    global_snake.heady = newy;    /* Finally, handle the tail */    /* If we are growing, then handle that here (the tail doesn't move) */    if (global_snake.growth) {	global_snake.growth--;	global_snake.length++;	off = GET_SNAKE_OFFSET(global_snake.body[0]);	SET_SNAKE_OFFSET(&global_snake.body[0], off + 1);	return (ret);    }    /* If there is only one segment, then handle that here */    if (!global_snake.tailpointer) {	SET_SNAKE_OFFSET(&global_snake.body[0], global_snake.length);	return (ret);    }    /* Otherwise, we need to move the whole snake */    off = GET_SNAKE_OFFSET(global_snake.body[0]);    SET_SNAKE_OFFSET(&global_snake.body[0], off + 1);    while (global_snake.body[pos]) {	off = GET_SNAKE_OFFSET(global_snake.body[pos]);	/* If the size ends here, then clear the rest of the */	/* snake */	if (netoff + off >= global_snake.length) {	    if (global_snake.tailpointer > pos + 1)		printf		    ("OOPS!  You have a gap between the length and the tail\n");	    global_snake.body[pos + 1] = 0;	    global_snake.tailpointer = pos;	    SET_SNAKE_OFFSET(&global_snake.body[pos],			     global_snake.length - netoff);	    break;	}	netoff += off;	pos++;    }    return (ret);}intredirect_snake(GR_EVENT_KEYSTROKE event){    unsigned char newdir = 0;    int i = 0;    unsigned char dir = GET_SNAKE_DIRECTION(global_snake.body[0]);    switch (event.ch) {    case MWKEY_UP:    case MWKEY_KP8:	newdir = SNAKE_DIR_UP;	break;    case MWKEY_DOWN:    case MWKEY_KP2:	newdir = SNAKE_DIR_DOWN;	break;    case MWKEY_LEFT:    case MWKEY_KP4:	newdir = SNAKE_DIR_LEFT;	break;    case MWKEY_RIGHT:    case MWKEY_KP6:	newdir = SNAKE_DIR_RIGHT;	break;    default:	return (0);    }    if (dir == newdir)	return (0);    if (dir == SNAKE_DIR_LEFT && newdir == SNAKE_DIR_RIGHT)	return (0);    if (dir == SNAKE_DIR_RIGHT && newdir == SNAKE_DIR_LEFT)	return (0);    if (dir == SNAKE_DIR_UP && newdir == SNAKE_DIR_DOWN)	return (0);    if (dir == SNAKE_DIR_DOWN && newdir == SNAKE_DIR_UP)	return (0);    for (i = global_snake.tailpointer + 1; i > 0; i--)	global_snake.body[i] = global_snake.body[i - 1];    global_snake.tailpointer++;    SET_SNAKE_DIRECTION(&global_snake.body[0], newdir);    SET_SNAKE_OFFSET(&global_snake.body[0], 0);    /* No bounds checking, that will be done on the next advance */    return (1);}voidshow_buffer(void){    GR_GC_ID gc = GrNewGC();#ifdef NOTUSED    if (draw_fullscreen == 0 && level_clipmask)	GrSetGCRegion(gc, level_clipmask);#endif    GrCopyArea(swindow, gc, 0, 0, WWIDTH, WHEIGHT,	       offscreen, 0, 0, MWROP_SRCCOPY);    GrDestroyGC(gc);}voiddraw_string(char *array, int mode){    char *txtptr = array;    int xpos, ypos;    int maxwidth = 0, maxheight = 0;    int i = 0;    int count = 0;    GR_GC_ID gc = GrNewGC();    GR_FONT_ID font = GrCreateFont((GR_CHAR *) GR_FONT_GUI_VAR, 0, 0);    GrSetGCFont(gc, font);    /* Count how many lines we have */    while (txtptr) {	int tw, th, tb;	if (strlen(txtptr) == 0)	    break;	GrGetGCTextSize(gc, txtptr, -1, 0, &tw, &th, &tb);	if (maxwidth < tw)	    maxwidth = tw;	if (maxheight < th)	    maxheight = th;	txtptr += 50;	count++;    }    txtptr = array;    maxwidth += 10;    maxheight += 10;    /* mode == 1, clear the screen,       mode == 2, draw a box     */    if (mode == 1) {	GrSetGCForeground(gc, BGCOLOR);	GrFillRect(offscreen, gc, 0, 0, WWIDTH, WHEIGHT);	GrSetGCForeground(gc, TXTCOLOR);	GrSetGCBackground(gc, BGCOLOR);    } else {	xpos = (PWIDTH / 2) - (maxwidth / 2);	ypos = (PHEIGHT / 2) - ((count * maxheight) / 2);	/* Draw a box */	GrSetGCForeground(gc, FGCOLOR);	GrFillRect(offscreen, gc, xpos, ypos, maxwidth, (count * maxheight));	GrSetGCForeground(gc, BGCOLOR);	GrRect(offscreen, gc,	       xpos + 3, ypos + 3, maxwidth - 6, (count * maxheight) - 6);	GrSetGCBackground(gc, FGCOLOR);    }    ypos = (WHEIGHT / 2) - ((count * maxheight) / 2) + 5;    while (1) {	int tw, th, tb;	if (strlen(txtptr) == 0)	    break;	GrGetGCTextSize(gc, txtptr, -1, 0, &tw, &th, &tb);	GrText(offscreen, gc, (WWIDTH / 2) - (tw / 2),	       ypos + (i * th), txtptr, -1, 0);	i++;	txtptr += 50;    }    GrDestroyGC(gc);    GrDestroyFont(font);}/* Make a region that should clip out border */voidmake_clipmask(int l){    unsigned char *ptr = level[l].bitmap;    GR_RECT rect;    int x, y;    if (level_clipmask)	GrDestroyRegion(level_clipmask);    level_clipmask = GrNewRegion();    for (y = 0; y < YUNITS; y++) {	int state = 0;	for (x = 0; x < XUNITS; x++) {	    if (*ptr != PLAYGROUND_BORDER && !state) {		rect.x = (x * XUNITSIZE);		rect.y = (y * YUNITSIZE);		rect.height = YUNITSIZE;		state = 1;	    }	    if (*ptr == PLAYGROUND_BORDER && state) {		rect.width = (x * XUNITSIZE) - rect.x;		GrUnionRectWithRegion(level_clipmask, &rect);		state = 0;	    }	    ptr++;	}	if (state) {	    rect.width = (x * XUNITSIZE) - rect.x;	    GrUnionRectWithRegion(level_clipmask, &rect);	}    }}voiddraw_screen(int full){    int bstart, bend;    int x = 0, y = 0;    GR_GC_ID gc = GrNewGC();    /* Avoid drawing the background if we don't need to */    if (draw_fullscreen == 0 && level_clipmask) {	GrSetGCRegion(gc, level_clipmask);    }    for (y = 0; y < YUNITS; y++) {	bstart = -1;	bend = 0;	for (x = 0; x < XUNITS; x++) {	    if (playground[y][x] == PLAYGROUND_EMPTY) {		if (bstart == -1)		    bend = bstart = x;		else		    bend++;		continue;	    }	    /* Draw the background block */	    if (bstart != -1) {		GrSetGCForeground(gc, BGCOLOR);		GrFillRect(offscreen, gc, (bstart * XUNITSIZE),			   (y * YUNITSIZE), (bend - bstart + 1) * XUNITSIZE,			   YUNITSIZE);		skipped += (bend - bstart);		bstart = -1;		bend = 0;	    }	    if (!full && playground[y][x] == PLAYGROUND_BORDER)		continue;	    switch (playground[y][x]) {	    case PLAYGROUND_BORDER:		draw_tile(TILE_BORDER, (x * XUNITSIZE), (y * YUNITSIZE));		/* GrSetGCForeground(gc, BLUE); */		break;	    case PLAYGROUND_SNAKE:	    case PLAYGROUND_TAIL:		draw_tile(TILE_SNAKE, (x * XUNITSIZE), (y * YUNITSIZE));		/* GrSetGCForeground(gc, RED); */		break;

⌨️ 快捷键说明

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