// ... Tick off delta time and run timeout routines as needed static int serviceTimers (int ifProcessExpiredTimers) { ULONG numberOfTicks, smallestDelta; // is this the first time? if (timerList->lastTick == 0ULL) { timerList->lastTick = radTimeGetMSSinceEpoch (); } numberOfTicks = (ULONG)(radTimeGetMSSinceEpoch () - timerList->lastTick); timerList->lastTick = radTimeGetMSSinceEpoch (); // update timers with number of expired ticks smallestDelta = updateTimers (numberOfTicks); if (ifProcessExpiredTimers && smallestDelta == 0) { // process expired timer(s) processExpiredTimers (); // re-process timers with zero ticks to get smallest delta value smallestDelta = updateTimers (0); } return smallestDelta; }
void emulate(void) { _u8 i; //Execute several instructions to boost performance for (i = 0; i < 64; i++) { updateTimers(TLCS900h_interpret()); if (Z80ACTIVE) Z80EMULATE updateTimers(TLCS900h_interpret()); } }
EXPORT void FrameAdvance(MyFrameInfo* frame) { lagged = true; bool MeowMeow = 0; MDFN_Surface surface; surface.pixels = frame->VideoBuffer; surface.pitch32 = 160; frame->Width = 160; frame->Height = 152; frontend_time = frame->FrontendTime; storeB(0x6f82, frame->Buttons); ngpc_soundTS = 0; NGPFrameSkip = frame->SkipRendering; do { int32 timetime = (uint8)TLCS900h_interpret(); // This is sooo not right, but it's replicating the old behavior(which is necessary // now since I've fixed the TLCS900h core and other places not to truncate cycle counts // internally to 8-bits). Switch to the #if 0'd block of code once we fix cycle counts in the // TLCS900h core(they're all sorts of messed up), and investigate if certain long // instructions are interruptable(by interrupts) and later resumable, RE Rockman Battle // & Fighters voice sample playback. //if(timetime > 255) // printf("%d\n", timetime); // Note: Don't call updateTimers with a time/tick/cycle/whatever count greater than 255. MeowMeow |= updateTimers(&surface, timetime); z80_runtime += timetime; while (z80_runtime > 0) { int z80rantime = Z80_RunOP(); if (z80rantime < 0) // Z80 inactive, so take up all run time! { z80_runtime = 0; break; } z80_runtime -= z80rantime << 1; } } while (!MeowMeow); frame->Cycles = ngpc_soundTS; frame->Samples = MDFNNGPCSOUND_Flush(frame->SoundBuffer, 8192); frame->Lagged = lagged; }
RegularBattleScene::RegularBattleScene(battledata_ptr dat, BattleDefaultTheme *theme, bool logNames) : mData(dat), unpausing(false), pauseCount(0), info(dat->numberOfSlots()), mLogNames(logNames) { gui.theme = theme; /* Sets the bar in non-percentage mode for players */ for (int i = 0; i < data()->numberOfSlots(); i++) { if (isPlayer(i)) { info.percentage[i] = false; } } setupGui(); updateTimers(); }
/* FIXME, change to take TimeRecords ?? or not*/ void ClockDisplay::setTimeInfo(int btime, int bstones_periods, int wtime, int wstones_periods) { /* FIXME DOUBLECHECK if this is allowed. We want to be able * to pass empty records but, this may not be the way to * do it */ if(wtime != 0 || wstones_periods != -1) { w_time = wtime; w_stones_periods = wstones_periods; } if(btime != 0 || bstones_periods != -1) { b_time = btime; b_stones_periods = bstones_periods; } //printf("wb %d %d %d %d\n", w_time, b_time, w_stones_periods, b_stones_periods); updateTimers(); }
void ClockDisplay::makeMove(bool black) { if (black) { if(timeSystem == canadian && b_stones_periods != -1) { b_stones_periods--; } } else { if(timeSystem == canadian && w_stones_periods != -1) { w_stones_periods--; } } updateTimers(); }
void ClockDisplay::rerackTime(bool black) { if (black) { if(timeSystem == canadian && b_stones_periods == 0) { b_time = periodtime; b_stones_periods = periods; } else if(timeSystem == byoyomi && b_stones_periods != -1) { b_time = periodtime; //b_stones_periods = periods; } else if(timeSystem == tvasia) { b_time = maintime; b_stones_periods = -1; } } else { if(timeSystem == canadian && w_stones_periods == 0) { w_time = periodtime; w_stones_periods = periods; } else if(timeSystem == byoyomi && w_stones_periods != -1) { w_time = periodtime; //w_stones_periods = periods; } else if(timeSystem == tvasia) { w_time = maintime; w_stones_periods = -1; } } updateTimers(); }
void RegularBattleScene::setupGui() { int nslots = data()->numberOfSlots(); gui.nick.resize(nslots); gui.level.resize(nslots); gui.gender.resize(nslots); gui.bars.resize(nslots); gui.status.resize(nslots); QVBoxLayout *l= new QVBoxLayout(this); l->setMargin(0); /* As anyway the GraphicsZone is a fixed size, it's useless to resize that part, might as well let the chat be resized */ l->setSizeConstraint(QLayout::SetFixedSize); QHBoxLayout *firstLine = new QHBoxLayout(); l->addLayout(firstLine); QHBoxLayout *midzone = new QHBoxLayout(); l->addLayout(midzone); QHBoxLayout *lastLine = new QHBoxLayout(); l->addLayout(lastLine); QVBoxLayout *teamAndName[2]; for (int i = 0; i < 2; i++) { teamAndName[i] = new QVBoxLayout(); teamAndName[i]->addLayout(createTeamLayout(gui.pokeballs[i])); teamAndName[i]->addWidget(gui.trainers[i] = new QLabel(data()->name(i)),0, Qt::AlignRight); gui.trainers[i]->setObjectName("TrainerNick"); } firstLine->addWidget(gui.fullBars[opponent()] = createFullBarLayout(nslots, opponent())); firstLine->addLayout(teamAndName[opponent()]); gui.zone = new GraphicsZone(data(), gui.theme); /* Make the code below more generic? */ QVBoxLayout *midme = new QVBoxLayout(); midzone->addLayout(midme); midme->addStretch(100); gui.timers[myself()] = new QProgressBar(); gui.timers[myself()]->setObjectName("TimeOut"); //for style sheets gui.timers[myself()]->setRange(0,300); QLabel *mybox = new QLabel(); mybox->setObjectName("MyTrainerBox"); mybox->setFixedSize(82,82); mybox->setPixmap(gui.theme->trainerSprite(data()->avatar(myself()))); midme->addWidget(gui.timers[myself()]); midme->addWidget(mybox); midzone->addWidget(gui.zone); QVBoxLayout *midopp = new QVBoxLayout(); midzone->addLayout(midopp); midopp->addStretch(100); gui.timers[opponent()] = new QProgressBar(); gui.timers[opponent()]->setObjectName("TimeOut"); //for style sheets gui.timers[opponent()]->setRange(0,300); QLabel *oppbox = new QLabel(); oppbox->setPixmap(gui.theme->trainerSprite(data()->avatar(opponent()))); oppbox->setObjectName("OppTrainerBox"); oppbox->setFixedSize(82,82); midopp->addWidget(oppbox); midopp->addWidget(gui.timers[opponent()]); lastLine->addLayout(teamAndName[myself()]); lastLine->addWidget(gui.fullBars[myself()] = createFullBarLayout(nslots, myself())); QTimer *t = new QTimer (this); t->start(200); connect(t, SIGNAL(timeout()), SLOT(updateTimers())); }
void update() { updateTimers(); }
static void Emulate(EmulateSpecStruct *espec) { bool MeowMeow = 0; espec->DisplayRect.x = 0; espec->DisplayRect.y = 0; espec->DisplayRect.w = 160; espec->DisplayRect.h = 152; if(espec->VideoFormatChanged) NGPGfx->set_pixel_format(espec->surface->format); if(espec->SoundFormatChanged) MDFNNGPC_SetSoundRate(espec->SoundRate); NGPJoyLatch = *chee; storeB(0x6F82, *chee); MDFNMP_ApplyPeriodicCheats(); ngpc_soundTS = 0; NGPFrameSkip = espec->skip; do { #if 0 int32 timetime; if(main_timeaccum == 0) { main_timeaccum = TLCS900h_interpret(); if(main_timeaccum > 255) { main_timeaccum = 255; printf("%d\n", main_timeaccum); } } timetime = std::min<int32>(main_timeaccum, 24); main_timeaccum -= timetime; #else #if 0 uint32 old_pc = pc; { uint32 xix = gpr[0]; uint32 xiz = gpr[2]; printf("%08x %08x --- %s\n", xix, xiz, TLCS900h_disassemble()); } pc = old_pc; #endif int32 timetime = (uint8)TLCS900h_interpret(); // This is sooo not right, but it's replicating the old behavior(which is necessary // now since I've fixed the TLCS900h core and other places not to truncate cycle counts // internally to 8-bits). Switch to the #if 0'd block of code once we fix cycle counts in the // TLCS900h core(they're all sorts of messed up), and investigate if certain long // instructions are interruptable(by interrupts) and later resumable, RE Rockman Battle // & Fighters voice sample playback. #endif //if(timetime > 255) // printf("%d\n", timetime); // Note: Don't call updateTimers with a time/tick/cycle/whatever count greater than 255. MeowMeow |= updateTimers(espec->surface, timetime); z80_runtime += timetime; while(z80_runtime > 0) { int z80rantime = Z80_RunOP(); if(z80rantime < 0) // Z80 inactive, so take up all run time! { z80_runtime = 0; break; } z80_runtime -= z80rantime << 1; } } while(!MeowMeow); espec->MasterCycles = ngpc_soundTS; espec->SoundBufSize = MDFNNGPCSOUND_Flush(espec->SoundBuf, espec->SoundBufMaxSize); }
void emulate_debug(BOOL dis_TLCS900h, BOOL dis_Z80) { _u32 storePC = pc; debug_abort_memory = FALSE; debug_abort_instruction = FALSE; system_debug_history_add(); //For the debugger if (dis_TLCS900h) { char* s; //Disassemble TLCS-900h _u32 oldpc = pc; s = disassemble(); system_debug_message(s); system_debug_message_associate_address(oldpc); free(s); pc = oldpc; } if (dis_Z80) { //Disassemble Z80 if (Z80ACTIVE) { char* s; _u16 pc = Z80_getReg(Z80_REG_PC); _u16 store_pc = pc; //Disassemble s = Z80_disassemble(&pc); system_debug_message(s); system_debug_message_associate_address(store_pc + 0x7000); free(s); } } debug_abort_memory = FALSE; debug_abort_instruction = FALSE; //================== // EMULATE //================== { //TLCS900h instruction updateTimers(TLCS900h_interpret()); //Z80 Instruction if (Z80ACTIVE) Z80EMULATE; } //Check register code error if (rErr != RERR_VALUE) instruction_error("Invalid register code used."); //Memory Exception if (debug_abort_memory && filter_mem) { _u32 oldpc = pc; char* s; debug_abort_memory = FALSE; //Try to disassemble the erroneous instruction pc = storePC; debug_mask_memory_error_messages = TRUE; s = disassemble(); debug_mask_memory_error_messages = FALSE; if (debug_abort_memory == FALSE) { system_debug_message("Stopped due to memory exception caused by"); system_debug_message(" %s", s); system_debug_message_associate_address(storePC); system_debug_message("\n"); } else { system_debug_message("Stopped due to memory exception caused at %06X", storePC); system_debug_message_associate_address(storePC); } free(s); pc = oldpc; system_debug_stop(); system_debug_refresh(); return; } //Unimplemented Instruction if (debug_abort_instruction) { _u32 oldpc = pc; char* s; debug_abort_memory = FALSE; //Try to disassemble the erroneous instruction pc = storePC; debug_mask_memory_error_messages = TRUE; s = disassemble(); debug_mask_memory_error_messages = FALSE; if (debug_abort_memory == FALSE) { system_debug_message("Stopped due to instruction"); system_debug_message(" %s", s); system_debug_message_associate_address(storePC); system_debug_message("\n"); } else { system_debug_message("Stopped due to instruction at %06X", storePC); system_debug_message_associate_address(storePC); } free(s); pc = oldpc; system_debug_stop(); system_debug_refresh(); return; } }
void RegularBattleScene::setupGui() { int nslots = data()->numberOfSlots(); gui.nick.resize(nslots); gui.level.resize(nslots); gui.gender.resize(nslots); gui.bars.resize(nslots); gui.status.resize(nslots); QGridLayout *window = new QGridLayout(this); window->setSizeConstraint(QLayout::SetFixedSize); QVBoxLayout *team[2]; QVBoxLayout *name[2]; for (int i = 0; i < 2; i++) { team[i] = new QVBoxLayout(); team[i]->addLayout(createTeamLayout(gui.pokeballs[i])); name[i] = new QVBoxLayout(); name[i]->addWidget(gui.trainers[i] = new QLabel(data()->name(i)),0, Qt::AlignRight); gui.trainers[i]->setObjectName("TrainerNick"); } gui.zone = new GraphicsZone(data(), gui.theme); /* Set up our data */ QVBoxLayout *midme = new QVBoxLayout(); gui.timers[myself()] = new QProgressBar(); gui.timers[myself()]->setObjectName("TimeOut"); //for style sheets gui.timers[myself()]->setRange(0, data()->rated() ? ratedTime : unratedTime); QLabel *mybox = new QLabel(); mybox->setObjectName("MyTrainerBox"); mybox->setFixedSize(82,82); mybox->setPixmap(gui.theme->trainerSprite(data()->avatar(myself()))); midme->addLayout(team[myself()]); midme->addWidget(gui.timers[myself()]); midme->addWidget(mybox); midme->addLayout(name[myself()]); /* Set up Opponent's data */ QVBoxLayout *midopp = new QVBoxLayout(); gui.timers[opponent()] = new QProgressBar(); gui.timers[opponent()]->setObjectName("TimeOut"); //for style sheets gui.timers[opponent()]->setRange(0, data()->rated() ? ratedTime : unratedTime); QLabel *oppbox = new QLabel(); oppbox->setPixmap(gui.theme->trainerSprite(data()->avatar(opponent()))); oppbox->setObjectName("OppTrainerBox"); oppbox->setFixedSize(82,82); midopp->addLayout(name[opponent()]); midopp->addWidget(oppbox); midopp->addWidget(gui.timers[opponent()]); midopp->addLayout(team[opponent()]); /* Field must be at least 215 pixels tall otherwise the side elements will collide, causing display issues */ gui.zone->setMinimumSize(400,240); gui.zone->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); gui.zone->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /* Arrange everything */ window->addLayout(midopp,0,4,3,1,Qt::AlignTop); window->addWidget(gui.fullBars[opponent()] = createFullBarLayout(nslots, opponent()),0,1,1,3,Qt::AlignRight); window->addWidget(gui.zone,1,1,2,3); window->addWidget(gui.fullBars[myself()] = createFullBarLayout(nslots, myself()),3,1,1,3,Qt::AlignLeft); window->addLayout(midme,1,0,3,1,Qt::AlignBottom); QTimer *t = new QTimer (this); t->start(200); connect(t, SIGNAL(timeout()), SLOT(updateTimers())); }
/* * decrease the timer info according to the step, and updates the clocks */ void ClockDisplay::setTimeStep(bool black) { if (black) { b_time--; if(b_time == 0 && b_stones_periods != 0) { /* FIXME, maybe we should have one clock and subclass * the time system for different clocks??*/ if(timeSystem == byoyomi || (timeSystem == tvasia && b_stones_periods != -1)) { //printf("b by: %d %d %d %d\n", b_time, b_stones_periods, periodtime, periods); if(b_stones_periods > -1 || timeSystem == tvasia) b_stones_periods--; else b_stones_periods = periods; if(b_stones_periods != 0) b_time = periodtime; } else if(b_stones_periods == -1) { if(timeSystem == canadian) { b_time = periodtime; b_stones_periods = periods; } else if(timeSystem == tvasia) { b_time = periodtime; b_stones_periods = periods - 1; } } else printf("other timesystem\n"); /* IGS gets here a lot due to lag. I.e., canadian time steps down to 0 with stones * still remainaining to be played, then opponent plays and turns out they have five * seconds left or something. Would be neat to adjust for lag or something. FIXME */ } /* FIXME * major thing, we need to get time to switch * over into byoyomi time on IGS * I think the issue was that IGS sends a byoyomi entering * message... */ } else { w_time--; if(w_time == 0 && w_stones_periods != 0) { if(timeSystem == byoyomi || (timeSystem == tvasia && w_stones_periods != -1)) { //printf("w by: %d %d %d %d\n", w_time, w_stones_periods, periodtime, periods); if(w_stones_periods > -1 || timeSystem == tvasia) w_stones_periods--; else w_stones_periods = periods; if(w_stones_periods != 0) w_time = periodtime; } else if(w_stones_periods == -1) { if(timeSystem == canadian) { w_time = periodtime; w_stones_periods = periods; } else if(timeSystem == tvasia) { w_time = periodtime; w_stones_periods = periods - 1; } } else printf("other timesystem\n"); } } updateTimers(); }
// This function determines which command to issue next based on our // policy decisions. void policyManager(FILE *ofile) { command chosenCommand = WAIT; command nextCommand; bool isLegal = TRUE; int chosenPriority = -2; int comparePriority = 0; int chosenIndex; int queueIndex; // Check for a starving command and give it priority if it is legal. int starveCheck = findStarvation(); if (starveCheck != -1) { chosenIndex = starveCheck; chosenCommand = findNextCommand(starveCheck); chosenPriority = 10; // Update starving struct with info starvationStatus.isCommandStarving = TRUE; starvationStatus.name = chosenCommand; starvationStatus.bank = requestQueue[chosenIndex].bank; // Determine and store window that is locked out to other banks calculateWindow(starvationStatus.name, starvationStatus.bank, &starvationStatus.lowerWindow, &starvationStatus.upperWindow); // If command is not legal assign a WAIT command and low priority. if (!isCommandLegal(chosenCommand, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].row, chosenIndex, TRUE)) { chosenCommand = WAIT; chosenPriority = -1; } } else { // No starving requests. starvationStatus.isCommandStarving = FALSE; } // Look through queue and find highest priority legal commands. for (queueIndex = 0; queueIndex < 16; ++queueIndex) { // Array element must be valid and not the most starving request. if (requestQueue[queueIndex].occupied && !requestQueue[queueIndex].finished && queueIndex != starveCheck) { nextCommand = findNextCommand(queueIndex); isLegal = isCommandLegal(nextCommand, requestQueue[queueIndex].bank, requestQueue[queueIndex].row, queueIndex, FALSE); // Skip illegal commands. if (!isLegal) continue; // Assign priority based on command. switch(nextCommand) { case PRE : comparePriority = prechargePriority(queueIndex); break; case ACT : comparePriority = 2; break; case RD : comparePriority = 4; break; case WR : comparePriority = 4; break; case WAIT: comparePriority = -1; default : printf("\nERROR: Unknown Command\n"); } // Keep highest priority command. if (comparePriority > chosenPriority) { chosenPriority = comparePriority; chosenIndex = queueIndex; chosenCommand = nextCommand; } // The oldest request wins if priority tie. else if (comparePriority == chosenPriority) { if (requestQueue[queueIndex].timeIssued < requestQueue[chosenIndex].timeIssued) { chosenIndex = queueIndex; chosenCommand = nextCommand; } } } } // Print the correct output based on command chosen. switch (chosenCommand) { case PRE: fprintf(ofile, "%llu\tPRE\t%d\n", currentCPUTick, requestQueue[chosenIndex].bank); updateDimmStatus(chosenCommand, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].row); updateTimers(chosenCommand, requestQueue[chosenIndex].bank); break; case ACT: fprintf(ofile, "%llu\tACT\t%d\t%d\n", currentCPUTick, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].row); updateDimmStatus(chosenCommand, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].row); updateTimers(chosenCommand, requestQueue[chosenIndex].bank); break; case RD: fprintf(ofile, "%llu\tRD\t%d\t%d\n", currentCPUTick, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].column); requestQueue[chosenIndex].finished = TRUE; // Read requests will stay until data is finished. requestQueue[chosenIndex].timeRemaining = tCAS + tBURST; updateDimmStatus(chosenCommand, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].row); updateTimers(chosenCommand, requestQueue[chosenIndex].bank); break; case WR: fprintf(ofile, "%llu\tWR\t%d\t%d\n", currentCPUTick, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].column); requestQueue[chosenIndex].finished = TRUE; requestQueue[chosenIndex].occupied = FALSE; countSlotsOccupied -= 1; updateDimmStatus(chosenCommand, requestQueue[chosenIndex].bank, requestQueue[chosenIndex].row); updateTimers(chosenCommand, requestQueue[chosenIndex].bank); break; default: //printf("CPU:%llu ---\n", currentCPUTick); incrementTimers(1); break; } }