summaryrefslogtreecommitdiff
path: root/reverse-engineering/dosbox_snif/dos_lemm_sim.c
diff options
context:
space:
mode:
Diffstat (limited to 'reverse-engineering/dosbox_snif/dos_lemm_sim.c')
-rw-r--r--reverse-engineering/dosbox_snif/dos_lemm_sim.c341
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);
}