/* * rest_worm() * * Restore the worm information from the save file. Called from restore.c */ void rest_worm(struct memfile *mf, struct level *lev) { int i, j, count; struct wseg *curr, *temp; for (i = 1; i < MAX_NUM_WORMS; i++) { count = mread32(mf); if (!count) continue; /* none */ /* Get the segments. */ for (curr = NULL, j = 0; j < count; j++) { temp = malloc(sizeof (struct wseg)); temp->nseg = NULL; temp->wx = mread8(mf); temp->wy = mread8(mf); if (curr) curr->nseg = temp; else lev->wtails[i] = temp; curr = temp; } lev->wgrowtime[i] = mread32(mf); lev->wheads[i] = curr; } }
static void restore_rect(struct memfile *mf, struct nhrect *r) { r->lx = mread8(mf); r->ly = mread8(mf); r->hx = mread8(mf); r->hy = mread8(mf); }
static uint8 sms_debug_memread(uint16 addr) { uint8 res = mread8(addr); memread[debug_mem_reads1].addr = addr; memread[debug_mem_reads1].write = 0; memread[debug_mem_reads1++].val = res; return res; }
uint8 hio_read8(HIO_HANDLE *h) { switch (HIO_HANDLE_TYPE(h)) { case HIO_HANDLE_TYPE_FILE: return read8(h->handle.file); case HIO_HANDLE_TYPE_MEMORY: return mread8(h->handle.mem); default: return 0; } }
UINT8 program_read_byte_8(UINT32 addr) { int i; for(i = 0; i < debug_mem_reads1; ++i) { if(memread[i].addr == (addr & 0xFFFF)) return memread[i].val; } printf("reading other addr: %04x %04X\n", addr & 0xFFFF, Z80.pc.w.l); return mread8(addr); }
/* * Pull in the structures from disk, but don't recalculate the object * pointers. */ void restore_light_sources(struct memfile *mf, struct level *lev) { int count; intptr_t id; /* we need to restore and preserve order *but* we don't need * to preserve the absolute order, only the relative orders of all * global lights and all local lights---this is because global * lights are for stored on the level and moved around as you do. * As a result, they are saved in different places, and consequently * it will *not* cause a desync as long as relative order is preserved. * So it doesn't actually matter that we retain relative order to other * light sources on the level, only that we restore the light sources here * in reverse order. Inserting immediately after the first light leads to * the simplest code. */ light_source *ls, *prev = lev->lev_lights, *rest = prev ? prev->next : NULL; /* restore elements */ count = mread32(mf); while (count-- > 0) { ls = malloc(sizeof (light_source)); ls->type = mread32(mf); ls->range = mread16(mf); ls->flags = mread16(mf); id = mread32(mf); ls->id = (void *)id; ls->x = mread8(mf); ls->y = mread8(mf); ls->next = rest; if (prev) prev->next = ls; else lev->lev_lights = ls; prev = ls; } }
static void rest_room(struct memfile *mf, struct level *lev, struct mkroom *r) { short i; r->lx = mread8(mf); r->hx = mread8(mf); r->ly = mread8(mf); r->hy = mread8(mf); r->rtype = mread8(mf); r->rlit = mread8(mf); r->doorct = mread8(mf); r->fdoor = mread8(mf); r->nsubrooms = mread8(mf); r->irregular = mread8(mf); for (i = 0; i < r->nsubrooms; i++) { r->sbrooms[i] = &lev->subrooms[lev->nsubroom]; rest_room(mf, lev, &lev->subrooms[lev->nsubroom]); lev->subrooms[lev->nsubroom++].resident = NULL; } }
/* * Pull in the structures from disk, but don't recalculate the object * pointers. */ void restore_light_sources(struct memfile *mf, struct level *lev) { int count; long id; light_source *ls; /* restore elements */ count = mread32(mf); while (count-- > 0) { ls = malloc(sizeof(light_source)); ls->type = mread32(mf); ls->range = mread16(mf); ls->flags = mread16(mf); id = mread32(mf); /* prevent: "cast to pointer from integer of different size" */ ls->id = (void*)id; ls->x = mread8(mf); ls->y = mread8(mf); ls->next = lev->lev_lights; lev->lev_lights = ls; } }
struct obj *restore_obj(struct memfile *mf) { unsigned int oflags; char namelen; struct obj *otmp; mfmagic_check(mf, OBJ_MAGIC); namelen = mread32(mf); otmp = newobj(namelen); memset(otmp, 0, namelen + sizeof(struct obj)); otmp->o_id = mread32(mf); otmp->owt = mread32(mf); otmp->quan = mread32(mf); otmp->corpsenm = mread32(mf); otmp->oeaten = mread32(mf); otmp->age = mread32(mf); otmp->owornmask = mread32(mf); oflags = mread32(mf); otmp->otyp = mread16(mf); otmp->ox = mread8(mf); otmp->oy = mread8(mf); otmp->spe = mread8(mf); otmp->oclass = mread8(mf); otmp->invlet = mread8(mf); otmp->oartifact = mread8(mf); otmp->where = mread8(mf); otmp->timed = mread8(mf); otmp->cobj = mread8(mf) ? (void*)1 : NULL; /* set the pointer to 1 if there will be contents */ otmp->onamelth = namelen; otmp->cursed = (oflags >> 31) & 1; otmp->blessed = (oflags >> 30) & 1; otmp->unpaid = (oflags >> 29) & 1; otmp->no_charge = (oflags >> 28) & 1; otmp->known = (oflags >> 27) & 1; otmp->dknown = (oflags >> 26) & 1; otmp->bknown = (oflags >> 25) & 1; otmp->rknown = (oflags >> 24) & 1; otmp->oeroded = (oflags >> 22) & 3; otmp->oeroded2 = (oflags >> 20) & 3; otmp->oerodeproof = (oflags >> 19) & 1; otmp->olocked = (oflags >> 18) & 1; otmp->obroken = (oflags >> 17) & 1; otmp->otrapped = (oflags >> 16) & 1; otmp->recharged = (oflags >> 13) & 7; otmp->lamplit = (oflags >> 12) & 1; otmp->greased = (oflags >> 11) & 1; otmp->oattached = (oflags >> 9) & 3; otmp->in_use = (oflags >> 8) & 1; otmp->was_thrown = (oflags >> 7) & 1; otmp->bypass = (oflags >> 6) & 1; if (otmp->onamelth) mread(mf, ONAME(otmp), otmp->onamelth); if (otmp->oattached == OATTACHED_MONST) { struct monst *mtmp = restore_mon(mf); int monlen = sizeof(struct monst) + mtmp->mnamelth + mtmp->mxlth; otmp = realloc_obj(otmp, monlen, mtmp, otmp->onamelth, ONAME(otmp)); dealloc_monst(mtmp); } else if (otmp->oattached == OATTACHED_M_ID) { unsigned int mid = mread32(mf); otmp = obj_attach_mid(otmp, mid); } return otmp; }
uint32 sms_z80_run(uint32 cycles) { uint32 cyclesdone = 0; uint32 opcode; uint16 pc; int tmp; static char last_str[256]; char str[256]; static uint16 last_pc = 0; uint32 c1, c2; while(cyclesdone < cycles) { debug_crab_ents = debug_mz80_ents = 0; debug_port_reads1 = debug_port_reads2 = 0; debug_mem_reads1 = debug_mem_reads2 = 0; debug_crab_ports = debug_mz80_ports = 0; pc = cpuz80->pc.w; opcode = mread8(cpuz80->pc.w); if(opcode == 0xED || opcode == 0xCB || opcode == 0xDD || opcode == 0xFD) { opcode |= (mread8(cpuz80->pc.w + 1) << 8); } if((opcode & 0xFF00) == 0xCB00) { opcode |= (mread8(cpuz80->pc.w + 2) << 16) | (mread8(cpuz80->pc.w + 3) << 24); } c1 = CrabZ80_execute(cpuz80, 1); c2 = z80_execute(1); cyclesdone += c1; tmp = _compare_registers() + _compare_memory() + _compare_ports(); CrabZ80_disassemble(str, cpuz80, pc); if(tmp) { printf("Cycles done: %d %d\n", (int)c1, (int)c2); printf("%d errors at: PC = 0x%04X, old_pc = 0x%04X Opcode = 0x%02X", tmp, pc, last_pc, opcode & 0xFF); switch(opcode & 0xFF) { case 0xED: case 0xCB: printf("%02X (%s -- %s)\n", (opcode & 0xFF00) >> 8, str, last_str); break; case 0xDD: case 0xFD: if((opcode & 0xFF00) == 0xCB00) printf("%02X%02X%02X (%s -- %s)\n", (opcode & 0xFF00) >> 8, (opcode & 0xFF0000) >> 16, (opcode & 0xFF000000) >> 24, str, last_str); else printf("%02X (%s -- %s)\n", (opcode & 0xFF00) >> 8, str, last_str); break; default: printf("(%s -- %s)\n", str, last_str); } } strcpy(last_str, str); last_pc = pc; }
void rest_regions(struct memfile *mf, struct level *lev, boolean ghostly) { /* If a bones file restore */ int i, j; unsigned len1, len2; long tmstamp; char *msg_buf; struct region *r; free_regions(lev); /* Just for security */ mfmagic_check(mf, REGION_MAGIC); tmstamp = save_decode_32(mread32(mf), moves, moves); if (ghostly) tmstamp = 0; else tmstamp = (moves - tmstamp); lev->n_regions = mread32(mf); lev->max_regions = lev->n_regions; if (lev->n_regions > 0) lev->regions = malloc(sizeof (struct region *) * lev->n_regions); for (i = 0; i < lev->n_regions; i++) { lev->regions[i] = malloc(sizeof (struct region)); r = lev->regions[i]; memset(r, 0, sizeof (struct region)); r->lev = lev; restore_rect(mf, &r->bounding_box); r->attach_2_m = mread32(mf); r->effect_id = mread32(mf); r->arg = mread32(mf); r->nrects = mread16(mf); if (r->nrects > 0) r->rects = malloc(sizeof (struct nhrect) * r->nrects); for (j = 0; j < r->nrects; j++) restore_rect(mf, &r->rects[j]); r->ttl = mread16(mf); r->expire_f = mread16(mf); r->can_enter_f = mread16(mf); r->enter_f = mread16(mf); r->can_leave_f = mread16(mf); r->leave_f = mread16(mf); r->inside_f = mread16(mf); r->n_monst = mread16(mf); r->max_monst = r->n_monst; r->player_flags = mread8(mf); r->attach_2_u = mread8(mf); r->visible = mread8(mf); if (r->n_monst > 0) r->monsters = malloc(sizeof (unsigned) * r->n_monst); for (j = 0; j < r->n_monst; j++) r->monsters[j] = mread32(mf); len1 = mread16(mf); len2 = mread16(mf); if (len1 > 0) { msg_buf = malloc(len1); mread(mf, msg_buf, len1); msg_buf[len1 - 1] = '\0'; r->enter_msg = msg_buf; } if (len2 > 0) { msg_buf = malloc(len2); mread(mf, msg_buf, len2); msg_buf[len2 - 1] = '\0'; r->leave_msg = msg_buf; } /* check for expired region */ if (r->ttl >= 0) r->ttl = (r->ttl > tmstamp) ? r->ttl - tmstamp : 0; if (ghostly) { /* settings pertained to old player */ clear_hero_inside(r); clear_heros_fault(r); } } for (i = lev->n_regions - 1; i >= 0; i--) if (ghostly && lev->regions[i]->n_monst > 0) reset_region_mids(lev->regions[i]); }