int emu_SaveLoadSRAM(int load) { int ret = 0; static char saveFname[512]; romfname_ext(saveFname, NULL, (PicoMCD & 1) ? ".brm" : ".srm"); if (load && !try_ropen_file(saveFname)) return 0; FILE *sramFile; int sram_size; unsigned char *sram_data; int truncate = 1; if (PicoMCD & 1) { if (PicoOpt & PicoOpt_enable_cd_ramcart) { // MCD RAM cart? sram_size = 0x12000; sram_data = SRam.data; if (sram_data) memcpy32((int *)sram_data, (int *)Pico_mcd->bram, 0x2000/4); } else { sram_size = 0x2000; sram_data = Pico_mcd->bram; truncate = 0; // the .brm may contain RAM cart data after normal brm } } else { sram_size = SRam.end - SRam.start + 1; if(Pico.m.sram_reg & 4) sram_size=0x2000; sram_data = SRam.data; } if (!sram_data) return 0; // SRam forcefully disabled for this game if (load) { sramFile = fopen(saveFname, "rb"); if(!sramFile) return -1; fread(sram_data, 1, sram_size, sramFile); fclose(sramFile); if ((PicoMCD & 1) && (PicoOpt & PicoOpt_enable_cd_ramcart)) memcpy32((int *)Pico_mcd->bram, (int *)sram_data, 0x2000/4); } else { // sram save needs some special processing // see if we have anything to save for (; sram_size > 0; sram_size--) if (sram_data[sram_size - 1]) break; if (sram_size) { sramFile = fopen(saveFname, truncate ? "wb" : "r+b"); if (!sramFile) sramFile = fopen(saveFname, "wb"); // retry if (!sramFile) return -1; ret = fwrite(sram_data, 1, sram_size, sramFile); ret = (ret != sram_size) ? -1 : 0; fclose(sramFile); } } return ret; }
int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow ) { TIMERINFO ti; DWORD beforeTickCountFast, afterTickCountFast; DWORD beforeTickCountSlow, afterTickCountSlow, i; BYTE __huge *hpvSrc; BYTE __huge *hpvDest; char szBuffer[256]; hpvSrc = GlobalAllocPtr( GMEM_MOVEABLE, BLOCK_SIZE ); hpvDest = GlobalAllocPtr( GMEM_MOVEABLE, BLOCK_SIZE ); if ( !hpvSrc || !hpvDest ) { MessageBox(0, "Couldn't allocate src/dest segs", 0, MB_OK); return 0; } // Call the 32 bit function once without timing it to let it switch // to a 32 bit segment. memcpy32( SELECTOROF(hpvDest), OFFSETOF(hpvDest), SELECTOROF(hpvSrc), OFFSETOF(hpvSrc), BLOCK_SIZE ); ti.dwSize = sizeof(ti); TimerCount(&ti); beforeTickCountFast = ti.dwmsThisVM; // Now call the 32 bit function again, this time timing it. memcpy32( SELECTOROF(hpvDest), OFFSETOF(hpvDest), SELECTOROF(hpvSrc), OFFSETOF(hpvSrc), BLOCK_SIZE ); TimerCount( &ti ); afterTickCountFast = ti.dwmsThisVM; TimerCount(&ti); beforeTickCountSlow = ti.dwmsThisVM; for ( i=0; i < BLOCK_SIZE; i++) *hpvDest++ = *hpvSrc++; TimerCount( &ti ); afterTickCountSlow = ti.dwmsThisVM; wsprintf(szBuffer, "32 bit move: %lu milliseconds\r\n" "huge pointer move: %lu milliseconds", afterTickCountFast - beforeTickCountFast, afterTickCountSlow - beforeTickCountSlow); MessageBox( 0, szBuffer, "MIX1632 - Matt Pietrek 1994", MB_OK ); return 0; }
void cpu_set_cwp(CPUSPARCState *env, int new_cwp) { /* put the modified wrap registers at their proper location */ if (env->cwp == env->nwindows - 1) { memcpy32(env->regbase, env->regbase + env->nwindows * 16); } env->cwp = new_cwp; /* put the wrap registers at their temporary location */ if (new_cwp == env->nwindows - 1) { memcpy32(env->regbase + env->nwindows * 16, env->regbase); } env->regwptr = env->regbase + (new_cwp * 16); }
static int make_local_pal_md(int fast_mode) { int pallen = 0xc0; bgr444_to_rgb32(localPal, Pico.cram); if (fast_mode) return 0x40; if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode bgr444_to_rgb32_sh(localPal, Pico.cram); localPal[0xc0] = 0x0000c000; localPal[0xd0] = 0x00c00000; localPal[0xe0] = 0x00000000; // reserved pixels for OSD localPal[0xf0] = 0x00ffffff; pallen = 0x100; } else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes bgr444_to_rgb32(localPal+0x40, HighPal); bgr444_to_rgb32(localPal+0x80, HighPal+0x40); } else memcpy32(localPal+0x80, localPal, 0x40); // for spr prio mess return pallen; }
static void process_pkt(void* data) { struct pkt_buff pkt; struct ioq_header *ioq = data; unsigned int size = ntohs(ioq->byte_length); unsigned short dest = ntohs(ioq->src_port) ^ 2; //print_pkt(data, size + sizeof(struct ioq_header)); log("%hd -> %hd (%d)\n", ntohs(ioq->src_port), dest, size); // log("ioq_hdr: dst=%hx words=%hu src=%hu bytes=%hu\n", ntohs(ioq->dst_port), ntohs(ioq->word_length), ntohs(ioq->src_port), size); pkt_fill(&pkt, data, size + sizeof(struct ioq_header)); struct pkt_buff reply; struct ioq_header *dioq; pkt_push_all(&pkt); while (pkt_alloc(&reply, pkt.len) == 0) { log("Failed to alloc\n"); } memcpy32(reply.data+ sizeof(struct ioq_header), pkt.data + sizeof(struct ioq_header), reply.len - sizeof(struct ioq_header)); nf_pktin_free(data); dioq = pkt_pull_type(&reply, struct ioq_header); fill_ioq(dioq, dest, size); nf_pktout_send(reply.data, reply.data + reply.total_size); }
static void blit(const char *fps, const char *notice) { int emu_opt = currentConfig.EmuOpt; if (PicoOpt&0x10) { int lines_flags = 224; // 8bit fast renderer if (Pico.m.dirtyPal) { Pico.m.dirtyPal = 0; vidConvCpyRGB565(localPal, Pico.cram, 0x40); } // a hack for VR if (PicoAHW & PAHW_SVP) memset32((int *)(PicoDraw2FB+328*8+328*223), 0xe0e0e0e0, 328); if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; if (currentConfig.EmuOpt&0x4000) lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000; vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags); } else if (!(emu_opt&0x80)) { int lines_flags; // 8bit accurate renderer if (Pico.m.dirtyPal) { Pico.m.dirtyPal = 0; vidConvCpyRGB565(localPal, Pico.cram, 0x40); if (Pico.video.reg[0xC]&8) { // shadow/hilight mode //vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40); //vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); // TODO? memcpy32((void *)(localPal+0xc0), (void *)(localPal+0x40), 0x40*2/4); localPal[0xc0] = 0x0600; localPal[0xd0] = 0xc000; localPal[0xe0] = 0x0000; // reserved pixels for OSD localPal[0xf0] = 0xffff; } /* no support else if (rendstatus & 0x20) { // mid-frame palette changes vidConvCpyRGB565(localPal+0x40, HighPal, 0x40); vidConvCpyRGB565(localPal+0x80, HighPal+0x40, 0x40); } */ } lines_flags = (Pico.video.reg[1]&8) ? 240 : 224; if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; if (currentConfig.EmuOpt&0x4000) lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000; vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags); } if (notice || (emu_opt & 2)) { int h = 232; if (notice) osd_text(4, h, notice); if (emu_opt & 2) osd_text(OSD_FPS_X, h, fps); } if ((emu_opt & 0x400) && (PicoAHW & PAHW_MCD)) cd_leds(); }
void MusicEngine::Update() { memcpy32((void*)0x04000060, &buffer, 8); *(u16*)0x04000080 = buffer[16]; buffer[2] &= 0x7FF; buffer[6] &= 0x7FF; buffer[10] &= 0x7FF; buffer[14] &= 0x7FF; }
int patch_options(void *address, uint32_t size, uint8_t options, enum types type) { if (options & patch_option_keyx) { print("Patch option: Adding keyX"); if (read_file(fcram_temp, PATH_SLOT0X25KEYX, AES_BLOCK_SIZE) != 0) { print("Failed to load keyX"); draw_message("Failed to load keyX", "Make sure the keyX is\n located at /slot0x25keyX.bin"); return 1; } void *pos = memsearch(address, "slot0x25keyXhere", size, AES_BLOCK_SIZE); if (pos) { memcpy32(pos, fcram_temp, AES_BLOCK_SIZE); } else { print("I don't know where to add keyX.\n Ignoring..."); } } if (options & patch_option_emunand) { print("Patch option: Setting emuNAND offsets"); uint32_t offset = 0; uint32_t header = 0; if (get_emunand_offsets(config->emunand_location, &offset, &header)) { print("Failed to get the emuNAND offsets"); draw_message("Failed to get the emuNAND offsets", "There's 3 possible causes for this error:\n" " - You don't even have an emuNAND installed\n" " - Your SD card can't be read\n" " - You're using an unsupported emuNAND format"); return 1; } uint32_t *pos_offset = memsearch(address, "NAND", size, 4); uint32_t *pos_header = memsearch(address, "NCSD", size, 4); if (pos_offset && pos_header) { *pos_offset = offset; *pos_header = header; } else { print("I don't know where to set the offsets.\n" " Ignoring..."); } } if (options & patch_option_save && type == NATIVE_FIRM) { print("Patch option: Save firm"); save_firm = 1; // This absolutely requires the -fshort-wchar option to be enabled. char *offset = address + size; memcpy(offset, L"sdmc:", 10); memcpy(offset + 10, L"" PATH_PATCHED_FIRMWARE, sizeof(PATH_PATCHED_FIRMWARE) * 2); } return 0; }
int loadxc(int xcno) { /* stop xmac / xpec */ XMAC_REG(xcno, XMAC_RPU_HOLD_PC) = RPU_HOLD_PC; XMAC_REG(xcno, XMAC_TPU_HOLD_PC) = TPU_HOLD_PC; XPEC_REG(xcno, XPEC_XPU_HOLD_PC) = XPU_HOLD_PC; XPEC_REG(xcno, XPEC_PC) = 0; /* load firmware */ memset32((void*)NETX_PA_XPEC(xcno) + XPEC_RAM_START, 0, 0x2000); memset32((void*)NETX_PA_XMAC(xcno), 0, 0x800); /* can't use barebox memcpy here, we need 32bit accesses */ if(xcno == 0) { memcpy32((void*)(NETX_PA_XMAC(xcno) + XMAC_RPU_PROGRAM_START), rpu_eth0, sizeof(rpu_eth0)); memcpy32((void*)(NETX_PA_XMAC(xcno) + XMAC_TPU_PROGRAM_START), tpu_eth0, sizeof(tpu_eth0)); memcpy32((void*)NETX_PA_XPEC(xcno) + XPEC_RAM_START, xpec_eth0_mac, sizeof(xpec_eth0_mac)); xc_patch(xcno, rpu_eth0_patch, ARRAY_SIZE(rpu_eth0_patch) >> 1); xc_patch(xcno, tpu_eth0_patch, ARRAY_SIZE(tpu_eth0_patch) >> 1); xc_patch(xcno, xpec_eth0_mac_patch, ARRAY_SIZE(xpec_eth0_mac_patch) >> 1); } else {
int main() { THREAD_ID ptid; long res; if ((res = InitFS()) != NO_ERROR) return res; InitPart(); KCreateThread((void(*)(void*))CacheProc, 0x40000, (void*)PROC_INTERVAL, &ptid); /*启动后台定时缓冲保存线程*/ for (;;) { DWORD data[MSG_DATA_LEN + 1]; if ((res = KRecvMsg((THREAD_ID*)&data[PTID_ID], data, INVALID)) != NO_ERROR) /*等待消息*/ break; if ((data[MSG_ATTR_ID] & MSG_ATTR_MASK) == MSG_ATTR_THEDEXIT) /*子线程退出*/ SubthCou--; else if ((data[MSG_ATTR_ID] & MSG_ATTR_MASK) == MSG_ATTR_PROCEXIT) data[MSG_ATTR_ID] = MSG_ATTR_FS | FS_API_PROCEXIT; if ((data[MSG_ATTR_ID] & MSG_MAP_MASK) == MSG_ATTR_ROMAP || (data[MSG_ATTR_ID] & MSG_ATTR_MASK) == MSG_ATTR_FS) { DWORD *buf; if ((data[MSG_API_ID] & MSG_API_MASK) >= sizeof(ApiTable) / sizeof(void*)) { data[MSG_RES_ID] = FS_ERR_WRONG_ARGS; if (data[MSG_ATTR_ID] < MSG_ATTR_USER) KUnmapProcAddr((void*)data[MSG_ADDR_ID], data); else KSendMsg((THREAD_ID*)&data[PTID_ID], data, 0); } else if ((buf = (DWORD*)malloc(sizeof(DWORD) * (MSG_DATA_LEN + 1))) == NULL) { data[MSG_RES_ID] = FS_ERR_HAVENO_MEMORY; if (data[MSG_ATTR_ID] < MSG_ATTR_USER) KUnmapProcAddr((void*)data[MSG_ADDR_ID], data); else KSendMsg((THREAD_ID*)&data[PTID_ID], data, 0); } else { memcpy32(buf, data, MSG_DATA_LEN + 1); KCreateThread((void(*)(void*))ApiProc, 0x40000, buf, &ptid); SubthCou++; } } else if (data[MSG_ATTR_ID] == MSG_ATTR_EXTPROCREQ) break; } CloseFS(); return NO_ERROR; }
/** * @brief This function do write operation by DMA * * @param[in] nVirDstAddr : virtual destination address * @param[in] nVirSrcAddr : virtual source address * @param[in] nSize : size to be invalidated * * @return FSR_OAM_SUCCESS * * @author SongHo Yoon * @version 1.0.0 * */ PUBLIC INT32 FSR_OAM_WriteDMA(UINT32 nVirDstAddr, UINT32 nVirSrcAddr, UINT32 nSize) { FSR_STACK_VAR; FSR_STACK_END; memcpy32((void *) nVirDstAddr, (void *) nVirSrcAddr, nSize); return FSR_OAM_SUCCESS; }
PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count) { if ((((long)dest | (long)src) & 3) == 0) { if (count >= 32) { memcpy32((int *)dest, (int *)src, count/2); count&=1; } else { for (; count >= 2; count -= 2, dest+=2, src+=2) *(int *)dest = *(int *)src; } } while (count--) *dest++ = *src++; }
// Entry Point void reset_handler(void) { // Disable Watchdog hw_watchdog_disable(); // Init sections memcpy32(__data_load_start__, __data_start__, __data_end__); meminit32(__bss_start__, __bss_end__); memcpy32(__fast_load_start__, __fast_start__, __fast_end__); // Init heap __heap_start__[0] = 0; __heap_start__[1] = ((uint32_t)__heap_end__ - (uint32_t)__heap_start__); // Init hardware hw_init(); // Start main extern void main(void); main(); // Application has ended, so busy wait while(1); }
fastcall void VBE_SetPalette(int firstColor, int numColors, uint32 *colors) { Regs reg = {}; uint32 *tempColors = (void*) BIOS_SHARED->userdata; memcpy32(tempColors, colors, numColors); reg.ax = 0x4f09; reg.bx = 0x0000; // Set palette data reg.cx = numColors; reg.dx = firstColor; reg.di = PTR_32_TO_NEAR(tempColors, 0); BIOS_Call(0x10, ®); }
/* Entry Point */ void reset_handler(void) { #ifdef USE_WOLF_ARM_STARTUP /* Init sections */ memcpy32(__data_load_start__, __data_start__, __data_end__); meminit32(__bss_start__, __bss_end__); /* Init heap */ __heap_start__[0] = 0; __heap_start__[1] = ((uint32_t)__heap_end__ - (uint32_t)__heap_start__); #endif /* USE_WOLF_ARM_STARTUP */ /* Start main */ extern int main(void); main(); /* Application has ended, so busy wait */ while(1); }
void restore_more_variables_for_loadstate() { //restore palette //PaletteTxAll(); //restore other graphics loadstate_gfx(); //restore sound - This puts the known frequency and volume back into the GBA sound channels. reset_sound_after_loadstate(); //copy sprite tables memcpy32(dmanesoambuff,nesoambuff,256); #if DIRTYTILES //make all tiles dirty memset32(dirty_tiles,0xFFFFFFFF,512); memset32(dirty_rows,0xFFFFFFFF,32); #endif //make background dirty _bg_cache_full=1; }
static int EmuScanEnd16_ld(unsigned int num) { void *oldline = DrawLineDest; if (emu_scan_end) emu_scan_end(ld_counter); ld_counter++; ld_left--; if (ld_left <= 0) { ld_left = ld_lines; EmuScanBegin16_ld(num); memcpy32(DrawLineDest, oldline, 320 * gp2x_current_bpp / 8 / 4); if (emu_scan_end) emu_scan_end(ld_counter); ld_counter++; } return 0; }
/*! * \brief Enqueue new event. * * \param thread [in] jthread object which occurs new event. * \param event [in] New thread event. * \param additionalData [in] Additional data if exist. */ void TThreadRecorder::putEvent(jthread thread, TThreadEvent event, jlong additionalData) { struct timeval tv; gettimeofday(&tv, NULL); TEventRecord eventRecord __attribute__((aligned(32))); // for YMM vmovdqa eventRecord.time = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); eventRecord.thread_id = TVMFunctions::getInstance()->GetThreadId(*(void **)thread); eventRecord.event = event; eventRecord.additionalData = additionalData; if (unlikely(top_of_buffer->event == ThreadEnd)) { spinLockWait(&idmapLockVal); { std::tr1::unordered_map<jlong, char *, TNumericalHasher<jlong> > ::iterator entry = threadIDMap.find(top_of_buffer->thread_id); if (likely(entry != threadIDMap.end())) { free(entry->second); threadIDMap.erase(entry); } } spinLockRelease(&idmapLockVal); } spinLockWait(&bufferLockVal); { memcpy32(top_of_buffer, &eventRecord); if (unlikely(++top_of_buffer == end_of_buffer)) { top_of_buffer = (TEventRecord *)record_buffer; } } spinLockRelease(&bufferLockVal); }
/* this is was a try to fight slow SD access of GP2X */ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba) { int is_bin, offs, read_len, moved = 0; reads++; is_bin = Pico_mcd->TOC.Tracks[0].ftype == CT_BIN; if (PicoCDBuffers <= 0) { /* no buffering */ int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11); pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET); pm_read(dest, 2048, Pico_mcd->TOC.Tracks[0].F); return; } /* hit? */ offs = lba - prev_lba; if (offs >= 0 && offs < PicoCDBuffers) { hits++; if (offs == 0) dprintf("CD buffer seek to old %i -> %i\n", prev_lba, lba); memcpy32(dest, (int *)(cd_buffer + offs*2048), 2048/4); return; } if (prev_lba + PicoCDBuffers != lba) { int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11); dprintf("CD buffer seek %i -> %i\n", prev_lba, lba); pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET); } dprintf("CD buffer miss %i -> %i\n", prev_lba, lba); if (lba < prev_lba && prev_lba - lba < PicoCDBuffers) { read_len = prev_lba - lba; dprintf("CD buffer move=%i, read_len=%i", PicoCDBuffers - read_len, read_len); memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048); moved = 1; } else { read_len = PicoCDBuffers; } if (PicoMessage != NULL && read_len >= 512) { PicoMessage("Buffering data..."); } if (is_bin) { int i = 0; #ifdef _PSP_FW_VERSION int bufs = (read_len*2048) / (2048+304); pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F); for (i = 1; i < bufs; i++) // should really use memmove here, but my memcpy32 implementation is also suitable here memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4); #endif for (; i < read_len - 1; i++) { pm_read(cd_buffer + i*2048, 2048 + 304, Pico_mcd->TOC.Tracks[0].F); // pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); // seeking is slower, in PSP case even more } // further data might be moved, do not overwrite pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F); pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); } else { pm_read(cd_buffer, read_len*2048, Pico_mcd->TOC.Tracks[0].F); } memcpy32(dest, (int *) cd_buffer, 2048/4); prev_lba = lba; if (moved) { /* file pointer must point to the same data in file, as would-be data after our buffer */ int where_seek; lba += PicoCDBuffers; where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11); pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET); } }
// A bunch of wrappers inline void memcpy32( volatile void* dst, const void* src, u32 wordcount ) { memcpy32( (void*)dst, src, wordcount ); }
void cheat_memcopy(void) { u8 *const values=cheatfinder_values; memcpy32(values,NES_RAM,10240); // memcpy32(values+2048,NES_SRAM,8192); }
inline void arr_memcpy32( type* dst, const void* src, u32 num_elems ) { memcpy32( (void*)dst, (const void*)src, num_elems * sizeof(type) / sizeof(u32) ); }
int emu_SaveLoadGame(int load, int sram) { int ret = 0; char *saveFname; // make save filename saveFname = emu_GetSaveFName(load, sram, state_slot); if (saveFname == NULL) { if (!sram) { strcpy(noticeMsg, load ? "LOAD FAILED (missing file)" : "SAVE FAILED "); emu_noticeMsgUpdated(); } return -1; } lprintf("saveLoad (%i, %i): %s\n", load, sram, saveFname); if (sram) { FILE *sramFile; int sram_size; unsigned char *sram_data; int truncate = 1; if (PicoMCD&1) { if (PicoOpt&0x8000) { // MCD RAM cart? sram_size = 0x12000; sram_data = SRam.data; if (sram_data) memcpy32((int *)sram_data, (int *)Pico_mcd->bram, 0x2000/4); } else { sram_size = 0x2000; sram_data = Pico_mcd->bram; truncate = 0; // the .brm may contain RAM cart data after normal brm } } else { sram_size = SRam.end-SRam.start+1; if(Pico.m.sram_reg & 4) sram_size=0x2000; sram_data = SRam.data; } if (!sram_data) return 0; // SRam forcefully disabled for this game if (load) { sramFile = fopen(saveFname, "rb"); if(!sramFile) return -1; fread(sram_data, 1, sram_size, sramFile); fclose(sramFile); if ((PicoMCD&1) && (PicoOpt&0x8000)) memcpy32((int *)Pico_mcd->bram, (int *)sram_data, 0x2000/4); } else { // sram save needs some special processing // see if we have anything to save for (; sram_size > 0; sram_size--) if (sram_data[sram_size-1]) break; if (sram_size) { sramFile = fopen(saveFname, truncate ? "wb" : "r+b"); if (!sramFile) sramFile = fopen(saveFname, "wb"); // retry if (!sramFile) return -1; ret = fwrite(sram_data, 1, sram_size, sramFile); ret = (ret != sram_size) ? -1 : 0; fclose(sramFile); #ifndef NO_SYNC sync(); #endif } } return ret; } else { void *PmovFile = NULL; if (strcmp(saveFname + strlen(saveFname) - 3, ".gz") == 0) { if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) { emu_setSaveStateCbs(1); if (!load) gzsetparams(PmovFile, 9, Z_DEFAULT_STRATEGY); } } else { if( (PmovFile = fopen(saveFname, load ? "rb" : "wb")) ) { emu_setSaveStateCbs(0); } } if(PmovFile) { ret = PmovState(load ? 6 : 5, PmovFile); areaClose(PmovFile); PmovFile = 0; if (load) Pico.m.dirtyPal=1; #ifndef NO_SYNC else sync(); #endif } else ret = -1; if (!ret) strcpy(noticeMsg, load ? "GAME LOADED " : "GAME SAVED "); else { strcpy(noticeMsg, load ? "LOAD FAILED " : "SAVE FAILED "); ret = -1; } emu_noticeMsgUpdated(); return ret; } }