summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-05-05 13:32:37 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-05-05 13:32:37 +0200
commitbf1d71d5e192e242c7ce7cdb3d4c70c6a7ae4858 (patch)
tree13fdb2d07e850768429dc87c00a0943d7e18ff18 /commands
parent8fb1d4e0758fbeb91dd82541f7c769e2d1e6900a (diff)
parent7af9c3a84384b4330ba961ea5bf3a7a79d8ad1f1 (diff)
downloadbarebox-bf1d71d5e192e242c7ce7cdb3d4c70c6a7ae4858.tar.gz
barebox-bf1d71d5e192e242c7ce7cdb3d4c70c6a7ae4858.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'commands')
-rw-r--r--commands/2048.c389
-rw-r--r--commands/Kconfig6
-rw-r--r--commands/Makefile1
-rw-r--r--commands/mount.c9
-rw-r--r--commands/umount.c8
-rw-r--r--commands/usbserial.c3
6 files changed, 399 insertions, 17 deletions
diff --git a/commands/2048.c b/commands/2048.c
new file mode 100644
index 0000000000..5d6c766563
--- /dev/null
+++ b/commands/2048.c
@@ -0,0 +1,389 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014 Maurits van der Schee
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ *
+ * ============================================================================
+ * Name : 2048.c
+ * Author : Maurits van der Schee
+ * Description : Console version of the game "2048" for GNU/Linux
+ * ============================================================================
+ */
+
+#include <common.h>
+#include <readkey.h>
+#include <command.h>
+#include <stdlib.h>
+
+#define SIZE 4
+static uint32_t score;
+
+static void getColor(uint16_t value, char *color, size_t length)
+{
+ uint8_t original[] = {8,255,1,255,2,255,3,255,4,255,5,255,6,255,7,255,9,0,10,0,11,0,12,0,13,0,14,0,255,0,255,0};
+ uint8_t *scheme = original;
+ uint8_t *background = scheme+0;
+ uint8_t *foreground = scheme+1;
+ if (value > 0) while (value >>= 1) {
+ if (background+2<scheme+sizeof(original)) {
+ background+=2;
+ foreground+=2;
+ }
+ }
+ snprintf(color,length,"\033[38;5;%d;48;5;%dm",*foreground,*background);
+}
+
+static void drawBoard(uint16_t board[SIZE][SIZE])
+{
+ int8_t x,y;
+ char color[40], reset[] = "\033[m";
+ printf("\033[H");
+
+ printf("2048.c %17d pts\n\n",score);
+
+ for (y=0;y<SIZE;y++) {
+ for (x=0;x<SIZE;x++) {
+ getColor(board[x][y],color,40);
+ printf("%s",color);
+ printf(" ");
+ printf("%s",reset);
+ }
+ printf("\n");
+ for (x=0;x<SIZE;x++) {
+ getColor(board[x][y],color,40);
+ printf("%s",color);
+ if (board[x][y]!=0) {
+ char s[8];
+ int8_t t;
+ snprintf(s,8,"%u",board[x][y]);
+ t = 7-strlen(s);
+ printf("%*s%s%*s",t-t/2,"",s,t/2,"");
+ } else {
+ printf(" · ");
+ }
+ printf("%s",reset);
+ }
+ printf("\n");
+ for (x=0;x<SIZE;x++) {
+ getColor(board[x][y],color,40);
+ printf("%s",color);
+ printf(" ");
+ printf("%s",reset);
+ }
+ printf("\n");
+ }
+ printf("\n");
+ printf(" ←,↑,→,↓ or q \n");
+ printf("\033[A");
+}
+
+static int8_t findTarget(uint16_t array[SIZE],int8_t x,int8_t stop)
+{
+ int8_t t;
+ /* if the position is already on the first, don't evaluate */
+ if (x==0) {
+ return x;
+ }
+ for(t=x-1;t>=0;t--) {
+ if (array[t]!=0) {
+ if (array[t]!=array[x]) {
+ /* merge is not possible, take next position */
+ return t+1;
+ }
+ return t;
+ } else {
+ /* we should not slide further, return this one */
+ if (t==stop) {
+ return t;
+ }
+ }
+ }
+ /* we did not find a */
+ return x;
+}
+
+static bool slideArray(uint16_t array[SIZE])
+{
+ bool success = false;
+ int8_t x,t,stop=0;
+
+ for (x=0;x<SIZE;x++) {
+ if (array[x]!=0) {
+ t = findTarget(array,x,stop);
+ /* if target is not original position, then move or merge */
+ if (t!=x) {
+ /* if target is not zero, set stop to avoid double merge */
+ if (array[t]!=0) {
+ score+=array[t]+array[x];
+ stop = t+1;
+ }
+ array[t]+=array[x];
+ array[x]=0;
+ success = true;
+ }
+ }
+ }
+ return success;
+}
+
+static void rotateBoard(uint16_t board[SIZE][SIZE])
+{
+ int8_t i,j,n=SIZE;
+ uint16_t tmp;
+ for (i=0; i<n/2; i++){
+ for (j=i; j<n-i-1; j++){
+ tmp = board[i][j];
+ board[i][j] = board[j][n-i-1];
+ board[j][n-i-1] = board[n-i-1][n-j-1];
+ board[n-i-1][n-j-1] = board[n-j-1][i];
+ board[n-j-1][i] = tmp;
+ }
+ }
+}
+
+static bool moveUp(uint16_t board[SIZE][SIZE])
+{
+ bool success = false;
+ int8_t x;
+ for (x=0;x<SIZE;x++) {
+ success |= slideArray(board[x]);
+ }
+ return success;
+}
+
+static bool moveLeft(uint16_t board[SIZE][SIZE])
+{
+ bool success;
+ rotateBoard(board);
+ success = moveUp(board);
+ rotateBoard(board);
+ rotateBoard(board);
+ rotateBoard(board);
+ return success;
+}
+
+static bool moveDown(uint16_t board[SIZE][SIZE])
+{
+ bool success;
+ rotateBoard(board);
+ rotateBoard(board);
+ success = moveUp(board);
+ rotateBoard(board);
+ rotateBoard(board);
+ return success;
+}
+
+static bool moveRight(uint16_t board[SIZE][SIZE])
+{
+ bool success;
+ rotateBoard(board);
+ rotateBoard(board);
+ rotateBoard(board);
+ success = moveUp(board);
+ rotateBoard(board);
+ return success;
+}
+
+static bool findPairDown(uint16_t board[SIZE][SIZE])
+{
+ bool success = false;
+ int8_t x,y;
+ for (x=0;x<SIZE;x++) {
+ for (y=0;y<SIZE-1;y++) {
+ if (board[x][y]==board[x][y+1]) return true;
+ }
+ }
+ return success;
+}
+
+static int16_t countEmpty(uint16_t board[SIZE][SIZE])
+{
+ int8_t x,y;
+ int16_t count=0;
+ for (x=0;x<SIZE;x++) {
+ for (y=0;y<SIZE;y++) {
+ if (board[x][y]==0) {
+ count++;
+ }
+ }
+ }
+ return count;
+}
+
+static bool gameEnded(uint16_t board[SIZE][SIZE])
+{
+ bool ended = true;
+ if (countEmpty(board)>0) return false;
+ if (findPairDown(board)) return false;
+ rotateBoard(board);
+ if (findPairDown(board)) ended = false;
+ rotateBoard(board);
+ rotateBoard(board);
+ rotateBoard(board);
+ return ended;
+}
+
+static void addRandom(uint16_t board[SIZE][SIZE])
+{
+ int8_t x,y;
+ int16_t r,len=0;
+ uint16_t n,list[SIZE*SIZE][2];
+
+ for (x=0;x<SIZE;x++) {
+ for (y=0;y<SIZE;y++) {
+ if (board[x][y]==0) {
+ list[len][0]=x;
+ list[len][1]=y;
+ len++;
+ }
+ }
+ }
+
+ if (len>0) {
+ r = rand()%len;
+ x = list[r][0];
+ y = list[r][1];
+ n = ((rand()%10)/9+1)*2;
+ board[x][y]=n;
+ }
+}
+
+static int test(void)
+{
+ uint16_t array[SIZE];
+ uint16_t data[] = {
+ 0,0,0,2, 2,0,0,0,
+ 0,0,2,2, 4,0,0,0,
+ 0,2,0,2, 4,0,0,0,
+ 2,0,0,2, 4,0,0,0,
+ 2,0,2,0, 4,0,0,0,
+ 2,2,2,0, 4,2,0,0,
+ 2,0,2,2, 4,2,0,0,
+ 2,2,0,2, 4,2,0,0,
+ 2,2,2,2, 4,4,0,0,
+ 4,4,2,2, 8,4,0,0,
+ 2,2,4,4, 4,8,0,0,
+ 8,0,2,2, 8,4,0,0,
+ 4,0,2,2, 4,4,0,0
+ };
+ uint16_t *in,*out;
+ uint16_t t,tests;
+ uint8_t i;
+ bool success = true;
+
+ tests = (sizeof(data)/sizeof(data[0]))/(2*SIZE);
+ for (t=0;t<tests;t++) {
+ in = data+t*2*SIZE;
+ out = in + SIZE;
+ for (i=0;i<SIZE;i++) {
+ array[i] = in[i];
+ }
+ slideArray(array);
+ for (i=0;i<SIZE;i++) {
+ if (array[i] != out[i]) {
+ success = false;
+ }
+ }
+ if (success==false) {
+ for (i=0;i<SIZE;i++) {
+ printf("%d ",in[i]);
+ }
+ printf("=> ");
+ for (i=0;i<SIZE;i++) {
+ printf("%d ",array[i]);
+ }
+ printf("expected ");
+ for (i=0;i<SIZE;i++) {
+ printf("%d ",in[i]);
+ }
+ printf("=> ");
+ for (i=0;i<SIZE;i++) {
+ printf("%d ",out[i]);
+ }
+ printf("\n");
+ break;
+ }
+ }
+ if (success) {
+ printf("All %u tests executed successfully\n",tests);
+ }
+ return !success;
+}
+
+static int do_2048(int argc, char *argv[])
+{
+ uint16_t board[SIZE][SIZE];
+ char c;
+ bool success;
+
+ if (argc == 2 && strcmp(argv[1],"test")==0) {
+ return test();
+ }
+
+ printf("\033[?25l\033[2J\033[H");
+
+ memset(board,0,sizeof(board));
+ addRandom(board);
+ addRandom(board);
+ drawBoard(board);
+ while (true) {
+ c=read_key();
+ switch(c) {
+ case BB_KEY_LEFT: /* left arrow */
+ success = moveLeft(board); break;
+ case BB_KEY_RIGHT: /* right arrow */
+ success = moveRight(board); break;
+ case BB_KEY_UP: /* up arrow */
+ success = moveUp(board); break;
+ case BB_KEY_DOWN: /* down arrow */
+ success = moveDown(board); break;
+ default: success = false;
+ }
+ if (success) {
+ drawBoard(board);
+ udelay(150000);
+ addRandom(board);
+ drawBoard(board);
+ if (gameEnded(board)) {
+ printf(" GAME OVER \n");
+ break;
+ }
+ }
+ if (c=='q') {
+ printf(" QUIT \n");
+ break;
+ }
+ }
+
+ printf("\033[?25h");
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(2048)
+BAREBOX_CMD_HELP_USAGE("2048\n")
+BAREBOX_CMD_HELP_SHORT("The 2048 game\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(2048)
+ .cmd = do_2048,
+ .usage = "Usage: 2048",
+ BAREBOX_CMD_HELP(cmd_2048_help)
+BAREBOX_CMD_END
diff --git a/commands/Kconfig b/commands/Kconfig
index ced2edb71b..3e384f127a 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -597,6 +597,12 @@ config CMD_MEMTEST
flags support, the memtest is running twice with cache enabled
and with cache disabled
+config CMD_2048
+ tristate
+ prompt "2048"
+ help
+ Console version of the game "2048" for GNU/Linux
+
endmenu
menu "video command"
diff --git a/commands/Makefile b/commands/Makefile
index dded48f915..1bb6a08e2e 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -95,3 +95,4 @@ obj-$(CONFIG_CMD_BOOT) += boot.o
obj-$(CONFIG_CMD_DEVINFO) += devinfo.o
obj-$(CONFIG_CMD_READF) += readf.o
obj-$(CONFIG_CMD_MENUTREE) += menutree.o
+obj-$(CONFIG_CMD_2048) += 2048.o
diff --git a/commands/mount.c b/commands/mount.c
index 691bc2911e..8629bacf49 100644
--- a/commands/mount.c
+++ b/commands/mount.c
@@ -31,8 +31,7 @@
static int do_mount(int argc, char *argv[])
{
- int opt;
- int ret = 0, verbose = 0;
+ int opt, verbose = 0;
struct driver_d *drv;
const char *type = NULL;
const char *mountpoint, *dev;
@@ -113,11 +112,7 @@ static int do_mount(int argc, char *argv[])
mountpoint = argv[optind + 1];
}
- if ((ret = mount(dev, type, mountpoint, fsoptions))) {
- perror("mount");
- return 1;
- }
- return 0;
+ return mount(dev, type, mountpoint, fsoptions);
}
BAREBOX_CMD_HELP_START(mount)
diff --git a/commands/umount.c b/commands/umount.c
index e6de1bc8ff..f0f9fcee2b 100644
--- a/commands/umount.c
+++ b/commands/umount.c
@@ -23,16 +23,10 @@
static int do_umount(int argc, char *argv[])
{
- int ret = 0;
-
if (argc != 2)
return COMMAND_ERROR_USAGE;
- if ((ret = umount(argv[1]))) {
- perror("umount");
- return 1;
- }
- return 0;
+ return umount(argv[1]);
}
static const __maybe_unused char cmd_umount_help[] =
diff --git a/commands/usbserial.c b/commands/usbserial.c
index bd5067f7a4..969fd253b9 100644
--- a/commands/usbserial.c
+++ b/commands/usbserial.c
@@ -31,7 +31,6 @@ static int do_usbserial(int argc, char *argv[])
{
int opt;
struct usb_serial_pdata pdata;
- char *argstr;
char *manufacturer = "barebox";
const char *productname = barebox_get_model();
u16 idVendor = 0, idProduct = 0;
@@ -68,8 +67,6 @@ static int do_usbserial(int argc, char *argv[])
}
}
- argstr = argv[optind];
-
pdata.manufacturer = manufacturer;
pdata.productname = productname;
pdata.idVendor = idVendor;