Пример #1
0
bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) {
    union {
        char c[0x1C];
        int32_t i;
    } buffer;
    int32_t size = strlen(SHARKPORT_HEADER);
    STORE_32(size, 0, &buffer.i);
    if (vf->write(vf, &buffer.i, 4) < 4) {
        return false;
    }
    if (vf->write(vf, SHARKPORT_HEADER, size) < size) {
        return false;
    }

    size = 0x000F0000;
    STORE_32(size, 0, &buffer.i);
    if (vf->write(vf, &buffer.i, 4) < 4) {
        return false;
    }

    const struct GBACartridge* cart = (const struct GBACartridge*) gba->memory.rom;
    size = sizeof(cart->title);
    STORE_32(size, 0, &buffer.i);
    if (vf->write(vf, &buffer.i, 4) < 4) {
        return false;
    }
    if (vf->write(vf, cart->title, size) < 4) {
        return false;
    }

    time_t t = time(0);
    struct tm* tm = localtime(&t);
    size = strftime(&buffer.c[4], sizeof(buffer.c) - 4, "%m/%d/%Y %I:%M:%S %p", tm);
    STORE_32(size, 0, &buffer.i);
    if (vf->write(vf, buffer.c, size + 4) < size + 4) {
        return false;
    }

    // Last field is blank
    size = 0;
    STORE_32(size, 0, &buffer.i);
    if (vf->write(vf, &buffer.i, 4) < 4) {
        return false;
    }

    // Write payload
    size = 0x1C;
    switch (gba->memory.savedata.type) {
    case SAVEDATA_SRAM:
        size += SIZE_CART_SRAM;
        break;
    case SAVEDATA_FLASH512:
        size += SIZE_CART_FLASH512;
        break;
    case SAVEDATA_FLASH1M:
        size += SIZE_CART_FLASH1M;
        break;
    case SAVEDATA_EEPROM:
        size += SIZE_CART_EEPROM;
        break;
    case SAVEDATA_FORCE_NONE:
    case SAVEDATA_AUTODETECT:
        return false;
    }
    STORE_32(size, 0, &buffer.i);
    if (vf->write(vf, &buffer.i, 4) < 4) {
        return false;
    }
    size -= 0x1C;

    memcpy(buffer.c, &cart->title, 16);
    buffer.c[0x10] = 0;
    buffer.c[0x11] = 0;
    buffer.c[0x12] = cart->checksum;
    buffer.c[0x13] = cart->maker;
    buffer.c[0x14] = 1;
    buffer.c[0x15] = 0;
    buffer.c[0x16] = 0;
    buffer.c[0x17] = 0;
    buffer.c[0x18] = 0;
    buffer.c[0x19] = 0;
    buffer.c[0x1A] = 0;
    buffer.c[0x1B] = 0;
    if (vf->write(vf, buffer.c, 0x1C) < 0x1C) {
        return false;
    }

    uint32_t checksum = 0;
    int i;
    for (i = 0; i < 0x1C; ++i) {
        checksum += buffer.c[i] << (checksum % 24);
    }

    if (vf->write(vf, gba->memory.savedata.data, size) < size) {
        return false;
    }

    for (i = 0; i < size; ++i) {
        checksum += ((char) gba->memory.savedata.data[i]) << (checksum % 24);
    }

    STORE_32(checksum, 0, &buffer.i);
    if (vf->write(vf, &buffer.i, 4) < 4) {
        return false;
    }

    return true;
}
Пример #2
0
void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
	STORE_32(GBA_SAVESTATE_MAGIC + GBA_SAVESTATE_VERSION, 0, &state->versionMagic);
	STORE_32(gba->biosChecksum, 0, &state->biosChecksum);
	STORE_32(gba->romCrc32, 0, &state->romCrc32);

	if (gba->memory.rom) {
		state->id = ((struct GBACartridge*) gba->memory.rom)->id;
		memcpy(state->title, ((struct GBACartridge*) gba->memory.rom)->title, sizeof(state->title));
	} else {
		state->id = 0;
		memset(state->title, 0, sizeof(state->title));
	}

	int i;
	for (i = 0; i < 16; ++i) {
		STORE_32(gba->cpu->gprs[i], i * sizeof(state->cpu.gprs[0]), state->cpu.gprs);
	}
	STORE_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
	STORE_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
	STORE_32(gba->cpu->cycles, 0, &state->cpu.cycles);
	STORE_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
	for (i = 0; i < 6; ++i) {
		int j;
		for (j = 0; j < 7; ++j) {
			STORE_32(gba->cpu->bankedRegisters[i][j], (i * 7 + j) * sizeof(gba->cpu->bankedRegisters[0][0]), state->cpu.bankedRegisters);
		}
		STORE_32(gba->cpu->bankedSPSRs[i], i * sizeof(gba->cpu->bankedSPSRs[0]), state->cpu.bankedSPSRs);
	}

	STORE_32(gba->memory.biosPrefetch, 0, &state->biosPrefetch);
	STORE_32(gba->cpu->prefetch[0], 0, state->cpuPrefetch);
	STORE_32(gba->cpu->prefetch[1], 4, state->cpuPrefetch);
	STORE_32(gba->memory.lastPrefetchedPc, 0, &state->lastPrefetchedPc);

	GBASerializedMiscFlags miscFlags = 0;
	miscFlags = GBASerializedMiscFlagsSetHalted(miscFlags, gba->cpu->halted);
	STORE_32(miscFlags, 0, &state->miscFlags);

	GBAMemorySerialize(&gba->memory, state);
	GBAIOSerialize(gba, state);
	GBAVideoSerialize(&gba->video, state);
	GBAAudioSerialize(&gba->audio, state);
	GBASavedataSerialize(&gba->memory.savedata, state);


#ifndef _MSC_VER
	struct timeval tv;
	if (!gettimeofday(&tv, 0)) {
		uint64_t usec = tv.tv_usec;
		usec += tv.tv_sec * 1000000LL;
		STORE_64(usec, 0, &state->creationUsec);
	}
#else
	struct timespec ts;
	if (timespec_get(&ts, TIME_UTC)) {
		uint64_t usec = ts.tv_nsec / 1000;
		usec += ts.tv_sec * 1000000LL;
		STORE_64(usec, 0, &state->creationUsec);
	}
#endif
	else {
		state->creationUsec = 0;
	}
	state->associatedStreamId = 0;
	if (gba->rr) {
		gba->rr->stateSaved(gba->rr, state);
	}
}