apps/games: Add shift game
This commit is contained in:
parent
75155532b6
commit
8a177cd797
1
games/.gitignore
vendored
Normal file
1
games/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/Kconfig
|
21
games/Make.defs
Normal file
21
games/Make.defs
Normal file
@ -0,0 +1,21 @@
|
||||
############################################################################
|
||||
# apps/games/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(wildcard $(APPDIR)/games/*/Make.defs)
|
23
games/Makefile
Normal file
23
games/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
############################################################################
|
||||
# apps/games/Makefile
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
MENUDESC = "Games"
|
||||
|
||||
include $(APPDIR)/Directory.mk
|
58
games/shift/Kconfig
Normal file
58
games/shift/Kconfig
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config GAMES_SHIFT
|
||||
bool "Shift Game"
|
||||
default n
|
||||
---help---
|
||||
Enable Shift games. Shift is a brick game, like a mix
|
||||
between Tetris and Crush Candy. The inspiration came
|
||||
from a Shift game that was available for Android in the
|
||||
F-Droid store. The original game source code still here:
|
||||
https://github.com/boombuler/Shift/ but the game only works
|
||||
for old Android versions (4.x).
|
||||
NOTE: The source code here is not based on that code from
|
||||
above github.
|
||||
|
||||
if GAMES_SHIFT
|
||||
|
||||
config GAMES_SHIFT_PROGNAME
|
||||
string "Program name"
|
||||
default "shift"
|
||||
---help---
|
||||
This is the name of the program that will be used when the NSH ELF
|
||||
program is installed.
|
||||
|
||||
config GAMES_SHIFT_PRIORITY
|
||||
int "Shift Game task priority"
|
||||
default 100
|
||||
|
||||
config GAMES_SHIFT_STACKSIZE
|
||||
int "Shift Game stack size"
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
|
||||
#
|
||||
# Input Device Selection
|
||||
#
|
||||
|
||||
choice
|
||||
prompt "Input Device (Joystick, Gesture Sensor, etc)"
|
||||
default GAMES_SHIFT_USE_CONSOLEKEY
|
||||
|
||||
config GAMES_SHIFT_USE_CONSOLEKEY
|
||||
bool "Serial Console as Input"
|
||||
depends on !INPUT_DJOYSTICK && !SENSORS_APDS9960
|
||||
|
||||
config GAMES_SHIFT_USE_DJOYSTICK
|
||||
bool "Discrete Joystick as Input"
|
||||
depends on INPUT_DJOYSTICK
|
||||
|
||||
config GAMES_SHIFT_USE_GESTURE
|
||||
bool "Gesture Sensor APDS-9960 as Input"
|
||||
depends on SENSORS_APDS9960
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
23
games/shift/Make.defs
Normal file
23
games/shift/Make.defs
Normal file
@ -0,0 +1,23 @@
|
||||
############################################################################
|
||||
# apps/games/shift/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_GAMES_SHIFT),y)
|
||||
CONFIGURED_APPS += $(APPDIR)/games/shift
|
||||
endif
|
34
games/shift/Makefile
Normal file
34
games/shift/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
############################################################################
|
||||
# apps/games/shift/Makefile
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
# Shift game info
|
||||
|
||||
PROGNAME = $(CONFIG_GAMES_SHIFT_PROGNAME)
|
||||
PRIORITY = $(CONFIG_GAMES_SHIFT_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_GAMES_SHIFT_STACKSIZE)
|
||||
MODULE = $(CONFIG_GAMES_SHIFT)
|
||||
|
||||
# Shift game application
|
||||
|
||||
MAINSRC = shift_main.c
|
||||
|
||||
include $(APPDIR)/Application.mk
|
133
games/shift/shift_input_console.h
Normal file
133
games/shift/shift_input_console.h
Normal file
@ -0,0 +1,133 @@
|
||||
/****************************************************************************
|
||||
* apps/games/shift/shift_input_console.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "shift_inputs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Termios functions to have getch on Linux/NuttX */
|
||||
|
||||
static struct termios g_old;
|
||||
static struct termios g_new;
|
||||
|
||||
/* Initialize g_new terminal I/O settings */
|
||||
|
||||
void init_termios(int echo)
|
||||
{
|
||||
tcgetattr(0, &g_old); /* grab old terminal i/o settings */
|
||||
g_new = g_old; /* use old settings as starting */
|
||||
g_new.c_lflag &= ~ICANON; /* disable buffered I/O */
|
||||
g_new.c_lflag &= ~ECHO; /* disable ECHO bit */
|
||||
g_new.c_lflag |= echo ? ECHO : 0; /* set echo mode if requested */
|
||||
tcsetattr(0, TCSANOW, &g_new); /* apply terminal I/O settings */
|
||||
}
|
||||
|
||||
/* Restore g_old terminal i/o settings */
|
||||
|
||||
void reset_termios(void)
|
||||
{
|
||||
tcsetattr(0, TCSANOW, &g_old);
|
||||
}
|
||||
|
||||
/* Read 1 character - echo defines echo mode */
|
||||
|
||||
char getch_(int echo)
|
||||
{
|
||||
char ch;
|
||||
|
||||
init_termios(echo);
|
||||
ch = getchar();
|
||||
reset_termios();
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* Read 1 character without echo getch() function definition. */
|
||||
|
||||
char getch(void)
|
||||
{
|
||||
return getch_(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* dev_input_init
|
||||
****************************************************************************/
|
||||
|
||||
int dev_input_init(FAR struct input_state_s *dev)
|
||||
{
|
||||
init_termios(0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* dev_read_input
|
||||
****************************************************************************/
|
||||
|
||||
int dev_read_input(FAR struct input_state_s *dev)
|
||||
{
|
||||
char ch;
|
||||
|
||||
/* Arrows keys return three bytes: 27 91 [65-68] */
|
||||
|
||||
if ((ch = getch()) == 27)
|
||||
{
|
||||
if ((ch = getch()) == 91)
|
||||
{
|
||||
ch = getch();
|
||||
if (ch == 65)
|
||||
{
|
||||
dev->dir = DIR_UP;
|
||||
}
|
||||
else if (ch == 66)
|
||||
{
|
||||
dev->dir = DIR_DOWN;
|
||||
}
|
||||
else if (ch == 67)
|
||||
{
|
||||
dev->dir = DIR_RIGHT;
|
||||
}
|
||||
else if (ch == 68)
|
||||
{
|
||||
dev->dir = DIR_LEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->dir = DIR_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->dir = DIR_NONE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
78
games/shift/shift_input_gesture.h
Normal file
78
games/shift/shift_input_gesture.h
Normal file
@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
* apps/games/shift/shift_input_gesture.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/sensors/apds9960.h>
|
||||
|
||||
#include "shift_inputs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define APDS9960_DEVNAME "/dev/gest0"
|
||||
|
||||
/****************************************************************************
|
||||
* dev_input_init
|
||||
****************************************************************************/
|
||||
|
||||
int dev_input_init(FAR struct input_state_s *dev)
|
||||
{
|
||||
/* Open the gesture sensor APDS9960 */
|
||||
|
||||
dev->fd_gest = open(APDS9960_DEVNAME, O_RDONLY | O_NONBLOCK);
|
||||
if (dev->fd_gest < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("ERROR: Failed to open %s: %d\n", APDS9960_DEVNAME, errcode);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* dev_read_input
|
||||
****************************************************************************/
|
||||
|
||||
int dev_read_input(FAR struct input_state_s *dev)
|
||||
{
|
||||
int nbytes;
|
||||
uint8_t gest;
|
||||
|
||||
nbytes = read(dev->fd_gest, (void *)&gest, sizeof(gest));
|
||||
if (nbytes == sizeof(gest))
|
||||
{
|
||||
dev->dir = gest;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->dir = DIR_NONE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
166
games/shift/shift_input_joystick.h
Normal file
166
games/shift/shift_input_joystick.h
Normal file
@ -0,0 +1,166 @@
|
||||
/****************************************************************************
|
||||
* apps/games/shift/shift_input_joystick.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/input/djoystick.h>
|
||||
|
||||
#include "shift_inputs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DJOYSTICK_DEVNAME "/dev/djoy0"
|
||||
#define DJOYSTICK_SIGNO 13
|
||||
|
||||
/* The set of supported joystick discretes */
|
||||
|
||||
static djoy_buttonset_t g_djoysupported;
|
||||
|
||||
/* Last sampled discrete set */
|
||||
|
||||
static djoy_buttonset_t g_djoylast;
|
||||
|
||||
struct djoy_notify_s notify;
|
||||
|
||||
/****************************************************************************
|
||||
* dev_input_init
|
||||
****************************************************************************/
|
||||
|
||||
int dev_input_init(FAR struct input_state_s *dev)
|
||||
{
|
||||
int tmp;
|
||||
int ret;
|
||||
|
||||
/* Open the djoystick device */
|
||||
|
||||
dev->fd_joy = open(DJOYSTICK_DEVNAME, O_RDONLY);
|
||||
if (dev->fd_joy < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to open %s: %d\n",
|
||||
DJOYSTICK_DEVNAME, errno);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Get the set of supported discretes */
|
||||
|
||||
ret = ioctl(dev->fd_joy, DJOYIOC_SUPPORTED,
|
||||
(unsigned long)((uintptr_t)&tmp));
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: ioctl(DJOYIOC_SUPPORTED) failed: %d\n", errno);
|
||||
goto errout_with_fd;
|
||||
}
|
||||
|
||||
g_djoysupported = (djoy_buttonset_t)tmp;
|
||||
|
||||
/* Register to receive a signal on any change in the joystick discretes. */
|
||||
|
||||
notify.dn_press = g_djoysupported;
|
||||
notify.dn_release = g_djoysupported;
|
||||
|
||||
notify.dn_event.sigev_notify = SIGEV_SIGNAL;
|
||||
notify.dn_event.sigev_signo = DJOYSTICK_SIGNO;
|
||||
|
||||
ret = ioctl(dev->fd_joy, DJOYIOC_REGISTER,
|
||||
(unsigned long)((uintptr_t)¬ify));
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: ioctl(DJOYIOC_REGISTER) failed: %d\n", errno);
|
||||
goto errout_with_fd;
|
||||
}
|
||||
|
||||
/* Ignore the default signal action */
|
||||
|
||||
signal(DJOYSTICK_SIGNO, SIG_IGN);
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_fd:
|
||||
close(dev->fd_joy);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* dev_read_input
|
||||
****************************************************************************/
|
||||
|
||||
int dev_read_input(FAR struct input_state_s *dev)
|
||||
{
|
||||
struct siginfo value;
|
||||
sigset_t set;
|
||||
djoy_buttonset_t newset;
|
||||
ssize_t nread;
|
||||
int ret;
|
||||
|
||||
/* Wait for a signal */
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, DJOYSTICK_SIGNO);
|
||||
ret = sigwaitinfo(&set, &value);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: sigwaitinfo() failed: %d\n", errno);
|
||||
}
|
||||
|
||||
newset = (djoy_buttonset_t)value.si_value.sival_int;
|
||||
|
||||
g_djoylast = newset;
|
||||
|
||||
/* Read the signal set and compare */
|
||||
|
||||
nread = read(dev->fd_joy, &newset, sizeof(djoy_buttonset_t));
|
||||
if (nread < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: read() failed: %d\n", errno);
|
||||
}
|
||||
else if (nread != sizeof(djoy_buttonset_t))
|
||||
{
|
||||
fprintf(stderr, "ERROR: read() unexpected size: %ld vs %d\n",
|
||||
(long)nread, sizeof(djoy_buttonset_t));
|
||||
}
|
||||
|
||||
g_djoylast = newset;
|
||||
|
||||
switch (newset)
|
||||
{
|
||||
case DJOY_UP_BIT:
|
||||
dev->dir = DIR_UP;
|
||||
break;
|
||||
case DJOY_DOWN_BIT:
|
||||
dev->dir = DIR_DOWN;
|
||||
break;
|
||||
case DJOY_LEFT_BIT:
|
||||
dev->dir = DIR_LEFT;
|
||||
break;
|
||||
case DJOY_RIGHT_BIT:
|
||||
dev->dir = DIR_RIGHT;
|
||||
break;
|
||||
default:
|
||||
dev->dir = DIR_NONE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
64
games/shift/shift_inputs.h
Normal file
64
games/shift/shift_inputs.h
Normal file
@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
* apps/games/shift/shift_inputs.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DIR_NONE
|
||||
# define DIR_NONE 0
|
||||
#endif
|
||||
|
||||
#ifndef DIR_LEFT
|
||||
# define DIR_LEFT 1
|
||||
#endif
|
||||
|
||||
#ifndef DIR_RIGHT
|
||||
# define DIR_RIGHT 2
|
||||
#endif
|
||||
|
||||
#ifndef DIR_UP
|
||||
# define DIR_UP 3
|
||||
#endif
|
||||
|
||||
#ifndef DIR_DOWN
|
||||
# define DIR_DOWN 4
|
||||
#endif
|
||||
|
||||
struct input_state_s
|
||||
{
|
||||
#ifdef CONFIG_GAMES_SHIFT_USE_CONSOLEKEY
|
||||
int fd_con;
|
||||
#endif
|
||||
#ifdef CONFIG_GAMES_SHIFT_USE_DJOYSTICK
|
||||
int fd_joy;
|
||||
#endif
|
||||
#ifdef CONFIG_GAMES_SHIFT_USE_GESTURE
|
||||
int fd_gest;
|
||||
#endif
|
||||
int dir; /* Direction to move the blocks */
|
||||
};
|
||||
|
927
games/shift/shift_main.c
Normal file
927
games/shift/shift_main.c
Normal file
@ -0,0 +1,927 @@
|
||||
/****************************************************************************
|
||||
* apps/games/shift/shift_main.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <nuttx/video/fb.h>
|
||||
#include <nuttx/video/rgbcolors.h>
|
||||
|
||||
#ifdef CONFIG_GAMES_SHIFT_USE_CONSOLEKEY
|
||||
#include "shift_input_console.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GAMES_SHIFT_USE_DJOYSTICK
|
||||
#include "shift_input_joystick.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GAMES_SHIFT_USE_GESTURE
|
||||
#include "shift_input_gesture.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BOARDX_SIZE 6
|
||||
#define BOARDY_SIZE 6
|
||||
|
||||
#define ROW 8
|
||||
#define COL 8
|
||||
|
||||
/* Difficult mode: 4, 5, 6 */
|
||||
|
||||
#define GAMEMODE 6
|
||||
|
||||
#define NCOLORS GAMEMODE
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct screen_state_s
|
||||
{
|
||||
int fd_fb;
|
||||
struct fb_videoinfo_s vinfo;
|
||||
struct fb_planeinfo_s pinfo;
|
||||
#ifdef CONFIG_FB_OVERLAY
|
||||
struct fb_overlayinfo_s oinfo;
|
||||
#endif
|
||||
FAR void *fbmem;
|
||||
};
|
||||
|
||||
struct game_screen_s
|
||||
{
|
||||
int xres; /* X display resolution */
|
||||
int yres; /* Y display resolution */
|
||||
int xoff; /* X offset to start drawing */
|
||||
int yoff; /* Y offset to start drawing */
|
||||
int ncolors; /* Supported number of colors */
|
||||
int blklen; /* Size of side of the blocks */
|
||||
int steps; /* Steps to slide a block for a now position */
|
||||
int stepinc; /* Step increment during the sliding */
|
||||
int dir; /* Direction to move the blocks */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char g_default_fbdev[] = "/dev/fb0";
|
||||
|
||||
/* The edge of the board is invisible to user */
|
||||
|
||||
int board[ROW][COL] =
|
||||
{
|
||||
{1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1}
|
||||
};
|
||||
|
||||
int prev_board[ROW][COL] =
|
||||
{
|
||||
{1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 0, 0, 1},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1}
|
||||
};
|
||||
|
||||
/* Colors used in the game plus Black */
|
||||
|
||||
static const uint16_t pallete[NCOLORS + 1] =
|
||||
{
|
||||
RGB16_BLACK,
|
||||
RGB16_BLUE,
|
||||
RGB16_GREEN,
|
||||
RGB16_RED,
|
||||
RGB16_CYAN,
|
||||
RGB16_WHITE,
|
||||
RGB16_GOLD,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void draw_rect(FAR struct screen_state_s *state,
|
||||
FAR struct fb_area_s *area, int color)
|
||||
{
|
||||
FAR uint16_t *dest;
|
||||
FAR uint8_t *row;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
row = (FAR uint8_t *)state->fbmem + state->pinfo.stride * area->y;
|
||||
for (y = 0; y < area->h; y++)
|
||||
{
|
||||
dest = ((FAR uint16_t *)row) + area->x;
|
||||
for (x = 0; x < area->w; x++)
|
||||
{
|
||||
*dest++ = pallete[color];
|
||||
}
|
||||
|
||||
row += state->pinfo.stride;
|
||||
}
|
||||
}
|
||||
|
||||
void update_screen(FAR struct screen_state_s *state,
|
||||
FAR struct fb_area_s *area)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_FB_UPDATE
|
||||
ret = ioctl(state->fd_fb, FBIO_UPDATE,
|
||||
(unsigned long)((uintptr_t)area));
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: ioctl(FBIO_UPDATE) failed: %d\n",
|
||||
errcode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Draw the user board without the edges */
|
||||
|
||||
void draw_board(FAR struct screen_state_s *state,
|
||||
FAR struct fb_area_s *area,
|
||||
FAR struct game_screen_s *screen)
|
||||
{
|
||||
int row;
|
||||
int col;
|
||||
int x;
|
||||
int y;
|
||||
int i;
|
||||
int color;
|
||||
|
||||
/* Clear the framebuffer, but don't update yet */
|
||||
|
||||
area->x = 0;
|
||||
area->y = 0;
|
||||
area->w = screen->xres;
|
||||
area->h = screen->yres;
|
||||
|
||||
draw_rect(state, area, 0);
|
||||
|
||||
for (i = screen->steps; i > 0; i--)
|
||||
{
|
||||
for (row = 1; row <= BOARDX_SIZE; row++)
|
||||
{
|
||||
for (col = 1; col <= BOARDY_SIZE; col++)
|
||||
{
|
||||
color = board[row][col];
|
||||
|
||||
x = (col - 1) * screen->blklen + screen->xoff;
|
||||
y = (row - 1) * screen->blklen + screen->yoff;
|
||||
|
||||
/* Get original width and height of blocks */
|
||||
|
||||
area->w = screen->blklen;
|
||||
area->h = screen->blklen;
|
||||
|
||||
/* Only do the sliding for blocks that changed */
|
||||
|
||||
if (prev_board[row][col] != board[row][col])
|
||||
{
|
||||
if (screen->dir == DIR_NONE)
|
||||
{
|
||||
area->x = x;
|
||||
area->y = y;
|
||||
}
|
||||
|
||||
if (screen->dir == DIR_UP)
|
||||
{
|
||||
area->x = x;
|
||||
area->y = y + ((i - 1) * screen->stepinc);
|
||||
}
|
||||
|
||||
if (screen->dir == DIR_DOWN)
|
||||
{
|
||||
area->x = x;
|
||||
area->y = y - ((i - 1) * screen->stepinc);
|
||||
}
|
||||
|
||||
if (screen->dir == DIR_LEFT)
|
||||
{
|
||||
area->x = x + ((i - 1) * screen->stepinc);
|
||||
area->y = y;
|
||||
}
|
||||
|
||||
if (screen->dir == DIR_RIGHT)
|
||||
{
|
||||
area->x = x - ((i - 1) * screen->stepinc);
|
||||
area->y = y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
area->x = x;
|
||||
area->y = y;
|
||||
}
|
||||
|
||||
/* Drawn only part of block if above margin */
|
||||
|
||||
if (area->x > (screen->xres - 2 * screen->xoff))
|
||||
{
|
||||
area->x = (screen->xres - 2 * screen->xoff) + 1;
|
||||
area->w = 1;
|
||||
}
|
||||
|
||||
if (area->x < screen->xoff)
|
||||
{
|
||||
area->x = screen->xoff;
|
||||
}
|
||||
|
||||
if (area->y > (screen->yres - 2 * screen->yoff))
|
||||
{
|
||||
area->y = (screen->yres - 2 * screen->yoff) + 1;
|
||||
area->h = 1;
|
||||
}
|
||||
|
||||
if (area->y < screen->yoff)
|
||||
{
|
||||
area->y = screen->yoff;
|
||||
}
|
||||
|
||||
draw_rect(state, area, color);
|
||||
}
|
||||
}
|
||||
|
||||
area->x = 0;
|
||||
area->y = 0;
|
||||
area->w = screen->xres;
|
||||
area->h = screen->yres;
|
||||
|
||||
update_screen(state, area);
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: print_board
|
||||
*
|
||||
* Description:
|
||||
* Draw the board including the user non-visible border for debugging.
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef DEBUG_SHIFT_GAME
|
||||
void print_board(void)
|
||||
{
|
||||
int row;
|
||||
int col;
|
||||
|
||||
for (row = 0; row < ROW; row++)
|
||||
{
|
||||
printf("+---+---+---+---+---+---+---+---+\n");
|
||||
|
||||
for (col = 0; col < COL; col++)
|
||||
{
|
||||
if (row == 0 || col == 0 || row == ROW - 1 || col == COL - 1)
|
||||
{
|
||||
printf("|>%c<", board[row][col] + 48);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("| %c ", board[row][col] + 48);
|
||||
}
|
||||
}
|
||||
|
||||
printf("|\n");
|
||||
}
|
||||
|
||||
printf("+---+---+---+---+---+---+---+---+\n\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: move_board
|
||||
*
|
||||
* Description:
|
||||
* Move the blocks (represented by numbers) to 'dir' direction (L,R,U,D).
|
||||
****************************************************************************/
|
||||
|
||||
void move_board(int dir)
|
||||
{
|
||||
int row;
|
||||
int row_ini;
|
||||
int col;
|
||||
int col_ini;
|
||||
int row_dir;
|
||||
int row_pos;
|
||||
int col_dir;
|
||||
int col_pos;
|
||||
int row_lim;
|
||||
int col_lim;
|
||||
|
||||
if (dir == DIR_UP)
|
||||
{
|
||||
row_ini = 0;
|
||||
row_dir = 1;
|
||||
row_pos = 1;
|
||||
row_lim = BOARDY_SIZE + 1;
|
||||
|
||||
col_ini = 0;
|
||||
col_dir = 1;
|
||||
col_pos = 0;
|
||||
col_lim = BOARDX_SIZE + 1;
|
||||
}
|
||||
|
||||
if (dir == DIR_DOWN)
|
||||
{
|
||||
row_ini = BOARDY_SIZE + 1;
|
||||
row_dir = -1;
|
||||
row_pos = -1;
|
||||
row_lim = 0;
|
||||
|
||||
col_ini = 0;
|
||||
col_dir = 1;
|
||||
col_pos = 0;
|
||||
col_lim = BOARDX_SIZE + 1;
|
||||
}
|
||||
|
||||
if (dir == DIR_RIGHT)
|
||||
{
|
||||
row_ini = 0;
|
||||
row_dir = 1;
|
||||
row_pos = 0;
|
||||
row_lim = BOARDY_SIZE + 1;
|
||||
|
||||
col_ini = BOARDX_SIZE + 1;
|
||||
col_dir = -1;
|
||||
col_pos = -1;
|
||||
col_lim = 0;
|
||||
}
|
||||
|
||||
if (dir == DIR_LEFT)
|
||||
{
|
||||
row_ini = 0;
|
||||
row_dir = 1;
|
||||
row_pos = 0;
|
||||
row_lim = BOARDY_SIZE + 1;
|
||||
|
||||
col_ini = 0;
|
||||
col_dir = 1;
|
||||
col_pos = 1;
|
||||
col_lim = BOARDX_SIZE + 1;
|
||||
}
|
||||
|
||||
for (row = row_ini; row != row_lim; row += row_dir)
|
||||
{
|
||||
for (col = col_ini; col != col_lim; col += col_dir)
|
||||
{
|
||||
/* Never move item if we are in the cache border */
|
||||
|
||||
if ((row != 0 && col != 0) &&
|
||||
(row != 0 && col != BOARDX_SIZE + 1) &&
|
||||
(row != BOARDY_SIZE + 1 && col != 0) &&
|
||||
(row != BOARDY_SIZE + 1 && col != BOARDX_SIZE + 1))
|
||||
{
|
||||
if (board[row][col] == 0)
|
||||
{
|
||||
board[row][col] = board[row + row_pos][col + col_pos];
|
||||
board[row + row_pos][col + col_pos] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fill_edge
|
||||
*
|
||||
* Description:
|
||||
* Fill the invisible border with "colored" blocks
|
||||
****************************************************************************/
|
||||
|
||||
void fill_edge(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= BOARDX_SIZE + 1; i++)
|
||||
{
|
||||
board[0][i] = (random() % GAMEMODE) + 1;
|
||||
board[BOARDY_SIZE + 1][i] = (random() % GAMEMODE) + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i <= BOARDY_SIZE + 1; i++)
|
||||
{
|
||||
board[i][0] = (random() % GAMEMODE) + 1;
|
||||
board[i][BOARDY_SIZE + 1] = (random() % GAMEMODE) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fill_border
|
||||
*
|
||||
* Description:
|
||||
* Fill the visible border with "colored" blocks
|
||||
****************************************************************************/
|
||||
|
||||
void fill_border(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < BOARDX_SIZE + 1; i++)
|
||||
{
|
||||
board[1][i] = (random() % GAMEMODE) + 1;
|
||||
board[BOARDY_SIZE][i] = (random() % GAMEMODE) + 1;
|
||||
}
|
||||
|
||||
for (i = 1; i < BOARDY_SIZE + 1; i++)
|
||||
{
|
||||
board[i][1] = (random() % GAMEMODE) + 1;
|
||||
board[i][BOARDY_SIZE] = (random() % GAMEMODE) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: search_board_squares
|
||||
*
|
||||
* Description:
|
||||
* Search for squares or triples of same colors.
|
||||
****************************************************************************/
|
||||
|
||||
int search_board_squares(void)
|
||||
{
|
||||
int row;
|
||||
int col;
|
||||
int found = 0;
|
||||
|
||||
for (row = 1; row < BOARDY_SIZE; row++)
|
||||
{
|
||||
for (col = 1; col < BOARDX_SIZE; col++)
|
||||
{
|
||||
if (board[row][col] != 0)
|
||||
{
|
||||
if (fabs(board[row][col]) == fabs(board[row][col + 1]))
|
||||
{
|
||||
/* Square */
|
||||
|
||||
if (fabs(board[row][col]) == fabs(board[row + 1][col]) &&
|
||||
fabs(board[row][col + 1]) ==
|
||||
fabs(board[row + 1][col + 1]))
|
||||
{
|
||||
found = 1;
|
||||
board[row][col] = board[row][col] > 0 ?
|
||||
-board[row][col] : board[row][col];
|
||||
board[row][col + 1] = board[row][col + 1] > 0 ?
|
||||
-board[row][col + 1] :
|
||||
board[row][col + 1];
|
||||
board[row + 1][col] = board[row + 1][col] > 0 ?
|
||||
-board[row + 1][col] :
|
||||
board[row + 1][col];
|
||||
board[row + 1][col + 1] = board[row + 1][col + 1] > 0 ?
|
||||
-board[row + 1][col + 1] :
|
||||
board[row + 1][col + 1];
|
||||
}
|
||||
|
||||
/* |- */
|
||||
|
||||
if (fabs(board[row][col]) == fabs(board[row + 1][col]))
|
||||
{
|
||||
found = 1;
|
||||
board[row][col] = board[row][col] > 0 ?
|
||||
-board[row][col] :
|
||||
board[row][col];
|
||||
board[row][col + 1] = board[row][col + 1] > 0 ?
|
||||
-board[row][col + 1] :
|
||||
board[row][col + 1];
|
||||
board[row + 1][col] = board[row + 1][col] > 0 ?
|
||||
-board[row + 1][col] :
|
||||
board[row + 1][col];
|
||||
}
|
||||
|
||||
/* -| */
|
||||
|
||||
if (fabs(board[row][col + 1]) ==
|
||||
fabs(board[row + 1][col + 1]))
|
||||
{
|
||||
found = 1;
|
||||
board[row][col] = board[row][col] > 0 ?
|
||||
-board[row][col] : board[row][col];
|
||||
board[row][col + 1] = board[row][col + 1] > 0 ?
|
||||
-board[row][col + 1] :
|
||||
board[row][col + 1];
|
||||
board[row + 1][col + 1] = board[row + 1][col + 1] > 0 ?
|
||||
-board[row + 1][col + 1] :
|
||||
board[row + 1][col + 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (fabs(board[row][col]) == fabs(board[row + 1][col]))
|
||||
{
|
||||
/* |_ */
|
||||
|
||||
if (fabs(board[row + 1][col]) ==
|
||||
fabs(board[row + 1][col + 1]))
|
||||
{
|
||||
found = 1;
|
||||
board[row][col] = board[row][col] > 0 ?
|
||||
-board[row][col] : board[row][col];
|
||||
board[row + 1][col] = board[row + 1][col] > 0 ?
|
||||
-board[row + 1][col] :
|
||||
board[row + 1][col];
|
||||
board[row + 1][col + 1] = board[row + 1][col + 1] > 0 ?
|
||||
-board[row + 1][col + 1] :
|
||||
board[row + 1][col + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (board[row + 1][col] != 0)
|
||||
{
|
||||
/* _| */
|
||||
|
||||
if (fabs(board[row + 1][col]) == fabs(board[row + 1][col + 1]))
|
||||
{
|
||||
if (fabs(board[row + 1][col + 1]) ==
|
||||
fabs(board[row][col + 1]))
|
||||
{
|
||||
found = 1;
|
||||
board[row][col + 1] = board[row][col + 1] > 0 ?
|
||||
-board[row][col + 1] :
|
||||
board[row][col + 1];
|
||||
board[row + 1][col] = board[row + 1][col] > 0 ?
|
||||
-board[row + 1][col] :
|
||||
board[row + 1][col];
|
||||
board[row + 1][col + 1] = board[row + 1][col + 1] > 0 ?
|
||||
-board[row + 1][col + 1] :
|
||||
board[row + 1][col + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: search_board_squares
|
||||
*
|
||||
* Description:
|
||||
* Search for vertical/horizontal lines of same colours.
|
||||
****************************************************************************/
|
||||
|
||||
int search_board_lines(void)
|
||||
{
|
||||
int row;
|
||||
int col;
|
||||
int h = 0;
|
||||
int hpos = 0;
|
||||
int hfound = 0;
|
||||
int v = 0;
|
||||
int vpos = 0;
|
||||
int vfound = 0;
|
||||
int found = 0;
|
||||
int prev_sym = 0;
|
||||
|
||||
/* Search horizontal lines */
|
||||
|
||||
for (row = 1; row < BOARDY_SIZE + 1; row++)
|
||||
{
|
||||
prev_sym = board[row][1];
|
||||
|
||||
for (col = 1; col < BOARDX_SIZE; col++)
|
||||
{
|
||||
if (board[row][col] != 0)
|
||||
{
|
||||
if (fabs(board[row][col]) == fabs(board[row][col + 1]))
|
||||
{
|
||||
if (!hfound)
|
||||
{
|
||||
hpos = col;
|
||||
hfound = 1;
|
||||
prev_sym = board[row][col];
|
||||
}
|
||||
|
||||
if (fabs(board[row][col]) == fabs(prev_sym))
|
||||
{
|
||||
h++;
|
||||
}
|
||||
}
|
||||
else if (h < 2)
|
||||
{
|
||||
h = 0;
|
||||
hpos = 1;
|
||||
hfound = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (h >= 2)
|
||||
{
|
||||
for (int i = hpos; i <= hpos + h; i++)
|
||||
{
|
||||
board[row][i] = board[row][i] > 0 ?
|
||||
-board[row][i] : board[row][i];
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
h = 0;
|
||||
hpos = 1;
|
||||
hfound = 0;
|
||||
}
|
||||
|
||||
/* Search vertical lines */
|
||||
|
||||
for (col = 1; col < BOARDX_SIZE + 1; col++)
|
||||
{
|
||||
prev_sym = board[1][col];
|
||||
|
||||
for (row = 1; row < BOARDY_SIZE; row++)
|
||||
{
|
||||
if (board[row][col] != 0)
|
||||
{
|
||||
if (fabs(board[row][col]) == fabs(board[row + 1][col]))
|
||||
{
|
||||
if (!vfound)
|
||||
{
|
||||
vpos = row;
|
||||
vfound = 1;
|
||||
prev_sym = board[row][col];
|
||||
}
|
||||
|
||||
if (fabs(board[row][col]) == fabs(prev_sym))
|
||||
{
|
||||
v++;
|
||||
}
|
||||
}
|
||||
else if (v < 2)
|
||||
{
|
||||
v = 0;
|
||||
vpos = 1;
|
||||
vfound = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (v >= 2)
|
||||
{
|
||||
for (int i = vpos; i <= vpos + v; i++)
|
||||
{
|
||||
board[i][col] = board[i][col] > 0 ?
|
||||
-board[i][col] : board[i][col];
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
v = 0;
|
||||
vpos = 1;
|
||||
vfound = 0;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: check_board
|
||||
*
|
||||
* Description:
|
||||
* Verify if there are match lines/squares and remove them
|
||||
****************************************************************************/
|
||||
|
||||
int check_board(void)
|
||||
{
|
||||
int found = 0;
|
||||
int row;
|
||||
int col;
|
||||
|
||||
found = search_board_lines();
|
||||
found |= search_board_squares();
|
||||
|
||||
/* Remove all negative values */
|
||||
|
||||
for (row = 0; row < ROW; row++)
|
||||
{
|
||||
for (col = 0; col < COL; col++)
|
||||
{
|
||||
if (board[row][col] < 0)
|
||||
{
|
||||
board[row][col] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* shift_main
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
FAR const char *fbdev = g_default_fbdev;
|
||||
struct game_screen_s screen;
|
||||
struct input_state_s input;
|
||||
struct screen_state_s state;
|
||||
struct fb_area_s area;
|
||||
int score = 0;
|
||||
int ret;
|
||||
|
||||
/* Open the framebuffer driver */
|
||||
|
||||
state.fd_fb = open(fbdev, O_RDWR);
|
||||
if (state.fd_fb < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: Failed to open %s: %d\n", fbdev, errcode);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Get the characteristics of the framebuffer */
|
||||
|
||||
ret = ioctl(state.fd_fb, FBIOGET_VIDEOINFO,
|
||||
(unsigned long)((uintptr_t)&state.vinfo));
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: ioctl(FBIOGET_VIDEOINFO) failed: %d\n",
|
||||
errcode);
|
||||
close(state.fd_fb);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("VideoInfo:\n");
|
||||
printf(" fmt: %u\n", state.vinfo.fmt);
|
||||
printf(" xres: %u\n", state.vinfo.xres);
|
||||
printf(" yres: %u\n", state.vinfo.yres);
|
||||
printf(" nplanes: %u\n", state.vinfo.nplanes);
|
||||
|
||||
/* Setup the screen information */
|
||||
|
||||
screen.xres = state.vinfo.xres > state.vinfo.yres ?
|
||||
state.vinfo.yres : state.vinfo.xres;
|
||||
screen.yres = state.vinfo.yres > state.vinfo.xres ?
|
||||
state.vinfo.xres : state.vinfo.yres;
|
||||
screen.xoff = (screen.xres % NCOLORS) / 2;
|
||||
screen.yoff = (screen.yres % NCOLORS) / 2;
|
||||
screen.steps = 2;
|
||||
screen.stepinc = 1;
|
||||
screen.blklen = (screen.xres / NCOLORS);
|
||||
screen.ncolors = NCOLORS;
|
||||
|
||||
/* Get the display planeinfo */
|
||||
|
||||
ret = ioctl(state.fd_fb, FBIOGET_PLANEINFO,
|
||||
(unsigned long)((uintptr_t)&state.pinfo));
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n",
|
||||
errcode);
|
||||
close(state.fd_fb);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("PlaneInfo (plane 0):\n");
|
||||
printf(" fbmem: %p\n", state.pinfo.fbmem);
|
||||
printf(" fblen: %lu\n", (unsigned long)state.pinfo.fblen);
|
||||
printf(" stride: %u\n", state.pinfo.stride);
|
||||
printf(" display: %u\n", state.pinfo.display);
|
||||
printf(" bpp: %u\n", state.pinfo.bpp);
|
||||
|
||||
state.fbmem = mmap(NULL, state.pinfo.fblen, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_FILE, state.fd_fb, 0);
|
||||
if (state.fbmem == MAP_FAILED)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n",
|
||||
errcode);
|
||||
close(state.fd_fb);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Mapped FB: %p\n", state.fbmem);
|
||||
|
||||
/* Fill the edge with random values */
|
||||
|
||||
fill_edge();
|
||||
fill_border();
|
||||
|
||||
/* Draw the empty board to user */
|
||||
|
||||
draw_board(&state, &area, &screen);
|
||||
|
||||
dev_input_init(&input);
|
||||
|
||||
while (1)
|
||||
{
|
||||
ret = dev_read_input(&input);
|
||||
|
||||
screen.dir = input.dir;
|
||||
|
||||
#ifdef DEBUG_SHIFT_GAME
|
||||
printf("Before moving:\n");
|
||||
print_board();
|
||||
usleep(2000000);
|
||||
#endif
|
||||
|
||||
/* Save a copy of the board before moving to new position */
|
||||
|
||||
memcpy(prev_board, board, (sizeof(int) * ROW * COL));
|
||||
|
||||
move_board(screen.dir);
|
||||
|
||||
draw_board(&state, &area, &screen);
|
||||
|
||||
#ifdef DEBUG_SHIFT_GAME
|
||||
printf("After moving:\n");
|
||||
print_board();
|
||||
usleep(1000000);
|
||||
#endif
|
||||
|
||||
/* Save a copy of the board after moving the pieces */
|
||||
|
||||
memcpy(prev_board, board, (sizeof(int) * ROW * COL));
|
||||
|
||||
screen.dir = DIR_NONE;
|
||||
|
||||
/* If we found bricks with same colors */
|
||||
|
||||
if (check_board() == 1)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Lets do a blinking effect */
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* Draw the board with the pieces */
|
||||
|
||||
memcpy(board, prev_board, (sizeof(int) * ROW * COL));
|
||||
|
||||
draw_board(&state, &area, &screen);
|
||||
usleep(100000);
|
||||
|
||||
/* Draw the board without the pieces */
|
||||
|
||||
check_board();
|
||||
draw_board(&state, &area, &screen);
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
usleep(500000);
|
||||
|
||||
score += 100;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SHIFT_GAME
|
||||
printf("After checking:\n");
|
||||
print_board();
|
||||
usleep(1000000);
|
||||
#endif
|
||||
|
||||
usleep(1000000);
|
||||
|
||||
/* Add random pieces in the not visible border */
|
||||
|
||||
fill_edge();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user