diff options
Diffstat (limited to 'reverse-engineering/dosbox_snif/dos_lemm_sim.c')
-rw-r--r-- | reverse-engineering/dosbox_snif/dos_lemm_sim.c | 341 |
1 files changed, 337 insertions, 4 deletions
diff --git a/reverse-engineering/dosbox_snif/dos_lemm_sim.c b/reverse-engineering/dosbox_snif/dos_lemm_sim.c index 97657d8..e4f7e49 100644 --- a/reverse-engineering/dosbox_snif/dos_lemm_sim.c +++ b/reverse-engineering/dosbox_snif/dos_lemm_sim.c @@ -1,11 +1,344 @@ #include "dos_lemm_sim.h" +#include "utils.h" /* imin() */ -int game_data_diff(struct game_data *g1, struct game_data *g2) { - return 1; +uint8_t is_solid(uint16_t x, uint16_t y); + +// Code segment 0x0208, offsets in comments +void move_lemmings(struct game_data *g) { + uint8_t *g_raw = (uint8_t *) g; + struct _lemm_data *lemm; + uint8_t *lemm_raw; + uint16_t y_test=0x55AA; //=21930 remarkable value if we hit a bug + int i; + + //182F + if ( g->paused ) { + g_raw[0x4d] = FALSE; + return; + } + //1839 + //TODO vga_set_read_mode1_compare_plan3_to_color_8(); + + //183C + g_raw[0x4d] = TRUE; + + //1841 + lemm=&(g->lemmings[0]); + lemm_raw = (uint8_t *) lemm; // Instrumentation + // Replaced (instrumentation) + //g->lemm_count_to_process = g->lemm_spawned_count; + g->lemm_count_to_process = imin(g->lemm_spawned_count, (sizeof(g->lemmings) / sizeof(struct _lemm_data))); + + //184A + while ( g->lemm_count_to_process != 0 ) { + //XXX push es + //1852 + if ( lemm->is_gone ) { + goto next_lemming; + } + //185B + if ( lemm->expl_countdown != 0 ) { + //TODO if ( commit_suicide() != FALSE ) goto next_lemming; + } + //186A + if ( lemm->flags1.bits.walk_pause_for_shruggling ) { + goto lbl_anim_but_no_move; + } + //1877 + if ( lemm->state.raw == 0x0 ) goto lbl_walking; + if ( lemm->state.bits.s_exploding_spe ) goto lbl_exploding_spe; + if ( lemm->state.bits.s_exploding ) goto lbl_exploding; + if ( lemm->state.bits.s_falling ) goto lbl_falling; + if ( lemm->state.bits.s_floating ) goto lbl_floating; + if ( lemm->state.bits.s_splatting ) goto lbl_splatting; + if ( lemm->state.bits.s_ascending ) goto lbl_ascending; + if ( lemm->state.bits.s_digging ) goto lbl_digging; + if ( lemm->state.bits.s_climbing ) goto lbl_climbing; + if ( lemm->state.bits.s_climb_ending ) goto lbl_climb_ending; + if ( lemm->state.bits.s_building ) goto lbl_building; + if ( lemm->state.bits.s_blocking ) goto lbl_blocking; + if ( lemm->state.bits.s_bashing ) goto lbl_bashing; + if ( lemm->state.bits.s_mining ) goto lbl_mining; + if ( lemm->state.bits.s_drawning ) goto lbl_drawning; + if ( lemm->state.bits.s_ending ) goto lbl_ending; + if ( lemm->state.bits.s_dying ) goto lbl_dying; + +check_this_and_go_next_lemming: //18FE + //TODO process_if_in_special_zone(); +next_lemming: //1901 + //XXX pop es + lemm++; + g->lemm_count_to_process--; + //1909 + if ( g->lemm_count_to_process != 0 ) continue; + //190E + if ( g->nuke_all_in_progress ) { + goto nuke_one_by_one; + } + } //1913 end while + + g_raw[0x4d] = FALSE; + //191A + return; // General case end point + +nuke_one_by_one: //191B + if ( g->nuke_i == g->lemm_spawned_count ) { + //1952 + g->nuke_all_in_progress = 0; + g_raw[0x4d] = FALSE; + return; + } + //1924 + lemm=&(g->lemmings[g->nuke_i]); + //1930 + if ( lemm->expl_countdown == 0 ) { + //1936 + if ( lemm->is_gone ) { + //193C + g->nuke_i++; + goto nuke_one_by_one; + } + //1942 + if ( ( lemm->state.raw & (s_exploding | s_splatting | s_exploding_spe) ) == 0 ) { + lemm->expl_countdown = 79; + } + } + //194D + g->nuke_i++; + return; + +lbl_walking: //195D + lemm->spr_frame = (lemm->spr_frame + 1) % 8; + lemm->x_effective += lemm->direction; + //196D + if ( lemm->x_effective<16 || lemm->x_effective>=LEVEL_WIDTH ) { + //1A5B + lemm->direction = - lemm->direction; + goto check_this_and_go_next_lemming; + } + //197E + //TODO vga_mem_read_prepare_registers(); + y_test = lemm->y_effective; + lemm->y_effective--;//XXX rustine + + if ( ! is_solid(lemm->x_effective, y_test) ) { + //19FF + for (i=0;i<3;i++) { + if ( ! is_solid(lemm->x_effective, y_test) ) { + goto walker_adjust_y_or_U_turn; + } + y_test--; + } + //1A26 + for (i=0;i<3;i++) { + if ( ! is_solid(lemm->x_effective, y_test) ) { + //1A82 + //walker_become_ascender + lemm->state.bits.s_ascending=1; + lemm->spr_frame = 8; + y_test = lemm->y_effective - 2; + goto walker_adjust_y_or_U_turn; + } + y_test--; + } + //1A55 + //XXX Seems opposite cond in disassembly + if ( lemm->flags1.bits.cap_climber ) { + //1A92 + //walker_become_climber + lemm_raw[0x28]=0; + lemm_raw[0xa]=0; + lemm_raw[0xb]=0; + lemm_raw[0xc]=0; + lemm_raw[0xd]=0; + lemm->state.bits.s_climbing = 1; + lemm_raw[0x10]=0x48; + lemm_raw[0x11]=0x00; + lemm_raw[0x12]=0x30; + lemm_raw[0x13]=0x00; + lemm->x_spr_offset=-8; + lemm->y_spr_offset=-12; + lemm_raw[0x14]=g_raw[0x2d]; + lemm_raw[0x15]=g_raw[0x2e]; + lemm->draw_trick1 = TRUE; + lemm->draw_hint = 8; + } else { + //1A5B + lemm->direction = - lemm->direction; + } + goto check_this_and_go_next_lemming; + } + //198B + for (i=0; i<3; i++) { + lemm->y_effective++; + if ( is_solid(lemm->x_effective, lemm->y_effective) ) { + goto walker_check_fall_out_of_screen; + } + } +//walker_become_faller: //19AF + lemm->y_effective++; + lemm->state.bits.s_falling=1; + lemm_raw[0xa]=0; + lemm->spr_data_ptr = 0xa42; + lemm_raw[0x10]=0x5a; + lemm_raw[0x11]=0x00; + lemm_raw[0x12]=0x3c; + lemm_raw[0x13]=0x00; + lemm->spr_frame = 0; + lemm->falldist = 3; + lemm->x_spr_offset = -8; + lemm->y_spr_offset = -10; + lemm->draw_hint = hint_falling; + //19DE + lemm->ptr2 = g_raw[0x2b]; + lemm->draw_trick1 = FALSE; + lemm->flags1.bits.walk_pause_for_shruggling = 0; +walker_check_fall_out_of_screen: //19EC + y_test = lemm->y_effective; + if ( y_test >= 180 /* LEVEL_HEIGHT + 20 */ ) { + lemm->is_gone=TRUE; + goto next_lemming; + } + //19F5 + goto check_this_and_go_next_lemming; + + +walker_adjust_y_or_U_turn: //1A61 + lemm->y_effective = y_test; + if ( y_test + lemm->y_spr_offset <= 10 ) { + //1A6F + lemm->y_effective = 9 - lemm->y_spr_offset; + lemm->direction = -lemm->direction; + lemm->state.bits.s_ascending=0; + } + //1A7F + goto check_this_and_go_next_lemming; + +lbl_falling: + //1AC9 + lemm->spr_frame = (lemm->spr_frame + 1) % 4; + if ( lemm->falldist >= 16 && lemm->cap_floater ) { + //1ADF + lemm->state.raw = s_floating; + lemm_raw[0xa]=0; + lemm_raw[0xc]=0x0b; + lemm_raw[0xd]=0xaa; + lemm_raw[0x10]=0x80; + lemm_raw[0x11]=0x00; + lemm_raw[0x12]=0x60; + lemm_raw[0x13]=0x00; + lemm->spr_frame = 0; + lemm->floattime_dble = 0; + lemm->y_spr_offset = -16; + lemm->draw_hint = hint_special1; + //1B0A + lemm->ptr2 = g_raw[0x37]; + lemm->draw_trick1 = TRUE; + lemm->flags1.bits.walk_pause_for_shruggling = 0; + goto check_this_and_go_next_lemming; + } + //1B1B + //TODO vga_mem_read_prepare_registers(); + //TODO + goto check_this_and_go_next_lemming; +lbl_splatting: + //TODO + goto next_lemming; +lbl_drawning: + //TODO + goto next_lemming; +lbl_ending: + //TODO + goto next_lemming; +lbl_dying: + //TODO + goto next_lemming; +lbl_exploding_spe: + //TODO + goto next_lemming; +lbl_ascending: + //TODO + goto walker_adjust_y_or_U_turn; +lbl_digging: + //TODO + goto check_this_and_go_next_lemming; +lbl_climbing: + //TODO + goto walker_adjust_y_or_U_turn; +lbl_climb_ending: + //TODO + goto next_lemming; +lbl_building: + //TODO + goto check_this_and_go_next_lemming; +lbl_blocking: + //TODO + goto next_lemming; +lbl_bashing: + //TODO + goto check_this_and_go_next_lemming; +lbl_floating: + //TODO + goto check_this_and_go_next_lemming; +lbl_mining: + //TODO + goto check_this_and_go_next_lemming; +lbl_exploding: + //TODO + goto next_lemming; +lbl_anim_but_no_move: + //TODO + goto check_this_and_go_next_lemming; + +} // 26F5 end move_lemmings() + + + + +uint8_t is_solid(uint16_t x, uint16_t y) { + //FIXME : memdump the video memory once at start + return TRUE; } -int move_lemmings(struct game_data *g) { +void spawn_lemming(struct game_data *g) { + // 0208:299A + //TODO ecrit à l'intuitive, cf disassembly + g->next_spawn_ticks = ( g->next_spawn_ticks - 1) % g->spawn_rate_ticks; + return; +} + +void draw_lemmings(struct game_data *g) { + // 0208:2F23 + //TODO très incomplet + ((uint8_t *) g)[0x4d] = FALSE; +} + +void fixups_before(struct game_data *g) { + ((uint8_t *) g)[0x4f]++; +} + +void fixups_after(struct game_data *g) { + ((uint8_t *) g)[0x53] += 0x10; + if ( ((uint8_t *) g)[0x53] == 0xD0 ) { + ((uint8_t *) g)[0x53] = 0; + } + //0F4F + if ( ! g->paused ) { + ((uint8_t *) g)[0x82]--; + if ( ((uint8_t *) g)[0x82] == 0 ) { + ((uint8_t *) g)[0x82] = ((uint8_t *) g)[0x83]; + } + } +} + +void main_loop_ingame(struct game_data *g) { + //TODO + fixups_before(g); + + move_lemmings(g); + draw_lemmings(g); + spawn_lemming(g); - return 0; + fixups_after(g); } |