2006-03-11 15:44:35 +00:00
/***************************************************************************
* __________ __ ___ .
* Open \ ______ \ ____ ____ | | _ \ _ | __ _______ ___
* Source | _ // _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( < _ > ) \ ___ | < | \ _ \ ( < _ > > < <
* Firmware | ____ | _ / \ ____ / \ ___ > __ | _ \ | ___ / \ ____ / __ / \ _ \
* \ / \ / \ / \ / \ /
* $ Id $
*
* Pacbox - a Pacman Emulator for Rockbox
*
* Based on PIE - Pacman Instructional Emulator
*
* Copyright ( c ) 1997 - 2003 , 2004 Alessandro Scotti
* http : //www.ascotti.org/
2018-04-02 04:34:15 +00:00
* AI code ( c ) 2017 Moshe Piekarski
*
* ToDo convert all score to pinky location
2006-03-11 15:44:35 +00:00
*
2008-06-28 18:10:04 +00:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
2006-03-11 15:44:35 +00:00
*
* This software is distributed on an " AS IS " basis , WITHOUT WARRANTY OF ANY
* KIND , either express or implied .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "plugin.h"
# include "arcade.h"
2006-03-13 01:42:11 +00:00
# include "pacbox.h"
# include "pacbox_lcd.h"
2010-07-01 00:26:01 +00:00
# include "wsg3.h"
2006-03-15 17:32:18 +00:00
# include "lib/configfile.h"
2009-08-05 14:29:29 +00:00
# include "lib/playback_control.h"
2018-04-02 04:34:15 +00:00
# include "lib/helper.h"
2020-10-07 06:01:35 +00:00
static fb_data * lcd_fb ;
2018-04-02 04:34:15 +00:00
/*Allows split screen jump and makes pacman invincible if you start at 18 credits (for testing purposes)*/
//#define CHEATS 1
2006-03-11 15:44:35 +00:00
2019-07-29 01:03:38 +00:00
/* Enable AI on all targets */
# define AI 1
2006-03-11 15:44:35 +00:00
struct pacman_settings {
int difficulty ;
int numlives ;
int bonus ;
int ghostnames ;
int showfps ;
2010-07-01 00:26:01 +00:00
int sound ;
2018-04-02 04:34:15 +00:00
int ai ;
2006-03-11 15:44:35 +00:00
} ;
2006-03-15 17:32:18 +00:00
static struct pacman_settings settings ;
static struct pacman_settings old_settings ;
2010-07-01 00:26:01 +00:00
static bool sound_playing = false ;
2006-03-11 15:44:35 +00:00
2018-04-02 04:34:15 +00:00
# define SETTINGS_VERSION 2
# define SETTINGS_MIN_VERSION 2
2006-03-15 17:32:18 +00:00
# define SETTINGS_FILENAME "pacbox.cfg"
static char * difficulty_options [ ] = { " Normal " , " Hard " } ;
static char * numlives_options [ ] = { " 1 " , " 2 " , " 3 " , " 5 " } ;
static char * bonus_options [ ] = { " 10000 " , " 15000 " , " 20000 " , " No Bonus " } ;
static char * ghostnames_options [ ] = { " Normal " , " Alternate " } ;
2010-07-01 00:26:01 +00:00
static char * yesno_options [ ] = { " No " , " Yes " } ;
2006-03-15 17:32:18 +00:00
2018-04-02 04:34:15 +00:00
# ifdef AI
static unsigned char ai_direction [ 15 ] [ 205 ] = /* level turn directions */
{
{ 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 0 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 0 , 2 , 0 , 2 , 0 , 2 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 3 , 2 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 4 } , /* first level */
{ 2 , 0 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 3 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 0 , 3 , 0 , 3 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 0 , 3 , 2 , 0 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 2 } , /* second level*/
{ 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 3 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 3 , 0 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 1 , 3 , 0 , 1 , 2 , 1 , 2 , 0 } , /*third level*/
{ 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 3 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 3 , 0 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 1 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 1 , 3 , 2 , 0 , 2 , 0 , 2 , 0 , 2 } , /*level four*/
2019-11-03 22:46:07 +00:00
{ 2 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 0 , 3 , 1 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 0 , 2 } , /*levels 5,7,8,11*/
2018-04-02 04:34:15 +00:00
{ 2 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 1 , 0 , 3 , 1 } , /*level six*/
{ 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 2 , 1 , 3 , 0 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 1 , 2 , 0 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 } , /*level nine*/
{ 2 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 3 , 0 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 0 , 3 , 0 , 2 , 0 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 3 , 0 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 0 , 3 , 0 , 2 , 0 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , } , /*level ten*/
{ 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 2 , 1 , 3 , 0 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 1 , 3 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 0 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 0 , 2 } , /*level twelve*/
{ 2 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 3 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 3 , 1 , 3 , 2 , 1 } , /*level fourteen*/
{ 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 2 , 1 , 3 , 0 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 0 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 0 , 1 , 2 , 1 , 3 , 0 , 2 , 0 , 2 , 1 , 2 , 0 , 2 , 1 , 3 , 2 } ,
{ 2 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 3 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 0 , 2 , 0 , 3 , 0 , 2 } ,
{ 2 , 2 , 1 , 2 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 2 , 0 , 3 , 1 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 1 , 3 , 1 , 2 , 1 } ,
{ 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 0 , 2 , 1 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 0 , 2 , 1 , 3 , 1 , 3 , 1 , 3 , 0 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 1 , 2 , 1 , 3 , 0 } ,
{ 2 , 1 , 3 , 1 , 2 , 0 , 3 , 0 , 2 , 0 , 3 , 1 , 2 , 0 , 3 , 1 , 2 , 1 , 2 , 0 , 2 , 0 , 2 , 0 , 3 , 0 , 3 , 0 , 2 , 1 , 3 , 0 , 2 , 1 , 3 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 2 , 1 , 2 , 1 , 2 , 1 , 3 , 0 , 1 , 3 , 0 , 1 , 2 , 1 , 2 , 1 , 2 , 0 , 3 , 1 , 2 }
} ;
static unsigned char ai_location [ 15 ] [ 205 ] = /* level turn locations */
{
2019-11-03 22:46:07 +00:00
{ 0 , 52 , 58 , 57 , 61 , 34 , 60 , 37 , 54 , 43 , 55 , 42 , 58 , 43 , 61 , 46 , 60 , 49 , 57 , 48 , 54 , 49 , 51 , 42 , 52 , 43 , 55 , 39 , 54 , 34 , 55 , 34 , 58 , 37 , 26 , 52 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 52 , 42 , 57 , 39 , 48 , 35 , 57 , 40 , 54 , 39 , 48 , 35 , 52 , 37 , 51 , 40 , 48 , 43 , 45 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 49 , 40 , 48 , 43 , 42 , 49 , 49 , 45 , 45 , 42 , 42 , 39 , 39 , 40 , 34 , 39 , 43 , 35 , 34 , 40 , 37 , 39 , 3 , 39 , 55 , 52 , 54 , 57 , 55 , 57 , 58 , 54 , 57 , 3 , 52 , 58 , 55 , 57 , 57 , 54 , 53 } , /* first level */
{ 0 , 47 , 54 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 39 , 54 , 43 , 55 , 49 , 58 , 48 , 61 , 34 , 60 , 37 , 54 , 40 , 51 , 49 , 52 , 57 , 55 , 57 , 58 , 54 , 54 , 51 , 48 , 52 , 39 , 48 , 35 , 57 , 40 , 54 , 39 , 57 , 40 , 54 , 35 , 48 , 37 , 40 , 56 , 37 , 57 , 33 , 54 , 37 , 2 , 54 , 40 , 51 , 4 , 42 , 48 , 39 , 39 , 34 , 35 , 37 , 1 , 39 , 4 , 45 , 35 , 39 , 37 , 34 , 40 , 37 , 39 , 40 , 40 , 43 , 43 , 46 , 42 , 49 , 16 , 40 , 48 , 42 , 48 , 45 , 52 , 55 } , /*second level */
{ 0 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 43 , 54 , 39 , 55 , 49 , 58 , 48 , 61 , 34 , 60 , 37 , 54 , 40 , 51 , 49 , 52 , 57 , 55 , 57 , 58 , 54 , 54 , 51 , 51 , 4 , 49 , 48 , 52 , 42 , 57 , 39 , 48 , 35 , 57 , 40 , 54 , 39 , 48 , 35 , 52 , 37 , 51 , 40 , 48 , 43 , 49 , 46 , 52 , 55 , 39 , 54 , 34 , 55 , 34 , 58 , 37 , 57 , 43 , 54 , 42 , 51 , 49 , 52 , 48 , 55 , 39 , 35 , 43 , 37 , 49 , 40 , 48 , 43 , 45 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 39 , 35 , 34 , 37 , 43 , 3 , 37 , 39 , 40 , 34 } , /*third level */
{ 0 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 43 , 54 , 39 , 55 , 49 , 58 , 48 , 61 , 34 , 60 , 37 , 54 , 40 , 51 , 49 , 52 , 57 , 55 , 57 , 58 , 54 , 54 , 51 , 51 , 4 , 49 , 48 , 52 , 42 , 57 , 39 , 48 , 35 , 57 , 40 , 54 , 39 , 48 , 35 , 52 , 37 , 51 , 40 , 48 , 43 , 49 , 46 , 52 , 55 , 45 , 54 , 39 , 48 , 40 , 49 , 49 , 52 , 48 , 55 , 45 , 54 , 42 , 45 , 43 , 42 , 42 , 39 , 43 , 35 , 39 , 37 , 34 , 40 , 37 , 39 , 43 , 35 , 34 , 1 , 35 , 37 , 37 , 49 , 40 , 48 , 43 , 42 , 52 , 43 , 55 , 46 , 54 , 49 , 51 , 42 , 48 , 39 , 52 , 34 , 55 , 34 , 58 , 37 , 54 , 43 , 55 , 4 , 45 , 54 , 42 , 48 , 39 , 1 } , /*fourth level */
{ 0 , 14 , 39 , 58 , 34 , 61 , 46 , 60 , 49 , 57 , 45 , 54 , 42 , 45 , 43 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 52 , 48 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 54 , 57 , 48 , 54 , 52 , 39 , 48 , 35 , 52 , 37 , 57 , 35 , 54 , 46 , 51 , 49 , 42 , 48 , 39 , 42 , 34 , 39 , 37 , 35 , 43 , 37 , 49 , 40 , 48 , 43 , 49 , 46 , 52 , 42 , 57 , 39 , 39 , 35 , 34 , 37 , 40 , 3 , 43 , 35 , 39 , 40 , 34 , 39 , 40 , 40 , 43 , 43 , 49 , 52 , 48 , 55 , 45 , 54 , 39 , 58 , 36 , 57 , 34 , 54 , 37 , 55 , 43 , 54 , 39 , 51 } , /*fifth level */
{ 0 , 14 , 39 , 58 , 34 , 61 , 46 , 60 , 49 , 57 , 45 , 54 , 42 , 45 , 43 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 52 , 48 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 54 , 57 , 48 , 54 , 52 , 39 , 48 , 35 , 52 , 37 , 57 , 35 , 54 , 46 , 51 , 49 , 42 , 45 , 43 , 42 , 42 , 39 , 52 , 40 , 57 , 39 , 51 , 40 , 48 , 43 , 45 , 42 , 42 , 39 , 43 , 35 , 39 , 40 , 34 , 39 , 37 , 35 , 34 , 37 , 37 , 35 , 34 , 3 , 37 , 46 , 40 , 45 , 49 , 49 , 42 , 52 , 39 , 58 , 36 , 57 , 34 , 54 , 37 , 55 , 52 , 4 , 54 , 48 , 37 , } , /*sixth level*/
{ 0 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 43 , 54 , 42 , 51 , 49 , 48 , 52 , 55 , 45 , 54 , 42 , 48 , 39 , 52 , 40 , 45 , 49 , 52 , 52 , 48 , 51 , 49 , 42 , 45 , 49 , 52 , 52 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 48 , 54 , 52 , 55 , 48 , 54 , 52 , 55 , 51 , 58 , 48 , 61 , 45 , 60 , 42 , 57 , 39 , 48 , 40 , 45 , 49 , 46 , 40 , 49 , 49 , 48 , 52 , 52 , 48 , 55 , 52 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 42 , 58 , 43 , 61 , 34 , 60 , 37 , 54 , 34 , 55 , 34 , 58 , 1 , 34 , 61 , 43 , 60 , 42 , 57 , 39 , 48 , 54 , 52 , 57 , 55 , 57 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 39 , 48 , 40 , 52 , 43 , 55 , 39 , 42 , 34 , 39 , 37 , 40 , 34 , 39 , 37 , 35 , 34 , 37 , 37 , 35 , 43 , 37 , 42 , 40 , 43 , 43 , 42 , 46 , 51 , 49 , 42 , 48 , 39 , 55 , 52 , 48 , 51 , 49 , 42 , 52 , 39 , 48 , 54 , 52 , 51 , 51 , 42 , 52 , 39 , 48 , 54 , 42 , 57 , 39 , 54 , 35 , 57 , 37 , 4 , 35 , 48 , 37 , 49 , 40 , 48 , 43 , 49 , 46 , 52 , 39 } , /*ninth level*/
{ 0 , 14 , 39 , 58 , 34 , 61 , 46 , 60 , 49 , 57 , 45 , 54 , 42 , 45 , 43 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 52 , 48 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 54 , 57 , 48 , 54 , 52 , 39 , 48 , 35 , 52 , 37 , 57 , 35 , 54 , 46 , 51 , 49 , 42 , 45 , 43 , 42 , 42 , 39 , 57 , 40 , 54 , 39 , 51 , 40 , 48 , 43 , 42 , 46 , 39 , 42 , 34 , 39 , 37 , 35 , 34 , 40 , 37 , 39 , 43 , 3 , 37 , 42 , 40 , 43 , 43 , 42 , 4 , 45 , 43 , 42 , 42 , 39 , 39 , 58 , 36 , 57 , 34 , 54 , 37 , 55 , 52 , 48 , 51 , 49 , 42 , 52 , 45 , 60 , } , /*tenth level*/
{ 0 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 43 , 54 , 42 , 51 , 49 , 48 , 52 , 55 , 45 , 54 , 42 , 48 , 39 , 52 , 40 , 45 , 49 , 52 , 52 , 48 , 51 , 49 , 42 , 45 , 49 , 52 , 52 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 48 , 54 , 52 , 55 , 48 , 54 , 52 , 55 , 51 , 58 , 48 , 61 , 45 , 60 , 42 , 57 , 39 , 48 , 40 , 45 , 49 , 46 , 40 , 49 , 49 , 48 , 52 , 52 , 48 , 55 , 52 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 42 , 58 , 43 , 61 , 34 , 60 , 37 , 54 , 34 , 55 , 34 , 58 , 1 , 34 , 61 , 43 , 60 , 42 , 57 , 39 , 48 , 54 , 52 , 57 , 55 , 57 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 39 , 48 , 40 , 52 , 43 , 55 , 39 , 42 , 34 , 39 , 37 , 40 , 34 , 39 , 37 , 35 , 34 , 37 , 37 , 4 , 46 , 40 , 45 , 49 , 46 , 52 , 39 , 42 , 40 , 43 , 43 , 49 , 49 , 42 , 52 , 39 , 55 , 52 , 48 , 51 , 49 , 42 , 52 , 39 , 48 , 54 , 39 , 48 , 35 , 57 , 37 , 51 , 40 , 48 , 43 , 45 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 57 , 40 , 54 , 35 } , /*twelfth level*/
{ 0 , 14 , 39 , 58 , 34 , 61 , 46 , 60 , 49 , 57 , 45 , 54 , 42 , 45 , 43 , 42 , 42 , 39 , 39 , 35 , 43 , 37 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 52 , 48 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 54 , 57 , 48 , 54 , 52 , 39 , 48 , 35 , 52 , 37 , 48 , 35 , 57 , 37 , 54 , 35 , 4 , 52 , 37 , 51 , 40 , 48 , 43 , 49 , 49 , 42 , 48 , 39 , 42 , 34 , 39 , 57 , 40 , 54 , 46 , 51 , 49 , 42 , 48 , 39 , 52 , 34 , 55 , 34 , 58 , 37 , 54 , 40 , 51 , 49 , 48 , 52 , 39 , 42 , 40 , 43 , 43 , 49 , 52 , 52 , 48 , 37 , 42 , 34 , 39 , 37 , 35 , 34 , 37 , 37 , 35 , 43 , 37 , 4 , 39 } , /*fourteenth level*/
{ 0 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 43 , 54 , 42 , 51 , 49 , 48 , 52 , 55 , 45 , 54 , 42 , 48 , 39 , 52 , 40 , 45 , 45 , 52 , 52 , 48 , 51 , 49 , 42 , 45 , 49 , 52 , 52 , 55 , 42 , 58 , 43 , 61 , 57 , 60 , 54 , 54 , 57 , 55 , 57 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 48 , 54 , 52 , 55 , 48 , 54 , 52 , 55 , 51 , 58 , 48 , 61 , 45 , 60 , 42 , 57 , 39 , 48 , 40 , 45 , 49 , 46 , 40 , 49 , 49 , 48 , 52 , 52 , 48 , 55 , 52 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 42 , 58 , 43 , 61 , 34 , 60 , 37 , 54 , 34 , 55 , 34 , 58 , 1 , 34 , 61 , 43 , 60 , 42 , 57 , 39 , 48 , 54 , 52 , 57 , 55 , 57 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 39 , 48 , 40 , 52 , 43 , 55 , 39 , 54 , 40 , 45 , 49 , 49 , 42 , 52 , 43 , 55 , 52 , 54 , 51 , 48 , 37 , 41 , 34 , 39 , 37 , 35 , 34 , 37 , 37 , 46 , 40 , 45 , 46 , 42 , 49 , 39 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 48 , 52 , 55 , 39 , 54 , 40 , 48 , 54 , 39 , 48 , 35 , 57 , 2 , 3 , 37 , 54 , 40 , 57 , 39 , 54 , 35 , 48 , 37 , 45 , 35 , 39 , 37 , 40 } ,
2018-04-02 04:34:15 +00:00
{ 0 , 14 , 39 , 58 , 34 , 61 , 46 , 60 , 49 , 57 , 48 , 54 , 52 , 48 , 51 , 45 , 48 , 42 , 49 , 39 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 52 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 39 , 39 , 52 , 55 , 45 , 54 , 39 , 42 , 34 , 39 , 37 , 35 , 43 , 37 , 46 , 35 , 52 , 46 , 51 , 49 , 42 , 48 , 54 , 42 , 57 , 35 , 54 , 37 , 57 , 40 , 54 , 39 , 45 , 35 , 34 , 40 , 37 , 52 , 34 , 55 , 34 , 58 , 34 , 61 , 57 , 60 , 57 , 57 , 57 , 53 } ,
{ 0 , 14 , 39 , 58 , 34 , 61 , 46 , 60 , 49 , 57 , 48 , 54 , 52 , 48 , 51 , 45 , 48 , 42 , 49 , 39 , 42 , 40 , 43 , 43 , 42 , 49 , 49 , 52 , 52 , 58 , 57 , 61 , 45 , 60 , 42 , 57 , 39 , 39 , 52 , 55 , 45 , 54 , 39 , 42 , 34 , 39 , 37 , 35 , 43 , 37 , 49 , 40 , 48 , 43 , 49 , 49 , 42 , 52 , 34 , 55 , 34 , 58 , 37 , 42 , 34 , 35 , 43 , 37 , 57 , 35 , 54 , 37 , 57 , 40 , 54 , 35 , 48 , 37 , 49 , 40 , 48 , 43 , 49 , 46 , 52 , 52 , 57 , 55 , 57 } ,
{ 0 , 52 , 58 , 57 , 61 , 34 , 60 , 37 , 54 , 43 , 55 , 42 , 58 , 43 , 61 , 46 , 60 , 49 , 57 , 52 , 54 , 48 , 55 , 52 , 58 , 55 , 57 , 57 , 54 , 54 , 48 , 51 , 49 , 42 , 52 , 43 , 55 , 39 , 58 , 36 , 57 , 34 , 54 , 37 , 42 , 34 , 39 , 37 , 35 , 43 , 37 , 39 , 35 , 34 , 37 , 37 , 46 , 40 , 49 , 49 , 48 , 52 , 35 , 48 , 37 , 49 , 40 , 48 , 43 , 45 , 42 , 42 , 39 , 52 , 35 , 57 , 37 , 54 , 40 , 57 } ,
{ 0 , 52 , 58 , 57 , 61 , 48 , 60 , 49 , 57 , 48 , 54 , 52 , 55 , 48 , 54 , 57 , 55 , 57 , 58 , 54 , 48 , 51 , 45 , 48 , 42 , 49 , 39 , 52 , 35 , 48 , 37 , 52 , 34 , 48 , 37 , 52 , 46 , 51 , 49 , 45 , 37 , 39 , 33 , 38 , 35 , 35 , 49 , 34 , 60 , 37 , 53 , 60 , 42 , 55 , 60 , 38 , 35 , 58 , 40 , 54 , 35 , 57 , 37 }
} ;
# endif
2006-03-15 17:32:18 +00:00
static struct configdata config [ ] =
{
2009-01-17 22:53:12 +00:00
{ TYPE_ENUM , 0 , 2 , { . int_p = & settings . difficulty } , " Difficulty " ,
difficulty_options } ,
{ TYPE_ENUM , 0 , 4 , { . int_p = & settings . numlives } , " Pacmen Per Game " ,
numlives_options } ,
{ TYPE_ENUM , 0 , 4 , { . int_p = & settings . bonus } , " Bonus " , bonus_options } ,
{ TYPE_ENUM , 0 , 2 , { . int_p = & settings . ghostnames } , " Ghost Names " ,
ghostnames_options } ,
{ TYPE_ENUM , 0 , 2 , { . int_p = & settings . showfps } , " Show FPS " ,
2010-07-01 00:26:01 +00:00
yesno_options } ,
{ TYPE_ENUM , 0 , 2 , { . int_p = & settings . sound } , " Sound " ,
yesno_options } ,
2018-04-02 04:34:15 +00:00
# ifdef AI
{ TYPE_ENUM , 0 , 2 , { . int_p = & settings . ai } , " AI " ,
yesno_options } ,
# endif
2006-03-15 17:32:18 +00:00
} ;
static bool loadFile ( const char * name , unsigned char * buf , int len )
2006-03-11 15:44:35 +00:00
{
char filename [ MAX_PATH ] ;
2007-09-10 09:46:36 +00:00
rb - > snprintf ( filename , sizeof ( filename ) , ROCKBOX_DIR " /pacman/%s " , name ) ;
2006-03-11 15:44:35 +00:00
int fd = rb - > open ( filename , O_RDONLY ) ;
if ( fd < 0 ) {
return false ;
}
2009-08-05 14:29:29 +00:00
2006-03-11 15:44:35 +00:00
int n = rb - > read ( fd , buf , len ) ;
2009-08-05 14:29:29 +00:00
2006-03-11 15:44:35 +00:00
rb - > close ( fd ) ;
if ( n ! = len ) {
return false ;
}
return true ;
}
2006-03-15 17:32:18 +00:00
static bool loadROMS ( void )
2006-03-11 15:44:35 +00:00
{
bool romsLoaded = false ;
romsLoaded = loadFile ( " pacman.6e " , ram_ , 0x1000 ) & &
loadFile ( " pacman.6f " , ram_ + 0x1000 , 0x1000 ) & &
loadFile ( " pacman.6h " , ram_ + 0x2000 , 0x1000 ) & &
loadFile ( " pacman.6j " , ram_ + 0x3000 , 0x1000 ) & &
loadFile ( " pacman.5e " , charset_rom_ , 0x1000 ) & &
loadFile ( " pacman.5f " , spriteset_rom_ , 0x1000 ) ;
if ( romsLoaded ) {
decodeROMs ( ) ;
reset_PacmanMachine ( ) ;
}
return romsLoaded ;
}
/* A buffer to render Pacman's 244x288 screen into */
2006-03-18 09:14:10 +00:00
static unsigned char video_buffer [ ScreenWidth * ScreenHeight ] __attribute__ ( ( aligned ( 16 ) ) ) ;
2006-03-11 15:44:35 +00:00
2006-03-15 17:32:18 +00:00
static long start_time ;
static long video_frames = 0 ;
2006-03-11 15:44:35 +00:00
2006-03-15 17:32:18 +00:00
static int dipDifficulty [ ] = { DipDifficulty_Normal , DipDifficulty_Hard } ;
static int dipLives [ ] = { DipLives_1 , DipLives_2 , DipLives_3 , DipLives_5 } ;
static int dipBonus [ ] = { DipBonus_10000 , DipBonus_15000 , DipBonus_20000 ,
DipBonus_None } ;
static int dipGhostNames [ ] = { DipGhostNames_Normal , DipGhostNames_Alternate } ;
2006-03-11 15:44:35 +00:00
2006-03-15 17:32:18 +00:00
static int settings_to_dip ( struct pacman_settings settings )
2006-03-11 15:44:35 +00:00
{
return ( DipPlay_OneCoinOneGame |
DipCabinet_Upright |
DipMode_Play |
DipRackAdvance_Off |
dipDifficulty [ settings . difficulty ] |
dipLives [ settings . numlives ] |
dipBonus [ settings . bonus ] |
dipGhostNames [ settings . ghostnames ]
) ;
}
2006-03-15 17:32:18 +00:00
static bool pacbox_menu ( void )
2006-03-11 15:44:35 +00:00
{
2009-06-16 04:25:21 +00:00
int selected = 0 ;
2006-03-11 15:44:35 +00:00
int result ;
int menu_quit = 0 ;
int new_setting ;
bool need_restart = false ;
static const struct opt_items noyes [ 2 ] = {
2006-08-11 12:48:36 +00:00
{ " No " , - 1 } ,
{ " Yes " , - 1 } ,
2006-03-11 15:44:35 +00:00
} ;
static const struct opt_items difficulty_options [ 2 ] = {
2006-08-11 12:48:36 +00:00
{ " Normal " , - 1 } ,
{ " Harder " , - 1 } ,
2006-03-11 15:44:35 +00:00
} ;
static const struct opt_items numlives_options [ 4 ] = {
2006-08-11 12:48:36 +00:00
{ " 1 " , - 1 } ,
{ " 2 " , - 1 } ,
{ " 3 " , - 1 } ,
{ " 5 " , - 1 } ,
2006-03-11 15:44:35 +00:00
} ;
static const struct opt_items bonus_options [ 4 ] = {
2006-08-11 12:48:36 +00:00
{ " 10000 points " , - 1 } ,
{ " 15000 points " , - 1 } ,
{ " 20000 points " , - 1 } ,
{ " No bonus " , - 1 } ,
2006-03-11 15:44:35 +00:00
} ;
static const struct opt_items ghostname_options [ 2 ] = {
2006-08-11 12:48:36 +00:00
{ " Normal " , - 1 } ,
{ " Alternate " , - 1 } ,
2006-03-11 15:44:35 +00:00
} ;
2010-07-01 00:26:01 +00:00
enum
{
PBMI_DIFFICULTY = 0 ,
PBMI_PACMEN_PER_GAME ,
PBMI_BONUS_LIFE ,
PBMI_GHOST_NAMES ,
PBMI_DISPLAY_FPS ,
PBMI_SOUND ,
2018-04-02 04:34:15 +00:00
# ifdef AI
PBMI_AI ,
# endif
2010-07-01 00:26:01 +00:00
PBMI_RESTART ,
PBMI_QUIT ,
} ;
2009-06-16 04:25:21 +00:00
MENUITEM_STRINGLIST ( menu , " Pacbox Menu " , NULL ,
" Difficulty " , " Pacmen Per Game " , " Bonus Life " ,
2010-07-01 00:26:01 +00:00
" Ghost Names " , " Display FPS " , " Sound " ,
2018-04-02 04:34:15 +00:00
# ifdef AI
" AI " ,
# endif
2010-03-19 23:24:22 +00:00
" Restart " , " Quit " ) ;
2006-03-11 15:44:35 +00:00
rb - > button_clear_queue ( ) ;
2009-09-07 21:41:10 +00:00
# if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
rb - > lcd_set_mode ( LCD_MODE_RGB565 ) ;
# endif
2006-03-11 15:44:35 +00:00
while ( ! menu_quit ) {
2009-06-16 04:25:21 +00:00
result = rb - > do_menu ( & menu , & selected , NULL , false ) ;
2006-03-11 15:44:35 +00:00
switch ( result )
{
2010-07-01 00:26:01 +00:00
case PBMI_DIFFICULTY :
2006-03-11 15:44:35 +00:00
new_setting = settings . difficulty ;
rb - > set_option ( " Difficulty " , & new_setting , INT ,
difficulty_options , 2 , NULL ) ;
if ( new_setting ! = settings . difficulty ) {
settings . difficulty = new_setting ;
need_restart = true ;
}
break ;
2010-07-01 00:26:01 +00:00
case PBMI_PACMEN_PER_GAME :
2006-03-11 15:44:35 +00:00
new_setting = settings . numlives ;
rb - > set_option ( " Pacmen Per Game " , & new_setting , INT ,
numlives_options , 4 , NULL ) ;
if ( new_setting ! = settings . numlives ) {
settings . numlives = new_setting ;
need_restart = true ;
}
break ;
2010-07-01 00:26:01 +00:00
case PBMI_BONUS_LIFE :
2006-03-11 15:44:35 +00:00
new_setting = settings . bonus ;
rb - > set_option ( " Bonus Life " , & new_setting , INT ,
bonus_options , 4 , NULL ) ;
if ( new_setting ! = settings . bonus ) {
settings . bonus = new_setting ;
need_restart = true ;
}
break ;
2010-07-01 00:26:01 +00:00
case PBMI_GHOST_NAMES :
2006-03-11 15:44:35 +00:00
new_setting = settings . ghostnames ;
rb - > set_option ( " Ghost Names " , & new_setting , INT ,
ghostname_options , 2 , NULL ) ;
if ( new_setting ! = settings . ghostnames ) {
settings . ghostnames = new_setting ;
need_restart = true ;
}
break ;
2010-07-01 00:26:01 +00:00
case PBMI_DISPLAY_FPS :
2009-08-05 14:29:29 +00:00
rb - > set_option ( " Display FPS " , & settings . showfps , INT ,
2006-03-15 17:32:18 +00:00
noyes , 2 , NULL ) ;
2006-03-11 15:44:35 +00:00
break ;
2010-07-01 00:26:01 +00:00
case PBMI_SOUND :
rb - > set_option ( " Sound " , & settings . sound , INT ,
noyes , 2 , NULL ) ;
break ;
2018-04-02 04:34:15 +00:00
# ifdef AI
case PBMI_AI :
rb - > set_option ( " AI " , & settings . ai , INT ,
noyes , 2 , NULL ) ;
break ;
# endif
2010-07-01 00:26:01 +00:00
case PBMI_RESTART :
2006-03-11 15:44:35 +00:00
need_restart = true ;
menu_quit = 1 ;
break ;
default :
menu_quit = 1 ;
break ;
}
}
2009-09-07 21:41:10 +00:00
# if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
rb - > lcd_set_mode ( LCD_MODE_PAL256 ) ;
# endif
2006-03-11 15:44:35 +00:00
if ( need_restart ) {
init_PacmanMachine ( settings_to_dip ( settings ) ) ;
}
/* Possible results:
exit game
restart game
usb connected
*/
2010-07-01 00:26:01 +00:00
return ( result = = PBMI_QUIT ) ;
}
/* Sound is emulated in ISR context, so not much is done per sound frame */
# define NBSAMPLES 128
static uint32_t sound_buf [ NBSAMPLES ] ;
2010-07-01 00:46:15 +00:00
# if CONFIG_CPU == MCF5249
/* Not enough to put this in IRAM */
2010-07-01 03:57:37 +00:00
static int16_t raw_buf [ NBSAMPLES ] ;
2010-07-01 00:46:15 +00:00
# else
2010-07-01 03:57:37 +00:00
static int16_t raw_buf [ NBSAMPLES ] IBSS_ATTR ;
2010-07-01 00:46:15 +00:00
# endif
2010-07-01 00:26:01 +00:00
/*
Audio callback
*/
2012-02-23 13:14:46 +00:00
static void get_more ( const void * * start , size_t * size )
2010-07-01 00:26:01 +00:00
{
2010-07-01 03:57:37 +00:00
int32_t * out , * outend ;
int16_t * raw ;
2010-07-01 00:26:01 +00:00
/* Emulate the audio for the current register settings */
playSound ( raw_buf , NBSAMPLES ) ;
out = sound_buf ;
2010-07-01 03:57:37 +00:00
outend = out + NBSAMPLES ;
2010-07-01 00:26:01 +00:00
raw = raw_buf ;
2010-07-01 03:57:37 +00:00
/* Convert to stereo */
do
2010-07-01 00:26:01 +00:00
{
2010-07-01 03:57:37 +00:00
uint32_t sample = ( uint16_t ) * raw + + ;
2010-07-01 00:26:01 +00:00
* out + + = sample | ( sample < < 16 ) ;
}
2010-07-01 03:57:37 +00:00
while ( out < outend ) ;
2010-07-01 00:26:01 +00:00
2012-02-23 13:14:46 +00:00
* start = sound_buf ;
2010-07-01 00:26:01 +00:00
* size = NBSAMPLES * sizeof ( sound_buf [ 0 ] ) ;
}
/*
Start the sound emulation
*/
static void start_sound ( void )
{
int sr_index ;
if ( sound_playing )
return ;
# ifndef PLUGIN_USE_IRAM
2018-04-02 04:34:15 +00:00
/* Ensure control of PCM - stopping music itn't obligatory */
2010-07-01 00:26:01 +00:00
rb - > plugin_get_audio_buffer ( NULL ) ;
# endif
/* Get the closest rate >= to what is preferred */
sr_index = rb - > round_value_to_list32 ( PREFERRED_SAMPLING_RATE ,
rb - > hw_freq_sampr , HW_NUM_FREQ , false ) ;
if ( rb - > hw_freq_sampr [ sr_index ] < PREFERRED_SAMPLING_RATE
& & sr_index > 0 )
{
/* Round up */
sr_index - - ;
}
wsg3_set_sampling_rate ( rb - > hw_freq_sampr [ sr_index ] ) ;
rb - > pcm_set_frequency ( rb - > hw_freq_sampr [ sr_index ] ) ;
2012-02-23 13:14:46 +00:00
rb - > pcm_play_data ( get_more , NULL , NULL , 0 ) ;
2010-07-01 00:26:01 +00:00
sound_playing = true ;
2006-03-11 15:44:35 +00:00
}
2010-07-01 00:26:01 +00:00
/*
Stop the sound emulation
*/
static void stop_sound ( void )
{
if ( ! sound_playing )
return ;
rb - > pcm_play_stop ( ) ;
rb - > pcm_set_frequency ( HW_SAMPR_DEFAULT ) ;
sound_playing = false ;
}
2006-03-11 15:44:35 +00:00
2018-04-02 04:34:15 +00:00
/* use buttons for joystick */
void joystick ( void )
{
int status ;
/* Check the button status */
status = rb - > button_status ( ) ;
rb - > button_clear_queue ( ) ;
/*handle buttons if AI is off */
# ifdef PACMAN_HAS_REMOTE
setDeviceMode ( Joy1_Left , ( status & PACMAN_LEFT | | status = = PACMAN_RC_LEFT ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Joy1_Right , ( status & PACMAN_RIGHT | | status = = PACMAN_RC_RIGHT ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Joy1_Up , ( status & PACMAN_UP | | status = = PACMAN_RC_UP ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Joy1_Down , ( status & PACMAN_DOWN | | status = = PACMAN_RC_DOWN ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( CoinSlot_1 , ( status & PACMAN_COIN | | status = = PACMAN_RC_COIN ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Key_OnePlayer , ( status & PACMAN_1UP | | status = = PACMAN_RC_1UP ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Key_TwoPlayers , ( status & PACMAN_2UP | | status = = PACMAN_RC_2UP ) ? DeviceOn : DeviceOff ) ;
# else
setDeviceMode ( Joy1_Left , ( status & PACMAN_LEFT ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Joy1_Right , ( status & PACMAN_RIGHT ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Joy1_Up , ( status & PACMAN_UP ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Joy1_Down , ( status & PACMAN_DOWN ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( CoinSlot_1 , ( status & PACMAN_COIN ) ? DeviceOn : DeviceOff ) ;
setDeviceMode ( Key_OnePlayer , ( status & PACMAN_1UP ) ? DeviceOn : DeviceOff ) ;
# ifdef PACMAN_2UP
setDeviceMode ( Key_TwoPlayers , ( status & PACMAN_2UP ) ? DeviceOn : DeviceOff ) ;
# endif
# endif
# ifdef CHEATS
// skip level for testing purposes
if ( status = = SKIP_LEVEL )
{
//dots
ram_ [ 0x4E0E ] = 242 ;
//level
ram_ [ 0x4E13 ] = 254 ;
}
# endif
}
# ifdef AI
/* blank controls */
void clear_joystick ( void )
{
setDeviceMode ( Joy1_Left , DeviceOff ) ;
setDeviceMode ( Joy1_Right , DeviceOff ) ;
setDeviceMode ( Joy1_Up , DeviceOff ) ;
setDeviceMode ( Joy1_Down , DeviceOff ) ;
}
/* Make turns */
void ai_turn ( unsigned char level , unsigned char turn )
{
switch ( ai_direction [ level ] [ turn ] )
{
case 0 :
clear_joystick ( ) ;
setDeviceMode ( Joy1_Up , DeviceOn ) ;
break ;
case 1 :
clear_joystick ( ) ;
setDeviceMode ( Joy1_Down , DeviceOn ) ;
break ;
case 2 :
clear_joystick ( ) ;
setDeviceMode ( Joy1_Right , DeviceOn ) ;
break ;
case 3 :
clear_joystick ( ) ;
setDeviceMode ( Joy1_Left , DeviceOn ) ;
break ;
case 4 :
clear_joystick ( ) ;
break ;
}
}
/*
Decide turns automatically
*/
unsigned char ai ( unsigned char turn )
{
unsigned char position ; /* pac-mans current position */
unsigned char level ; /* current game level */
unsigned char map [ 20 ] = { 0 , 1 , 2 , 3 , 4 , 5 , 4 , 4 , 6 , 7 , 4 , 8 , 8 , 9 , 10 , 10 , 11 , 10 , 12 , 12 } ;
/*Select level map*/
if ( ram_ [ 0x4E13 ] < 20 )
level = map [ ram_ [ 0x4E13 ] ] ;
2019-11-03 22:46:07 +00:00
else if ( ram_ [ 0x4E13 ] ! = 255 )
2018-04-02 04:34:15 +00:00
level = 13 ;
else
level = 14 ;
/* AI can't start in middle of a level */
2019-11-03 22:46:07 +00:00
if ( turn > 210 )
2018-04-02 04:34:15 +00:00
{
rb - > splash ( HZ / 2 , " AI will engage at next level start " ) ;
return 0 ;
}
2019-11-03 22:46:07 +00:00
/* reset joystick direction on level start */
if ( ! ( ram_ [ 0x4E0E ] | | turn ) )
{
/*levels that start facing right */
if ( ( level ! = 4 ) & & ( level ! = 11 ) & & ( level ! = 7 ) & & ( level ! = 5 ) & & ( level ! = 9 ) & & ( level ! = 12 ) )
clear_joystick ( ) ;
else
{
clear_joystick ( ) ;
setDeviceMode ( Joy1_Right , DeviceOn ) ;
}
return 1 ;
}
2018-04-02 04:34:15 +00:00
if ( turn = = 0 )
{
if ( ( ram_ [ 0x4E0E ] = = 1 ) & & ( ram_ [ 0x4D3A ] = = 47 ) )
{
2019-11-03 22:46:07 +00:00
turn = 1 ;
2018-04-02 04:34:15 +00:00
}
joystick ( ) ;
return turn ;
}
2019-11-03 22:46:07 +00:00
if ( ( turn ! = 0 ) & & ( turn ! = 209 ) )
2018-04-02 04:34:15 +00:00
{
/* set which axis to look for pac-man along */
position = ram_ [ 0x4D3A ] ;
if ( ai_direction [ level ] [ turn - 1 ] < 2 )
{
position = ram_ [ 0x4D39 ] ;
}
/*move joystick if necessary */
2019-11-04 08:04:21 +00:00
if ( ai_location [ level ] [ turn ] < 30 )
2018-04-02 04:34:15 +00:00
{
2019-11-04 08:04:21 +00:00
if ( ( ai_location [ level ] [ turn ] < 10 ) & & ( ai_location [ level ] [ turn ] > 0 ) ) /* handle turns using ghosts eaten as basis for turn timing */
2019-11-03 22:46:07 +00:00
{
if ( ram_ [ 0x4DD0 ] = = ai_location [ level ] [ turn ] )
{
ai_turn ( level , turn ) ;
turn + + ;
}
}
2019-11-04 08:04:21 +00:00
if ( ram_ [ 0x4D31 ] = = ( ai_location [ level ] [ turn ] + 30 ) ) /* handle turns using pinky's location as basis for turn timing */
2018-04-02 04:34:15 +00:00
{
ai_turn ( level , turn ) ;
turn + + ;
}
} else if ( position = = ai_location [ level ] [ turn ] ) /* handle turns using pacman's location as basis for turn timing */
{
ai_turn ( level , turn ) ;
turn + + ;
}
}
/* reset turn counter and joystick direction on level start */
if ( ram_ [ 0x4E0E ] = = 0 )
{
/*levels that start facing right */
if ( ( level ! = 4 ) & & ( level ! = 11 ) & & ( level ! = 7 ) & & ( level ! = 5 ) & & ( level ! = 9 ) & & ( level ! = 12 ) )
clear_joystick ( ) ;
2019-11-03 22:46:07 +00:00
else
{
clear_joystick ( ) ;
setDeviceMode ( Joy1_Right , DeviceOn ) ;
}
2018-04-02 04:34:15 +00:00
return 1 ;
}
return turn ;
}
# endif
2006-03-11 15:44:35 +00:00
/*
Runs the game engine for one frame .
*/
2006-03-15 17:32:18 +00:00
static int gameProc ( void )
2006-03-11 15:44:35 +00:00
{
int fps ;
int status ;
long end_time ;
2006-03-20 23:01:28 +00:00
int frame_counter = 0 ;
int yield_counter = 0 ;
2019-07-29 01:03:38 +00:00
# ifdef AI
2018-04-02 04:34:15 +00:00
unsigned char turn = 250 ;
2019-07-29 01:03:38 +00:00
# endif
2006-03-11 15:44:35 +00:00
2010-07-01 00:26:01 +00:00
if ( settings . sound )
start_sound ( ) ;
2006-03-20 23:01:28 +00:00
while ( 1 )
{
/* Run the machine for one frame (1/60th second) */
run ( ) ;
2006-03-11 15:44:35 +00:00
2018-04-02 04:34:15 +00:00
/*Make Pac-man invincible*/
# ifdef CHEATS
if ( ram_ [ 0x4E6E ] = = 23 )
ram_ [ 0x4DA5 ] = 00 ;
# endif
2006-03-20 23:01:28 +00:00
frame_counter + + ;
2006-03-16 23:21:47 +00:00
2006-03-20 23:01:28 +00:00
/* Check the button status */
status = rb - > button_status ( ) ;
2018-04-02 04:34:15 +00:00
rb - > button_clear_queue ( ) ;
2006-03-11 15:44:35 +00:00
2006-07-30 03:10:09 +00:00
# ifdef HAS_BUTTON_HOLD
if ( rb - > button_hold ( ) )
status = PACMAN_MENU ;
# endif
2006-03-20 23:01:28 +00:00
if ( ( status & PACMAN_MENU ) = = PACMAN_MENU
2006-03-18 09:14:10 +00:00
# ifdef PACMAN_RC_MENU
2006-03-20 23:01:28 +00:00
| | status = = PACMAN_RC_MENU
2006-03-18 09:14:10 +00:00
# endif
2006-03-20 23:01:28 +00:00
) {
2010-07-01 00:26:01 +00:00
bool menu_res ;
2006-03-20 23:01:28 +00:00
end_time = * rb - > current_tick ;
2010-07-01 00:26:01 +00:00
stop_sound ( ) ;
menu_res = pacbox_menu ( ) ;
2006-03-20 23:01:28 +00:00
rb - > lcd_clear_display ( ) ;
2006-03-11 15:44:35 +00:00
# ifdef HAVE_REMOTE_LCD
2006-03-20 23:01:28 +00:00
rb - > lcd_remote_clear_display ( ) ;
rb - > lcd_remote_update ( ) ;
2006-03-11 15:44:35 +00:00
# endif
2010-07-01 00:26:01 +00:00
if ( menu_res )
return 1 ;
if ( settings . sound )
start_sound ( ) ;
2006-03-20 23:01:28 +00:00
start_time + = * rb - > current_tick - end_time ;
}
2018-04-02 04:34:15 +00:00
# ifdef AI
if ( ! settings . ai )
{
joystick ( ) ;
turn = 250 ;
}
/* run ai */
2019-11-03 22:46:07 +00:00
if ( settings . ai & & ! ram_ [ 0x4E02 ] )
2018-04-02 04:34:15 +00:00
turn = ai ( turn ) ;
2019-11-03 22:46:07 +00:00
else
joystick ( ) ;
2006-03-18 09:14:10 +00:00
# else
2018-04-02 04:34:15 +00:00
joystick ( ) ;
2006-03-18 09:14:10 +00:00
# endif
2006-03-20 23:01:28 +00:00
/* We only update the screen every third frame - Pacman's native
framerate is 60f ps , so we are attempting to display 20f ps */
if ( frame_counter = = 60 / FPS ) {
2006-03-11 15:44:35 +00:00
2006-03-20 23:01:28 +00:00
frame_counter = 0 ;
video_frames + + ;
2006-03-11 15:44:35 +00:00
2006-03-20 23:01:28 +00:00
yield_counter + + ;
2006-03-13 01:42:11 +00:00
2006-03-20 23:01:28 +00:00
if ( yield_counter = = FPS ) {
yield_counter = 0 ;
rb - > yield ( ) ;
}
2009-08-05 14:29:29 +00:00
2006-03-20 23:01:28 +00:00
/* The following functions render the Pacman screen from the
contents of the video and color ram . We first update the
background , and then draw the Sprites on top .
*/
2006-03-13 01:42:11 +00:00
2006-03-20 23:01:28 +00:00
renderBackground ( video_buffer ) ;
renderSprites ( video_buffer ) ;
2006-03-11 15:44:35 +00:00
2009-09-07 21:41:10 +00:00
# if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
rb - > lcd_blit_pal256 ( video_buffer , 0 , 0 , XOFS , YOFS ,
ScreenWidth , ScreenHeight ) ;
# else
2020-10-07 06:01:35 +00:00
blit_display ( lcd_fb , video_buffer ) ;
2009-09-07 21:41:10 +00:00
# endif
2006-03-20 23:01:28 +00:00
if ( settings . showfps ) {
fps = ( video_frames * HZ * 100 ) / ( * rb - > current_tick - start_time ) ;
2010-08-28 21:46:45 +00:00
rb - > lcd_putsxyf ( 0 , 0 , " %d.%02d / %d fps " , fps / 100 , fps % 100 , FPS ) ;
2006-03-20 23:01:28 +00:00
}
2006-03-11 15:44:35 +00:00
2009-09-07 21:41:10 +00:00
# if !defined(HAVE_LCD_MODES) || \
defined ( HAVE_LCD_MODES ) & & ! ( HAVE_LCD_MODES & LCD_MODE_PAL256 )
2006-03-20 23:01:28 +00:00
rb - > lcd_update ( ) ;
2009-09-07 21:41:10 +00:00
# endif
2006-03-11 15:44:35 +00:00
2009-08-05 14:29:29 +00:00
/* Keep the framerate at Pacman's 60fps */
2006-03-20 23:01:28 +00:00
end_time = start_time + ( video_frames * HZ ) / FPS ;
while ( TIME_BEFORE ( * rb - > current_tick , end_time ) ) {
2009-08-05 14:29:29 +00:00
rb - > sleep ( 1 ) ;
2006-03-20 23:01:28 +00:00
}
2006-03-11 15:44:35 +00:00
}
}
2010-07-01 00:26:01 +00:00
stop_sound ( ) ;
2006-03-11 15:44:35 +00:00
return 0 ;
}
2009-01-16 10:34:40 +00:00
enum plugin_status plugin_start ( const void * parameter )
2006-03-11 15:44:35 +00:00
{
( void ) parameter ;
# ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb - > cpu_boost ( true ) ;
# endif
2006-11-15 06:14:27 +00:00
rb - > lcd_set_backdrop ( NULL ) ;
2006-03-11 15:44:35 +00:00
rb - > lcd_set_foreground ( LCD_WHITE ) ;
rb - > lcd_set_background ( LCD_BLACK ) ;
rb - > lcd_clear_display ( ) ;
rb - > lcd_update ( ) ;
2020-10-07 06:01:35 +00:00
struct viewport * vp_main = rb - > lcd_set_viewport ( NULL ) ;
lcd_fb = vp_main - > buffer - > fb_ptr ;
2006-03-15 17:32:18 +00:00
/* Set the default settings */
2006-03-11 15:44:35 +00:00
settings . difficulty = 0 ; /* Normal */
settings . numlives = 2 ; /* 3 lives */
settings . bonus = 0 ; /* 10000 points */
settings . ghostnames = 0 ; /* Normal names */
2006-03-13 01:52:11 +00:00
settings . showfps = 0 ; /* Do not show FPS */
2010-07-01 00:26:01 +00:00
settings . sound = 0 ; /* Sound off by default */
2018-04-02 04:34:15 +00:00
settings . ai = 0 ; /* AI off by default */
2006-03-11 15:44:35 +00:00
2006-03-15 17:32:18 +00:00
if ( configfile_load ( SETTINGS_FILENAME , config ,
sizeof ( config ) / sizeof ( * config ) ,
SETTINGS_MIN_VERSION
) < 0 )
{
/* If the loading failed, save a new config file (as the disk is
already spinning ) */
configfile_save ( SETTINGS_FILENAME , config ,
sizeof ( config ) / sizeof ( * config ) ,
SETTINGS_VERSION ) ;
}
/* Keep a copy of the saved version of the settings - so we can check if
the settings have changed when we quit */
old_settings = settings ;
2020-07-24 23:20:15 +00:00
# ifdef HAVE_BACKLIGHT
2018-04-02 04:34:15 +00:00
/*Turn off backlight for ai*/
if ( settings . ai )
backlight_ignore_timeout ( ) ;
2020-07-24 23:20:15 +00:00
# endif
2018-04-02 04:34:15 +00:00
2006-03-11 15:44:35 +00:00
/* Initialise the hardware */
init_PacmanMachine ( settings_to_dip ( settings ) ) ;
2009-09-07 21:41:10 +00:00
# if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
rb - > lcd_set_mode ( LCD_MODE_PAL256 ) ;
# endif
2006-03-11 15:44:35 +00:00
/* Load the romset */
if ( loadROMS ( ) ) {
start_time = * rb - > current_tick - 1 ;
2006-03-20 23:01:28 +00:00
gameProc ( ) ;
2006-03-15 17:32:18 +00:00
/* Save the user settings if they have changed */
if ( rb - > memcmp ( & settings , & old_settings , sizeof ( settings ) ) ! = 0 ) {
2007-03-16 21:56:08 +00:00
rb - > splash ( 0 , " Saving settings... " ) ;
2006-03-15 17:32:18 +00:00
configfile_save ( SETTINGS_FILENAME , config ,
sizeof ( config ) / sizeof ( * config ) ,
SETTINGS_VERSION ) ;
}
2006-03-11 15:44:35 +00:00
} else {
2008-08-15 08:27:39 +00:00
rb - > splashf ( HZ * 2 , " No ROMs in %s/pacman/ " , ROCKBOX_DIR ) ;
2006-03-11 15:44:35 +00:00
}
2009-09-07 21:41:10 +00:00
# if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
rb - > lcd_set_mode ( LCD_MODE_RGB565 ) ;
# endif
2006-03-11 15:44:35 +00:00
# ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb - > cpu_boost ( false ) ;
# endif
2022-11-24 04:00:29 +00:00
2018-04-02 04:34:15 +00:00
backlight_use_settings ( ) ;
2022-11-24 04:00:29 +00:00
2006-03-11 15:44:35 +00:00
return PLUGIN_OK ;
2019-11-03 22:46:07 +00:00
}