mirror of
https://github.com/libretro/mrboom-libretro.git
synced 2024-11-30 11:50:27 +00:00
Updating with new uncrustify.cfg
This commit is contained in:
parent
d35f547152
commit
3b67587df6
113
Assets/uncrustify.cfg
Normal file
113
Assets/uncrustify.cfg
Normal file
@ -0,0 +1,113 @@
|
||||
|
||||
#
|
||||
# My favorite format
|
||||
#
|
||||
|
||||
newlines = LF # AUTO (default), CRLF, CR, or LF
|
||||
|
||||
indent_with_tabs = 0 # 1=indent to level only, 2=indent with tabs
|
||||
input_tab_size = 8 # original tab size
|
||||
output_tab_size = 3 # new tab size
|
||||
indent_columns = output_tab_size
|
||||
# indent_label = 0 # pos: absolute col, neg: relative column
|
||||
indent_align_string = False # align broken strings
|
||||
indent_brace = 0
|
||||
indent_class = true
|
||||
|
||||
nl_start_of_file = remove
|
||||
# nl_start_of_file_min = 0
|
||||
nl_end_of_file = force
|
||||
nl_end_of_file_min = 1
|
||||
nl_max = 4
|
||||
nl_before_block_comment = 2
|
||||
nl_after_func_body = 2
|
||||
nl_after_func_proto_group = 2
|
||||
|
||||
nl_assign_brace = add # "= {" vs "= \n {"
|
||||
nl_enum_brace = add # "enum {" vs "enum \n {"
|
||||
nl_union_brace = add # "union {" vs "union \n {"
|
||||
nl_struct_brace = add # "struct {" vs "struct \n {"
|
||||
nl_do_brace = add # "do {" vs "do \n {"
|
||||
nl_if_brace = add # "if () {" vs "if () \n {"
|
||||
nl_for_brace = add # "for () {" vs "for () \n {"
|
||||
nl_else_brace = add # "else {" vs "else \n {"
|
||||
nl_while_brace = add # "while () {" vs "while () \n {"
|
||||
nl_switch_brace = add # "switch () {" vs "switch () \n {"
|
||||
nl_func_var_def_blk = 1
|
||||
nl_before_case = 1
|
||||
nl_fcall_brace = add # "foo() {" vs "foo()\n{"
|
||||
nl_fdef_brace = add # "int foo() {" vs "int foo()\n{"
|
||||
nl_after_return = TRUE
|
||||
nl_brace_while = remove
|
||||
nl_brace_else = add
|
||||
nl_squeeze_ifdef = TRUE
|
||||
|
||||
pos_bool = trail # BOOL ops on trailing end
|
||||
|
||||
eat_blanks_before_close_brace = TRUE
|
||||
eat_blanks_after_open_brace = TRUE
|
||||
|
||||
|
||||
mod_paren_on_return = add # "return 1;" vs "return (1);"
|
||||
mod_full_brace_if = add # "if (a) a--;" vs "if (a) { a--; }"
|
||||
mod_full_brace_for = add # "for () a--;" vs "for () { a--; }"
|
||||
mod_full_brace_do = add # "do a--; while ();" vs "do { a--; } while ();"
|
||||
mod_full_brace_while = add # "while (a) a--;" vs "while (a) { a--; }"
|
||||
|
||||
sp_before_byref = remove
|
||||
sp_before_semi = remove
|
||||
sp_paren_paren = remove # space between (( and ))
|
||||
sp_return_paren = remove # "return (1);" vs "return(1);"
|
||||
sp_sizeof_paren = remove # "sizeof (int)" vs "sizeof(int)"
|
||||
sp_before_sparen = force # "if (" vs "if("
|
||||
sp_after_sparen = force # "if () {" vs "if (){"
|
||||
sp_after_cast = remove # "(int) a" vs "(int)a"
|
||||
sp_inside_braces = force # "{ 1 }" vs "{1}"
|
||||
sp_inside_braces_struct = force # "{ 1 }" vs "{1}"
|
||||
sp_inside_braces_enum = force # "{ 1 }" vs "{1}"
|
||||
sp_inside_paren = remove
|
||||
sp_inside_fparen = remove
|
||||
sp_inside_sparen = remove
|
||||
sp_inside_square = remove
|
||||
#sp_type_func = ignore
|
||||
sp_assign = force
|
||||
sp_arith = force
|
||||
sp_bool = force
|
||||
sp_compare = force
|
||||
sp_assign = force
|
||||
sp_after_comma = force
|
||||
sp_func_def_paren = remove # "int foo (){" vs "int foo(){"
|
||||
sp_func_call_paren = remove # "foo (" vs "foo("
|
||||
sp_func_proto_paren = remove # "int foo ();" vs "int foo();"
|
||||
sp_func_class_paren = remove
|
||||
sp_before_angle = force
|
||||
sp_after_angle = force
|
||||
sp_inside_angle = remove
|
||||
sp_sparen_brace = add
|
||||
sp_fparen_brace = add
|
||||
sp_after_ptr_star = remove
|
||||
sp_before_ptr_star = force
|
||||
sp_between_ptr_star = remove
|
||||
|
||||
align_with_tabs = FALSE # use tabs to align
|
||||
align_on_tabstop = FALSE # align on tabstops
|
||||
align_enum_equ_span = 4
|
||||
align_nl_cont = TRUE
|
||||
align_var_def_span = 1
|
||||
align_var_def_thresh = 12
|
||||
align_var_def_inline = TRUE
|
||||
#align_var_def_star = TRUE
|
||||
align_var_def_colon = TRUE
|
||||
align_assign_span = 1
|
||||
align_assign_thresh = 12
|
||||
align_struct_init_span = 3
|
||||
align_var_struct_span = 99
|
||||
align_right_cmt_span = 3
|
||||
align_pp_define_span = 3
|
||||
align_pp_define_gap = 4
|
||||
align_number_right = TRUE
|
||||
align_typedef_span = 5
|
||||
align_typedef_gap = 3
|
||||
|
||||
cmt_star_cont = TRUE
|
||||
|
317
ai/Bot.cpp
317
ai/Bot.cpp
@ -6,16 +6,20 @@
|
||||
|
||||
#define IFTRACES ((debugTracesPlayer(_playerIndex)) && (traceMask & DEBUG_MASK_GRIDS))
|
||||
|
||||
Bot::Bot(int playerIndex) {
|
||||
Bot::Bot(int playerIndex)
|
||||
{
|
||||
_playerIndex = playerIndex;
|
||||
initBot();
|
||||
}
|
||||
|
||||
void Bot::initBot() {
|
||||
void Bot::initBot()
|
||||
{
|
||||
calculatedBestCellToDropABomb = 0;
|
||||
calculatedBestCellToPickUpBonus = 0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
bestExplosionsGrid[i][j] = 0;
|
||||
noDangerGrid[i][j] = false;
|
||||
}
|
||||
@ -25,35 +29,55 @@ void Bot::initBot() {
|
||||
_shiveringCounter = 0;
|
||||
}
|
||||
|
||||
bool Bot::cellSafe(int cell) {
|
||||
bool Bot::cellSafe(int cell)
|
||||
{
|
||||
int cellX = CELLX(cell);
|
||||
int cellY = CELLY(cell);
|
||||
|
||||
return(!dangerGrid[cellX][cellY] && !flameGrid[cellX][cellY]);
|
||||
}
|
||||
|
||||
int Bot::bestBonusCell() {
|
||||
if (!isAboutToWin() && travelGrid.cost(calculatedBestCellToPickUpBonus)!=TRAVELCOST_CANTGO
|
||||
&& cellSafe(calculatedBestCellToPickUpBonus))
|
||||
int Bot::bestBonusCell()
|
||||
{
|
||||
return calculatedBestCellToPickUpBonus;
|
||||
} else {
|
||||
return -1;
|
||||
if (!isAboutToWin() && travelGrid.cost(calculatedBestCellToPickUpBonus) != TRAVELCOST_CANTGO &&
|
||||
cellSafe(calculatedBestCellToPickUpBonus))
|
||||
{
|
||||
return(calculatedBestCellToPickUpBonus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int Bot::scoreForBonus(Bonus bonus,int x,int y) {
|
||||
if (!bonusPlayerWouldLike(_playerIndex,bonus)) {
|
||||
if (((bonus==bonus_remote) || (bonus==bonus_egg) || (bonus==bonus_roller)) && (isPlayerFastestToCell(_playerIndex,x,y))) {
|
||||
if (isSameTeamTwoFastestToCell(x,y)) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("%d we are the fastest 2 to bonus %d (%d/%d) ignoring\n",_playerIndex,bonus,x,y);
|
||||
return 0;
|
||||
} else {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("%d should pick bonus %d (%d/%d) for safety reason\n",_playerIndex,bonus,x,y);
|
||||
int Bot::scoreForBonus(Bonus bonus, int x, int y)
|
||||
{
|
||||
if (!bonusPlayerWouldLike(_playerIndex, bonus))
|
||||
{
|
||||
if (((bonus == bonus_remote) || (bonus == bonus_egg) || (bonus == bonus_roller)) && (isPlayerFastestToCell(_playerIndex, x, y)))
|
||||
{
|
||||
if (isSameTeamTwoFastestToCell(x, y))
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("%d we are the fastest 2 to bonus %d (%d/%d) ignoring\n", _playerIndex, bonus, x, y);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("%d should pick bonus %d (%d/%d) for safety reason\n", _playerIndex, bonus, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int distance = travelSafeGrid.cost(x, y);
|
||||
if (distance==TRAVELCOST_CANTGO) return 0;
|
||||
if (distance == TRAVELCOST_CANTGO)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
switch (bonus)
|
||||
{
|
||||
case bonus_push:
|
||||
@ -61,33 +85,45 @@ int Bot::scoreForBonus(Bonus bonus,int x,int y) {
|
||||
case bonus_bulletproofjacket:
|
||||
distance /= 4;
|
||||
break;
|
||||
|
||||
case bonus_egg:
|
||||
case bonus_heart:
|
||||
case bonus_roller:
|
||||
distance /= 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (distance<100) {
|
||||
if (distance < 100)
|
||||
{
|
||||
return(TRAVELCOST_CANTGO - distance);
|
||||
} else {
|
||||
if (isPlayerFastestToCell(_playerIndex,x,y)) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isPlayerFastestToCell(_playerIndex, x, y))
|
||||
{
|
||||
return(TRAVELCOST_CANTGO - distance);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint8_t Bot::calculateBestCellToPickUpBonus() {
|
||||
uint8_t Bot::calculateBestCellToPickUpBonus()
|
||||
{
|
||||
int bestCell = -1;
|
||||
int bestScore = 0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
Bonus bonus = bonusInCell(i, j);
|
||||
if (bonus!=no_bonus) {
|
||||
if (bonus != no_bonus)
|
||||
{
|
||||
int score = scoreForBonus(bonus, i, j);
|
||||
if (score>bestScore) {
|
||||
if (score > bestScore)
|
||||
{
|
||||
int cellIndex = CELLINDEX(i, j);
|
||||
bestCell = cellIndex;
|
||||
bestScore = score;
|
||||
@ -95,46 +131,62 @@ uint8_t Bot::calculateBestCellToPickUpBonus() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/calculateBestCellToPickUpBonus: %d/%d:bestCell=%d bestScore=%d\n",frameNumber(),_playerIndex,bestCell,bestScore);
|
||||
return bestCell;
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/calculateBestCellToPickUpBonus: %d/%d:bestCell=%d bestScore=%d\n", frameNumber(), _playerIndex, bestCell, bestScore);
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
|
||||
|
||||
int noise(int player,int x,int y) {
|
||||
return (x+player+y)%nb_dyna;
|
||||
int noise(int player, int x, int y)
|
||||
{
|
||||
return((x + player + y) % nb_dyna);
|
||||
}
|
||||
|
||||
|
||||
int Bot::bestCellToDropABomb() {
|
||||
int Bot::bestCellToDropABomb()
|
||||
{
|
||||
int bestCell = -1;
|
||||
int bestScore = 0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
int score = bestExplosionsGrid[i][j] * 128;
|
||||
if (score) score+=noise(_playerIndex,i,j);
|
||||
if (score)
|
||||
{
|
||||
score += noise(_playerIndex, i, j);
|
||||
}
|
||||
int travelCost = 1 + travelGrid.cost(i, j) / 16;
|
||||
if (score>travelCost) {
|
||||
if (score > travelCost)
|
||||
{
|
||||
score = score / travelCost;
|
||||
}
|
||||
|
||||
if (score>bestScore) {
|
||||
if (score > bestScore)
|
||||
{
|
||||
bestCell = CELLINDEX(i, j);
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestCell;
|
||||
return(bestCell);
|
||||
}
|
||||
|
||||
int Bot::bestSafeCell() {
|
||||
int Bot::bestSafeCell()
|
||||
{
|
||||
int bestCell = cellPlayer(_playerIndex);
|
||||
int bestScore = 0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
if (!somethingThatIsNoTABombAndThatWouldStopPlayer(i,j)) {
|
||||
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
if (!somethingThatIsNoTABombAndThatWouldStopPlayer(i, j))
|
||||
{
|
||||
int score = TRAVELCOST_CANTGO - travelGrid.cost(i, j);
|
||||
if ((score>bestScore) && cellSafe(CELLINDEX(i,j))) {
|
||||
if ((score > bestScore) && cellSafe(CELLINDEX(i, j)))
|
||||
{
|
||||
int cellIndex = CELLINDEX(i, j);
|
||||
bestCell = cellIndex;
|
||||
bestScore = score;
|
||||
@ -142,57 +194,78 @@ int Bot::bestSafeCell() {
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestCell;
|
||||
return(bestCell);
|
||||
}
|
||||
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
|
||||
|
||||
|
||||
bool Bot::isSomewhatInTheMiddleOfCell() {
|
||||
bool Bot::isSomewhatInTheMiddleOfCell()
|
||||
{
|
||||
int x = GETXPIXELSTOCENTEROFCELL(_playerIndex);
|
||||
int y = GETYPIXELSTOCENTEROFCELL(_playerIndex);
|
||||
|
||||
return((x > -MAX_PIXELS_PER_FRAME / 2) && (x < MAX_PIXELS_PER_FRAME / 2) && (y < MAX_PIXELS_PER_FRAME / 2) && (y > -MAX_PIXELS_PER_FRAME / 2));
|
||||
}
|
||||
|
||||
bool Bot::amISafe() {
|
||||
return cellSafe(cellPlayer(_playerIndex));
|
||||
bool Bot::amISafe()
|
||||
{
|
||||
return(cellSafe(cellPlayer(_playerIndex)));
|
||||
}
|
||||
|
||||
bool Bot::isThereABombUnderMe() {
|
||||
bool Bot::isThereABombUnderMe()
|
||||
{
|
||||
int x = xPlayer(_playerIndex);
|
||||
int y = yPlayer(_playerIndex);
|
||||
return bombInCell(x,y);
|
||||
|
||||
return(bombInCell(x, y));
|
||||
}
|
||||
|
||||
int Bot::howManyBombsLeft() {
|
||||
return nbBombsLeft(_playerIndex);
|
||||
int Bot::howManyBombsLeft()
|
||||
{
|
||||
return(nbBombsLeft(_playerIndex));
|
||||
}
|
||||
|
||||
void Bot::printGrid()
|
||||
{
|
||||
if (IFTRACES) {
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
if (IFTRACES)
|
||||
{
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
db brickKind = m.truc[i + j * grid_size_x_with_padding];
|
||||
if (monsterInCell(i,j) || playerInCell(i,j)) {
|
||||
if (monsterInCell(i,j)) {
|
||||
if (monsterInCell(i, j) || playerInCell(i, j))
|
||||
{
|
||||
if (monsterInCell(i, j))
|
||||
{
|
||||
log_debug(" 8( ");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug(" 8) ");
|
||||
}
|
||||
} else {
|
||||
switch (brickKind) {
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (brickKind)
|
||||
{
|
||||
case 1:
|
||||
log_debug("[======]");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
log_debug("(******)");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (no_bonus!=bonusInCell(i,j)) {
|
||||
if (no_bonus != bonusInCell(i, j))
|
||||
{
|
||||
log_debug(" (%d) ", bonusInCell(i, j));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug(" ");
|
||||
}
|
||||
break;
|
||||
@ -202,12 +275,17 @@ void Bot::printGrid()
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("bestExplosionsGrid player %d\n", _playerIndex);
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
log_debug("%04d", bestExplosionsGrid[i][j]);
|
||||
if (dangerGrid[i][j]) {
|
||||
if (dangerGrid[i][j])
|
||||
{
|
||||
log_debug("x");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("_");
|
||||
}
|
||||
}
|
||||
@ -221,8 +299,10 @@ void Bot::printGrid()
|
||||
travelSafeGrid.print();
|
||||
|
||||
log_debug("%d flameGrid player %d\n", m.changement, _playerIndex);
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
log_debug("%04d ", flameGrid[i][j]);
|
||||
}
|
||||
log_debug("\n");
|
||||
@ -231,68 +311,84 @@ void Bot::printGrid()
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::stopWalking() {
|
||||
void Bot::stopWalking()
|
||||
{
|
||||
mrboom_update_input(button_up, _playerIndex, 0, true);
|
||||
mrboom_update_input(button_down, _playerIndex, 0, true);
|
||||
mrboom_update_input(button_left, _playerIndex, 0, true);
|
||||
mrboom_update_input(button_right, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
void Bot::startPushingRemoteButton() {
|
||||
void Bot::startPushingRemoteButton()
|
||||
{
|
||||
mrboom_update_input(button_a, _playerIndex, 1, true);
|
||||
}
|
||||
|
||||
void Bot::stopPushingRemoteButton() {
|
||||
void Bot::stopPushingRemoteButton()
|
||||
{
|
||||
mrboom_update_input(button_a, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
void Bot::startPushingJumpButton() {
|
||||
void Bot::startPushingJumpButton()
|
||||
{
|
||||
mrboom_update_input(button_x, _playerIndex, 1, true);
|
||||
}
|
||||
|
||||
void Bot::stopPushingJumpButton() {
|
||||
void Bot::stopPushingJumpButton()
|
||||
{
|
||||
mrboom_update_input(button_x, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
void Bot::startPushingBombDropButton() {
|
||||
void Bot::startPushingBombDropButton()
|
||||
{
|
||||
pushingDropBombButton = true;
|
||||
mrboom_update_input(button_b, _playerIndex, 1, true);
|
||||
}
|
||||
|
||||
void Bot::stopPushingBombDropButton() {
|
||||
void Bot::stopPushingBombDropButton()
|
||||
{
|
||||
pushingDropBombButton = false;
|
||||
mrboom_update_input(button_b, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int howToGoDebug;
|
||||
#endif
|
||||
bool Bot::walkToCell(int cell) {
|
||||
bool Bot::walkToCell(int cell)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
howToGoDebug = 0;
|
||||
#endif
|
||||
bool shouldJump = false;
|
||||
enum Button direction = howToGo(_playerIndex, CELLX(cell), CELLY(cell), travelSafeGrid, shouldJump);
|
||||
if (direction==button_error) {
|
||||
if (direction == button_error)
|
||||
{
|
||||
direction = howToGo(_playerIndex, CELLX(cell), CELLY(cell), travelGrid, shouldJump);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
walkingToCell[_playerIndex] = cell;
|
||||
if (tracesDecisions(_playerIndex)) {
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
char *directionText = (char *)"?";
|
||||
switch (direction) {
|
||||
switch (direction)
|
||||
{
|
||||
case button_up:
|
||||
directionText = (char *)"button_up";
|
||||
break;
|
||||
|
||||
case button_down:
|
||||
directionText = (char *)"button_down";
|
||||
break;
|
||||
|
||||
case button_left:
|
||||
directionText = (char *)"button_left";
|
||||
break;
|
||||
|
||||
case button_right:
|
||||
directionText = (char *)"button_right";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -301,24 +397,31 @@ bool Bot::walkToCell(int cell) {
|
||||
#endif
|
||||
stopWalking();
|
||||
|
||||
if (shouldJump) {
|
||||
if (shouldJump)
|
||||
{
|
||||
startPushingJumpButton();
|
||||
}
|
||||
|
||||
if (hasInvertedDisease(_playerIndex)) {
|
||||
switch (direction) {
|
||||
if (hasInvertedDisease(_playerIndex))
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case button_up:
|
||||
direction = button_down;
|
||||
break;
|
||||
|
||||
case button_down:
|
||||
direction = button_up;
|
||||
break;
|
||||
|
||||
case button_left:
|
||||
direction = button_right;
|
||||
break;
|
||||
|
||||
case button_right:
|
||||
direction = button_left;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -327,21 +430,36 @@ bool Bot::walkToCell(int cell) {
|
||||
mrboom_update_input(direction, _playerIndex, 1, true);
|
||||
|
||||
#define MAX_SHIVERING 3
|
||||
if ((_direction2FramesAgo==direction) && (_direction1FrameAgo!=direction)) {
|
||||
if ((_direction2FramesAgo == direction) && (_direction1FrameAgo != direction))
|
||||
{
|
||||
_shiveringCounter++;
|
||||
if (_shiveringCounter>=MAX_SHIVERING) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingBombDropButton\n",frameNumber(),_playerIndex);
|
||||
if (_shiveringCounter >= MAX_SHIVERING)
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingBombDropButton\n", frameNumber(), _playerIndex);
|
||||
}
|
||||
startPushingBombDropButton();
|
||||
}
|
||||
if (_shiveringCounter>=MAX_SHIVERING*2) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingJumpButton\n",frameNumber(),_playerIndex);
|
||||
if (_shiveringCounter >= MAX_SHIVERING * 2)
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingJumpButton\n", frameNumber(), _playerIndex);
|
||||
}
|
||||
startPushingJumpButton();
|
||||
}
|
||||
if (_shiveringCounter>=MAX_SHIVERING*3) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingRemoteButton\n",frameNumber(),_playerIndex);
|
||||
if (_shiveringCounter >= MAX_SHIVERING * 3)
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingRemoteButton\n", frameNumber(), _playerIndex);
|
||||
}
|
||||
startPushingRemoteButton();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_shiveringCounter = 0;
|
||||
}
|
||||
_direction2FramesAgo = _direction1FrameAgo;
|
||||
@ -350,16 +468,15 @@ bool Bot::walkToCell(int cell) {
|
||||
return(direction != button_error);
|
||||
}
|
||||
|
||||
int Bot::getCurrentCell() {
|
||||
int Bot::getCurrentCell()
|
||||
{
|
||||
int x = xPlayer(_playerIndex);
|
||||
int y = yPlayer(_playerIndex);
|
||||
return CELLINDEX(x,y);
|
||||
|
||||
return(CELLINDEX(x, y));
|
||||
}
|
||||
|
||||
void Bot::printCellInfo(int cell) {
|
||||
void Bot::printCellInfo(int cell)
|
||||
{
|
||||
log_debug("printCellInfoBot Cell:%d Bot:%d: travelCostGrid=%d bestExplosionsGrid=%d flameGrid=%d dangerGrid=%d\n", cell, _playerIndex, travelGrid.cost(cell), bestExplosionsGrid[CELLX(cell)][CELLY(cell)], flameGrid[CELLX(cell)][CELLY(cell)], dangerGrid[CELLX(cell)][CELLY(cell)]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@ int howManyBombsLeft();
|
||||
uint8_t calculateBestCellToPickUpBonus();
|
||||
bool cellSafe(int cell);
|
||||
int scoreForBonus(Bonus bonus, int x, int y);
|
||||
|
||||
int _playerIndex;
|
||||
uint8_t _direction1FrameAgo;
|
||||
uint8_t _direction2FramesAgo;
|
||||
|
173
ai/BotTree.cpp
173
ai/BotTree.cpp
@ -3,24 +3,34 @@
|
||||
#include "BotTree.hpp"
|
||||
|
||||
#ifdef IOS
|
||||
void std::__throw_out_of_range(char const*) {
|
||||
void std::__throw_out_of_range(char const *)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
class ConditionNode : public bt::Node
|
||||
{
|
||||
public:
|
||||
ConditionNode(Bot * bot) : Node(), bot(bot) {
|
||||
ConditionNode(Bot *bot) : Node(), bot(bot)
|
||||
{
|
||||
}
|
||||
void Initialize() {
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Condition() = 0;
|
||||
|
||||
bt::Status Update()
|
||||
{
|
||||
if (Condition())
|
||||
return bt::Success;
|
||||
return bt::Failure;
|
||||
{
|
||||
return(bt::Success);
|
||||
}
|
||||
return(bt::Failure);
|
||||
}
|
||||
|
||||
protected:
|
||||
Bot *bot;
|
||||
};
|
||||
@ -28,33 +38,50 @@ Bot * bot;
|
||||
class MoveToNode : public bt::Node
|
||||
{
|
||||
public:
|
||||
MoveToNode(Bot * bot) : Node(), bot(bot) {
|
||||
MoveToNode(Bot *bot) : Node(), bot(bot)
|
||||
{
|
||||
}
|
||||
void Initialize() {
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual int Cell() = 0;
|
||||
|
||||
bt::Status Update()
|
||||
{
|
||||
int cell = Cell();
|
||||
if (cell==-1) {
|
||||
if (isInMiddleOfCell(bot->_playerIndex)) {
|
||||
|
||||
if (cell == -1)
|
||||
{
|
||||
if (isInMiddleOfCell(bot->_playerIndex))
|
||||
{
|
||||
bot->stopWalking();
|
||||
}
|
||||
return bt::Failure;
|
||||
return(bt::Failure);
|
||||
}
|
||||
|
||||
if (((!(isInMiddleOfCell(bot->_playerIndex) && bot->getCurrentCell() == cell))) || (bot->getCurrentCell() != cell))
|
||||
{
|
||||
if (bot->walkToCell(cell))
|
||||
return bt::Running;
|
||||
{
|
||||
return(bt::Running);
|
||||
}
|
||||
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:Failed to go to %d (%d/%d)\n",frameNumber(),bot->_playerIndex,cell,CELLX(cell),CELLY(cell));
|
||||
return bt::Failure;
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:Failed to go to %d (%d/%d)\n", frameNumber(), bot->_playerIndex, cell, CELLX(cell), CELLY(cell));
|
||||
}
|
||||
return(bt::Failure);
|
||||
}
|
||||
bot->stopWalking();
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:stopWalking arrived in %d (%d/%d)\n",frameNumber(),bot->_playerIndex,cell,CELLX(cell),CELLY(cell));
|
||||
return bt::Success;
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:stopWalking arrived in %d (%d/%d)\n", frameNumber(), bot->_playerIndex, cell, CELLX(cell), CELLY(cell));
|
||||
}
|
||||
return(bt::Success);
|
||||
}
|
||||
|
||||
protected:
|
||||
Bot *bot;
|
||||
};
|
||||
@ -62,73 +89,105 @@ Bot * bot;
|
||||
class MoveToBonus : public MoveToNode
|
||||
{
|
||||
public:
|
||||
MoveToBonus(Bot * bot) : MoveToNode(bot) {
|
||||
MoveToBonus(Bot *bot) : MoveToNode(bot)
|
||||
{
|
||||
}
|
||||
int Cell() {
|
||||
|
||||
int Cell()
|
||||
{
|
||||
int bestCell = bot->bestBonusCell();
|
||||
|
||||
#ifdef DEBUG
|
||||
botStates[bot->_playerIndex] = goingBonus;
|
||||
#endif
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBonus:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
|
||||
return bestCell;
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:gotoBonus:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
};
|
||||
|
||||
class MoveToBombBestBombCell : public MoveToNode
|
||||
{
|
||||
public:
|
||||
MoveToBombBestBombCell(Bot * bot) : MoveToNode(bot) {
|
||||
MoveToBombBestBombCell(Bot *bot) : MoveToNode(bot)
|
||||
{
|
||||
}
|
||||
int Cell() {
|
||||
|
||||
int Cell()
|
||||
{
|
||||
int bestCell = bot->bestCellToDropABomb();
|
||||
|
||||
#ifdef DEBUG
|
||||
botStates[bot->_playerIndex] = goingBomb;
|
||||
#endif
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBestBombCell:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
|
||||
return bestCell;
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:gotoBestBombCell:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
};
|
||||
|
||||
class MoveToSafeCell : public MoveToNode
|
||||
{
|
||||
public:
|
||||
MoveToSafeCell(Bot * bot) : MoveToNode(bot) {
|
||||
MoveToSafeCell(Bot *bot) : MoveToNode(bot)
|
||||
{
|
||||
}
|
||||
int Cell() {
|
||||
|
||||
int Cell()
|
||||
{
|
||||
int bestCell = bot->bestSafeCell();
|
||||
|
||||
#ifdef DEBUG
|
||||
botStates[bot->_playerIndex] = goingSafe;
|
||||
#endif
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBestSafeCell:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
|
||||
return bestCell;
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:gotoBestSafeCell:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
};
|
||||
|
||||
class ConditionBombsLeft : public ConditionNode
|
||||
{
|
||||
public:
|
||||
ConditionBombsLeft(Bot * bot) : ConditionNode(bot) {
|
||||
}
|
||||
bool Condition() {
|
||||
// condition "i have more bombs"
|
||||
int howManyBombs=bot->howManyBombsLeft();
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:bombLeft:%d\n",frameNumber(),bot->_playerIndex,howManyBombs);
|
||||
return (howManyBombs);
|
||||
ConditionBombsLeft(Bot *bot) : ConditionNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
bool Condition()
|
||||
{
|
||||
// condition "i have more bombs"
|
||||
int howManyBombs = bot->howManyBombsLeft();
|
||||
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:bombLeft:%d\n", frameNumber(), bot->_playerIndex, howManyBombs);
|
||||
}
|
||||
return(howManyBombs);
|
||||
}
|
||||
};
|
||||
|
||||
class ConditionDropBomb : public ConditionNode
|
||||
{
|
||||
public:
|
||||
ConditionDropBomb(Bot * bot) : ConditionNode(bot) {
|
||||
}
|
||||
bool Condition() {
|
||||
bot->startPushingBombDropButton(); //TOFIX ? return false or running ?
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:dropBomb\n",frameNumber(),bot->_playerIndex);
|
||||
return true;
|
||||
ConditionDropBomb(Bot *bot) : ConditionNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
bool Condition()
|
||||
{
|
||||
bot->startPushingBombDropButton(); //TOFIX ? return false or running ?
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:dropBomb\n", frameNumber(), bot->_playerIndex);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
};
|
||||
|
||||
BotTree::BotTree(int playerIndex) : Bot(playerIndex)
|
||||
@ -174,18 +233,21 @@ void BotTree::updateGrids()
|
||||
updateBestExplosionGrid(_playerIndex, bestExplosionsGrid, travelGrid, flameGrid, dangerGrid);
|
||||
}
|
||||
|
||||
|
||||
void BotTree::tick() {
|
||||
void BotTree::tick()
|
||||
{
|
||||
stopPushingRemoteButton();
|
||||
stopPushingBombDropButton();
|
||||
stopPushingJumpButton();
|
||||
tree->Update();
|
||||
if (monsterIsComingGrid[cellPlayer(_playerIndex)]) {
|
||||
if (monsterIsComingGrid[cellPlayer(_playerIndex)])
|
||||
{
|
||||
startPushingBombDropButton();
|
||||
}
|
||||
if (isSomewhatInTheMiddleOfCell() && frameNumber()%2 && pushingDropBombButton==false) {
|
||||
if (isSomewhatInTheMiddleOfCell() && frameNumber() % 2 && pushingDropBombButton == false)
|
||||
{
|
||||
bool cantPlaceMoreBombsAndSafe = (((bestCellToDropABomb() == -1) || (howManyBombsLeft() == 0)) && amISafe());
|
||||
if (cantPlaceMoreBombsAndSafe || shouldActivateRemote(_playerIndex)) {
|
||||
if (cantPlaceMoreBombsAndSafe || shouldActivateRemote(_playerIndex))
|
||||
{
|
||||
startPushingRemoteButton();
|
||||
}
|
||||
}
|
||||
@ -194,16 +256,20 @@ void BotTree::tick() {
|
||||
// filled by serialize...
|
||||
static size_t serializeSize = 0;
|
||||
|
||||
size_t BotTree::serialize_size(void) {
|
||||
if(serializeSize==0) {
|
||||
size_t BotTree::serialize_size(void)
|
||||
{
|
||||
if (serializeSize == 0)
|
||||
{
|
||||
uint8_t tmpBuffer[MEM_STREAM_BUFFER_SIZE];
|
||||
serialize(tmpBuffer);
|
||||
log_error("HARDCODED_RETRO_SERIALIZE_SIZE=SIZE_SER+%d*8\n", serializeSize);
|
||||
}
|
||||
assert(serializeSize != 0);
|
||||
return serializeSize;
|
||||
return(serializeSize);
|
||||
}
|
||||
bool BotTree::serialize(void *data_) {
|
||||
|
||||
bool BotTree::serialize(void *data_)
|
||||
{
|
||||
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
|
||||
static memstream_t *stream = memstream_open(1);
|
||||
assert(stream != NULL);
|
||||
@ -217,9 +283,11 @@ bool BotTree::serialize(void *data_) {
|
||||
serializeSize = memstream_pos(stream);
|
||||
memstream_rewind(stream);
|
||||
memstream_read(stream, data_, serializeSize); // read from the stream
|
||||
return true;
|
||||
return(true);
|
||||
}
|
||||
bool BotTree::unserialize(const void *data_) {
|
||||
|
||||
bool BotTree::unserialize(const void *data_)
|
||||
{
|
||||
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
|
||||
static memstream_t *stream = memstream_open(1);
|
||||
assert(stream != NULL);
|
||||
@ -232,6 +300,5 @@ bool BotTree::unserialize(const void *data_) {
|
||||
memstream_read(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
|
||||
memstream_read(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
|
||||
memstream_read(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
|
||||
return true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ bool serialize(void *data_);
|
||||
bool unserialize(const void *data_);
|
||||
void updateGrids();
|
||||
void tick();
|
||||
|
||||
private:
|
||||
bt::BehaviorTree *tree;
|
||||
uint8_t buffer[MEM_STREAM_BUFFER_SIZE];
|
||||
|
@ -3,10 +3,15 @@
|
||||
#include "common.hpp"
|
||||
#include "MrboomHelper.hpp"
|
||||
#include <algorithm> // std::min
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include "assert.h"
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct bombInfo {
|
||||
typedef struct bombInfo
|
||||
{
|
||||
dd infojoueur;
|
||||
dd countDown;
|
||||
dd offsetCell;
|
||||
@ -16,165 +21,247 @@ typedef struct bombInfo {
|
||||
dw adderY; //+1,0,-1
|
||||
dw offsetX; // 0 = middle
|
||||
dw offsetY;
|
||||
void cell(int cell) {
|
||||
void cell(int cell)
|
||||
{
|
||||
offsetCell = CELLX(cell) + CELLY(cell) * grid_size_x_with_padding;
|
||||
}
|
||||
int x() {
|
||||
return CELLXWITHPADDING(offsetCell);
|
||||
|
||||
int x()
|
||||
{
|
||||
return(CELLXWITHPADDING(offsetCell));
|
||||
};
|
||||
int y() {
|
||||
return CELLYWITHPADDING(offsetCell);
|
||||
int y()
|
||||
{
|
||||
return(CELLYWITHPADDING(offsetCell));
|
||||
};
|
||||
int getPlayer() {
|
||||
int getPlayer()
|
||||
{
|
||||
int bombPlayer = -1; //will return -1 on a end of level 2 bomb.
|
||||
if (offsetof(struct Mem,j1)==infojoueur) bombPlayer=0;
|
||||
if (offsetof(struct Mem,j2)==infojoueur) bombPlayer=1;
|
||||
if (offsetof(struct Mem,j3)==infojoueur) bombPlayer=2;
|
||||
if (offsetof(struct Mem,j4)==infojoueur) bombPlayer=3;
|
||||
if (offsetof(struct Mem,j5)==infojoueur) bombPlayer=4;
|
||||
if (offsetof(struct Mem,j6)==infojoueur) bombPlayer=5;
|
||||
if (offsetof(struct Mem,j7)==infojoueur) bombPlayer=6;
|
||||
if (offsetof(struct Mem,j8)==infojoueur) bombPlayer=7;
|
||||
return bombPlayer;
|
||||
|
||||
if (offsetof(struct Mem, j1) == infojoueur)
|
||||
{
|
||||
bombPlayer = 0;
|
||||
}
|
||||
if (offsetof(struct Mem, j2) == infojoueur)
|
||||
{
|
||||
bombPlayer = 1;
|
||||
}
|
||||
if (offsetof(struct Mem, j3) == infojoueur)
|
||||
{
|
||||
bombPlayer = 2;
|
||||
}
|
||||
if (offsetof(struct Mem, j4) == infojoueur)
|
||||
{
|
||||
bombPlayer = 3;
|
||||
}
|
||||
if (offsetof(struct Mem, j5) == infojoueur)
|
||||
{
|
||||
bombPlayer = 4;
|
||||
}
|
||||
if (offsetof(struct Mem, j6) == infojoueur)
|
||||
{
|
||||
bombPlayer = 5;
|
||||
}
|
||||
if (offsetof(struct Mem, j7) == infojoueur)
|
||||
{
|
||||
bombPlayer = 6;
|
||||
}
|
||||
if (offsetof(struct Mem, j8) == infojoueur)
|
||||
{
|
||||
bombPlayer = 7;
|
||||
}
|
||||
return(bombPlayer);
|
||||
}
|
||||
} bombInfo;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct travelCostGrid {
|
||||
typedef struct travelCostGrid
|
||||
{
|
||||
uint32_t travelCostGrid[grid_size_x][grid_size_y]; // safe to walk walking distance, TRAVELCOST_CANTGO if cant go, -7 to +8 if player is here...
|
||||
uint32_t travelCostGridJumpLeftRight[grid_size_x][grid_size_y];
|
||||
uint32_t travelCostGridJumpUpDown[grid_size_x][grid_size_y];
|
||||
|
||||
uint32_t cost(int i,int j, int direction) const {
|
||||
return std::min(jumpingCost(i,j,direction),travelCostGrid[i][j]); // min: to be able to jump on a flame and come back later using the walking way. (otherwise the comeback breaks the path)
|
||||
uint32_t cost(int i, int j, int direction) const
|
||||
{
|
||||
return(std::min(jumpingCost(i, j, direction), travelCostGrid[i][j])); // min: to be able to jump on a flame and come back later using the walking way. (otherwise the comeback breaks the path)
|
||||
}
|
||||
bool wouldInvolveJumping(int i,int j, int direction) const {
|
||||
|
||||
bool wouldInvolveJumping(int i, int j, int direction) const
|
||||
{
|
||||
return(jumpingCost(i, j, direction) < travelCostGrid[i][j]);
|
||||
}
|
||||
uint32_t cost(int i,int j) const {
|
||||
return travelCostGrid[i][j];
|
||||
|
||||
uint32_t cost(int i, int j) const
|
||||
{
|
||||
return(travelCostGrid[i][j]);
|
||||
}
|
||||
uint32_t cost(int cell) const {
|
||||
return cost(CELLX(cell),CELLY(cell));
|
||||
|
||||
uint32_t cost(int cell) const
|
||||
{
|
||||
return(cost(CELLX(cell), CELLY(cell)));
|
||||
}
|
||||
void setWalkingCost(int cell,uint32_t cost) {
|
||||
|
||||
void setWalkingCost(int cell, uint32_t cost)
|
||||
{
|
||||
travelCostGrid[CELLX(cell)][CELLY(cell)] = cost;
|
||||
}
|
||||
void printCell(int i,int j) {
|
||||
|
||||
void printCell(int i, int j)
|
||||
{
|
||||
int lr = costLeftRight(i, j);
|
||||
int up = costUpDown(i, j);
|
||||
int w = cost(i, j);
|
||||
|
||||
if (TRAVELCOST_CANTGO!=w) {
|
||||
if (TRAVELCOST_CANTGO != w)
|
||||
{
|
||||
log_debug(" %03d ", w);
|
||||
} else {
|
||||
|
||||
if ((lr!=TRAVELCOST_CANTGO) || (up!=TRAVELCOST_CANTGO)) {
|
||||
|
||||
|
||||
if (TRAVELCOST_CANTGO!=lr) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((lr != TRAVELCOST_CANTGO) || (up != TRAVELCOST_CANTGO))
|
||||
{
|
||||
if (TRAVELCOST_CANTGO != lr)
|
||||
{
|
||||
log_debug("%03d/", lr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("---/");
|
||||
}
|
||||
if (TRAVELCOST_CANTGO!=up) {
|
||||
if (TRAVELCOST_CANTGO != up)
|
||||
{
|
||||
log_debug("%03d ", up);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("--- ");
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug(" --- ");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t jumpingCost(int i,int j,int direction) const {
|
||||
switch (direction) {
|
||||
uint32_t jumpingCost(int i, int j, int direction) const
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case button_left:
|
||||
return travelCostGridJumpLeftRight[i][j];
|
||||
return(travelCostGridJumpLeftRight[i][j]);
|
||||
|
||||
break;
|
||||
|
||||
case button_right:
|
||||
return travelCostGridJumpLeftRight[i][j];
|
||||
return(travelCostGridJumpLeftRight[i][j]);
|
||||
|
||||
break;
|
||||
|
||||
case button_up:
|
||||
return travelCostGridJumpUpDown[i][j];
|
||||
return(travelCostGridJumpUpDown[i][j]);
|
||||
|
||||
break;
|
||||
|
||||
case button_down:
|
||||
return travelCostGridJumpUpDown[i][j];
|
||||
return(travelCostGridJumpUpDown[i][j]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
uint32_t jumpingCost(int cell,int direction) const {
|
||||
|
||||
uint32_t jumpingCost(int cell, int direction) const
|
||||
{
|
||||
int i = CELLX(cell);
|
||||
int j = CELLY(cell);
|
||||
return jumpingCost(i,j,direction);
|
||||
}
|
||||
uint32_t costLeftRight(int i,int j) const {
|
||||
return jumpingCost(i,j,button_left);
|
||||
|
||||
return(jumpingCost(i, j, direction));
|
||||
}
|
||||
|
||||
uint32_t costUpDown(int i,int j) const {
|
||||
return jumpingCost(i,j,button_up);
|
||||
uint32_t costLeftRight(int i, int j) const
|
||||
{
|
||||
return(jumpingCost(i, j, button_left));
|
||||
}
|
||||
|
||||
void setJumpingCost(int i,int j,uint32_t cost,int direction) {
|
||||
switch (direction) {
|
||||
uint32_t costUpDown(int i, int j) const
|
||||
{
|
||||
return(jumpingCost(i, j, button_up));
|
||||
}
|
||||
|
||||
void setJumpingCost(int i, int j, uint32_t cost, int direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case button_left:
|
||||
travelCostGridJumpLeftRight[i][j] = cost;
|
||||
break;
|
||||
|
||||
case button_right:
|
||||
travelCostGridJumpLeftRight[i][j] = cost;
|
||||
break;
|
||||
|
||||
case button_up:
|
||||
travelCostGridJumpUpDown[i][j] = cost;
|
||||
break;
|
||||
|
||||
case button_down:
|
||||
travelCostGridJumpUpDown[i][j] = cost;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setJumpingCost(int cell,uint32_t cost,int direction) {
|
||||
void setJumpingCost(int cell, uint32_t cost, int direction)
|
||||
{
|
||||
int i = CELLX(cell);
|
||||
int j = CELLY(cell);
|
||||
return setJumpingCost(i,j,cost,direction);
|
||||
|
||||
return(setJumpingCost(i, j, cost, direction));
|
||||
}
|
||||
|
||||
bool canWalk(int i,int j) const {
|
||||
bool canWalk(int i, int j) const
|
||||
{
|
||||
return(travelCostGrid[i][j] != TRAVELCOST_CANTGO);
|
||||
}
|
||||
bool canWalk(int cell) const {
|
||||
return canWalk(CELLX(cell),CELLY(cell));
|
||||
|
||||
bool canWalk(int cell) const
|
||||
{
|
||||
return(canWalk(CELLX(cell), CELLY(cell)));
|
||||
}
|
||||
void init() {
|
||||
|
||||
void init()
|
||||
{
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
travelCostGrid[i][j] = TRAVELCOST_CANTGO;
|
||||
travelCostGridJumpLeftRight[i][j] = TRAVELCOST_CANTGO;
|
||||
travelCostGridJumpUpDown[i][j] = TRAVELCOST_CANTGO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
void print() {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
void print()
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
log_debug("__%03d__ ", i);
|
||||
}
|
||||
log_debug("\n");
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
printCell(i, j);
|
||||
}
|
||||
log_debug("-%03d-", j);
|
||||
@ -188,8 +275,10 @@ typedef struct travelCostGrid {
|
||||
enum Button howToGo(int player, int toX, int toY, const travelCostGrid& travelGrid, bool&shouldJump);
|
||||
bool isPlayerFastestToCell(int player, int x, int y);
|
||||
bool isSameTeamTwoFastestToCell(int x, int y);
|
||||
|
||||
typedef void (*FunctionWithBombInfo)(struct bombInfo *);
|
||||
void iterateOnBombs(FunctionWithBombInfo f);
|
||||
|
||||
typedef void (*FunctionWithFlameDrawingHelpfulData)(int, int, int, int, uint32_t[grid_size_x][grid_size_y], bool[grid_size_x][grid_size_y], int&);
|
||||
void drawBombFlames(int player, int cell, int flameSize, FunctionWithFlameDrawingHelpfulData f, uint32_t[grid_size_x][grid_size_y], bool[grid_size_x][grid_size_y], int&);
|
||||
void updateBestExplosionGrid(int player, uint32_t bestExplosionsGrid[grid_size_x][grid_size_y], const travelCostGrid& travelGrid, const uint32_t flameGrid[grid_size_x][grid_size_y], const bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
@ -199,54 +288,88 @@ void updateDangerGridWithMonstersSickPlayersAndCulDeSacs(int player, bool danger
|
||||
void updateDangerGridWithMonster4CellsTerritories(bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
|
||||
bool flameInCell(int x, int y);
|
||||
|
||||
Bonus inline bonusInCell(int x, int y)
|
||||
{
|
||||
/*
|
||||
;1 = bombe... (2,3,4) respirant... si c sup a 4; on est mort...
|
||||
;5 = centre de bombe. de 5 a 11
|
||||
;12 = ligne droite...
|
||||
;19 = arrondie ligne droite vers la gauche...
|
||||
;26 = arrondie ligne droite vers la droite
|
||||
;33 = ligne verti
|
||||
;40 arrondie verti vers le haut
|
||||
;47-- bas
|
||||
;54-- bonus bombe... de 54 a 63 (offset 144)
|
||||
;64-- bonus flamme... de 64 a 73 (offset 144+320*16)
|
||||
;74-- tete de mort de 74 a 83
|
||||
;84-- bonus parre balle. de 84 a 93
|
||||
;94-- bonus COEUR !!!
|
||||
;104 -- bonus bombe retardement
|
||||
;114 --- bonus pousseur
|
||||
;124 --- patins a roulettes
|
||||
;134 --- HORLOGE
|
||||
;horloge
|
||||
bonus_4 134
|
||||
bonus_3 144,1,tribombe
|
||||
bonus_6 154
|
||||
;oeuf
|
||||
bonus_5 193
|
||||
* ;1 = bombe... (2,3,4) respirant... si c sup a 4; on est mort...
|
||||
* ;5 = centre de bombe. de 5 a 11
|
||||
* ;12 = ligne droite...
|
||||
* ;19 = arrondie ligne droite vers la gauche...
|
||||
* ;26 = arrondie ligne droite vers la droite
|
||||
* ;33 = ligne verti
|
||||
* ;40 arrondie verti vers le haut
|
||||
* ;47-- bas
|
||||
* ;54-- bonus bombe... de 54 a 63 (offset 144)
|
||||
* ;64-- bonus flamme... de 64 a 73 (offset 144+320*16)
|
||||
* ;74-- tete de mort de 74 a 83
|
||||
* ;84-- bonus parre balle. de 84 a 93
|
||||
* ;94-- bonus COEUR !!!
|
||||
* ;104 -- bonus bombe retardement
|
||||
* ;114 --- bonus pousseur
|
||||
* ;124 --- patins a roulettes
|
||||
* ;134 --- HORLOGE
|
||||
* ;horloge
|
||||
* bonus_4 134
|
||||
* bonus_3 144,1,tribombe
|
||||
* bonus_6 154
|
||||
* ;oeuf
|
||||
* bonus_5 193
|
||||
*/
|
||||
db z = m.truc2[x + y * grid_size_x_with_padding];
|
||||
|
||||
if ((z >= 54) && (z < 194))
|
||||
{
|
||||
if (z<64) return bonus_bomb;
|
||||
if (z<74) return bonus_flame;
|
||||
if (z<84) return bonus_skull;
|
||||
if (z<94) return bonus_bulletproofjacket;
|
||||
if (z<104) return bonus_heart;
|
||||
if (z<114) return bonus_remote;
|
||||
if (z<124) return bonus_push;
|
||||
if (z<134) return bonus_roller;
|
||||
if (z<144) return bonus_time;
|
||||
if (z<154) return bonus_tribomb;
|
||||
if (z<164) return bonus_banana;
|
||||
return bonus_egg;
|
||||
if (z < 64)
|
||||
{
|
||||
return(bonus_bomb);
|
||||
}
|
||||
if (z < 74)
|
||||
{
|
||||
return(bonus_flame);
|
||||
}
|
||||
if (z < 84)
|
||||
{
|
||||
return(bonus_skull);
|
||||
}
|
||||
if (z < 94)
|
||||
{
|
||||
return(bonus_bulletproofjacket);
|
||||
}
|
||||
if (z < 104)
|
||||
{
|
||||
return(bonus_heart);
|
||||
}
|
||||
if (z < 114)
|
||||
{
|
||||
return(bonus_remote);
|
||||
}
|
||||
if (z < 124)
|
||||
{
|
||||
return(bonus_push);
|
||||
}
|
||||
if (z < 134)
|
||||
{
|
||||
return(bonus_roller);
|
||||
}
|
||||
if (z < 144)
|
||||
{
|
||||
return(bonus_time);
|
||||
}
|
||||
if (z < 154)
|
||||
{
|
||||
return(bonus_tribomb);
|
||||
}
|
||||
if (z < 164)
|
||||
{
|
||||
return(bonus_banana);
|
||||
}
|
||||
return(bonus_egg);
|
||||
}
|
||||
|
||||
return no_bonus;
|
||||
return(no_bonus);
|
||||
}
|
||||
|
||||
|
||||
bool monsterInCell(int x, int y);
|
||||
bool playerInCell(int x, int y);
|
||||
bool enemyInCell(int player, int x, int y);
|
||||
@ -256,50 +379,73 @@ bool isCellCulDeSac(int x,int y);
|
||||
extern int lastBombGridUpdate;
|
||||
extern struct bombInfo *bombsGrid[grid_size_x][grid_size_y]; // NULL if no bomb, pointer to the bomb in m.liste_bombe
|
||||
|
||||
static void updateBombGrid(struct bombInfo * bomb) {
|
||||
static void updateBombGrid(struct bombInfo *bomb)
|
||||
{
|
||||
bombsGrid[bomb->x()][bomb->y()] = bomb;
|
||||
}
|
||||
|
||||
int inline updateBombGrid()
|
||||
{
|
||||
memset(bombsGrid, 0, sizeof(bombsGrid));
|
||||
iterateOnBombs(updateBombGrid);
|
||||
return frameNumber();
|
||||
return(frameNumber());
|
||||
}
|
||||
|
||||
bool inline bombInCell(int x, int y)
|
||||
{
|
||||
if ((!lastBombGridUpdate) || (frameNumber()!=lastBombGridUpdate)) lastBombGridUpdate=updateBombGrid();
|
||||
if ((!lastBombGridUpdate) || (frameNumber() != lastBombGridUpdate))
|
||||
{
|
||||
lastBombGridUpdate = updateBombGrid();
|
||||
}
|
||||
return(bombsGrid[x][y] != NULL);
|
||||
}
|
||||
|
||||
bool somethingThatWouldStopFlame(int x, int y);
|
||||
|
||||
bool inline mudbrickInCell(int x, int y)
|
||||
{
|
||||
db brickKind = m.truc[x + y * grid_size_x_with_padding];
|
||||
|
||||
return(brickKind == 2);
|
||||
}
|
||||
|
||||
bool inline brickInCell(int x, int y)
|
||||
{
|
||||
db brickKind = m.truc[x + y * grid_size_x_with_padding];
|
||||
|
||||
return((brickKind == 1) || ((brickKind >= 3) && (brickKind <= 11)));
|
||||
}
|
||||
|
||||
bool inline brickOrSkullBonus(int x,int y) {
|
||||
bool inline brickOrSkullBonus(int x, int y)
|
||||
{
|
||||
if (brickInCell(x, y))
|
||||
return true;
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (mudbrickInCell(x, y))
|
||||
return true;
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (bonusInCell(x, y) == bonus_skull)
|
||||
return true;
|
||||
return false;
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool inline somethingThatIsNoTABombAndThatWouldStopPlayer(int x,int y) {
|
||||
bool inline somethingThatIsNoTABombAndThatWouldStopPlayer(int x, int y)
|
||||
{
|
||||
if (brickOrSkullBonus(x, y))
|
||||
return true;
|
||||
if (monsterInCell(x,y))
|
||||
return true;
|
||||
return false;
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (monsterInCell(x, y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
void updateMonsterIsComingGrid(bool monsterIsComingGrid[NUMBER_OF_CELLS]);
|
||||
bool canPlayerBeReachedByMonster(int player);
|
||||
bool canPlayerReachEnemy(int player);
|
||||
|
@ -5,6 +5,7 @@
|
||||
void addOneAIPlayer()
|
||||
{
|
||||
db *keys = m.total_t;
|
||||
|
||||
keys[64 + 5 + m.nombre_de_dyna * 7] = 1;
|
||||
keys[8 * 7 + 2] = 1;
|
||||
m.nb_ai_bombermen++;
|
||||
@ -13,13 +14,18 @@ void addOneAIPlayer()
|
||||
void addXAIPlayers(int x)
|
||||
{
|
||||
db *keys = m.total_t;
|
||||
for (int i=0; i<x; i++) keys[64+5+i*7]=1;
|
||||
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
keys[64 + 5 + i * 7] = 1;
|
||||
}
|
||||
keys[8 * 7 + 2] = 1;
|
||||
}
|
||||
|
||||
void pressStart()
|
||||
{
|
||||
db *keys = m.total_t;
|
||||
|
||||
keys[8 * 7] = 1;
|
||||
keys[8 * 7 + 2] = 1;
|
||||
}
|
||||
@ -29,55 +35,75 @@ void pressESC()
|
||||
m.sortie = 1;
|
||||
}
|
||||
|
||||
bool isInTheApocalypse() {
|
||||
bool isInTheApocalypse()
|
||||
{
|
||||
return(m.in_the_apocalypse == 1);
|
||||
}
|
||||
|
||||
bool hasRollers(int player) {
|
||||
bool hasRollers(int player)
|
||||
{
|
||||
return(m.patineur[player] == 1);
|
||||
}
|
||||
|
||||
bool hasRemote(int player) {
|
||||
return m.j1[4+player*5];
|
||||
bool hasRemote(int player)
|
||||
{
|
||||
return(m.j1[4 + player * 5]);
|
||||
}
|
||||
|
||||
bool hasPush(int player) {
|
||||
bool hasPush(int player)
|
||||
{
|
||||
return(m.pousseur[player] == 1);
|
||||
}
|
||||
bool hasTriBomb(int player) {
|
||||
|
||||
bool hasTriBomb(int player)
|
||||
{
|
||||
return(m.tribombe[player] == 1);
|
||||
}
|
||||
|
||||
// Warning will be zero if less then 1
|
||||
int pixelsPerFrame(int player) {
|
||||
return CELLPIXELSSIZE/framesToCrossACell(player);
|
||||
int pixelsPerFrame(int player)
|
||||
{
|
||||
return(CELLPIXELSSIZE / framesToCrossACell(player));
|
||||
}
|
||||
|
||||
int framesToCrossACell(int player)
|
||||
{
|
||||
bool speed = hasSpeedDisease(player);
|
||||
bool slow = hasSlowDisease(player);
|
||||
|
||||
if (hasRollers(player))
|
||||
{
|
||||
if (slow)
|
||||
return (CELLPIXELSSIZE/2)*4; //32
|
||||
{
|
||||
return((CELLPIXELSSIZE / 2) * 4); //32
|
||||
}
|
||||
if (speed)
|
||||
return (CELLPIXELSSIZE/2)/4; //2
|
||||
return CELLPIXELSSIZE/2; //8
|
||||
{
|
||||
return((CELLPIXELSSIZE / 2) / 4); //2
|
||||
}
|
||||
return(CELLPIXELSSIZE / 2); //8
|
||||
}
|
||||
|
||||
if (slow)
|
||||
return CELLPIXELSSIZE*4; //64
|
||||
{
|
||||
return(CELLPIXELSSIZE * 4); //64
|
||||
}
|
||||
if (speed)
|
||||
return CELLPIXELSSIZE/4; //4
|
||||
return CELLPIXELSSIZE; //16
|
||||
{
|
||||
return(CELLPIXELSSIZE / 4); //4
|
||||
}
|
||||
return(CELLPIXELSSIZE); //16
|
||||
}
|
||||
|
||||
int nbLives(int player) {
|
||||
if (isAlive(player)) {
|
||||
int nbLives(int player)
|
||||
{
|
||||
if (isAlive(player))
|
||||
{
|
||||
return(m.nombre_de_coups[player] + 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,81 +117,109 @@ bool isAIActiveForPlayer(int player)
|
||||
return((m.control_joueur[player] >= 64) && (m.control_joueur[player] <= 64 * 2));
|
||||
}
|
||||
|
||||
bool hasAnyDisease(int player) {
|
||||
bool hasAnyDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] != 0);
|
||||
}
|
||||
|
||||
bool hasSlowDisease(int player) {
|
||||
bool hasSlowDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 2);
|
||||
}
|
||||
|
||||
bool hasSpeedDisease(int player) {
|
||||
bool hasSpeedDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 1);
|
||||
}
|
||||
|
||||
bool hasInvertedDisease(int player) {
|
||||
bool hasInvertedDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 4);
|
||||
}
|
||||
|
||||
bool hasDiarrheaDisease(int player) {
|
||||
bool hasDiarrheaDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 3);
|
||||
}
|
||||
bool hasSmallBombDisease(int player) {
|
||||
|
||||
bool hasSmallBombDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 6);
|
||||
}
|
||||
bool hasConstipationDisease(int player) {
|
||||
|
||||
bool hasConstipationDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 5);
|
||||
}
|
||||
|
||||
void setDisease(int player, int disease, int duration) {
|
||||
void setDisease(int player, int disease, int duration)
|
||||
{
|
||||
m.maladie[player * 2] = disease;
|
||||
m.maladie[player * 2 + 1] = duration;
|
||||
}
|
||||
|
||||
int numberOfPlayers()
|
||||
{
|
||||
return m.nombre_de_dyna;
|
||||
}
|
||||
bool replay() {
|
||||
return m.action_replay!=0;
|
||||
return(m.nombre_de_dyna);
|
||||
}
|
||||
|
||||
int level() {
|
||||
if (replay()) return -1;
|
||||
if (inTheMenu()) return -1;
|
||||
return m.viseur_liste_terrain;
|
||||
bool replay()
|
||||
{
|
||||
return(m.action_replay != 0);
|
||||
}
|
||||
|
||||
int level()
|
||||
{
|
||||
if (replay())
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
if (inTheMenu())
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
return(m.viseur_liste_terrain);
|
||||
}
|
||||
|
||||
void chooseLevel(int level)
|
||||
{
|
||||
m.viseur_liste_terrain = level;
|
||||
}
|
||||
|
||||
bool inTheMenu() {
|
||||
bool inTheMenu()
|
||||
{
|
||||
return((isGameActive() == false) && m.ordre == 'S');
|
||||
}
|
||||
|
||||
bool isGameActive()
|
||||
{
|
||||
if ((m.ordre == 1) && (m.ordre2 == 3))
|
||||
return true;
|
||||
return false;
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool isAboutToWin() {
|
||||
bool isAboutToWin()
|
||||
{
|
||||
return(m.attente_avant_med < 100);
|
||||
}
|
||||
|
||||
int nbBombsLeft(int player)
|
||||
{
|
||||
if (m.nombre_de_vbl_avant_le_droit_de_poser_bombe)
|
||||
return 0;
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
if (hasConstipationDisease(player))
|
||||
return 0;
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
if (isAboutToWin())
|
||||
return 0;
|
||||
return m.j1[player*5]; //nb of bombs
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
return(m.j1[player * 5]); //nb of bombs
|
||||
}
|
||||
|
||||
void activeApocalypse()
|
||||
@ -173,11 +227,11 @@ void activeApocalypse()
|
||||
m.temps = 2;
|
||||
}
|
||||
|
||||
int invincibility(int player) {
|
||||
return m.invinsible[player];
|
||||
int invincibility(int player)
|
||||
{
|
||||
return(m.invinsible[player]);
|
||||
}
|
||||
|
||||
|
||||
void activeCheatMode()
|
||||
{
|
||||
log_info("activeCheatMode\n");
|
||||
@ -185,14 +239,16 @@ void activeCheatMode()
|
||||
for (db i = 0; i < nb_dyna; i++)
|
||||
{
|
||||
// setDisease(i,3,1000); Diarrhea
|
||||
|
||||
/*
|
||||
if (i>= m.nombre_de_dyna)
|
||||
m.nombre_de_coups[i]=1; //number of lifes
|
||||
else
|
||||
m.nombre_de_coups[i]=99;
|
||||
* if (i>= m.nombre_de_dyna)
|
||||
* m.nombre_de_coups[i]=1; //number of lifes
|
||||
* else
|
||||
* m.nombre_de_coups[i]=99;
|
||||
*/
|
||||
|
||||
if (i< m.nombre_de_dyna) {
|
||||
if (i < m.nombre_de_dyna)
|
||||
{
|
||||
m.j1[i * 5] = 1; //nb of bombs
|
||||
//m.j1[1+i*5]=5; // power of bombs
|
||||
m.j1[4 + i * 5] = 1; // remote
|
||||
@ -209,8 +265,6 @@ void setNoMonsterMode(bool on)
|
||||
m.nomonster = on;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool bonusPlayerWouldLike(int player, enum Bonus bonus)
|
||||
{
|
||||
switch (bonus)
|
||||
@ -218,159 +272,217 @@ bool bonusPlayerWouldLike(int player,enum Bonus bonus)
|
||||
case no_bonus:
|
||||
case bonus_skull:
|
||||
case bonus_time:
|
||||
return false;
|
||||
return(false);
|
||||
|
||||
case bonus_roller:
|
||||
return(hasRollers(player) == false);
|
||||
|
||||
case bonus_remote:
|
||||
return(hasRemote(player) == false);
|
||||
|
||||
case bonus_tribomb:
|
||||
return false;
|
||||
return(false);
|
||||
|
||||
// return (hasTriBomb(player)==false);
|
||||
case bonus_push:
|
||||
return(hasPush(player) == false);
|
||||
|
||||
case bonus_egg:
|
||||
return(hasKangaroo(player) == false);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
void setFrameNumber(int frame) {
|
||||
void setFrameNumber(int frame)
|
||||
{
|
||||
m.changement = frame;
|
||||
}
|
||||
|
||||
int flameSize(int player)
|
||||
{
|
||||
if (hasSmallBombDisease(player))
|
||||
return 1;
|
||||
return m.j1[1+player*5];
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
return(m.j1[1 + player * 5]);
|
||||
}
|
||||
|
||||
void setTeamMode(int teamMode) {
|
||||
void setTeamMode(int teamMode)
|
||||
{
|
||||
m.team3_sauve = teamMode;
|
||||
}
|
||||
|
||||
int teamMode() {
|
||||
return m.team3_sauve;
|
||||
int teamMode()
|
||||
{
|
||||
return(m.team3_sauve);
|
||||
}
|
||||
|
||||
void setAutofire(bool on) {
|
||||
if (on) {
|
||||
void setAutofire(bool on)
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
m.autofire = 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
m.autofire = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool autofire() {
|
||||
bool autofire()
|
||||
{
|
||||
return(m.autofire == 1);
|
||||
}
|
||||
|
||||
int xPlayer(int player) {
|
||||
return (m.donnee[player]+DELTA_X)/CELLPIXELSSIZE;
|
||||
}
|
||||
int yPlayer(int player) {
|
||||
return (m.donnee[nb_dyna+player]+DELTA_Y)/CELLPIXELSSIZE;
|
||||
int xPlayer(int player)
|
||||
{
|
||||
return((m.donnee[player] + DELTA_X) / CELLPIXELSSIZE);
|
||||
}
|
||||
|
||||
int cellPlayer(int player) {
|
||||
int yPlayer(int player)
|
||||
{
|
||||
return((m.donnee[nb_dyna + player] + DELTA_Y) / CELLPIXELSSIZE);
|
||||
}
|
||||
|
||||
int cellPlayer(int player)
|
||||
{
|
||||
return(xPlayer(player) + yPlayer(player) * grid_size_x);
|
||||
}
|
||||
|
||||
bool tracesDecisions(int player) {
|
||||
bool tracesDecisions(int player)
|
||||
{
|
||||
return(debugTracesPlayer(player) && (traceMask & DEBUG_MASK_BOTTREEDECISIONS));
|
||||
}
|
||||
|
||||
bool isInMiddleOfCell(int player) {
|
||||
bool isInMiddleOfCell(int player)
|
||||
{
|
||||
int step = pixelsPerFrame(player);
|
||||
|
||||
assert(step <= MAX_PIXELS_PER_FRAME);
|
||||
int x = GETXPIXELSTOCENTEROFCELL(player);
|
||||
int y = GETYPIXELSTOCENTEROFCELL(player);
|
||||
if (step < 1)
|
||||
{
|
||||
return((!x) && (!y));
|
||||
}
|
||||
return((x >= -step / 2) && (x <= step / 2) && (y <= step / 2) && (y >= -step / 2));
|
||||
}
|
||||
|
||||
int dangerousCellForMonster(int player) {
|
||||
int dangerousCellForMonster(int player)
|
||||
{
|
||||
int cell = cellPlayer(player);
|
||||
int index = m.viseur_change_in[player] / 4;
|
||||
|
||||
index--;
|
||||
if (index<0) {
|
||||
if (index < 0)
|
||||
{
|
||||
index = 15;
|
||||
}
|
||||
switch (m.changeiny[index]) {
|
||||
switch (m.changeiny[index])
|
||||
{
|
||||
case 0:
|
||||
return cell+grid_size_x;
|
||||
return(cell + grid_size_x);
|
||||
|
||||
case 8:
|
||||
return cell+1;
|
||||
return(cell + 1);
|
||||
|
||||
case 16:
|
||||
return cell-1;
|
||||
return(cell - 1);
|
||||
|
||||
case 24:
|
||||
return cell-grid_size_x;
|
||||
return(cell - grid_size_x);
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int victories(int player) {
|
||||
int victories(int player)
|
||||
{
|
||||
int mode = teamMode();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
return m.victoires[player];
|
||||
return(m.victoires[player]);
|
||||
|
||||
break;
|
||||
|
||||
case 1: // color mode
|
||||
return m.victoires[player/2];
|
||||
return(m.victoires[player / 2]);
|
||||
|
||||
break;
|
||||
|
||||
case 2: // sex mode
|
||||
return m.victoires[player%2];
|
||||
return(m.victoires[player % 2]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
void pauseGameButton() {
|
||||
if (m.pauseur2) {
|
||||
m.pauseur2=0;
|
||||
|
||||
} else {
|
||||
void pauseGameButton()
|
||||
{
|
||||
if (m.pauseur2)
|
||||
{
|
||||
m.pauseur2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.pauseur2 = 4;
|
||||
}
|
||||
}
|
||||
|
||||
bool isGamePaused() {
|
||||
return m.pauseur2;
|
||||
bool isGamePaused()
|
||||
{
|
||||
return(m.pauseur2);
|
||||
}
|
||||
|
||||
bool isSuicideOK(int player) {
|
||||
bool isSuicideOK(int player)
|
||||
{
|
||||
int myTeam = teamOfPlayer(player);
|
||||
int nbLivesEnemies = 0;
|
||||
int nbLivesFriends = 0;
|
||||
for (int i=0; i<numberOfPlayers(); i++) {
|
||||
if (myTeam==teamOfPlayer(i)) {
|
||||
|
||||
for (int i = 0; i < numberOfPlayers(); i++)
|
||||
{
|
||||
if (myTeam == teamOfPlayer(i))
|
||||
{
|
||||
nbLivesFriends += nbLives(i);
|
||||
if (invincibility(i)) nbLivesFriends++;
|
||||
if (invincibility(i))
|
||||
{
|
||||
nbLivesFriends++;
|
||||
}
|
||||
if (myTeam!=teamOfPlayer(i)) {
|
||||
}
|
||||
if (myTeam != teamOfPlayer(i))
|
||||
{
|
||||
nbLivesEnemies += nbLives(i);
|
||||
if (invincibility(i)) nbLivesEnemies++;
|
||||
if (invincibility(i))
|
||||
{
|
||||
nbLivesEnemies++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return((nbLivesFriends > 1) && (nbLivesEnemies == 1));
|
||||
}
|
||||
|
||||
bool someHumanPlayersAlive() {
|
||||
for (int i=0; i<numberOfPlayers(); i++) {
|
||||
if (isAIActiveForPlayer(i)==false) {
|
||||
if (isAlive(i)) return true;
|
||||
bool someHumanPlayersAlive()
|
||||
{
|
||||
for (int i = 0; i < numberOfPlayers(); i++)
|
||||
{
|
||||
if (isAIActiveForPlayer(i) == false)
|
||||
{
|
||||
if (isAlive(i))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
@ -2,6 +2,10 @@
|
||||
#include <stdint.h>
|
||||
#include "mrboom.h"
|
||||
#include "common.hpp"
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include "assert.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -25,7 +29,8 @@ extern "C" {
|
||||
#define FLAME_DURATION (16 * 5 + 6 * 4 * 2)
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
|
||||
enum Bonus {
|
||||
enum Bonus
|
||||
{
|
||||
no_bonus,
|
||||
bonus_bomb,
|
||||
bonus_flame,
|
||||
@ -49,9 +54,12 @@ void addOneAIPlayer();
|
||||
void addXAIPlayers(int x);
|
||||
void pressStart();
|
||||
void pressESC();
|
||||
bool inline hasKangaroo(int player) {
|
||||
|
||||
bool inline hasKangaroo(int player)
|
||||
{
|
||||
return(m.lapipipino[player] == 1);
|
||||
}
|
||||
|
||||
bool hasRemote(int player);
|
||||
bool hasRollers(int player);
|
||||
bool hasPush(int player);
|
||||
@ -76,9 +84,12 @@ void setNoMonsterMode(bool on);
|
||||
int invincibility(int player);
|
||||
int framesToCrossACell(int player);
|
||||
int pixelsPerFrame(int player);
|
||||
int inline frameNumber() {
|
||||
return m.changement;
|
||||
|
||||
int inline frameNumber()
|
||||
{
|
||||
return(m.changement);
|
||||
}
|
||||
|
||||
void setFrameNumber(int frame);
|
||||
int flameSize(int player);
|
||||
void chooseLevel(int level);
|
||||
@ -97,12 +108,17 @@ bool tracesDecisions(int player);
|
||||
bool isInMiddleOfCell(int player);
|
||||
int dangerousCellForMonster(int player);
|
||||
int victories(int player);
|
||||
int inline getAdderX(int player) {
|
||||
return GETXPIXELSTOCENTEROFCELL(player)*framesToCrossACell(player)/CELLPIXELSSIZE;
|
||||
|
||||
int inline getAdderX(int player)
|
||||
{
|
||||
return(GETXPIXELSTOCENTEROFCELL(player) * framesToCrossACell(player) / CELLPIXELSSIZE);
|
||||
}
|
||||
int inline getAdderY(int player) {
|
||||
return GETYPIXELSTOCENTEROFCELL(player)*framesToCrossACell(player)/CELLPIXELSSIZE;
|
||||
|
||||
int inline getAdderY(int player)
|
||||
{
|
||||
return(GETYPIXELSTOCENTEROFCELL(player) * framesToCrossACell(player) / CELLPIXELSSIZE);
|
||||
}
|
||||
|
||||
bool isSuicideOK(int player);
|
||||
int nbLives(int player);
|
||||
|
||||
@ -130,6 +146,7 @@ enum playerKind inline teamOfPlayer(int player)
|
||||
case 0:
|
||||
result = static_cast <playerKind>(1 << player);
|
||||
break;
|
||||
|
||||
case 1: // color mode
|
||||
result = static_cast <playerKind>(1 << player / 2);
|
||||
break;
|
||||
@ -137,12 +154,14 @@ enum playerKind inline teamOfPlayer(int player)
|
||||
case 2: // sex mode
|
||||
result = static_cast <playerKind>(1 << player % 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -9,3 +9,4 @@
|
||||
![alt tag](bt.png)
|
||||
|
||||
Using a c++ 98 port of arvidsson 's [behavior tree library](https://github.com/arvidsson/bt).
|
||||
|
||||
|
@ -8,4 +8,3 @@
|
||||
// composites
|
||||
#include "bt/composites/Selector.hpp"
|
||||
#include "bt/composites/Sequence.hpp"
|
||||
|
||||
|
@ -4,35 +4,40 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
class BehaviorTree : public Node
|
||||
{
|
||||
public:
|
||||
BehaviorTree() {
|
||||
BehaviorTree()
|
||||
{
|
||||
root = NULL;
|
||||
}
|
||||
BehaviorTree(Node * rootNode) {
|
||||
|
||||
BehaviorTree(Node *rootNode)
|
||||
{
|
||||
root = rootNode;
|
||||
}
|
||||
|
||||
Status Update() {
|
||||
return root->Tick();
|
||||
Status Update()
|
||||
{
|
||||
return(root->Tick());
|
||||
}
|
||||
|
||||
void SetRoot(Node * node) {
|
||||
void SetRoot(Node *node)
|
||||
{
|
||||
root = node;
|
||||
}
|
||||
|
||||
void serialize(memstream_t * stream) {
|
||||
void serialize(memstream_t *stream)
|
||||
{
|
||||
root->serialize(stream);
|
||||
}
|
||||
|
||||
void unserialize(memstream_t * stream) {
|
||||
void unserialize(memstream_t *stream)
|
||||
{
|
||||
root->unserialize(stream);
|
||||
}
|
||||
|
||||
private:
|
||||
Node *root;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -4,41 +4,53 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
class Composite : public Node
|
||||
{
|
||||
public:
|
||||
|
||||
Composite() {
|
||||
Composite()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
virtual ~Composite() {
|
||||
|
||||
virtual ~Composite()
|
||||
{
|
||||
}
|
||||
|
||||
void AddChild(Node * child) {
|
||||
void AddChild(Node *child)
|
||||
{
|
||||
children.push_back(child);
|
||||
}
|
||||
bool HasNoChildren() const {
|
||||
return children.empty();
|
||||
}
|
||||
int GetIndex() const {
|
||||
return index;
|
||||
|
||||
bool HasNoChildren() const
|
||||
{
|
||||
return(children.empty());
|
||||
}
|
||||
|
||||
void serialize(memstream_t * stream) {
|
||||
int GetIndex() const
|
||||
{
|
||||
return(index);
|
||||
}
|
||||
|
||||
void serialize(memstream_t *stream)
|
||||
{
|
||||
// TOFIX big endian
|
||||
Node::serialize(stream);
|
||||
memstream_write(stream, &index, sizeof(index));
|
||||
for (int i=0; i<(signed)children.size(); i++) {
|
||||
for (int i = 0; i < (signed)children.size(); i++)
|
||||
{
|
||||
bt::Node *child = children.at(i);
|
||||
child->serialize(stream);
|
||||
}
|
||||
}
|
||||
void unserialize(memstream_t * stream) {
|
||||
|
||||
void unserialize(memstream_t *stream)
|
||||
{
|
||||
// TOFIX big endian
|
||||
Node::unserialize(stream);
|
||||
memstream_read(stream, &index, sizeof(index));
|
||||
for (int i=0; i<(signed)children.size(); i++) {
|
||||
for (int i = 0; i < (signed)children.size(); i++)
|
||||
{
|
||||
bt::Node *child = children.at(i);
|
||||
child->unserialize(stream);
|
||||
}
|
||||
@ -48,5 +60,4 @@ protected:
|
||||
std::vector <Node *> children;
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
enum Status
|
||||
{
|
||||
Invalid,
|
||||
@ -19,26 +18,36 @@ class Node
|
||||
{
|
||||
public:
|
||||
|
||||
Node() {
|
||||
Node()
|
||||
{
|
||||
status = Invalid;
|
||||
}
|
||||
|
||||
virtual ~Node() {
|
||||
virtual ~Node()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Status Update() = 0;
|
||||
virtual void Initialize() {
|
||||
}
|
||||
virtual void Terminate(Status s) {
|
||||
|
||||
virtual void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void serialize(memstream_t * stream) {
|
||||
virtual void Terminate(Status s)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void serialize(memstream_t *stream)
|
||||
{
|
||||
uint8_t s = (uint8_t)status;
|
||||
|
||||
memstream_write(stream, &s, sizeof(s));
|
||||
}
|
||||
|
||||
virtual void unserialize(memstream_t * stream) {
|
||||
virtual void unserialize(memstream_t *stream)
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memstream_read(stream, &s, sizeof(s));
|
||||
status = bt::Status(s);
|
||||
}
|
||||
@ -46,35 +55,48 @@ virtual void unserialize(memstream_t * stream) {
|
||||
Status Tick()
|
||||
{
|
||||
if (status != Running)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
status = Update();
|
||||
|
||||
if (status != Running)
|
||||
{
|
||||
Terminate(status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool IsSuccess() const {
|
||||
return status == Success;
|
||||
return(status);
|
||||
}
|
||||
bool IsFailure() const {
|
||||
return status == Failure;
|
||||
|
||||
bool IsSuccess() const
|
||||
{
|
||||
return(status == Success);
|
||||
}
|
||||
bool IsRunning() const {
|
||||
return status == Running;
|
||||
|
||||
bool IsFailure() const
|
||||
{
|
||||
return(status == Failure);
|
||||
}
|
||||
bool IsTerminated() const {
|
||||
return IsSuccess() || IsFailure();
|
||||
|
||||
bool IsRunning() const
|
||||
{
|
||||
return(status == Running);
|
||||
}
|
||||
void Reset() {
|
||||
|
||||
bool IsTerminated() const
|
||||
{
|
||||
return(IsSuccess() || IsFailure());
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
status = Invalid;
|
||||
}
|
||||
|
||||
protected:
|
||||
Status status;
|
||||
};
|
||||
|
||||
//using Nodes = std::vector<Node *>;
|
||||
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
/*
|
||||
The Selector composite ticks each child node in order.
|
||||
If a child succeeds or runs, the sequence returns the same status.
|
||||
In the next tick, it will try to run each child in order again.
|
||||
If all children fails, only then does the selector fail.
|
||||
* The Selector composite ticks each child node in order.
|
||||
* If a child succeeds or runs, the sequence returns the same status.
|
||||
* In the next tick, it will try to run each child in order again.
|
||||
* If all children fails, only then does the selector fail.
|
||||
*/
|
||||
class Selector : public Composite
|
||||
{
|
||||
@ -22,7 +21,9 @@ void Initialize()
|
||||
Status Update()
|
||||
{
|
||||
if (HasNoChildren())
|
||||
return Success;
|
||||
{
|
||||
return(Success);
|
||||
}
|
||||
|
||||
// Keep going until a child behavior says it's running.
|
||||
while (1)
|
||||
@ -32,14 +33,16 @@ Status Update()
|
||||
|
||||
// If the child succeeds, or keeps running, do the same.
|
||||
if (status != Failure)
|
||||
return status;
|
||||
{
|
||||
return(status);
|
||||
}
|
||||
|
||||
// Hit the end of the array, it didn't end well...
|
||||
if (++index == (signed)children.size())
|
||||
return Failure;
|
||||
{
|
||||
return(Failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
/*
|
||||
The Sequence composite ticks each child node in order.
|
||||
If a child fails or runs, the sequence returns the same status.
|
||||
In the next tick, it will try to run each child in order again.
|
||||
If all children succeeds, only then does the sequence succeed.
|
||||
* The Sequence composite ticks each child node in order.
|
||||
* If a child fails or runs, the sequence returns the same status.
|
||||
* In the next tick, it will try to run each child in order again.
|
||||
* If all children succeeds, only then does the sequence succeed.
|
||||
*/
|
||||
class Sequence : public Composite
|
||||
{
|
||||
@ -22,7 +21,9 @@ void Initialize()
|
||||
Status Update()
|
||||
{
|
||||
if (HasNoChildren())
|
||||
return Success;
|
||||
{
|
||||
return(Success);
|
||||
}
|
||||
|
||||
// Keep going until a child behavior says it's running.
|
||||
while (1)
|
||||
@ -32,13 +33,16 @@ Status Update()
|
||||
|
||||
// If the child fails, or keeps running, do the same.
|
||||
if (status != Success)
|
||||
return status;
|
||||
{
|
||||
return(status);
|
||||
}
|
||||
|
||||
// Hit the end of the array, job done!
|
||||
if (++index == (signed)children.size())
|
||||
return Success;
|
||||
{
|
||||
return(Success);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ extern "C" {
|
||||
|
||||
class BotTree;
|
||||
extern BotTree *tree[nb_dyna];
|
||||
enum Button {
|
||||
enum Button
|
||||
{
|
||||
button_b,
|
||||
button_y,
|
||||
button_select,
|
||||
@ -48,6 +49,7 @@ void mrboom_reset_special_keys();
|
||||
void mrboom_tick_ai();
|
||||
void mrboom_deal_with_autofire();
|
||||
bool debugTracesPlayer(int player);
|
||||
|
||||
extern bool cheatMode;
|
||||
#ifdef DEBUG
|
||||
enum BotState { goingNowhere, goingSafe, goingBonus, goingBomb };
|
||||
@ -61,6 +63,7 @@ extern int16_t *frame_sample_buf;
|
||||
extern uint32_t num_samples_per_frame;
|
||||
extern retro_audio_sample_batch_t audio_batch_cb;
|
||||
void audio_callback(void);
|
||||
|
||||
#define DEFAULT_TRACE_MAX 0
|
||||
#endif
|
||||
#ifdef __LIBSDL2__
|
||||
|
67
libretro.h
67
libretro.h
@ -33,6 +33,7 @@ extern "C" {
|
||||
|
||||
#ifndef __cplusplus
|
||||
#if defined(_MSC_VER) && !defined(SN_TARGET_PS3)
|
||||
|
||||
/* Hack applied for MSVC when compiling in C89 mode
|
||||
* as it isn't C99-compliant. */
|
||||
#define bool unsigned char
|
||||
@ -481,6 +482,7 @@ enum retro_mod
|
||||
* way to shutdown the game from a menu item or similar.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8
|
||||
|
||||
/* const unsigned * --
|
||||
* Gives a hint to the frontend how demanding this implementation
|
||||
* is on a system. E.g. reporting a level of 2 means
|
||||
@ -498,6 +500,7 @@ enum retro_mod
|
||||
* If called, it should be called in retro_load_game().
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9
|
||||
|
||||
/* const char ** --
|
||||
* Returns the "system" directory of the frontend.
|
||||
* This directory can be used to store system specific
|
||||
@ -512,6 +515,7 @@ enum retro_mod
|
||||
* use the new GET_SAVE_DIRECTORY.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10
|
||||
|
||||
/* const enum retro_pixel_format * --
|
||||
* Sets the internal pixel format used by the implementation.
|
||||
* The default pixel format is RETRO_PIXEL_FORMAT_0RGB1555.
|
||||
@ -523,6 +527,7 @@ enum retro_mod
|
||||
* retro_get_system_av_info().
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS 11
|
||||
|
||||
/* const struct retro_input_descriptor * --
|
||||
* Sets an array of retro_input_descriptors.
|
||||
* It is up to the frontend to present this in a usable way.
|
||||
@ -532,10 +537,12 @@ enum retro_mod
|
||||
* to call it as early as possible.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12
|
||||
|
||||
/* const struct retro_keyboard_callback * --
|
||||
* Sets a callback function used to notify core about keyboard events.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13
|
||||
|
||||
/* const struct retro_disk_control_callback * --
|
||||
* Sets an interface which frontend can use to eject and insert
|
||||
* disk images.
|
||||
@ -543,6 +550,7 @@ enum retro_mod
|
||||
* must be manually swapped out by the user (e.g. PSX).
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_HW_RENDER 14
|
||||
|
||||
/* struct retro_hw_render_callback * --
|
||||
* Sets an interface to let a libretro core render with
|
||||
* hardware acceleration.
|
||||
@ -555,6 +563,7 @@ enum retro_mod
|
||||
* NULL to retro_video_refresh_t.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_VARIABLE 15
|
||||
|
||||
/* struct retro_variable * --
|
||||
* Interface to acquire user-defined information from environment
|
||||
* that cannot feasibly be supported in a multi-system way.
|
||||
@ -563,6 +572,7 @@ enum retro_mod
|
||||
* 'data' will be set to a value or NULL.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_VARIABLES 16
|
||||
|
||||
/* const struct retro_variable * --
|
||||
* Allows an implementation to signal the environment
|
||||
* which variables it might want to check for later using
|
||||
@ -598,12 +608,14 @@ enum retro_mod
|
||||
* generally be displayed and stored as-is by the frontend.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE 17
|
||||
|
||||
/* bool * --
|
||||
* Result is set to true if some variables are updated by
|
||||
* frontend since last call to RETRO_ENVIRONMENT_GET_VARIABLE.
|
||||
* Variables should be queried with GET_VARIABLE.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME 18
|
||||
|
||||
/* const bool * --
|
||||
* If true, the libretro implementation supports calls to
|
||||
* retro_load_game() with NULL as argument.
|
||||
@ -611,6 +623,7 @@ enum retro_mod
|
||||
* This should be called within retro_set_environment() only.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_LIBRETRO_PATH 19
|
||||
|
||||
/* const char ** --
|
||||
* Retrieves the absolute path from where this libretro
|
||||
* implementation was loaded.
|
||||
@ -625,6 +638,7 @@ enum retro_mod
|
||||
* It was not used by any known core at the time,
|
||||
* and was removed from the API. */
|
||||
#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22
|
||||
|
||||
/* const struct retro_audio_callback * --
|
||||
* Sets an interface which is used to notify a libretro core about audio
|
||||
* being available for writing.
|
||||
@ -651,6 +665,7 @@ enum retro_mod
|
||||
* SET_FRAME_TIME_CALLBACK.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21
|
||||
|
||||
/* const struct retro_frame_time_callback * --
|
||||
* Lets the core know how much time has passed since last
|
||||
* invocation of retro_run().
|
||||
@ -660,6 +675,7 @@ enum retro_mod
|
||||
* in frame_time_callback..
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE 23
|
||||
|
||||
/* struct retro_rumble_interface * --
|
||||
* Gets an interface which is used by a libretro core to set
|
||||
* state of rumble motors in controllers.
|
||||
@ -667,6 +683,7 @@ enum retro_mod
|
||||
* controlled indepedently.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24
|
||||
|
||||
/* uint64_t * --
|
||||
* Gets a bitmask telling which device type are expected to be
|
||||
* handled properly in a call to retro_input_state_t.
|
||||
@ -676,6 +693,7 @@ enum retro_mod
|
||||
* Should only be called in retro_run().
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE (25 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* struct retro_sensor_interface * --
|
||||
* Gets access to the sensor interface.
|
||||
* The purpose of this interface is to allow
|
||||
@ -685,6 +703,7 @@ enum retro_mod
|
||||
* input_state_callback API.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE (26 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* struct retro_camera_callback * --
|
||||
* Gets an interface to a video camera driver.
|
||||
* A libretro core can use this interface to get access to a
|
||||
@ -710,6 +729,7 @@ enum retro_mod
|
||||
* start and stop the camera driver.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_LOG_INTERFACE 27
|
||||
|
||||
/* struct retro_log_callback * --
|
||||
* Gets an interface for logging. This is useful for
|
||||
* logging in a cross-platform way
|
||||
@ -720,12 +740,14 @@ enum retro_mod
|
||||
* log to stderr as desired.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28
|
||||
|
||||
/* struct retro_perf_callback * --
|
||||
* Gets an interface for performance counters. This is useful
|
||||
* for performance logging in a cross-platform way and for detecting
|
||||
* architecture-specific features, such as SIMD support.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29
|
||||
|
||||
/* struct retro_location_callback * --
|
||||
* Gets access to the location interface.
|
||||
* The purpose of this interface is to be able to retrieve
|
||||
@ -734,6 +756,7 @@ enum retro_mod
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30 /* Old name, kept for compatibility. */
|
||||
#define RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY 30
|
||||
|
||||
/* const char ** --
|
||||
* Returns the "core assets" directory of the frontend.
|
||||
* This directory can be used to store specific assets that the
|
||||
@ -744,6 +767,7 @@ enum retro_mod
|
||||
* and it's up to the implementation to find a suitable directory.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31
|
||||
|
||||
/* const char ** --
|
||||
* Returns the "save" directory of the frontend.
|
||||
* This directory can be used to store SRAM, memory cards,
|
||||
@ -758,6 +782,7 @@ enum retro_mod
|
||||
* frontend user has set a specific save path.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32
|
||||
|
||||
/* const struct retro_system_av_info * --
|
||||
* Sets a new av_info structure. This can only be called from
|
||||
* within retro_run().
|
||||
@ -791,6 +816,7 @@ enum retro_mod
|
||||
* changed av_info struct.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33
|
||||
|
||||
/* const struct retro_get_proc_address_interface * --
|
||||
* Allows a libretro core to announce support for the
|
||||
* get_proc_address() interface.
|
||||
@ -802,6 +828,7 @@ enum retro_mod
|
||||
* **MUST** be called from within retro_set_environment().
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO 34
|
||||
|
||||
/* const struct retro_subsystem_info * --
|
||||
* This environment call introduces the concept of libretro "subsystems".
|
||||
* A subsystem is a variant of a libretro core which supports
|
||||
@ -821,6 +848,7 @@ enum retro_mod
|
||||
* **MUST** be called from within retro_set_environment().
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35
|
||||
|
||||
/* const struct retro_controller_info * --
|
||||
* This environment call lets a libretro core tell the frontend
|
||||
* which controller types are recognized in calls to
|
||||
@ -846,6 +874,7 @@ enum retro_mod
|
||||
* libretro should only poll input based on the base input device types.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* const struct retro_memory_map * --
|
||||
* This environment call lets a libretro core tell the frontend
|
||||
* about the memory maps this core emulates.
|
||||
@ -859,6 +888,7 @@ enum retro_mod
|
||||
* Can be called from retro_init and retro_load_game.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_SET_GEOMETRY 37
|
||||
|
||||
/* const struct retro_game_geometry * --
|
||||
* This environment call is similar to SET_SYSTEM_AV_INFO for changing
|
||||
* video parameters, but provides a guarantee that drivers will not be
|
||||
@ -878,6 +908,7 @@ enum retro_mod
|
||||
* constant time.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_USERNAME 38
|
||||
|
||||
/* const char **
|
||||
* Returns the specified username of the frontend, if specified by the user.
|
||||
* This username can be used as a nickname for a core that has online facilities
|
||||
@ -887,11 +918,13 @@ enum retro_mod
|
||||
* a default username should be specified by the core.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_LANGUAGE 39
|
||||
|
||||
/* unsigned * --
|
||||
* Returns the specified language of the frontend, if specified by the user.
|
||||
* It can be used by the core for localization purposes.
|
||||
*/
|
||||
#define RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER (40 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* struct retro_framebuffer * --
|
||||
* Returns a preallocated framebuffer which the core can use for rendering
|
||||
* the frame into when not using SET_HW_RENDER.
|
||||
@ -936,6 +969,7 @@ struct retro_hw_render_interface
|
||||
unsigned interface_version;
|
||||
};
|
||||
#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* const struct retro_hw_render_interface ** --
|
||||
* Returns an API specific rendering interface for accessing API specific data.
|
||||
* Not all HW rendering APIs support or need this.
|
||||
@ -948,6 +982,7 @@ struct retro_hw_render_interface
|
||||
*/
|
||||
|
||||
#define RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* const bool * --
|
||||
* If true, the libretro implementation supports achievements
|
||||
* either via memory descriptors set with RETRO_ENVIRONMENT_SET_MEMORY_MAPS
|
||||
@ -970,6 +1005,7 @@ struct retro_hw_render_context_negotiation_interface
|
||||
unsigned interface_version;
|
||||
};
|
||||
#define RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE (43 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
|
||||
/* const struct retro_hw_render_context_negotiation_interface * --
|
||||
* Sets an interface which lets the libretro core negotiate with frontend how a context is created.
|
||||
* The semantics of this interface depends on which API is used in SET_HW_RENDER earlier.
|
||||
@ -982,26 +1018,31 @@ struct retro_hw_render_context_negotiation_interface
|
||||
* implement frame-sensitive frontend features such as netplay or
|
||||
* rerecording. */
|
||||
#define RETRO_SERIALIZATION_QUIRK_INCOMPLETE (1 << 0)
|
||||
|
||||
/* The core must spend some time initializing before serialization is
|
||||
* supported. retro_serialize() will initially fail; retro_unserialize()
|
||||
* and retro_serialize_size() may or may not work correctly either. */
|
||||
#define RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE (1 << 1)
|
||||
/* Serialization size may change within a session. */
|
||||
#define RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE (1 << 2)
|
||||
|
||||
/* Set by the frontend to acknowledge that it supports variable-sized
|
||||
* states. */
|
||||
#define RETRO_SERIALIZATION_QUIRK_FRONT_VARIABLE_SIZE (1 << 3)
|
||||
/* Serialized state can only be loaded during the same session. */
|
||||
#define RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION (1 << 4)
|
||||
|
||||
/* Serialized state cannot be loaded on an architecture with a different
|
||||
* endianness from the one it was saved on. */
|
||||
#define RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT (1 << 5)
|
||||
|
||||
/* Serialized state cannot be loaded on a different platform from the one it
|
||||
* was saved on for reasons other than endianness, such as word size
|
||||
* dependence */
|
||||
#define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6)
|
||||
|
||||
#define RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS 44
|
||||
|
||||
/* uint64_t * --
|
||||
* Sets quirk flags associated with serialization. The frontend will zero any flags it doesn't
|
||||
* recognize or support. Should be set in either retro_init or retro_load_game, but not both.
|
||||
@ -1615,6 +1656,7 @@ typedef void (RETRO_CALLCONV *retro_frame_time_callback_t)(retro_usec_t usec);
|
||||
struct retro_frame_time_callback
|
||||
{
|
||||
retro_frame_time_callback_t callback;
|
||||
|
||||
/* Represents the time of one frame. It is computed as
|
||||
* 1000000 / fps, but the implementation will resolve the
|
||||
* rounding to ensure that framestepping, etc is exact. */
|
||||
@ -1652,11 +1694,13 @@ enum retro_hw_context_type
|
||||
RETRO_HW_CONTEXT_OPENGL = 1,
|
||||
/* OpenGL ES 2.0. */
|
||||
RETRO_HW_CONTEXT_OPENGLES2 = 2,
|
||||
|
||||
/* Modern desktop core GL context. Use version_major/
|
||||
* version_minor fields to set GL version. */
|
||||
RETRO_HW_CONTEXT_OPENGL_CORE = 3,
|
||||
/* OpenGL ES 3.0 */
|
||||
RETRO_HW_CONTEXT_OPENGLES3 = 4,
|
||||
|
||||
/* OpenGL ES 3.1+. Set version_major/version_minor. For GLES2 and GLES3,
|
||||
* use the corresponding enums directly. */
|
||||
RETRO_HW_CONTEXT_OPENGLES_VERSION = 5,
|
||||
@ -1991,29 +2035,30 @@ struct retro_game_info
|
||||
#define RETRO_MEMORY_ACCESS_READ (1 << 1)
|
||||
/* The core will read from retro_framebuffer::data. */
|
||||
#define RETRO_MEMORY_TYPE_CACHED (1 << 0)
|
||||
|
||||
/* The memory in data is cached.
|
||||
* If not cached, random writes and/or reading from the buffer is expected to be very slow. */
|
||||
struct retro_framebuffer
|
||||
{
|
||||
void * data; /* The framebuffer which the core can render into.
|
||||
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER.
|
||||
The initial contents of data are unspecified. */
|
||||
* Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER.
|
||||
* The initial contents of data are unspecified. */
|
||||
unsigned width; /* The framebuffer width used by the core. Set by core. */
|
||||
unsigned height; /* The framebuffer height used by the core. Set by core. */
|
||||
size_t pitch; /* The number of bytes between the beginning of a scanline,
|
||||
and beginning of the next scanline.
|
||||
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
|
||||
* and beginning of the next scanline.
|
||||
* Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
|
||||
enum retro_pixel_format format; /* The pixel format the core must use to render into data.
|
||||
This format could differ from the format used in
|
||||
SET_PIXEL_FORMAT.
|
||||
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
|
||||
* This format could differ from the format used in
|
||||
* SET_PIXEL_FORMAT.
|
||||
* Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
|
||||
|
||||
unsigned access_flags; /* How the core will access the memory in the framebuffer.
|
||||
RETRO_MEMORY_ACCESS_* flags.
|
||||
Set by core. */
|
||||
* RETRO_MEMORY_ACCESS_* flags.
|
||||
* Set by core. */
|
||||
unsigned memory_flags; /* Flags telling core how the memory has been mapped.
|
||||
RETRO_MEMORY_TYPE_* flags.
|
||||
Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
|
||||
* RETRO_MEMORY_TYPE_* flags.
|
||||
* Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */
|
||||
};
|
||||
|
||||
/* Callbacks */
|
||||
|
485
mrboom.c
485
mrboom.c
@ -98,7 +98,8 @@
|
||||
#define max_s 16
|
||||
#define max_s2 8
|
||||
|
||||
Memory m = {
|
||||
Memory m =
|
||||
{
|
||||
{ { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, { { 0 } }, // registers
|
||||
0, 0, 0, 0, 0, 0, //flags
|
||||
0, //isLittle
|
||||
@ -264714,23 +264715,39 @@ time_bouboule, //changementzz2
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
, //heap
|
||||
{0},{0},{0}, NULL};
|
||||
{0 }, { 0 }, { 0 }, NULL
|
||||
};
|
||||
|
||||
int program() {
|
||||
int program()
|
||||
{
|
||||
jmp_buf jmpbuffer;
|
||||
void * dest;
|
||||
void * src;
|
||||
int i;
|
||||
|
||||
#ifdef INCLUDEMAIN
|
||||
dest = NULL; src = NULL; i = 0; //to avoid a warning.
|
||||
#endif
|
||||
if (m.executionFinished) goto moveToBackGround;
|
||||
if (m.jumpToBackGround) {
|
||||
if (m.executionFinished)
|
||||
{
|
||||
goto moveToBackGround;
|
||||
}
|
||||
if (m.jumpToBackGround)
|
||||
{
|
||||
m.jumpToBackGround = 0;
|
||||
#ifdef MRBOOM
|
||||
if (m.nosetjmp) m.stackPointer=0; // this an an hack to avoid setJmp in saved state.
|
||||
if (m.nosetjmp==2) goto directjeu;
|
||||
if (m.nosetjmp==1) goto directmenu;
|
||||
if (m.nosetjmp)
|
||||
{
|
||||
m.stackPointer = 0; // this an an hack to avoid setJmp in saved state.
|
||||
}
|
||||
if (m.nosetjmp == 2)
|
||||
{
|
||||
goto directjeu;
|
||||
}
|
||||
if (m.nosetjmp == 1)
|
||||
{
|
||||
goto directmenu;
|
||||
}
|
||||
#endif
|
||||
RET;
|
||||
}
|
||||
@ -276549,8 +276566,11 @@ m.executionFinished = 1;
|
||||
moveToBackGround:
|
||||
return(m.executionFinished == 0);
|
||||
}
|
||||
void asm2C_printOffsets(unsigned int offset) {
|
||||
|
||||
void asm2C_printOffsets(unsigned int offset)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
file = fopen("./memoryMap.log", "w");
|
||||
fprintf(file, "xox %x (from beg RW) %x:dummy1\n", (unsigned int)offsetof(struct Mem, dummy1) - offset, (unsigned int)offsetof(struct Mem, dummy1));
|
||||
fprintf(file, "xox %x (from beg RW) %x:beginningdata\n", (unsigned int)offsetof(struct Mem, beginningdata) - offset, (unsigned int)offsetof(struct Mem, beginningdata));
|
||||
@ -279020,19 +279040,30 @@ fclose(file);
|
||||
FILE *logDebug = NULL;
|
||||
|
||||
#define MAX_FMT_SIZE 1024
|
||||
void log_error(const char *fmt, ...) {
|
||||
void log_error(const char *fmt, ...)
|
||||
{
|
||||
char formatted_string[MAX_FMT_SIZE];
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(formatted_string, fmt, argptr);
|
||||
va_end(argptr);
|
||||
#ifdef __LIBRETRO__
|
||||
log_cb(RETRO_LOG_ERROR, "%s", formatted_string);
|
||||
#else
|
||||
if (logDebug!=NULL) { fprintf(logDebug,"%s",formatted_string); } else { printf("%s",formatted_string); }
|
||||
if (logDebug != NULL)
|
||||
{
|
||||
fprintf(logDebug, "%s", formatted_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", formatted_string);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void log_debug(const char *fmt, ...) {
|
||||
|
||||
void log_debug(const char *fmt, ...)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
char formatted_string[MAX_FMT_SIZE];
|
||||
va_list argptr;
|
||||
@ -279042,25 +279073,42 @@ void log_debug(const char *fmt, ...) {
|
||||
#ifdef __LIBRETRO__
|
||||
log_cb(RETRO_LOG_DEBUG, "%s", formatted_string);
|
||||
#else
|
||||
if (logDebug!=NULL) { fprintf(logDebug,"%s",formatted_string); } else { printf("%s",formatted_string); }
|
||||
if (logDebug != NULL)
|
||||
{
|
||||
fprintf(logDebug, "%s", formatted_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", formatted_string);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_info(const char *fmt, ...) {
|
||||
void log_info(const char *fmt, ...)
|
||||
{
|
||||
char formatted_string[MAX_FMT_SIZE];
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(formatted_string, fmt, argptr);
|
||||
va_end(argptr);
|
||||
#ifdef __LIBRETRO__
|
||||
log_cb(RETRO_LOG_INFO, "%s", formatted_string);
|
||||
#else
|
||||
if (logDebug!=NULL) { fprintf(logDebug,"%s",formatted_string); } else { printf("%s",formatted_string); }
|
||||
if (logDebug != NULL)
|
||||
{
|
||||
fprintf(logDebug, "%s", formatted_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s", formatted_string);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_debug2(const char *fmt, ...) {
|
||||
void log_debug2(const char *fmt, ...)
|
||||
{
|
||||
#if DEBUG == 2
|
||||
char formatted_string[MAX_FMT_SIZE];
|
||||
va_list argptr;
|
||||
@ -279071,17 +279119,24 @@ void log_debug2(const char *fmt, ...) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkIfVgaRamEmpty() {
|
||||
void checkIfVgaRamEmpty()
|
||||
{
|
||||
int i;
|
||||
int vgaram_empty = 1;
|
||||
|
||||
for (i = 0; i < VGARAM_SIZE; i++)
|
||||
{
|
||||
if (m.vgaRam[i])
|
||||
{
|
||||
vgaram_empty = 0;
|
||||
}
|
||||
}
|
||||
log_debug("vgaram_empty : %s\n", vgaram_empty ? "true" : "false");
|
||||
(void)vgaram_empty;
|
||||
}
|
||||
|
||||
void stackDump() {
|
||||
void stackDump()
|
||||
{
|
||||
log_debug("is_little_endian()=%d\n", m.isLittle);
|
||||
log_debug("sizeof(dd)=%zu\n", sizeof(dd));
|
||||
log_debug("sizeof(dd *)=%zu\n", sizeof(dd *));
|
||||
@ -279114,30 +279169,38 @@ void stackDump() {
|
||||
}
|
||||
|
||||
// thanks to paxdiablo http://stackoverflow.com/users/14860/paxdiablo for the hexDump function
|
||||
void hexDump (void *addr, int len) {
|
||||
void hexDump(void *addr, int len)
|
||||
{
|
||||
int i;
|
||||
unsigned char buff[17];
|
||||
unsigned char *pc = (unsigned char *)addr;
|
||||
|
||||
(void)buff;
|
||||
log_debug("hexDump %p:\n", addr);
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0)
|
||||
{
|
||||
log_debug(" ZERO LENGTH\n");
|
||||
return;
|
||||
}
|
||||
if (len < 0) {
|
||||
if (len < 0)
|
||||
{
|
||||
log_debug(" NEGATIVE LENGTH: %i\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
// Process every byte in the data.
|
||||
for (i = 0; i < len; i++) {
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
// Multiple of 16 means new line (with line offset).
|
||||
|
||||
if ((i % 16) == 0) {
|
||||
if ((i % 16) == 0)
|
||||
{
|
||||
// Just don't print ASCII for the zeroth line.
|
||||
if (i != 0)
|
||||
{
|
||||
log_debug(" %s\n", buff);
|
||||
}
|
||||
|
||||
// Output the offset.
|
||||
log_debug(" %04x ", i);
|
||||
@ -279148,14 +279211,19 @@ void hexDump (void *addr, int len) {
|
||||
|
||||
// And store a printable ASCII character for later.
|
||||
if ((pc[i] < 0x20) || (pc[i] > 0x7e))
|
||||
{
|
||||
buff[i % 16] = '.';
|
||||
}
|
||||
else
|
||||
{
|
||||
buff[i % 16] = pc[i];
|
||||
}
|
||||
buff[(i % 16) + 1] = '\0';
|
||||
}
|
||||
|
||||
// Pad out last line if not exactly 16 characters.
|
||||
while ((i % 16) != 0) {
|
||||
while ((i % 16) != 0)
|
||||
{
|
||||
log_debug(" ");
|
||||
i++;
|
||||
}
|
||||
@ -279164,46 +279232,62 @@ void hexDump (void *addr, int len) {
|
||||
log_debug(" %s\n", buff);
|
||||
}
|
||||
|
||||
void asm2C_OUT(int16_t address, int data) {
|
||||
void asm2C_OUT(int16_t address, int data)
|
||||
{
|
||||
static int indexPalette = 0;
|
||||
switch(address) {
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x3c8:
|
||||
indexPalette = data;
|
||||
break;
|
||||
|
||||
case 0x3c9:
|
||||
if (indexPalette<768) {
|
||||
if (indexPalette < 768)
|
||||
{
|
||||
m.vgaPalette[indexPalette] = data;
|
||||
indexPalette++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("error: indexPalette>767 %d\n", indexPalette);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("unknown OUT %d,%d\n", address, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t asm2C_IN(int16_t address) {
|
||||
int8_t asm2C_IN(int16_t address)
|
||||
{
|
||||
static bool vblTick = 1;
|
||||
switch(address) {
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x3DA:
|
||||
if (vblTick) {
|
||||
if (vblTick)
|
||||
{
|
||||
vblTick = 0;
|
||||
return 0;
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vblTick = 1;
|
||||
m.jumpToBackGround = 1;
|
||||
return 8;
|
||||
return(8);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unknown IN %d\n", address);
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_little_endian_real_check() {
|
||||
bool is_little_endian_real_check()
|
||||
{
|
||||
union
|
||||
{
|
||||
uint16_t x;
|
||||
@ -279211,7 +279295,7 @@ bool is_little_endian_real_check() {
|
||||
} u;
|
||||
|
||||
u.x = 1;
|
||||
return u.y[0];
|
||||
return(u.y[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -279225,31 +279309,34 @@ bool is_little_endian_real_check() {
|
||||
bool is_little_endian()
|
||||
{
|
||||
#if defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64)
|
||||
return 1;
|
||||
return(1);
|
||||
#elif defined(MSB_FIRST)
|
||||
return 0;
|
||||
return(0);
|
||||
#else
|
||||
return is_little_endian_real_check();
|
||||
return(is_little_endian_real_check());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void asm2C_init() {
|
||||
void asm2C_init()
|
||||
{
|
||||
m.isLittle = is_little_endian();
|
||||
#ifdef MSB_FIRST
|
||||
if (m.isLittle) {
|
||||
if (m.isLittle)
|
||||
{
|
||||
log_error("Inconsistency: is_little_endian=true and MSB_FIRST defined.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
if (m.isLittle!=is_little_endian_real_check()) {
|
||||
if (m.isLittle != is_little_endian_real_check())
|
||||
{
|
||||
log_error("Inconsistency in little/big endianness detection. Please check if the Makefile sets MSB_FIRST properly for this architecture.\n");
|
||||
exit(1);
|
||||
}
|
||||
log_debug2("asm2C_init is_little_endian:%d\n", m.isLittle);
|
||||
}
|
||||
|
||||
void asm2C_INT(int a) {
|
||||
void asm2C_INT(int a)
|
||||
{
|
||||
static FILE *file;
|
||||
int i;
|
||||
db ah = READDBh(eax);
|
||||
@ -279258,10 +279345,12 @@ void asm2C_INT(int a) {
|
||||
dw bx = READDW(ebx);
|
||||
dw cx = READDW(ecx);
|
||||
dw dx = READDW(edx);
|
||||
|
||||
m.CF = 0;
|
||||
log_debug2("asm2C_INT ah=%x al=%x ax=%x bx=%x cx=%x dx=%x\n", ah, al, ax, bx, cx, dx);
|
||||
|
||||
switch(a) {
|
||||
switch (a)
|
||||
{
|
||||
case 0x10:
|
||||
{
|
||||
switch (ax)
|
||||
@ -279270,6 +279359,7 @@ void asm2C_INT(int a) {
|
||||
log_debug2("Switch to text mode\n");
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x13: {
|
||||
log_debug2("Switch to VGA\n");
|
||||
stackDump();
|
||||
@ -279278,17 +279368,20 @@ void asm2C_INT(int a) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x21:
|
||||
switch (ah)
|
||||
{
|
||||
case 0x9:
|
||||
{
|
||||
char *s = (char *)realAddress(m.edx.dd.val, ds);
|
||||
for (i=0; s[i]!='$'; i++) {
|
||||
for (i = 0; s[i] != '$'; i++)
|
||||
{
|
||||
printf("%c", s[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x2c:
|
||||
{
|
||||
//MOV(8,8,READDBh(edx),(db)2);
|
||||
@ -279296,42 +279389,52 @@ void asm2C_INT(int a) {
|
||||
m.edx.dd.val = 0x200;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x3d:
|
||||
{
|
||||
char fileName[1000];
|
||||
if (m.path!=NULL) {
|
||||
if (m.path != NULL)
|
||||
{
|
||||
sprintf(fileName, "%s/%s", m.path, (const char *)realAddress(m.edx.dd.val, ds));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(fileName, "%s", (const char *)realAddress(m.edx.dd.val, ds));
|
||||
}
|
||||
file = fopen(fileName, "rb"); //TOFIX, multiple files support
|
||||
log_debug2("Opening file %s -> %p\n", fileName, (void *)file);
|
||||
if (file!=NULL) {
|
||||
if (file != NULL)
|
||||
{
|
||||
m.eax.dd.val = 1; //TOFIX
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
m.CF = 1;
|
||||
log_error("Error opening file %s\n", fileName);
|
||||
}
|
||||
|
||||
/*
|
||||
// [Index]AH = 3Dh - "OPEN" - OPEN EXISTING FILE
|
||||
Entry:
|
||||
|
||||
AL = access and sharing modes
|
||||
DS:DX -> ASCIZ filename
|
||||
Return:
|
||||
|
||||
CF clear if successful, AX = file handle
|
||||
CF set on error AX = error code (01h,02h,03h,04h,05h,0Ch,56h)
|
||||
* // [Index]AH = 3Dh - "OPEN" - OPEN EXISTING FILE
|
||||
* Entry:
|
||||
*
|
||||
* AL = access and sharing modes
|
||||
* DS:DX -> ASCIZ filename
|
||||
* Return:
|
||||
*
|
||||
* CF clear if successful, AX = file handle
|
||||
* CF set on error AX = error code (01h,02h,03h,04h,05h,0Ch,56h)
|
||||
*/
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x3e:
|
||||
{
|
||||
// bx: file handle to close
|
||||
//TOFIX
|
||||
log_debug2("Closing file. bx:%d\n", bx);
|
||||
if (fclose(file)) {
|
||||
if (fclose(file))
|
||||
{
|
||||
m.CF = 1;
|
||||
perror("Error");
|
||||
log_error("Error closing file ? bx:%d %p\n", bx, (void *)file);
|
||||
@ -279340,80 +279443,94 @@ void asm2C_INT(int a) {
|
||||
file = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x3f:
|
||||
{
|
||||
/*
|
||||
[Index]AH = 3Fh - "READ" - READ FROM FILE OR DEVICE
|
||||
|
||||
Entry:
|
||||
|
||||
BX = file handle
|
||||
CX = number of bytes to read
|
||||
DS:DX -> buffer for data
|
||||
Return:
|
||||
|
||||
CF clear if successful - AX = number of bytes actually read (0 if at EOF before call)
|
||||
CF set on error AX = error code (05h,06h)
|
||||
* [Index]AH = 3Fh - "READ" - READ FROM FILE OR DEVICE
|
||||
*
|
||||
* Entry:
|
||||
*
|
||||
* BX = file handle
|
||||
* CX = number of bytes to read
|
||||
* DS:DX -> buffer for data
|
||||
* Return:
|
||||
*
|
||||
* CF clear if successful - AX = number of bytes actually read (0 if at EOF before call)
|
||||
* CF set on error AX = error code (05h,06h)
|
||||
*/
|
||||
//char grosbuff[100000];
|
||||
void *buffer = (db *)realAddress(m.edx.dd.val, ds);
|
||||
// log_debug2("Reading ecx=%d cx=%d eds=%x edx=%x -> %p file: %p\n",m.ecx.dd.val,cx,m.ds,m.edx,buffer,(void *) file);
|
||||
|
||||
if (feof(file)) {
|
||||
if (feof(file))
|
||||
{
|
||||
log_debug2("feof(file)\n");
|
||||
m.eax.dd.val = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t r = fread(buffer, 1, cx, file);
|
||||
if (r!=cx) {
|
||||
if (r != cx)
|
||||
{
|
||||
perror("Error");
|
||||
log_error("r!=cx cx:%d R:%zu \n", cx, r);
|
||||
if(!feof(file)) {
|
||||
if (!feof(file))
|
||||
{
|
||||
log_error("Error reading ? %d %zu %p\n", cx, r, (void *)file);
|
||||
m.CF = 1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug2("Reading OK %p\n", (void *)file);
|
||||
}
|
||||
m.eax.dd.val = r;
|
||||
}
|
||||
/*
|
||||
if (ax!=cx) {
|
||||
log_debug("Error reading ? %d %d\n",ax,cx);
|
||||
m.CF = 1;
|
||||
|
||||
}
|
||||
/*
|
||||
* if (ax!=cx) {
|
||||
* log_debug("Error reading ? %d %d\n",ax,cx);
|
||||
* m.CF = 1;
|
||||
*
|
||||
* }
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
// [Index]AH=42h - "LSEEK" - SET CURRENT FILE POSITION
|
||||
case 0x42:
|
||||
{
|
||||
/*
|
||||
|
||||
AH=42h - "LSEEK" - SET CURRENT FILE POSITION
|
||||
|
||||
Entry:
|
||||
|
||||
AL = origin of move 00h start of file 01h current file position 02h end of file
|
||||
BX = file handle
|
||||
CX:DX = offset from origin of new file position
|
||||
|
||||
*
|
||||
* AH=42h - "LSEEK" - SET CURRENT FILE POSITION
|
||||
*
|
||||
* Entry:
|
||||
*
|
||||
* AL = origin of move 00h start of file 01h current file position 02h end of file
|
||||
* BX = file handle
|
||||
* CX:DX = offset from origin of new file position
|
||||
*
|
||||
*/
|
||||
int seek = 0;
|
||||
switch(ah) {
|
||||
switch (ah)
|
||||
{
|
||||
case 0x0:
|
||||
seek = SEEK_SET;
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
seek = SEEK_CUR;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
seek = SEEK_END;
|
||||
break;
|
||||
}
|
||||
long int offset = (cx << 16) + dx;
|
||||
log_debug2("Seeking to offset %ld %d\n", offset, seek);
|
||||
if (fseek(file,offset,seek)!=0) {
|
||||
if (fseek(file, offset, seek) != 0)
|
||||
{
|
||||
log_error("Error seeking\n");
|
||||
}
|
||||
return;
|
||||
@ -279427,54 +279544,61 @@ void asm2C_INT(int a) {
|
||||
m.exitCode = al;
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x31:
|
||||
switch (ax)
|
||||
{
|
||||
case 0x0:
|
||||
{
|
||||
/*
|
||||
;2.0 - Function 0000h - Allocate Descriptors:
|
||||
;--------------------------------------------
|
||||
; Allocates one or more descriptors in the client's descriptor table. The
|
||||
;descriptor(s) allocated must be initialized by the application with other
|
||||
;function calls.
|
||||
;In:
|
||||
; AX = 0000h
|
||||
; CX = number of descriptors to allocate
|
||||
;Out:
|
||||
; if successful:
|
||||
; carry flag clear
|
||||
; AX = base selector
|
||||
* ;2.0 - Function 0000h - Allocate Descriptors:
|
||||
* ;--------------------------------------------
|
||||
* ; Allocates one or more descriptors in the client's descriptor table. The
|
||||
* ;descriptor(s) allocated must be initialized by the application with other
|
||||
* ;function calls.
|
||||
* ;In:
|
||||
* ; AX = 0000h
|
||||
* ; CX = number of descriptors to allocate
|
||||
* ;Out:
|
||||
* ; if successful:
|
||||
* ; carry flag clear
|
||||
* ; AX = base selector
|
||||
*/
|
||||
log_debug2("Function 0000h - Allocate %d Descriptors\n", cx);
|
||||
if (m.selectorsPointer+cx>=NB_SELECTORS) {
|
||||
if (m.selectorsPointer + cx >= NB_SELECTORS)
|
||||
{
|
||||
m.CF = 1;
|
||||
log_error("Not enough free selectors (increase NB_SELECTORS)\n");
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
m.eax.dd.val = m.selectorsPointer;
|
||||
m.selectorsPointer += cx;
|
||||
log_debug2("Return %x\n", m.eax.dd.val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x02:
|
||||
{
|
||||
/*
|
||||
This function Converts a real mode segment into a protected mode descriptor.
|
||||
BX = real mode segment
|
||||
Out:
|
||||
if successful:
|
||||
carry flag clear
|
||||
AX = selector
|
||||
if failed:
|
||||
carry flag set
|
||||
* This function Converts a real mode segment into a protected mode descriptor.
|
||||
* BX = real mode segment
|
||||
* Out:
|
||||
* if successful:
|
||||
* carry flag clear
|
||||
* AX = selector
|
||||
* if failed:
|
||||
* carry flag set
|
||||
*/
|
||||
log_debug2("Function 0002h - Converts a real mode segment into a protected mode descriptor real mode segment: %d\n", m.ebx.dd.val);
|
||||
if (m.selectorsPointer+1>=NB_SELECTORS) {
|
||||
if (m.selectorsPointer + 1 >= NB_SELECTORS)
|
||||
{
|
||||
m.CF = 1;
|
||||
log_error("Not enough free selectors (increase NB_SELECTORS)\n");
|
||||
return;
|
||||
@ -279489,18 +279613,20 @@ void asm2C_INT(int a) {
|
||||
// Multiple calls for the same real mode segment return the same selector. The returned descriptor should never be modified or freed. <- TOFIX
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
;2.5 - Function 0007h - Set Segment Base Address:
|
||||
; Sets the 32bit linear base address field in the descriptor for the specified
|
||||
; segment.
|
||||
; In: AX = 0007h
|
||||
; BX = selector
|
||||
; CX:DX = 32bit linear base address of segment
|
||||
* ;2.5 - Function 0007h - Set Segment Base Address:
|
||||
* ; Sets the 32bit linear base address field in the descriptor for the specified
|
||||
* ; segment.
|
||||
* ; In: AX = 0007h
|
||||
* ; BX = selector
|
||||
* ; CX:DX = 32bit linear base address of segment
|
||||
*/
|
||||
case 0x07:
|
||||
{
|
||||
log_debug2("Function 0007h - Set Segment Base Address: ebx: %x, edx:%x ecx:%x\n", READDD(ebx), READDD(edx), READDD(ecx));
|
||||
if (bx>m.selectorsPointer) {
|
||||
if (bx > m.selectorsPointer)
|
||||
{
|
||||
m.CF = 1;
|
||||
log_error("Error: selector number doesn't exist\n");
|
||||
return;
|
||||
@ -279509,47 +279635,52 @@ void asm2C_INT(int a) {
|
||||
log_debug2("Address for selector %d: %x\n", bx, m.selectors[bx]);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x08:
|
||||
{
|
||||
/*
|
||||
;2.6 - Function 0008h - Set Segment Limit:
|
||||
;-----------------------------------------
|
||||
; Sets the limit field in the descriptor for the specified segment.
|
||||
; In:
|
||||
; AX = 0008h
|
||||
; BX = selector
|
||||
; CX:DX = 32bit segment limit
|
||||
; Out:
|
||||
; if successful:
|
||||
; carry flag clear
|
||||
; if failed:
|
||||
; carry flag set
|
||||
* ;2.6 - Function 0008h - Set Segment Limit:
|
||||
* ;-----------------------------------------
|
||||
* ; Sets the limit field in the descriptor for the specified segment.
|
||||
* ; In:
|
||||
* ; AX = 0008h
|
||||
* ; BX = selector
|
||||
* ; CX:DX = 32bit segment limit
|
||||
* ; Out:
|
||||
* ; if successful:
|
||||
* ; carry flag clear
|
||||
* ; if failed:
|
||||
* ; carry flag set
|
||||
*/
|
||||
|
||||
// To implement...
|
||||
log_debug2("Function 0008h - Set Segment Limit for selector %d (Ignored)\n", bx);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x501:
|
||||
{
|
||||
/*
|
||||
;2.29 - Function 0501h - Allocate Memory Block:
|
||||
;In: AX = 0501h
|
||||
; BX:CX = size of block in bytes (must be non-zero)
|
||||
;Out: if successful:
|
||||
; carry flag clear
|
||||
; BX:CX = linear address of allocated memory block
|
||||
; SI:DI = memory block handle (used to resize and free block)
|
||||
* ;2.29 - Function 0501h - Allocate Memory Block:
|
||||
* ;In: AX = 0501h
|
||||
* ; BX:CX = size of block in bytes (must be non-zero)
|
||||
* ;Out: if successful:
|
||||
* ; carry flag clear
|
||||
* ; BX:CX = linear address of allocated memory block
|
||||
* ; SI:DI = memory block handle (used to resize and free block)
|
||||
*/
|
||||
int32_t nbBlocks = (bx << 16) + cx;
|
||||
log_debug2("Function 0501h - Allocate Memory Block: %d bytes\n", nbBlocks);
|
||||
|
||||
if (m.heapPointer+nbBlocks>=HEAP_SIZE) {
|
||||
if (m.heapPointer + nbBlocks >= HEAP_SIZE)
|
||||
{
|
||||
m.CF = 1;
|
||||
log_error("Not enough memory (increase HEAP_SIZE)\n");
|
||||
exit(1);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dd a = offsetof(struct Mem, heap) + m.heapPointer;
|
||||
m.heapPointer += nbBlocks;
|
||||
{
|
||||
@ -279564,35 +279695,37 @@ void asm2C_INT(int a) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x205: {
|
||||
/*
|
||||
fo implement
|
||||
;2.18 - Function 0204h - Get Protected Mode Interrupt Vector:
|
||||
;------------------------------------------------------------
|
||||
;
|
||||
; Returns the address of the current protected mode interrupt handler for the
|
||||
;specified interrupt.
|
||||
;
|
||||
;In:
|
||||
; AX = 0204h
|
||||
; BL = interrupt number
|
||||
;
|
||||
;Out:
|
||||
; always successful:
|
||||
; carry flag clear
|
||||
; CX:EDX = selector:offset of protected mode interrupt handler
|
||||
|
||||
; AX = 0204h
|
||||
; BL = interrupt number
|
||||
;
|
||||
;Out:
|
||||
; always successful:
|
||||
; carry flag clear
|
||||
; CX:EDX = selector:offset of protected mode interrupt handler
|
||||
* fo implement
|
||||
* ;2.18 - Function 0204h - Get Protected Mode Interrupt Vector:
|
||||
* ;------------------------------------------------------------
|
||||
* ;
|
||||
* ; Returns the address of the current protected mode interrupt handler for the
|
||||
* ;specified interrupt.
|
||||
* ;
|
||||
* ;In:
|
||||
* ; AX = 0204h
|
||||
* ; BL = interrupt number
|
||||
* ;
|
||||
* ;Out:
|
||||
* ; always successful:
|
||||
* ; carry flag clear
|
||||
* ; CX:EDX = selector:offset of protected mode interrupt handler
|
||||
*
|
||||
* ; AX = 0204h
|
||||
* ; BL = interrupt number
|
||||
* ;
|
||||
* ;Out:
|
||||
* ; always successful:
|
||||
* ; carry flag clear
|
||||
* ; CX:EDX = selector:offset of protected mode interrupt handler
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -279619,8 +279752,10 @@ uint16_t * pointer=(uint16_t *) (((char *) data)+offset); \
|
||||
for (i = 0; i < b; i++) { \
|
||||
pointer[i] = SWAP16(pointer[i]); \
|
||||
} }
|
||||
void fixBigEndian(void *data) {
|
||||
void fixBigEndian(void *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
INITVAR_dd(offsetof(struct Mem, replayer_saver), 1);
|
||||
INITVAR_dd(offsetof(struct Mem, replayer_saver2), 1);
|
||||
INITVAR_dd(offsetof(struct Mem, replayer_saver3), 1);
|
||||
@ -280400,13 +280535,15 @@ INITVAR_dd(offsetof(struct Mem,dummy2089),3);
|
||||
INITVAR_dw(offsetof(struct Mem, dummy2090), 6);
|
||||
INITVAR_dd(offsetof(struct Mem, dummy2091), 3);
|
||||
INITVAR_dw(offsetof(struct Mem, dummy2092), 6);
|
||||
|
||||
}
|
||||
|
||||
#ifdef INCLUDEMAIN
|
||||
int main() {
|
||||
asm2C_init();stackDump();while (program()) { }
|
||||
return m.exitCode;
|
||||
int main()
|
||||
{
|
||||
asm2C_init(); stackDump(); while (program())
|
||||
{
|
||||
}
|
||||
return(m.exitCode);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
52
mrboom.h
52
mrboom.h
@ -8,7 +8,6 @@
|
||||
#include <setjmp.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -32,58 +31,69 @@ extern "C" {
|
||||
#define dd uint32_t
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
typedef struct dblReg {
|
||||
typedef struct dblReg
|
||||
{
|
||||
db v0;
|
||||
db v1;
|
||||
db v2;
|
||||
db val;
|
||||
} dblReg;
|
||||
typedef struct dbhReg {
|
||||
typedef struct dbhReg
|
||||
{
|
||||
db v0;
|
||||
db v1;
|
||||
db val;
|
||||
db v2;
|
||||
} dbhReg;
|
||||
typedef struct dwReg {
|
||||
typedef struct dwReg
|
||||
{
|
||||
dw v0;
|
||||
dw val;
|
||||
} dwReg;
|
||||
typedef struct dblReg16 {
|
||||
typedef struct dblReg16
|
||||
{
|
||||
db v0;
|
||||
db val;
|
||||
} dblReg16;
|
||||
typedef struct dbhReg16 {
|
||||
typedef struct dbhReg16
|
||||
{
|
||||
db val;
|
||||
db v0;
|
||||
} dbhReg16;
|
||||
#else
|
||||
typedef struct dblReg {
|
||||
typedef struct dblReg
|
||||
{
|
||||
db val;
|
||||
db v0;
|
||||
db v1;
|
||||
db v2;
|
||||
} dblReg;
|
||||
typedef struct dbhReg {
|
||||
typedef struct dbhReg
|
||||
{
|
||||
db v0;
|
||||
db val;
|
||||
db v1;
|
||||
db v2;
|
||||
} dbhReg;
|
||||
typedef struct dwReg {
|
||||
typedef struct dwReg
|
||||
{
|
||||
dw val;
|
||||
dw v0;
|
||||
} dwReg;
|
||||
typedef struct dblReg16 {
|
||||
typedef struct dblReg16
|
||||
{
|
||||
db val;
|
||||
db v0;
|
||||
} dblReg16;
|
||||
typedef struct dbhReg16 {
|
||||
typedef struct dbhReg16
|
||||
{
|
||||
db v0;
|
||||
db val;
|
||||
} dbhReg16;
|
||||
#endif
|
||||
|
||||
typedef struct ddReg {
|
||||
typedef struct ddReg
|
||||
{
|
||||
dd val;
|
||||
} ddReg;
|
||||
|
||||
@ -97,7 +107,8 @@ typedef union registry32Bits
|
||||
} registry32Bits;
|
||||
|
||||
|
||||
typedef struct dwReg16 {
|
||||
typedef struct dwReg16
|
||||
{
|
||||
dw val;
|
||||
} dwReg16;
|
||||
|
||||
@ -116,11 +127,11 @@ typedef union registry16Bits
|
||||
#define HEAP_SIZE 1024 * 1024 * 4
|
||||
#define NB_SELECTORS 128
|
||||
|
||||
#define PUSHAD memcpy (&m.stack[m.stackPointer], &m.eax.dd.val, sizeof (dd)*8); m.stackPointer+=sizeof(dd)*8; assert(m.stackPointer<STACK_SIZE)
|
||||
#define PUSHAD memcpy(&m.stack[m.stackPointer], &m.eax.dd.val, sizeof(dd) * 8); m.stackPointer += sizeof(dd) * 8
|
||||
|
||||
#define POPAD m.stackPointer -= sizeof(dd) * 8; memcpy(&m.eax.dd.val, &m.stack[m.stackPointer], sizeof(dd) * 8)
|
||||
|
||||
#define PUSH(nbBits,a) memcpy (&m.stack[m.stackPointer], &a, sizeof (a)); m.stackPointer+=sizeof(a); assert(m.stackPointer<STACK_SIZE)
|
||||
#define PUSH(nbBits, a) memcpy(&m.stack[m.stackPointer], &a, sizeof(a)); m.stackPointer += sizeof(a)
|
||||
|
||||
#define POP(nbBits, a) m.stackPointer -= sizeof(a); memcpy(&a, &m.stack[m.stackPointer], sizeof(a))
|
||||
|
||||
@ -279,11 +290,13 @@ void asm2C_printOffsets(unsigned int offset);
|
||||
// directmenu
|
||||
#define INT(a) asm2C_INT(a); TESTJUMPTOBACKGROUND
|
||||
|
||||
#define TESTJUMPTOBACKGROUND if (m.jumpToBackGround) CALL(moveToBackGround);
|
||||
#define TESTJUMPTOBACKGROUND if (m.jumpToBackGround) { CALL(moveToBackGround); }
|
||||
|
||||
void asm2C_OUT(int16_t address, int data);
|
||||
|
||||
#define OUT(a, b) asm2C_OUT(a, b)
|
||||
int8_t asm2C_IN(int16_t data);
|
||||
|
||||
#define IN(a, b) a = asm2C_IN(b); TESTJUMPTOBACKGROUND
|
||||
|
||||
#define STI // TODO: STI not implemented
|
||||
@ -349,7 +362,8 @@ extern "C" {
|
||||
#endif
|
||||
#define MRBOOM_H__
|
||||
#pragma pack(push, 1)
|
||||
typedef struct Mem {
|
||||
typedef struct Mem
|
||||
{
|
||||
registry32Bits eax;
|
||||
registry32Bits ebx;
|
||||
registry32Bits ecx;
|
||||
@ -2849,6 +2863,7 @@ char *path;
|
||||
#pragma pack(pop)
|
||||
extern Memory m;
|
||||
int program();
|
||||
|
||||
#define sizeOfeax 4
|
||||
#define sizeOfebx 4
|
||||
#define sizeOfecx 4
|
||||
@ -3234,9 +3249,8 @@ int program();
|
||||
#define sizeOfliste_bombe_array 4
|
||||
|
||||
void fixBigEndian(void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
112
retro.cpp
112
retro.cpp
@ -94,24 +94,31 @@ void retro_init(void)
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
|
||||
{
|
||||
if (strlen(dir))
|
||||
{
|
||||
snprintf(retro_base_directory, sizeof(retro_base_directory), "%s", dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
|
||||
{
|
||||
// If save directory is defined use it, otherwise use system directory
|
||||
if (strlen(dir))
|
||||
{
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", retro_base_directory);
|
||||
}
|
||||
}
|
||||
|
||||
frame_buf = (uint32_t *)calloc(WIDTH * HEIGHT, sizeof(uint32_t));
|
||||
|
||||
mrboom_init();
|
||||
|
||||
/* joypads Allocate descriptor values */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
|
||||
{
|
||||
desc = descriptors[i];
|
||||
size = DESC_NUM_PORTS(desc) * DESC_NUM_INDICES(desc) * DESC_NUM_IDS(desc);
|
||||
descriptors[i]->value = (uint16_t *)calloc(size, sizeof(uint16_t));
|
||||
@ -138,7 +145,7 @@ void retro_deinit(void)
|
||||
|
||||
unsigned retro_api_version(void)
|
||||
{
|
||||
return RETRO_API_VERSION;
|
||||
return(RETRO_API_VERSION);
|
||||
}
|
||||
|
||||
void retro_set_controller_port_device(unsigned port, unsigned device)
|
||||
@ -159,8 +166,6 @@ void retro_get_system_info(struct retro_system_info *info)
|
||||
info->valid_extensions = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||
{
|
||||
float aspect = 16.0f / 9.0f;
|
||||
@ -175,7 +180,6 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||
info->geometry.max_width = WIDTH;
|
||||
info->geometry.max_height = HEIGHT;
|
||||
info->geometry.aspect_ratio = aspect;
|
||||
|
||||
}
|
||||
|
||||
void retro_set_environment(retro_environment_t cb)
|
||||
@ -184,9 +188,13 @@ void retro_set_environment(retro_environment_t cb)
|
||||
bool no_content = true;
|
||||
cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content);
|
||||
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
|
||||
{
|
||||
log_cb = logging.log;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_cb = fallback_log;
|
||||
}
|
||||
std::vector <const retro_variable *> vars_systems;
|
||||
// Add the Global core options
|
||||
vars_systems.push_back(&var_mrboom_teammode);
|
||||
@ -256,7 +264,9 @@ static void update_input(void)
|
||||
|
||||
/* Go through range of ports/indices/IDs */
|
||||
for (port = desc->port_min; port <= desc->port_max; port++)
|
||||
{
|
||||
for (index = desc->index_min; index <= desc->index_max; index++)
|
||||
{
|
||||
for (id = desc->id_min; id <= desc->id_max; id++)
|
||||
{
|
||||
/* Compute offset into array */
|
||||
@ -268,13 +278,16 @@ static void update_input(void)
|
||||
index,
|
||||
id);
|
||||
/* Update state */
|
||||
if (desc->value[offset] != state) {
|
||||
if (desc->value[offset] != state)
|
||||
{
|
||||
mrboom_update_input(id, port, state, false);
|
||||
}
|
||||
desc->value[offset] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_vga(uint32_t *buf, unsigned stride)
|
||||
{
|
||||
@ -283,7 +296,8 @@ void update_vga(uint32_t *buf, unsigned stride)
|
||||
int z = 0;
|
||||
uint32_t * line = buf;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
matrixPalette[z / 3] = ((m.vgaPalette[z] * 4) << 16) | ((m.vgaPalette[z + 1] * 4) << 8) | (m.vgaPalette[z + 2] * 4);
|
||||
z += 3;
|
||||
} while (z != NB_COLORS_PALETTE * 3);
|
||||
@ -293,14 +307,15 @@ void update_vga(uint32_t *buf, unsigned stride)
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
if (y < HEIGHT)
|
||||
{
|
||||
line[x] = matrixPalette[m.vgaRam[x + y * WIDTH]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void render_checkered(void)
|
||||
{
|
||||
|
||||
mrboom_sound();
|
||||
|
||||
/* Try rendering straight into VRAM if we can. */
|
||||
@ -324,45 +339,62 @@ static void render_checkered(void)
|
||||
video_cb(buf, WIDTH, HEIGHT, stride << 2);
|
||||
}
|
||||
|
||||
|
||||
static void check_variables(void)
|
||||
{
|
||||
struct retro_variable var = { 0 };
|
||||
|
||||
var.key = var_mrboom_nomonster.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "ON") == 0)
|
||||
{
|
||||
setNoMonsterMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setNoMonsterMode(true);
|
||||
}
|
||||
}
|
||||
var.key = var_mrboom_autofire.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "ON") == 0)
|
||||
{
|
||||
setAutofire(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAutofire(false);
|
||||
}
|
||||
}
|
||||
var.key = var_mrboom_teammode.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "Selfie") == 0)
|
||||
{
|
||||
setTeamMode(0);
|
||||
}
|
||||
else if (strcmp(var.value, "Sex") == 0)
|
||||
{
|
||||
setTeamMode(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTeamMode(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void retro_run(void)
|
||||
{
|
||||
static int frame = 0;
|
||||
int newFrameNumber = frameNumber();
|
||||
|
||||
frame++;
|
||||
if (frame!=newFrameNumber) {
|
||||
if ((frame) && (newFrameNumber)) {
|
||||
if (frame != newFrameNumber)
|
||||
{
|
||||
if ((frame) && (newFrameNumber))
|
||||
{
|
||||
log_error("Network resynched: %d -> %d\n", frame, newFrameNumber);
|
||||
}
|
||||
}
|
||||
@ -374,29 +406,32 @@ void retro_run(void)
|
||||
program();
|
||||
mrboom_reset_special_keys();
|
||||
mrboom_tick_ai();
|
||||
if (m.executionFinished) {
|
||||
if (m.executionFinished)
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "Exit.\n");
|
||||
environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
|
||||
}
|
||||
bool updated = false;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
{
|
||||
check_variables();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool retro_load_game(const struct retro_game_info *info)
|
||||
{
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
|
||||
return false;
|
||||
return(false);
|
||||
}
|
||||
|
||||
check_variables();
|
||||
|
||||
(void)info;
|
||||
return true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
void retro_unload_game(void)
|
||||
@ -405,77 +440,88 @@ void retro_unload_game(void)
|
||||
|
||||
unsigned retro_get_region(void)
|
||||
{
|
||||
return RETRO_REGION_NTSC;
|
||||
return(RETRO_REGION_NTSC);
|
||||
}
|
||||
|
||||
bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
|
||||
{
|
||||
return retro_load_game(NULL);
|
||||
return(retro_load_game(NULL));
|
||||
}
|
||||
|
||||
#define HARDCODED_RETRO_SERIALIZE_SIZE SIZE_SER + 13 * 8
|
||||
size_t retro_serialize_size(void)
|
||||
{
|
||||
size_t result = HARDCODED_RETRO_SERIALIZE_SIZE;
|
||||
|
||||
assert(tree[0] != NULL);
|
||||
if (tree[0]!=NULL) {
|
||||
if (tree[0] != NULL)
|
||||
{
|
||||
result = (SIZE_SER + tree[0]->serialize_size() * nb_dyna);
|
||||
assert(HARDCODED_RETRO_SERIALIZE_SIZE == result);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("retro_serialize_size returning hardcoded value.\n");
|
||||
}
|
||||
assert(SIZE_MEM_MAX > result);
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool retro_serialize(void *data_, size_t size)
|
||||
{
|
||||
memcpy(data_, &m.FIRST_RW_VARIABLE, SIZE_SER);
|
||||
if (is_little_endian()==false) {
|
||||
if (is_little_endian() == false)
|
||||
{
|
||||
fixBigEndian(data_);
|
||||
}
|
||||
size_t offset = SIZE_SER;
|
||||
for (int i=0; i<nb_dyna; i++) {
|
||||
for (int i = 0; i < nb_dyna; i++)
|
||||
{
|
||||
assert(tree[i] != NULL);
|
||||
tree[i]->serialize(((char *)data_) + offset);
|
||||
offset += tree[i]->serialize_size();
|
||||
}
|
||||
return true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool retro_unserialize(const void *data_, size_t size)
|
||||
{
|
||||
if (size!=retro_serialize_size()) {
|
||||
if (size != retro_serialize_size())
|
||||
{
|
||||
log_error("retro_unserialize error %d/%d\n", size, retro_serialize_size());
|
||||
return false;
|
||||
return(false);
|
||||
}
|
||||
if (is_little_endian()==false) {
|
||||
if (is_little_endian() == false)
|
||||
{
|
||||
char dataTmp[SIZE_MEM_MAX];
|
||||
memcpy(dataTmp, data_, SIZE_SER);
|
||||
fixBigEndian(dataTmp);
|
||||
memcpy(&m.FIRST_RW_VARIABLE, dataTmp, SIZE_SER);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&m.FIRST_RW_VARIABLE, data_, SIZE_SER);
|
||||
}
|
||||
size_t offset = SIZE_SER;
|
||||
for (int i=0; i<nb_dyna; i++) {
|
||||
for (int i = 0; i < nb_dyna; i++)
|
||||
{
|
||||
assert(tree[i] != NULL);
|
||||
tree[i]->unserialize(((char *)data_) + offset);
|
||||
offset += tree[i]->serialize_size();
|
||||
}
|
||||
return true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
void *retro_get_memory_data(unsigned id)
|
||||
{
|
||||
(void)id;
|
||||
return NULL;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
size_t retro_get_memory_size(unsigned id)
|
||||
{
|
||||
(void)id;
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void retro_cheat_reset(void)
|
||||
@ -489,8 +535,10 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
|
||||
(void)code;
|
||||
}
|
||||
|
||||
void show_message(const char * message) {
|
||||
void show_message(const char *message)
|
||||
{
|
||||
struct retro_message msg;
|
||||
|
||||
msg.msg = message;
|
||||
msg.frames = 80;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void *)&msg);
|
||||
|
@ -9,6 +9,7 @@ void show_message(const char * show_message);
|
||||
size_t retro_serialize_size(void);
|
||||
bool retro_serialize(void *data_, size_t size);
|
||||
bool retro_unserialize(const void *data_, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
51
retro_data.h
51
retro_data.h
@ -388,7 +388,8 @@ static const uint32_t wav0_data [3108]= {
|
||||
0xFFC5FFC1, 0xFFF6FFD7, 0x0028FFFE, 0x00250018, 0xFFF40019, 0xFFDA0014, 0xFFF20018, 0x0010000E,
|
||||
0x0009FFED, 0xFFECFFD6, 0xFFDCFFE5, 0xFFDCFFFE, 0xFFD7FFFA, 0xFFCEFFDC, 0xFFCDFFC3, 0xFFC2FFB5,
|
||||
0xFFA1FFAA, 0xFF87FFA9, 0xFF9BFFBE, 0xFFD0FFDA, 0xFFF3FFE6, 0xFFEBFFE3, 0xFFD7FFE8, 0xFFD4FFFC,
|
||||
0xFFD7FFFF,0xFFCCFFDB,0xFFC3FFB3,0xFFCDFFAE};
|
||||
0xFFD7FFFF, 0xFFCCFFDB, 0xFFC3FFB3, 0xFFCDFFAE
|
||||
};
|
||||
static const uint32_t wav1_data [38135] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00010001, 0x00020002, 0x00030003,
|
||||
@ -5156,7 +5157,8 @@ static const uint32_t wav1_data [38135]= {
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFFFE, 0xFFFEFFFE, 0xFFFEFFFE, 0xFFFEFFFE, 0xFFFEFFFE,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00010001, 0x00000000, 0x00000000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF,0xFFFEFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000};
|
||||
0xFFFFFFFF, 0xFFFEFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
static const uint32_t wav2_data [43885] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFDFFFD, 0xFFFCFFFC,
|
||||
0xFFFCFFFC, 0xFFFDFFFD, 0x00000000, 0x00050005, 0x00050005, 0x00090009, 0x000B000B, 0x000D000D,
|
||||
@ -10643,7 +10645,8 @@ static const uint32_t wav2_data [43885]= {
|
||||
0x07D407D4, 0x07990799, 0x077C077C, 0x07820782, 0x07AA07AA, 0x07F207F2, 0x08530853, 0x08C408C4,
|
||||
0x093F093F, 0x09BB09BB, 0x0A300A30, 0x0A960A96, 0x0AE80AE8, 0x0B220B22, 0x0B470B47, 0x0B570B57,
|
||||
0x0B560B56, 0x0B460B46, 0x0B260B26, 0x0AFC0AFC, 0x0AC60AC6, 0x0A830A83, 0x0A310A31, 0x09CC09CC,
|
||||
0x09550955,0x08C808C8,0x08280828,0x07770777,0x06B906B9};
|
||||
0x09550955, 0x08C808C8, 0x08280828, 0x07770777, 0x06B906B9
|
||||
};
|
||||
static const uint32_t wav3_data [53356] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001, 0x00010001, 0x00010001,
|
||||
@ -17314,7 +17317,8 @@ static const uint32_t wav3_data [53356]= {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000};
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
static const uint32_t wav4_data [103118] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
@ -30205,7 +30209,8 @@ static const uint32_t wav4_data [103118]= {
|
||||
0x16D916D9, 0x16F616F6, 0x170C170C, 0x17191719, 0x171D171D, 0x17191719, 0x17101710, 0x17091709,
|
||||
0x17021702, 0x16FC16FC, 0x16F616F6, 0x16F216F2, 0x16EF16EF, 0x16F316F3, 0x16F716F7, 0x16FA16FA,
|
||||
0x16FC16FC, 0x16FD16FD, 0x17001700, 0x17051705, 0x17091709, 0x170B170B, 0x170B170B, 0x17081708,
|
||||
0x17051705,0x17021702,0x16FC16FC,0x16F316F3,0x16EA16EA,0x16E316E3};
|
||||
0x17051705, 0x17021702, 0x16FC16FC, 0x16F316F3, 0x16EA16EA, 0x16E316E3
|
||||
};
|
||||
static const uint32_t wav5_data [11554] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
@ -31651,7 +31656,8 @@ static const uint32_t wav5_data [11554]= {
|
||||
0xDC26DC26, 0xE92EE92E, 0xF768F768, 0x055D055D, 0x121C121C, 0x1CBE1CBE, 0x24FA24FA, 0x2B0D2B0D,
|
||||
0x2FA62FA6, 0x338D338D, 0x37F937F9, 0x3D843D84, 0x44854485, 0x4CCF4CCF, 0x55B655B6, 0x5E2A5E2A,
|
||||
0x64F064F0, 0x68DE68DE, 0x691A691A, 0x654A654A, 0x5DB05DB0, 0x531D531D, 0x46E846E8, 0x3A9E3A9E,
|
||||
0x2FBD2FBD,0x27792779};
|
||||
0x2FBD2FBD, 0x27792779
|
||||
};
|
||||
static const uint32_t wav6_data [37687] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
@ -36363,7 +36369,8 @@ static const uint32_t wav6_data [37687]= {
|
||||
0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00,
|
||||
0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00,
|
||||
0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00,
|
||||
0xFE00FE00,0xFE00FE00,0xFE00FE00,0xFE00FE00,0xFE01FE01,0xFE01FE01,0xFE01FE01};
|
||||
0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE00FE00, 0xFE01FE01, 0xFE01FE01, 0xFE01FE01
|
||||
};
|
||||
static const uint32_t wav7_data [18447] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00020002, 0x00020002,
|
||||
0x00020002, 0x00020002, 0x00000000, 0xFFFDFFFD, 0xFFFDFFFD, 0xFFFBFFFB, 0xFFF9FFF9, 0xFFF8FFF8,
|
||||
@ -38670,7 +38677,8 @@ static const uint32_t wav7_data [18447]= {
|
||||
0x05FC05FC, 0x05F905F9, 0x05EF05EF, 0x05DC05DC, 0x05C205C2, 0x05A005A0, 0x05760576, 0x05470547,
|
||||
0x05160516, 0x04E204E2, 0x04B004B0, 0x047F047F, 0x044E044E, 0x041C041C, 0x03E703E7, 0x03B503B5,
|
||||
0x03830383, 0x03530353, 0x03280328, 0x03060306, 0x02EC02EC, 0x02E102E1, 0x02E202E2, 0x02EF02EF,
|
||||
0x03030303,0x031A031A,0x032C032C,0x03390339,0x03370337,0x03240324,0x03000300};
|
||||
0x03030303, 0x031A031A, 0x032C032C, 0x03390339, 0x03370337, 0x03240324, 0x03000300
|
||||
};
|
||||
static const uint32_t wav8_data [18482] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFAFFFA, 0xFFF8FFF8,
|
||||
0xFFF8FFF8, 0xFFFAFFFA, 0x00010001, 0x000A000A, 0x000A000A, 0x00110011, 0x00170017, 0x00190019,
|
||||
@ -40982,7 +40990,8 @@ static const uint32_t wav8_data [18482]= {
|
||||
0xFFDAFFDA, 0xFFE1FFE1, 0xFFF4FFF4, 0x00140014, 0x003D003D, 0x006F006F, 0x00A400A4, 0x00D700D7,
|
||||
0x01030103, 0x01220122, 0x01320132, 0x01330133, 0x01240124, 0x01080108, 0x00E400E4, 0x00BB00BB,
|
||||
0x00920092, 0x006E006E, 0x00500050, 0x003A003A, 0x00290029, 0x001B001B, 0x000D000D, 0xFFFDFFFD,
|
||||
0xFFEAFFEA,0xFFD0FFD0};
|
||||
0xFFEAFFEA, 0xFFD0FFD0
|
||||
};
|
||||
static const uint32_t wav9_data [24368] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00020002, 0x00020002, 0x00010001, 0xFFFEFFFE, 0xFFFAFFFA, 0xFFF9FFF9, 0xFFF8FFF8,
|
||||
@ -44029,7 +44038,8 @@ static const uint32_t wav9_data [24368]= {
|
||||
0x2EF52EF5, 0x27902790, 0x230C230C, 0x21712171, 0x22722272, 0x25542554, 0x29162916, 0x2C972C97,
|
||||
0x2EC92EC9, 0x2EB62EB6, 0x2BA32BA3, 0x25162516, 0x1B131B13, 0x0DDE0DDE, 0xFE29FE29, 0xECF4ECF4,
|
||||
0xDB93DB93, 0xCB60CB60, 0xBDB2BDB2, 0xB399B399, 0xADD1ADD1, 0xAC77AC77, 0xAF1FAF1F, 0xB4D1B4D1,
|
||||
0xBC2CBC2C,0xC3C3C3C3,0xCA18CA18,0xCE14CE14,0xCF12CF12,0xCD45CD45,0xC916C916,0xC37DC37D};
|
||||
0xBC2CBC2C, 0xC3C3C3C3, 0xCA18CA18, 0xCE14CE14, 0xCF12CF12, 0xCD45CD45, 0xC916C916, 0xC37DC37D
|
||||
};
|
||||
static const uint32_t wav10_data [64330] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x001C001C, 0x00260026,
|
||||
0x00280028, 0x001B001B, 0xFFFDFFFD, 0xFFD0FFD0, 0xFFBBFFBB, 0xFF94FF94, 0xFF7BFF7B, 0xFF78FF78,
|
||||
@ -52072,7 +52082,8 @@ static const uint32_t wav10_data [64330]= {
|
||||
0x03BF03BF, 0x036C036C, 0x03250325, 0x02EB02EB, 0x02CA02CA, 0x02BD02BD, 0x02C402C4, 0x02DA02DA,
|
||||
0x02F502F5, 0x03140314, 0x032C032C, 0x03370337, 0x03320332, 0x031B031B, 0x02F102F1, 0x02BE02BE,
|
||||
0x02850285, 0x024E024E, 0x02210221, 0x02010201, 0x01EF01EF, 0x01F101F1, 0x01FE01FE, 0x02100210,
|
||||
0x021E021E,0x021E021E};
|
||||
0x021E021E, 0x021E021E
|
||||
};
|
||||
static const uint32_t wav11_data [5884] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
@ -52809,7 +52820,8 @@ static const uint32_t wav11_data [5884]= {
|
||||
0x380B380B, 0x35973597, 0x326A326A, 0x2E8F2E8F, 0x2A172A17, 0x252B252B, 0x1FB81FB8, 0x19E719E7,
|
||||
0x13D113D1, 0x0D8D0D8D, 0x074E074E, 0x00F500F5, 0xFAB0FAB0, 0xF48FF48F, 0xEE9EEE9E, 0xE8E8E8E8,
|
||||
0xE390E390, 0xDE68DE68, 0xD992D992, 0xD514D514, 0xD0F5D0F5, 0xCD3DCD3D, 0xCA0ACA0A, 0xC740C740,
|
||||
0xC4FEC4FE,0xC34EC34E,0xC23BC23B,0xC1CBC1CB};
|
||||
0xC4FEC4FE, 0xC34EC34E, 0xC23BC23B, 0xC1CBC1CB
|
||||
};
|
||||
static const uint32_t wav12_data [103118] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
@ -65700,7 +65712,8 @@ static const uint32_t wav12_data [103118]= {
|
||||
0xFAA2FAA2, 0xFE81FE81, 0x02600260, 0x062E062E, 0x09DE09DE, 0x0D5F0D5F, 0x10A010A0, 0x13871387,
|
||||
0x16151615, 0x183D183D, 0x19F719F7, 0x1B401B40, 0x1C161C16, 0x1C771C77, 0x1C6D1C6D, 0x1BFE1BFE,
|
||||
0x1B2F1B2F, 0x1A031A03, 0x187F187F, 0x16991699, 0x145F145F, 0x11D611D6, 0x0F010F01, 0x0BEA0BEA,
|
||||
0x089B089B,0x05150515,0x01720172,0xFDC4FDC4,0xFA1BFA1B,0xF684F684};
|
||||
0x089B089B, 0x05150515, 0x01720172, 0xFDC4FDC4, 0xFA1BFA1B, 0xF684F684
|
||||
};
|
||||
static const uint32_t wav13_data [5042] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
|
||||
0x00000003, 0x0001FFFA, 0xFFF7FFED, 0xFFF20009, 0x000A0037, 0x00270034, 0x0022FFFF, 0x000CFFE2,
|
||||
@ -66332,7 +66345,8 @@ static const uint32_t wav13_data [5042]= {
|
||||
0x00E30171, 0x00EA02C2, 0x0114040B, 0x012D043D, 0x010C0342, 0x00D3022B, 0x00E40244, 0x00CF0268,
|
||||
0x000A0125, 0xFFB000F2, 0x0071031D, 0x00A50366, 0xFFA9005C, 0xFF5DFEE1, 0x00220025, 0x004A001B,
|
||||
0xFFC5FE76, 0xFFD0FE2D, 0x005BFF2D, 0x00A4FFB9, 0x008DFF9E, 0x0053FF6B, 0x0035FF5D, 0x004CFF3E,
|
||||
0x007FFEFA,0x00BFFF27};
|
||||
0x007FFEFA, 0x00BFFF27
|
||||
};
|
||||
static const uint32_t wav14_data [9746] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0x00020002, 0x00040004, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFEFFFE, 0x00010001,
|
||||
@ -67552,7 +67566,8 @@ static const uint32_t wav14_data [9746]= {
|
||||
0x00010001, 0x00040004, 0x00020002, 0x00000000, 0x00030003, 0x00020002, 0x00020002, 0x00040004,
|
||||
0xFFFFFFFF, 0x00010001, 0x00020002, 0xFFFFFFFF, 0x00030003, 0x00020002, 0x00000000, 0x00020002,
|
||||
0x00010001, 0x00010001, 0x00020002, 0x00000000, 0x00000000, 0x00000000, 0x00020002, 0x00010001,
|
||||
0xFFFFFFFF,0x00010001};
|
||||
0xFFFFFFFF, 0x00010001
|
||||
};
|
||||
static const uint32_t wav15_data [8265] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0xFFFF0001, 0x0002FFFF, 0xFFFD0002, 0x0001FFFF, 0x0005FFFC,
|
||||
0xFFF0000E, 0x0029FFDB, 0x0088FF75, 0x0086FF5D, 0x007CFF63, 0x0082FF5F, 0x005BFF68, 0x0036FF7F,
|
||||
@ -68587,9 +68602,11 @@ static const uint32_t wav15_data [8265]= {
|
||||
0x0069004D, 0x005A0041, 0x0051003B, 0x00590045, 0x005B0047, 0x0041002E, 0x001F000C, 0x00150003,
|
||||
0x0022000F, 0x002A0018, 0x002A0018, 0x002B0014, 0x002B0011, 0x00270013, 0x0020001D, 0x001B0028,
|
||||
0x001E002C, 0x0021002A, 0x001E0025, 0x0015001A, 0x0009000B, 0xFFFD0005, 0xFFF80002, 0xFFFEFFFA,
|
||||
0x0009FFF4};
|
||||
0x0009FFF4
|
||||
};
|
||||
|
||||
static struct {
|
||||
static struct
|
||||
{
|
||||
const int16_t *samples;
|
||||
size_t num_samples;
|
||||
} wave[16] =
|
||||
|
557
sdl2/sdl2.cpp
557
sdl2/sdl2.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user