> compile NEMU

ysyx_22040000 李心杨
Linux calcite 6.6.19 #1-NixOS SMP PREEMPT_DYNAMIC Fri Mar  1 12:35:11 UTC 2024 x86_64 GNU/Linux
 16:26:21  up 4 days  3:32,  2 users,  load average: 0.85, 0.91, 0.95
This commit is contained in:
tracer-ysyx 2024-03-24 16:26:21 +08:00 committed by xinyangli
parent a210694e82
commit d08c2860da
415 changed files with 44314 additions and 11 deletions

View file

@ -0,0 +1,42 @@
This software is licensed under a BSD Style License
Copyright (c) 2015 Battelle Memorial Institute. All Rights Reserved.
http://www.battelle.org/
Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided that the
following conditions are met:
1. Redistributions of source code must retain copyright statements and
notices. Redistributions must also contain a copy of this document.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names "M/o/Vfuscator" and "Battelle" must not be used to endorse or
promote products derived from this Software without prior written
permission of Battelle Memorial Institute. For written permission,
please contact solutions@battelle.org
4. Products derived from this Software may not be called "M/o/Vfuscator" or
"Battelle", nor may "M/o/Vfuscator" or "Battelle" appear in their names
without prior written permission of Battelle Memorial Institute.
Battelle is a registered trademark of Battelle Memorial Institute.
5. Due credit should be given to the Battelle Memorial Institute.
THIS SOFTWARE IS PROVIDED BY BATTELLE MEMORIAL INSTITUTE "AS IS" AND ANY
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL BATTELLE MEMORIAL INSTITUTE OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The original author of this software is Christopher P. Domas, an employee of
the Battelle Memorial Institute.

View file

@ -0,0 +1,3 @@
NAME = snake
SRCS = snake.c
include $(AM_HOME)/Makefile

View file

@ -0,0 +1,188 @@
#include <stdlib.h>
#include <stdio.h>
#include <am.h>
#include <amdev.h>
#include <klib-macros.h>
#define MAX_LENGTH 100
#define TILE_W 8
typedef enum { NONE, UP, DOWN, LEFT, RIGHT } dir_t;
typedef struct {
int x, y;
} point_t;
typedef struct {
int width, height;
} dim_t;
typedef struct {
int top, bottom, left, right;
} rect_t;
typedef struct {
point_t body[MAX_LENGTH];
int length;
int index;
int dead;
} snake_t;
static void refresh() {
io_write(AM_GPU_FBDRAW, 0, 0, NULL, 0, 0, true);
}
static void draw_tile(int y, int x, uint32_t color) {
static uint32_t buf[TILE_W * TILE_W];
uint32_t last_color = 0xffffffff;
if (last_color != color) {
for (int i = 0; i < LENGTH(buf); i ++) { buf[i] = color; }
}
io_write(AM_GPU_FBDRAW, x * TILE_W, y * TILE_W, buf, TILE_W, TILE_W, false);
}
static int read_key() {
while (1) {
AM_INPUT_KEYBRD_T ev = io_read(AM_INPUT_KEYBRD);
if (ev.keydown || ev.keycode == AM_KEY_NONE) return ev.keycode;
}
}
static point_t create_food(dim_t game_size) {
point_t f;
f.x = rand() % game_size.width;
f.y = rand() % game_size.height;
return f;
}
static void print_board(rect_t board) {
uint32_t color = 0x0000ff00;
for (int i = board.left; i <= board.right; i++) {
draw_tile(board.top, i, color);
draw_tile(board.bottom, i, color);
}
for (int i = board.top; i <= board.bottom; i++) {
draw_tile(i, board.left, color);
draw_tile(i, board.right, color);
}
}
static void print_food(point_t food, rect_t board) {
draw_tile(food.y + board.top + 1, food.x + board.left + 1, 0x000000ff);
}
static void print_head(snake_t* snake, rect_t board) {
point_t *p = &snake->body[snake->index];
draw_tile(p->y + board.top + 1, p->x + board.left + 1, 0x00ff0000);
}
static void clear_tail(snake_t* snake, rect_t board) {
int t = snake->index-snake->length;
if (t < 0) { t += MAX_LENGTH; }
draw_tile(snake->body[t].y + board.top + 1, snake->body[t].x + board.left + 1, 0);
}
static dir_t get_dir(int c) {
switch (c) {
case AM_KEY_LEFT: return LEFT;
case AM_KEY_UP: return UP;
case AM_KEY_RIGHT: return RIGHT;
case AM_KEY_DOWN: return DOWN;
default: return NONE;
}
}
static void move_snake(snake_t* snake, dir_t dir) {
point_t p = snake->body[snake->index];
switch (dir) {
case LEFT: p.x --; break;
case DOWN: p.y ++; break;
case RIGHT: p.x ++; break;
case UP: p.y --; break;
default: break;
}
snake->index ++;
if (snake->index == MAX_LENGTH) { snake->index = 0; }
snake->body[snake->index] = p;
}
static int is_dead(snake_t* snake, dim_t game_size) {
point_t head = snake->body[snake->index];
if (head.x == -1) return 1;
if (head.x == game_size.width) return 1;
if (head.y == -1) return 1;
if (head.y == game_size.height) return 1;
for (int i = 1; i != snake->length; i ++) {
int j = snake->index-i;
if (j < 0) { j += MAX_LENGTH; }
if (head.x == snake->body[j].x && head.y == snake->body[j].y) { return 1; }
}
return 0;
}
static int has_food(snake_t* snake, point_t food) {
return snake->body[snake->index].x == food.x && snake->body[snake->index].y == food.y;
}
int main() {
snake_t snake = {0};
rect_t board;
dim_t screen;
dim_t game_size;
dir_t dir = RIGHT;
ioe_init();
screen.height = io_read(AM_GPU_CONFIG).height / TILE_W;
screen.width = io_read(AM_GPU_CONFIG).width / TILE_W;
game_size.width = screen.width - 2;
game_size.height = screen.height - 2;
snake.body[0].x = game_size.width / 2;
snake.body[0].y = game_size.height / 2;
snake.body[1].x = game_size.width / 2;
snake.body[1].y = game_size.height / 2 + 1;
snake.length = 2;
snake.index = 1;
board.left = screen.width / 2 - game_size.width / 2 - 1;
board.right = board.left + game_size.width + 1;
board.top = screen.height / 2 - game_size.height / 2 - 1;
board.bottom = board.top + game_size.height + 1;
print_board(board);
point_t food = create_food(game_size);
print_food(food, board);
do {
print_head(&snake, board);
clear_tail(&snake, board);
dir_t move_dir = get_dir(read_key());
switch (move_dir) {
case UP: if (dir != DOWN) dir = move_dir; break;
case DOWN: if (dir != UP) dir = move_dir; break;
case LEFT: if (dir != RIGHT) dir = move_dir; break;
case RIGHT: if (dir != LEFT) dir = move_dir; break;
default: break;
}
move_snake(&snake, dir);
snake.dead = is_dead(&snake, game_size);
if (has_food(&snake, food)) {
snake.length ++;
food = create_food(game_size);
print_food(food, board);
}
refresh();
uint64_t sleep = 100000 - snake.length * 5000 < 5000 ? 5000 : 100000 - snake.length * 5000;
uint64_t next_us = io_read(AM_TIMER_UPTIME).us + sleep;
while (io_read(AM_TIMER_UPTIME).us < next_us) ;
} while (!snake.dead);
printf("GAME OVER\nPress Q to Exit\n");
while (read_key() != AM_KEY_Q);
return 0;
}