Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (revision 19266) +++ apps/plugins/CATEGORIES (working copy) @@ -58,6 +58,7 @@ ppmviewer,viewers properties,viewers random_folder_advance_config,apps +rattax,games reversi,games robotfindskitten,games rockblox,games Index: apps/plugins/bitmaps/native/SOURCES =================================================================== --- apps/plugins/bitmaps/native/SOURCES (revision 19266) +++ apps/plugins/bitmaps/native/SOURCES (working copy) @@ -393,6 +393,16 @@ #endif #endif +/* Rattax */ +#if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 160) && (LCD_DEPTH >= 16) +rattax_cells.20x20x16.bmp +#elif (LCD_WIDTH >= 121) && (LCD_HEIGHT >= 121) +rattax_cells.17x17x2.bmp +#elif (LCD_WIDTH >= 79) && (LCD_HEIGHT >= 79) +rattax_cells.11x11x2.bmp +#else +rattax_cells.9x9x2.bmp +#endif /* Rockblox */ #if LCD_DEPTH == 16 /* colour versions*/ Index: apps/plugins/rattax/rattax.make =================================================================== --- apps/plugins/rattax/rattax.make (revision 0) +++ apps/plugins/rattax/rattax.make (revision 0) @@ -0,0 +1,21 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id: $ +# + +RATTAXSRCDIR := $(APPSDIR)/plugins/rattax +RATTAXBUILDDIR := $(BUILDDIR)/apps/plugins/rattax + +ROCKS += $(RATTAXBUILDDIR)/rattax.rock + +RATTAX_SRC := $(call preprocess, $(RATTAXSRCDIR)/SOURCES) +RATTAX_OBJ := $(call c2obj, $(RATTAX_SRC)) + +# add source files to OTHER_SRC to get automatic dependencies +OTHER_SRC += $(RATTAX_SRC) + +$(RATTAXBUILDDIR)/rattax.rock: $(RATTAX_OBJ) Index: apps/plugins/rattax/cplayer.c =================================================================== --- apps/plugins/rattax/cplayer.c (revision 0) +++ apps/plugins/rattax/cplayer.c (revision 0) @@ -0,0 +1,243 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "board.h" +#include "util.h" +#include "cplayer.h" + +#define MAX_MOVES 50 /* XXX: get exact number */ +#define MAX_DEPTH CPLAYER_MAX_DEPTH + +int scratch[MAX_DEPTH*BOARD_MAX_SIZE]; +move_t mlist[MAX_DEPTH*MAX_MOVES]; +int mvals[MAX_MOVES]; + +int cplayer_color = C_BLACK; +int cplayer_level = 4; + +#define NULL (void*)0 + +static int bvalue(int player); +static int list_moves(int cp, move_t* lst, int lst_length); +static int estimate(move_t* mlist, int ml, int cp, int depth, int ival); +static int is_glide(move_t* m); + +int* scratch_board(int i) +{ + if(i < 0 || (i + 1)*board_w*board_h > (int)(alength(scratch))) + return NULL; + + return scratch + i*board_w*board_h; +} + +void cplayer_make_move(void) +{ + move_t m; + if(cplayer(cur_player, &m)) + board_make_move(m.cr, m.cc, m.nr, m.nc, cur_player); + cur_player = other(cur_player); +} + +void cplayer_set_level(int l) +{ + cplayer_level = l; +} + +int cplayer(int cp, move_t* move) +{ + move_t* cm; + int i; + int nm; + int vl; + int best = -10000; + int bcnt = 0; + int gcnt = 0; + int sm; + + if(!(nm = list_moves(cp, mlist, alength(mlist)))) + return 0; + + if(!cplayer_level) { + *move = mlist[rbrand() % nm]; + return 1; + } + + for(i = 0; i < nm; i++) { + cm = &mlist[i]; + board_ptr(scratch_board(0)); + board_copy(board); + board_make_move(cm->cr, cm->cc, cm->nr, cm->nc, cp); + vl = -estimate(mlist + nm, alength(mlist) - nm, + other(cp), 1, 10000); + if(vl > best) { + best = vl; + bcnt = 1; + } else if(vl == best) { + bcnt++; + } + mvals[i] = vl; + } + board_ptr(board); + + if(!bcnt) + return 0; + + for(i = 0; i < nm; i++) + if(mvals[i] == best && is_glide(&mlist[i])) + gcnt++; + if(gcnt) { + bcnt = gcnt; + for(i = 0; i < nm; i++) + if(mvals[i] == best && !is_glide(&mlist[i])) + mvals[i] = -10000; + } + + sm = rbrand() % bcnt; + for(i = 0; i < nm; i++) + if(mvals[i] == best) + if(sm-- == 0) { + *move = mlist[i]; + return 1; + } + + return 0; +} + +static int is_glide_delta(int dx, int dy) +{ + return (rbabs(dx) < 2 && rbabs(dy) < 2); +} + +static int is_glide(move_t* m) +{ + return is_glide_delta(m->cr - m->nr, m->cc - m->nc); +} + +int estimate(move_t* mlist, int ml, int cp, int depth, int ival) +{ + move_t* cm; // current move + int nm; // num of moves + int i; + int vl; // disposition value + int best = -10000; + int* initial = board_ptr_get(); + + if(depth >= cplayer_level) + return bvalue(cp); + + if(!(nm = list_moves(cp, mlist, ml))) + return -10000; + + for(i = 0; i < nm; i++) { + cm = &mlist[i]; + board_ptr(scratch_board(depth)); + board_copy(initial); + board_make_move(cm->cr, cm->cc, cm->nr, cm->nc, cp); + vl = -estimate(mlist + nm, ml - ml, other(cp), depth + 1, -best); + if(vl > best) + best = vl; + if(best > ival) + break; + } + + return best; +} + +int bvalue(int player) +{ + int r, c; + int good = 0, bad = 0, empty = 0; + int sq; + int op = other(player); + + foreach_cell(r, c) { + sq = board_get(r, c); + if(sq == player) + good++; + else if(sq == op) + bad++; + else if(sq == C_EMPTY) + empty++; + } + + if(empty == 0) { + if(good == bad) + return 0; + else if(good > bad) + return 1000; + else + return -1000; + } else if(good == 0) { + return -1000; + } else if(bad == 0) { + return 1000; + } else { + return (good - bad); + } +} + +static int list_moves(int cp, move_t* lst, int lst_length) +{ + int r, c; + int* m; + move_t* p = lst; + + // huge moronic optimization: + // * don't list splits from different cells to the same cell + // * don't list jump if this cell is reachable by split -- REMOVED + // * do this all using primary board (no additional memory allocated) + + foreach_cell(r, c) { + if(board_get(r, c) != cp) + continue; + foreach_move(m) { + switch(board_get(r + m[0], c + m[1])) { + case C_MARK: + if(is_glide_delta(m[0], m[1])) + continue; + case C_EMPTY: + p->cr = r; + p->cc = c; + p->nr = r + m[0]; + p->nc = c + m[1]; + p++; + if(is_glide_delta(m[0], m[1])) + board_set(r + m[0], c + m[1], C_MARK); + if(p - lst >= lst_length) + goto exit; + } + } + } + +exit: + // remove marks, if any + foreach_cell(r, c) + if(board_get(r, c) == C_MARK) + board_set(r, c, C_EMPTY); + + return p - lst; +} Index: apps/plugins/rattax/draw.h =================================================================== --- apps/plugins/rattax/draw.h (revision 0) +++ apps/plugins/rattax/draw.h (revision 0) @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __DRAW_H__ +#define __DRAW_H__ + +void draw_board_init(void); +void draw_whole_board(void); + +#endif Index: apps/plugins/rattax/SOURCES =================================================================== --- apps/plugins/rattax/SOURCES (revision 0) +++ apps/plugins/rattax/SOURCES (revision 0) @@ -0,0 +1,7 @@ +rattax.c +board.c +bsets.c +draw.c +util.c +cplayer.c +state.c Index: apps/plugins/rattax/rattax.c =================================================================== --- apps/plugins/rattax/rattax.c (revision 0) +++ apps/plugins/rattax/rattax.c (revision 0) @@ -0,0 +1,218 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include "lib/pluginlib_actions.h" +#include "../lib/oldmenuapi.h" + +#include "rattax.h" +#include "board.h" +#include "cplayer.h" +#include "draw.h" +#include "util.h" +#include "state.h" + +PLUGIN_HEADER + +const struct plugin_api* rb; + +const struct button_mapping* plugin_contexts[]={ + generic_directions, + generic_actions +}; +const int plugin_contexts_count = alength(plugin_contexts); + +int done = 0; + +void cleanup(void* p) +{ + (void)p; +} + +static void reset_cursor(void) +{ + board_place_cursor_for(other(cplayer_color)); +} + +static bool game_menu_cplayer_level(void) +{ + static const struct opt_items items[] = { + { "Completely random", -1 }, + { "Greedy", -1 }, + { "1 turn", -1 }, + { "1.5 turns", -1 }, + { "2 turns", -1 }, + { "2.5 turns", -1 }, + { "3 turns", -1 }, + { "3.5 turns", -1 }, + { "4 turns", -1 } + }; + + return rb->set_option("Bot strategy", &cplayer_level, INT, + items, alength(items), NULL); +} + +static bool game_menu_cplayer_color(void) +{ + static const struct opt_items items[] = { + { "Black", -1 }, + { "White", -1 } + }; + + int value = cplayer_color == C_BLACK ? 0 : 1; + + bool ret = rb->set_option("Bot color", &value, INT, + items, alength(items), NULL); + + cplayer_color = value ? C_WHITE : C_BLACK; + return ret; +} + +/* Returns true iff USB ws connected while in the menu */ +static bool game_menu(void) +{ + int m; + int result; + + static const struct menu_item items[] = { + { "Start new game", NULL }, + { "Restart game", NULL }, + { "Pass the move", NULL }, + { "Bot level", NULL }, + { "Bot color", NULL }, + { "Quit", NULL }, + }; + + m = menu_init(rb, items, sizeof(items) / sizeof(*items), + NULL, NULL, NULL, NULL); + + result = menu_show(m); + + switch (result) { + case 0: + board_rand(); + draw_board_init(); + reset_cursor(); + break; + case 1: + board_clean(); + reset_cursor(); + break; + case 2: + cur_player = other(cur_player); + break; + case 3: + game_menu_cplayer_level(); + break; + case 4: + game_menu_cplayer_color(); + break; + case 5: + done = true; + break; + } + + menu_exit(m); + + return (result == MENU_ATTACHED_USB); +} + +enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter) +{ + int button; + char message[50]; + (void)parameter; + + rb = api; + rb->srand(*rb->current_tick); + if(board_load()) + board_rand(); + else + cur_player = other(cplayer_color); + draw_board_init(); + reset_cursor(); + + while(!done) { + draw_whole_board(); + if(cur_player != P_GEND && board_game_end()) { + int cw = board_count(C_WHITE); + int cb = board_count(C_BLACK); + if(cw == cb) + rb->snprintf(message, sizeof(message), + "%d:%d, draw", cw, cb + ); + else + rb->snprintf(message, sizeof(message), + "%d:%d %s won", cw, cb, + (cw > cb ? "white" : "black") + ); + rb->splash(2*HZ, message); + cur_player = P_GEND; + continue; + } + if(cur_player != P_GEND && !has_move(cur_player)) { + cur_player = other(cur_player); + continue; + } + if(cur_player != P_GEND && cur_player == cplayer_color) { + cplayer_make_move(); + continue; + } + button = pluginlib_getaction(rb, TIMEOUT_BLOCK, + plugin_contexts, plugin_contexts_count); + switch(button) { + case PLA_QUIT: + /* a bit illogical, but PLA_MENU shares + * a single button with PLA_DOWN on some + * targets (??!) */ + if(game_menu()) + return PLUGIN_USB_CONNECTED; + break; + case PLA_LEFT: + board_move_cursor( 0, -1); break; + case PLA_RIGHT: + board_move_cursor( 0, 1); break; + case PLA_UP: + board_move_cursor(-1, 0); break; + case PLA_DOWN: + board_move_cursor( 1, 0); break; + case PLA_FIRE: + board_act(); break; + default: + /* Don't know whether it's correct for PLA_*, + * but some other plugins do exactly this */ + if(rb->default_event_handler_ex(button, cleanup, NULL) == SYS_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; + } + } + if(!cur_player != P_GEND) + board_save(); + else + board_remove_file(); + + return PLUGIN_OK; +} Index: apps/plugins/rattax/cplayer.h =================================================================== --- apps/plugins/rattax/cplayer.h (revision 0) +++ apps/plugins/rattax/cplayer.h (revision 0) @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __CPLAYER_H__ +#define __CPLAYER_H__ + +#define CPLAYER_MAX_DEPTH 8 + +typedef struct { + int cr, cc; + int nr, nc; +} move_t; + +extern int cplayer_color; +extern int cplayer_level; + +void cplayer_make_move(void); + +// Find best move for player and put it to *move. +// Return true if such move was found, or false otherwise. +// Game position is given in global board.h structs +int cplayer(int player, move_t* move); + +#endif Index: apps/plugins/rattax/rattax.h =================================================================== --- apps/plugins/rattax/rattax.h (revision 0) +++ apps/plugins/rattax/rattax.h (revision 0) @@ -0,0 +1,35 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __RATTAX_H__ +#define __RATTAX_H__ + +#include "plugin.h" + +extern const struct plugin_api* rb; + +#endif Index: apps/plugins/rattax/util.c =================================================================== --- apps/plugins/rattax/util.c (revision 0) +++ apps/plugins/rattax/util.c (revision 0) @@ -0,0 +1,46 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "rattax.h" +#include "util.h" + +int rbabs(int x) { return x < 0 ? -x : x; } + +void rbmemcpy(void* dst, void* src, int n) +{ + rb->memcpy(dst, src, n); +} + +int rbrand(void) +{ + return rb->rand(); +} + +void rbmemset(void* dst, int c, int n) +{ + rb->memset(dst, c, n); +} Index: apps/plugins/rattax/bsets.c =================================================================== --- apps/plugins/rattax/bsets.c (revision 0) +++ apps/plugins/rattax/bsets.c (revision 0) @@ -0,0 +1,592 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "bsets.h" + +#define SET(a) { a, sizeof(a)/sizeof(*a) } +#define END { (void*)0, 0 } + +static int b1[] = { + 7, 7, + + 3, 0, + 3, 1, + 3, 2, + 0, 3, + 1, 3, + 2, 3, + 4, 3, + 5, 3, + 6, 3, + 3, 4, + 3, 5, + 3, 6 +}; + +static int b10[] = { + 7, 7, + + 2, 0, + 4, 0, + 2, 2, + 4, 2, + 1, 3, + 5, 3, + 2, 4, + 4, 4, + 2, 6, + 4, 6 +}; + +static int b11[] = { + 7, 7, + + 3, 1, + 3, 2, + 1, 3, + 2, 3, + 3, 3, + 4, 3, + 5, 3, + 3, 4, + 3, 5 +}; + +static int b12[] = { + 7, 7, + + 1, 1, + 2, 1, + 3, 1, + 4, 1, + 5, 1, + 1, 2, + 5, 2, + 1, 3, + 5, 3, + 1, 4, + 5, 4, + 1, 5, + 2, 5, + 3, 5, + 4, 5, + 5, 5 +}; + +static int b13[] = { + 7, 7, + + 2, 1, + 3, 1, + 4, 1, + 1, 2, + 5, 2, + 1, 3, + 5, 3, + 1, 4, + 5, 4, + 2, 5, + 3, 5, + 4, 5 +}; + +static int b14[] = { + 7, 7, + + 2, 1, + 4, 1, + 1, 2, + 2, 2, + 4, 2, + 5, 2, + 1, 4, + 2, 4, + 4, 4, + 5, 4, + 2, 5, + 4, 5 +}; + +static int b15[] = { + 7, 7, + + 1, 1, + 5, 5, + 1, 5, + 5, 1 +}; + +static int b16[] = { + 7, 7, + + 1, 1, + 2, 1, + 4, 1, + 5, 1, + 1, 2, + 5, 2, + 1, 4, + 5, 4, + 1, 5, + 2, 5, + 4, 5, + 5, 5 +}; + +static int b17[] = { + 7, 7, + + 3, 2, + 2, 3, + 3, 3, + 4, 3, + 3, 4 +}; + +static int b18[] = { + 7, 7, + + 3, 2, + 2, 3, + 4, 3, + 3, 4 +}; + +static int b19[] = { + 7, 7, + + 3, 1, + 3, 2, + 1, 3, + 2, 3, + 4, 3, + 5, 3, + 3, 4, + 3, 5 +}; + +static int b2[] = { + 7, 7, + + 3, 0, + 1, 2, + 2, 2, + 4, 2, + 5, 2, + 0, 3, + 1, 3, + 5, 3, + 6, 3, + 1, 4, + 2, 4, + 4, 4, + 5, 4, + 3, 6 +}; + +static int b20[] = { + 7, 7, + + 2, 0, + 3, 0, + 4, 0, + 3, 1, + 0, 2, + 6, 2, + 0, 3, + 1, 3, + 5, 3, + 6, 3, + 0, 4, + 6, 4, + 3, 5, + 2, 6, + 3, 6, + 4, 6 +}; + +static int b21[] = { + 7, 7, + + 2, 0, + 4, 0, + 3, 1, + 0, 2, + 6, 2, + 1, 3, + 5, 3, + 0, 4, + 6, 4, + 3, 5, + 2, 6, + 4, 6 +}; + +static int b22[] = { + 7, 7, + + 3, 1, + 1, 3, + 3, 3, + 5, 3, + 3, 5 +}; + +static int b23[] = { + 7, 7, + + 1, 1, + 3, 1, + 5, 1, + 1, 3, + 3, 3, + 5, 3, + 1, 5, + 3, 5, + 5, 5 +}; + +static int b24[] = { + 7, 7, + +}; + +static int b25[] = { + 7, 7, + + 2, 2, + 4, 2, + 3, 3, + 2, 4, + 4, 4 +}; + +static int b26[] = { + 7, 7, + + 1, 1, + 5, 1, + 2, 2, + 4, 2, + 3, 3, + 2, 4, + 4, 4, + 1, 5, + 5, 5 +}; + +static int b27[] = { + 7, 7, + + 2, 0, + 3, 0, + 4, 0, + 2, 1, + 4, 1, + 0, 3, + 6, 3, + 2, 5, + 4, 5, + 2, 6, + 3, 6, + 4, 6 +}; + +static int b28[] = { + 7, 7, + + 1, 0, + 3, 0, + 5, 0, + 0, 1, + 2, 1, + 4, 1, + 6, 1, + 1, 2, + 3, 2, + 5, 2, + 0, 3, + 2, 3, + 4, 3, + 6, 3, + 1, 4, + 3, 4, + 5, 4, + 0, 5, + 2, 5, + 4, 5, + 6, 5, + 1, 6, + 3, 6, + 5, 6 +}; + +static int b29[] = { + 7, 7, + + 1, 1, + 5, 1, + 2, 2, + 4, 2, + 2, 4, + 4, 4, + 1, 5, + 5, 5 +}; + +static int b3[] = { + 7, 7, + + 1, 0, + 5, 0, + 0, 1, + 6, 1, + 3, 3, + 0, 5, + 6, 5, + 1, 6, + 5, 6 +}; + +static int b30[] = { + 7, 7, + + 3, 0, + 2, 1, + 4, 1, + 0, 3, + 6, 3, + 2, 5, + 4, 5, + 3, 6 +}; + +static int b31[] = { + 7, 7, + + 3, 0, + 0, 3, + 6, 3, + 3, 6 +}; + +static int b32[] = { + 7, 7, + + 3, 1, + 1, 3, + 5, 3, + 3, 5 +}; + +static int b33[] = { + 7, 7, + + 2, 0, + 3, 0, + 4, 0, + 0, 2, + 1, 2, + 3, 2, + 5, 2, + 6, 2, + 0, 3, + 6, 3, + 0, 4, + 1, 4, + 3, 4, + 5, 4, + 6, 4, + 2, 6, + 3, 6, + 4, 6 +}; + +static int b34[] = { + 7, 7, + + 2, 1, + 4, 1, + 0, 2, + 1, 2, + 3, 2, + 5, 2, + 6, 2, + 3, 3, + 0, 4, + 1, 4, + 3, 4, + 5, 4, + 6, 4, + 2, 5, + 4, 5 +}; + +static int b35[] = { + 7, 7, + + 2, 0, + 4, 0, + 2, 1, + 4, 1, + 0, 2, + 6, 2, + 0, 3, + 3, 3, + 6, 3, + 0, 4, + 6, 4, + 2, 5, + 4, 5, + 2, 6, + 4, 6 +}; + +static int b4[] = { + 7, 7, + + 2, 0, + 4, 0, + 2, 1, + 4, 1, + 0, 3, + 6, 3, + 2, 5, + 4, 5, + 2, 6, + 4, 6 +}; + +static int b5[] = { + 7, 7, + + 3, 0, + 3, 1, + 0, 3, + 1, 3, + 5, 3, + 6, 3, + 3, 5, + 3, 6 +}; + +static int b6[] = { + 7, 7, + + 3, 1, + 2, 2, + 4, 2, + 1, 3, + 5, 3, + 2, 4, + 4, 4, + 3, 5 +}; + +static int b7[] = { + 7, 7, + + 2, 0, + 4, 0, + 0, 2, + 6, 2, + 0, 4, + 6, 4, + 2, 6, + 4, 6 +}; + +static int b8[] = { + 7, 7, + + 3, 0, + 2, 1, + 4, 1, + 1, 2, + 5, 2, + 0, 3, + 6, 3, + 1, 4, + 5, 4, + 2, 5, + 4, 5, + 3, 6 +}; + +static int b9[] = { + 7, 7, + + 2, 1, + 4, 1, + 1, 2, + 5, 2, + 1, 4, + 5, 4, + 2, 5, + 4, 5 +}; + +bset_t bsets[] = { + SET(b1), + SET(b10), + SET(b11), + SET(b12), + SET(b13), + SET(b14), + SET(b15), + SET(b16), + SET(b17), + SET(b18), + SET(b19), + SET(b2), + SET(b20), + SET(b21), + SET(b22), + SET(b23), + SET(b24), + SET(b25), + SET(b26), + SET(b27), + SET(b28), + SET(b29), + SET(b3), + SET(b30), + SET(b31), + SET(b32), + SET(b33), + SET(b34), + SET(b35), + SET(b4), + SET(b5), + SET(b6), + SET(b7), + SET(b8), + SET(b9), + END +}; + +int bset_count = sizeof(bsets) / sizeof(*bsets) - 1; Index: apps/plugins/rattax/state.c =================================================================== --- apps/plugins/rattax/state.c (revision 0) +++ apps/plugins/rattax/state.c (revision 0) @@ -0,0 +1,194 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "rattax.h" +#include "cplayer.h" +#include "board.h" +#include "state.h" +#include "util.h" + +#define FILE_BOARD ROCKBOX_DIR "/rattax.board" +#define FILE_SETUP ROCKBOX_DIR "/rattax.setting" + +static int board_position_load(void); +static int board_position_save(void); +static void board_settings_load(void); +static void board_settings_save(void); + +int board_save(void) +{ + board_settings_save(); + return board_position_save(); +} + +int board_load(void) +{ + board_settings_load(); + return board_position_load(); +} + +char saved_cell_mark(int v) +{ + switch(v) { + case C_WHITE: return 'W'; + case C_BLACK: return 'B'; + case C_OBST: return '*'; + case C_EMPTY: return '-'; + default: return '?'; + } +} + +int board_position_save(void) +{ + char buf[2*board_w + 2]; + int r, c; + int fd; + + if((fd = rb->open(FILE_BOARD, O_WRONLY | O_CREAT)) <= 0) + return -1; + + for(r = 0; r < board_h; r++) { + for(c = 0; c < board_w; c++) { + buf[2*c] = saved_cell_mark(board_get(r, c)); + buf[2*c + 1] = ' '; + } + buf[2*c - 1] = '\n'; + buf[2*c] = '\0'; + rb->write(fd, buf, 2*c); + } + + rb->close(fd); + return 0; +} + +int board_position_load(void) +{ + char buf[BOARD_MAX_SIZE]; + int len; + char* p; + int* b; + int* c; + int fd; + int ret = -2; + + board_settings_load(); + + if((fd = rb->open(FILE_BOARD, O_RDONLY)) <= 0) + return -1; + + board_clean(); + board_p = board; + board_w = board_h = 0; + b = board; c = b; + while((len = rb->read(fd, buf, sizeof(buf))) > 0) { + for(p = buf; p - buf < len; p++) { + switch(*p) { + case 'W': *(b++) = C_WHITE; break; + case 'B': *(b++) = C_BLACK; break; + case '-': *(b++) = C_EMPTY; break; + case '*': *(b++) = C_OBST; break; + case '\n': + if(board_w <= 0) + board_w = b - c; + else if(b - c != board_w) + goto exit; + c = b; + } + if(b - board > BOARD_MAX_SIZE) + goto exit; + } + } + + if(board_w <= 0) + goto exit; + + board_h = (b - board) / board_w; + if(board_h <= 0) + goto exit; + + if(board_game_end()) + ret = 1; + else + ret = 0; + +exit: + rb->close(fd); + return ret; +} + +void board_remove_file(void) +{ + rb->remove(FILE_BOARD); +} + +void board_settings_save(void) +{ + int fd; + + if((fd = rb->open(FILE_SETUP, O_WRONLY | O_CREAT)) <= 0) + return; + + rb->fdprintf(fd, "cplayer-level: %d\n", cplayer_level); + rb->fdprintf(fd, "cplayer-color: %s", + cplayer_color == C_BLACK ? "black" : "white"); + + rb->close(fd); +} + +#define LEN 200 + +int atoi_in_range(const char* val, int from, int to) +{ + int v = rb->atoi(val); + if(v < from) + return from; + if(v > to) + return to; + return v; +} + +void board_settings_load(void) +{ + int fd; + char line[LEN]; + char* name; + char* val; + + if((fd = rb->open(FILE_SETUP, O_RDONLY)) <= 0) + return; + + while(rb->read_line(fd, line, LEN) > 0) { + if(!rb->settings_parseline(line, &name, &val)) + continue; + if(!rb->strcmp(name, "cplayer-level")) + cplayer_level = atoi_in_range(val, 0, 7); + if(!rb->strcmp(name, "cplayer-color")) + cplayer_color = rb->strcmp(val, "white") ? C_BLACK : C_WHITE; + } + + rb->close(fd); +} Index: apps/plugins/rattax/util.h =================================================================== --- apps/plugins/rattax/util.h (revision 0) +++ apps/plugins/rattax/util.h (revision 0) @@ -0,0 +1,38 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#define alength(a) sizeof(a)/sizeof(*a) + +int rbabs(int x); +void rbmemcpy(void* dst, void* src, int n); +void rbmemset(void* dst, int c, int n); +int rbrand(void); + +#endif Index: apps/plugins/rattax/state.h =================================================================== --- apps/plugins/rattax/state.h (revision 0) +++ apps/plugins/rattax/state.h (revision 0) @@ -0,0 +1,35 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __STATE_H__ +#define __STATE_H__ + +int board_save(void); +int board_load(void); +void board_remove_file(void); + +#endif Index: apps/plugins/rattax/bsets.h =================================================================== --- apps/plugins/rattax/bsets.h (revision 0) +++ apps/plugins/rattax/bsets.h (revision 0) @@ -0,0 +1,39 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __BSETS_H__ +#define __BSETS_H__ + +typedef struct { + int* data; + int len; +} bset_t; + +extern bset_t bsets[]; +extern int bset_count; + +#endif Index: apps/plugins/rattax/board.c =================================================================== --- apps/plugins/rattax/board.c (revision 0) +++ apps/plugins/rattax/board.c (revision 0) @@ -0,0 +1,292 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "board.h" +#include "bsets.h" +#include "util.h" + +int* board_p; +int board_w, board_h; +int cur_player; +int cur_r, cur_c; +int tag_r, tag_c; + +int board[BOARD_MAX_SIZE]; + +#define array2(name, ...) \ + int name[] = { __VA_ARGS__ };\ + const int name##_size = sizeof(name)/sizeof(*name) + +/* Note: these are iterated backwards */ +array2(moves, + /* jump */ + 2, 0, + 2, 1, /* j j j j j */ + 2, 2, /* j j */ + 1, 2, /* j x j */ + 0, 2, /* j j */ + -1, 2, /* j j j j j */ + -2, 2, + -2, 1, + -2, 0, + -2, -1, + -2, -2, + -1, -2, + 0, -2, + 1, -2, + 2, -2, + 2, -1, + /* split */ + 1, 0, /* */ + 1, 1, /* s s s */ + 0, 1, /* s x s */ + -1, 1, /* s s s */ + -1, 0, /* */ + -1, -1, + 0, -1, + 1, -1 +); + +array2(ranges, + 1, 0, + 1, 1, + 0, 1, + -1, 1, + -1, 0, + -1, -1, + 0, -1, + 1, -1 +); + +int other(int player) +{ + if(player == P_BLACK) return P_WHITE; + if(player == P_WHITE) return P_BLACK; + return player; +} + +void board_ptr(int* p) +{ + board_p = p; +} + +int* board_ptr_get(void) +{ + return board_p; +} + +void board_set(int r, int c, int obj) +{ + if(r < 0 || r >= board_h) + return; + if(c < 0 || c >= board_w) + return; + + board_p[r*board_w + c] = obj; +} + +int board_get(int r, int c) +{ + if(r < 0 || r >= board_h) + return C_OBST; + if(c < 0 || c >= board_w) + return C_OBST; + + return board_p[r*board_w + c]; +} + +// tag{row,col} -> cur{row,col} by current player +int board_make_move(int tr, int tc, int cr, int cc, int cp) +{ + int dc, dr; + + if(board_get(tr, tc) != cp) + return 0; + + if(board_get(cr, cc) != C_EMPTY) + return 0; + + dc = rbabs(cc - tc); + dr = rbabs(cr - tr); + + if(dc <= 1 && dr <= 1) { + board_set(cr, cc, cp); + board_eat_pieces(cr, cc, cp); + return 1; + } + + if(dc <= 2 && dr <= 2) { + board_set(cr, cc, cp); + board_set(tr, tc, C_EMPTY); + board_eat_pieces(cr, cc, cp); + return 1; + } + + return 0; +} + +void board_eat_pieces(int r, int c, int player) +{ + int* p; + int oth = other(player); + + foreach_range(p) + if(board_get(r + p[0], c + p[1]) == oth) + board_set(r + p[0], c + p[1], player); +} + +int board_game_end(void) +{ + int r, c; + + foreach_cell(r, c) + if(board_get(r, c) == C_EMPTY) + return 0; + + return 1; +} + +int board_count(int player) +{ + int r, c; + int count = 0; + + foreach_cell(r, c) + if(board_get(r, c) == player) + count++; + + return count; +} + +int has_move(int player) +{ + int r, c, *p; + + foreach_cell(r, c) + if(board_get(r, c) == player) + foreach_move(p) + if(board_get(r + p[0], c + p[1]) == C_EMPTY) + return 1; + + return 0; +} + +void board_copy(int* data) +{ + rbmemcpy(board_p, data, board_w*board_h*sizeof(int)); +} + +void board_rand(void) +{ + int i; + int r = rbrand(); + bset_t set = bsets[r % bset_count]; + board_init(set.data[0], set.data[1]); + for(i = 2; i < set.len; i += 2) + board_set(set.data[i], set.data[i+1], C_OBST); +} + +void board_init(int w, int h) +{ + int r, c; + + if(w > 0 && h > 0 && w*h <= BOARD_MAX_SIZE) { + board_p = board; + board_w = w; + board_h = h; + foreach_cell(r, c) + board_set(r, c, C_EMPTY); + board_reset(); + } +} + +void board_reset(void) +{ + tag_c = -1; + tag_r = -1; + cur_player = P_WHITE; + + board_set( 0, 0, C_WHITE); + board_set(board_w-1, board_h-1, C_WHITE); + board_set(board_w-1, 0, C_BLACK); + board_set( 0, board_h-1, C_BLACK); +} + +/* this is "button press" over cur_r, cur_c */ +int board_act(void) +{ + if(tag_r < 0) { + if(board_get(cur_r, cur_c) == cur_player) { + tag_r = cur_r; + tag_c = cur_c; + }; + } else { + if(board_get(cur_r, cur_c) == cur_player) { + // tag another piece + tag_r = cur_r; + tag_c = cur_c; + } else if(!board_make_move(tag_r, tag_c, cur_r, cur_c, cur_player)) { + // incorrect move - do nothing + return 0; + } else { + // move done, reset tag + tag_r = -1; + tag_c = -1; + cur_player = other(cur_player); + return 1; + } + } + return 0; +} + +void board_move_cursor(int dr, int dc) +{ + cur_r = (board_h + cur_r + dr) % board_h; + cur_c = (board_w + cur_c + dc) % board_w; +} + +void board_clean(void) +{ + int r, c; + + foreach_cell(r, c) + if(board_get(r, c) != C_OBST) + board_set(r, c, C_EMPTY); + + board_reset(); +} + +void board_place_cursor_for(int player) +{ + if(player == P_BLACK) { + cur_r = board_w - 1; + cur_c = 0; + } else { + cur_r = 0; + cur_c = 0; + } +} Index: apps/plugins/rattax/board.h =================================================================== --- apps/plugins/rattax/board.h (revision 0) +++ apps/plugins/rattax/board.h (revision 0) @@ -0,0 +1,107 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#define C_EMPTY 0 +#define C_BLACK 1 +#define C_WHITE 2 +#define C_OBST 3 +#define C_MARK 4 // marks are used internally by bot + +#define P_BLACK C_BLACK +#define P_WHITE C_WHITE +#define P_GEND 5 // game end, no current player + +#define BOARD_MAX_SIZE 7*7 + +/* game UI state */ +extern int cur_r, cur_c; +extern int tag_r, tag_c; +extern int cur_player; + +/* internal "current board" */ +extern int* board_p; +extern int board_w, board_h; + +/* buffer for primary game board */ +extern int board[]; + +/* static lists of possible moves */ +extern int moves[]; +extern int ranges[]; +extern const int moves_size; +extern const int ranges_size; + +// end of array containing flat int pairs +#define eo2(array) (array + array##_size - 2) +// foreach pair in such array +#define foreach2(m,array) for(m = eo2(array); m >= array; m -= 2) + +#define foreach_cell(r, c) for(r = 0; r < board_h; r++) for(c = 0; c < board_w; c++) +#define foreach_range(m) foreach2(m, ranges) +#define foreach_move(m) foreach2(m, moves) + +int other(int player); + +/* get/set "current board" (the on board_{get,set,count,...} work with */ +void board_ptr(int* ptr); +int* board_ptr_get(void); + +void board_set(int r, int c, int obj); +int board_get(int r, int c); + +int board_game_end(void); + +void board_clean(void); +void board_reset(void); +int board_count(int player); +void board_copy(int* data); + +/* make a move from tag(r,c) to cur(r,c) as cur_player, return !0 if move is forbidden */ +int board_make_move(int tr, int tc, int cr, int cc, int cp); +/* change color of pieces affected after move */ +void board_eat_pieces(int r, int c, int player); +/* check whether player has valid moves */ +int has_move(int player); + +void board_rand(void); +void board_init(int w, int h); + +void board_move_cursor(int dr, int dc); +void board_place_cursor_for(int player); + +/* user pressed a button over cur_r, cur_c */ +int board_act(void); +/* make a move from tag(r,c) to cur(r,c) as cur_player, return !0 if move is forbidden */ +int board_make_move(int tr, int tc, int cr, int cc, int cp); +void board_eat_pieces(int r, int c, int player); +/* check whether player has valid moves */ +int has_move(int player); + +#endif Index: apps/plugins/rattax/draw.c =================================================================== --- apps/plugins/rattax/draw.c (revision 0) +++ apps/plugins/rattax/draw.c (revision 0) @@ -0,0 +1,149 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * RAttax - Attax arcade game implementation for Rockbox + * + * Copyright (c) 2008 Alex Suykov + * Inspired by XAttax originally written by + * Steven Gifford + * Jim Zelenka + * Andrew Plotkin + * + * 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "rattax.h" +#include "board.h" +#include "draw.h" +#include "util.h" + +#include "pluginbitmaps/rattax_cells.h" + +#define TILE_W BMPWIDTH_rattax_cells +#define TILE_H TILE_W + +int xofs = 0; +int yofs = 0; +int screen_w = -1; +int screen_h = -1; +int xend = -1; +int yend = -1; + +#define BMP_EMPTY 0 +#define BMP_OBST 2 +#define BMP_BLACK 4 +#define BMP_WHITE 7 + +void draw_board_init(void) +{ + struct screen* display = rb->screens[0]; + + if(screen_w < 0) + screen_w = display->getwidth(); + if(screen_h < 0) + screen_h = display->getheight(); + + xofs = (screen_w/2 - board_w*TILE_W/2); + yofs = (screen_h/2 - board_h*TILE_H/2); + xend = xofs + board_w*TILE_W; + yend = yofs + board_h*TILE_H; + +#if LCD_DEPTH > 1 + rb->lcd_set_backdrop(NULL); + rb->lcd_set_foreground(LCD_WHITE); + rb->lcd_set_background(LCD_BLACK); +#endif +} + +static int cell_bitmap_id(int r, int c) +{ + int val = board_get(r, c); + int cur; + int tag; + + cur = (r == cur_r && c == cur_c) ? 1 : 0; + tag = (r == tag_r && c == tag_c) ? 2 : 0; + + switch(val) { + case C_EMPTY: + return BMP_EMPTY + cur; + case C_OBST: + return BMP_OBST + cur; + case C_BLACK: + return tag ? BMP_BLACK + tag : BMP_BLACK + cur; + case C_WHITE: + return tag ? BMP_WHITE + tag : BMP_WHITE + cur; + default: + return BMP_EMPTY; + } +} + +#define CNT_BUF_SIZE 5 + +void draw_counters(void) +{ + int twb, thb; + int tww, thw; + char bufb[CNT_BUF_SIZE]; + char bufw[CNT_BUF_SIZE]; + int xw, yw, xb, yb; + + rb->snprintf(bufw, sizeof(bufw), "%d", board_count(C_WHITE)); + rb->lcd_getstringsize(bufw, &tww, &thw); + rb->snprintf(bufb, sizeof(bufb), "%d", board_count(C_BLACK)); + rb->lcd_getstringsize(bufb, &twb, &thb); + + if(yofs > thb + TILE_H/2) { + xw = xofs; yw = yofs - 1 - thw - TILE_H/2; + xb = xend - twb; yb = yofs - 1 - thb - TILE_H/2; + } else if(xofs > tww + TILE_W/2) { + xw = xofs - 1 - TILE_W/2 - tww; yw = yofs + TILE_H; + xb = xend + 1 + TILE_W/2; yb = yofs + TILE_H; + } else { + return; + } + + rb->lcd_putsxy(xw, yw, bufw); + rb->lcd_putsxy(xb, yb, bufb); + + if(cur_player == C_BLACK) + rb->lcd_hline(xb, xb + twb, yb + thb); + else if(cur_player == C_WHITE) + rb->lcd_hline(xw, xw + tww, yw + thw); +} + +void draw_whole_board(void) +{ + int r, c; + + rb->lcd_clear_display(); + rb->lcd_set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID); + rb->lcd_fillrect(0, 0, LCD_WIDTH, LCD_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); + rb->lcd_drawrect(xofs-1, yofs-1, board_w*TILE_W+2, board_h*TILE_H+2); + foreach_cell(r, c) + rb->lcd_bitmap_part(rattax_cells, + 0, TILE_H*cell_bitmap_id(r, c), + TILE_W, + xofs + c*TILE_W, + yofs + r*TILE_H, + TILE_W, + TILE_H + ); + + draw_counters(); + rb->lcd_update(); +} Index: apps/plugins/SUBDIRS =================================================================== --- apps/plugins/SUBDIRS (revision 19266) +++ apps/plugins/SUBDIRS (working copy) @@ -20,6 +20,7 @@ jpeg sudoku reversi +rattax #ifndef OLYMPUS_MROBE_500 zxbox #endif