// Returns FALSE if message not read, TRUE if it was read. Will always return TRUE if "blocking" is set. bool Read(CDIF_Message *message, bool blocking = TRUE) { TryAgain: MDFND_LockMutex(ze_mutex); if(ze_queue.size() > 0) { *message = ze_queue.front(); ze_queue.pop(); MDFND_UnlockMutex(ze_mutex); return(TRUE); } else if(blocking) { MDFND_UnlockMutex(ze_mutex); MDFND_Sleep(1); goto TryAgain; } else { MDFND_UnlockMutex(ze_mutex); return(FALSE); } }
static void CHEAT_gets(char *s, int size) { char* lpt = NULL; // // // MDFND_LockMutex(CheatMutex); while(!pending_text && !need_thread_exit) { MDFND_WaitCond(CheatCond, CheatMutex); } lpt = pending_text; pending_text = NULL; MDFND_UnlockMutex(CheatMutex); // // // if(lpt) { strncpy(s, lpt, size - 1); s[size - 1] = 0; free(lpt); CheatConsole.AppendLastLine(s); } if(need_thread_exit) { puts("WHEEE"); throw(0); // Sloppy laziness, but it works! SWEAT PANTS OF PRAGMATISM. } }
bool CDIF_ReadRawSector(uint8 *buf, uint32 lba) { bool found = FALSE; // This shouldn't happen, the emulated-system-specific CDROM emulation code should make sure the emulated program doesn't try // to read past the last "real" sector of the disc. if(lba >= toc.tracks[100].lba) { printf("Attempt to read LBA %d, >= LBA %d\n", lba, toc.tracks[100].lba); return(FALSE); } ReadThreadQueue->Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba, 0, 0, 0, NULL)); do { MDFND_LockMutex(SBMutex); for(int i = 0; i < SBSize; i++) { if(SectorBuffers[i].valid && SectorBuffers[i].lba == lba) { memcpy(buf, SectorBuffers[i].data, 2352 + 96); found = TRUE; } } MDFND_UnlockMutex(SBMutex); if(!found) MDFND_Sleep(1); } while(!found); return(TRUE); }
void Write(const CDIF_Message &message) { MDFND_LockMutex(ze_mutex); ze_queue.push(message); MDFND_UnlockMutex(ze_mutex); }
void Write(const CDIF_Message &message) { MDFND_LockMutex(ze_mutex); ze_queue.push(message); MDFND_UnlockMutex(ze_mutex); MDFND_SignalSemaphore(ze_semaphore); }
virtual bool TextHook(const std::string &text) override { char* tmp_ptr = strdup(text.c_str()); MDFND_LockMutex(CheatMutex); if(!pending_text) { pending_text = tmp_ptr; MDFND_SignalCond(CheatCond); } MDFND_UnlockMutex(CheatMutex); return(1); }
// Returns FALSE if message not read, TRUE if it was read. Will always return TRUE if "blocking" is set. bool Read(CDIF_Message *message, bool blocking = TRUE) { if(!blocking && ze_queue.size() == 0) { return FALSE; } MDFND_WaitSemaphore(ze_semaphore); MDFND_LockMutex(ze_mutex); assert(ze_queue.size() > 0); *message = ze_queue.front(); ze_queue.pop(); MDFND_UnlockMutex(ze_mutex); return TRUE; }
void AppendLastLine(const std::string &text) { MDFND_LockMutex(CheatMutex); MDFNConsole::AppendLastLine(text); MDFND_UnlockMutex(CheatMutex); }
void WriteLine(const std::string &text) { MDFND_LockMutex(CheatMutex); MDFNConsole::WriteLine(text); MDFND_UnlockMutex(CheatMutex); }
void Draw(MDFN_Surface *surface, const MDFN_Rect *src_rect) { MDFND_LockMutex(CheatMutex); MDFNConsole::Draw(surface, src_rect); MDFND_UnlockMutex(CheatMutex); }
static int ReadThreadStart(void *arg) { char *device_name = (char *)arg; bool Running = TRUE; MDFN_printf(_("Loading %s...\n\n"), device_name ? device_name : _("PHYSICAL CDROM DISC")); MDFN_indent(1); if(!(p_cdrfile = cdrfile_open(device_name))) { MDFN_indent(-1); EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, FALSE, 0, 0, 0, NULL)); return(0); } if(!cdrfile_read_toc(p_cdrfile, &toc)) { puts("Error reading TOC"); MDFN_indent(-1); EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, FALSE, 0, 0, 0, NULL)); return(0); } if(toc.first_track < 1 || toc.last_track > 99 || toc.first_track > toc.last_track) { puts("First/Last track numbers bad"); MDFN_indent(-1); EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, FALSE, 0, 0, 0, NULL)); return(0); } for(int32 track = toc.first_track; track <= toc.last_track; track++) { MDFN_printf(_("Track %2d, LBA: %6d %s\n"), track, toc.tracks[track].lba, (toc.tracks[track].control & 0x4) ? "DATA" : "AUDIO"); } MDFN_printf("Leadout: %6d\n", toc.tracks[100].lba); MDFN_indent(-1); EmuThreadQueue->Write(CDIF_Message(CDIF_MSG_INIT_DONE, TRUE, 0, 0, 0, NULL)); while(Running) { CDIF_Message msg; // Only do a blocking-wait for a message if we don't have any sectors to read-ahead. // MDFN_DispMessage("%d %d %d\n", last_read_lba, ra_lba, ra_count); if(ReadThreadQueue->Read(&msg, ra_count ? FALSE : TRUE)) { switch(msg.message) { case CDIF_MSG_DIEDIEDIE: Running = FALSE; break; case CDIF_MSG_READ_SECTOR: { static const int max_ra = 16; static const int initial_ra = 1; static const int speedmult_ra = 2; uint32 new_lba = msg.args[0]; assert((unsigned int)max_ra < (SBSize / 4)); if(new_lba == (last_read_lba + 1)) { int how_far_ahead = ra_lba - new_lba; assert(how_far_ahead >= 0); if(how_far_ahead <= max_ra) ra_count = std::min(speedmult_ra, 1 + max_ra - how_far_ahead); else ra_count++; } else { ra_lba = new_lba; ra_count = initial_ra; } last_read_lba = new_lba; } break; } } // Don't read >= the "end" of the disc, silly snake. Slither. if(ra_count && ra_lba == toc.tracks[100].lba) { ra_count = 0; //printf("Ephemeral scarabs: %d!\n", ra_lba); } if(ra_count) { uint8 tmpbuf[2352 + 96]; if(!cdrfile_read_raw_sector(p_cdrfile, tmpbuf, ra_lba)) { printf("Sector %d read error! Abandon ship!", ra_lba); memset(tmpbuf, 0, sizeof(tmpbuf)); } MDFND_LockMutex(SBMutex); SectorBuffers[SBWritePos].lba = ra_lba; memcpy(SectorBuffers[SBWritePos].data, tmpbuf, 2352 + 96); SectorBuffers[SBWritePos].valid = TRUE; SBWritePos = (SBWritePos + 1) % SBSize; MDFND_UnlockMutex(SBMutex); ra_lba++; ra_count--; } } if(p_cdrfile) { cdrfile_destroy(p_cdrfile); p_cdrfile = NULL; } return(1); }