static id0_boolean_t Wait(id0_longword_t time) { time += SD_GetTimeCount(); while ((SD_GetTimeCount() < time) && (!IN_IsUserInput())) { if (!(SD_GetTimeCount() % MINTICS)) RF_Refresh(); else BE_ST_ShortSleep(); } return(IN_IsUserInput()); }
static id0_boolean_t MoveTitleTo(id0_int_t offset) { id0_boolean_t done; id0_int_t dir, chunk, move; id0_longword_t lasttime,delay; if (offset < originxglobal) dir = -1; else dir = +1; chunk = dir * PIXGLOBAL; done = false; delay = 1; while (!done) { lasttime = SD_GetTimeCount(); move = delay * chunk; if (chunk < 0) done = originxglobal + move <= offset; else done = originxglobal + move >= offset; if (!done) { RF_Scroll(move,0); RF_Refresh(); } if (IN_IsUserInput()) return(true); delay = SD_GetTimeCount() - lasttime; } if (originxglobal != offset) { RF_Scroll(offset - originxglobal,0); RF_Refresh(); } return(false); }
void PlayLoop (void) { id0_char_t shot_color[3] = {4,9,14}; id0_int_t allgems[5]={GEM_DELAY_TIME, // used for Q & D comparison GEM_DELAY_TIME, // for having all gems... GEM_DELAY_TIME, // the "allgems" declaration MUST GEM_DELAY_TIME, // match the "gems" declaration in GEM_DELAY_TIME // the gametype structure! }; // id0_int_t originx=0; // id0_int_t i=100; id0_signed_long_t dx,dy/*,radius*/,psin,pcos,newx,newy; //id0_int_t give; id0_short_t objnum; id0_signed_long_t ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy; id0_short_t o_radius; void (*think)(struct objstruct *); // REFKEEN: C++ patch ingame = true; SD_SetTimeCount(0); playstate = (exittype)0; //playstate = TimeCount = 0; gamestate.shotpower = handheight = 0; pointcount = pointsleft = 0; status_flag = S_NONE; #if 0 // setup sky/ground colors and effects (based on level) // switch (gamestate.mapon) { case 255: if (!(BGFLAGS & BGF_NIGHT)) { InitBgChange(3*60,sky_daytonight,-1,NULL,BGF_NIGHT); groundcolor = &gnd_colors[0]; } else { skycolor = &sky_colors[0]; groundcolor = &gnd_colors[0]; } break; default: skycolor = &sky_colors[gamestate.mapon]; groundcolor = &gnd_colors[gamestate.mapon]; skytimer = groundtimer = -1; break; } #endif BGFLAGS |= BGF_NOT_LIGHTNING; skytimer = groundtimer = -1; debug_gnd = *groundcolor; debug_sky = *skycolor; RedrawStatusWindow(); ThreeDRefresh(); if (screenfaded) VW_FadeIn(); #ifndef PROFILE fizzlein = true; // fizzle fade in the first refresh #endif /*TimeCount = */lasttimecount = lastnuke = 0; SD_SetTimeCount(0); PollControls (); // center mouse // StartMusic (); do { #ifndef PROFILE PollControls(); #else control.xaxis = 1; //if (++TimeCount == 300) // return; SD_AddToTimeCount(1); if (SD_GetTimeCount() == 300) return; #endif DisplayStatus(&status_flag); objnum=0; for (obj = player;obj;obj = obj->next) { if ((obj->active >= yes) && (!(FreezeTime && (obj!=player)))) { if (obj->ticcount) { obj->ticcount-=realtics; while ( obj->ticcount <= 0) { think = obj->state->thinkptr; if (think) { statetype *oldstate=obj->state; think (obj); if (!obj->state) { RemoveObj (obj); goto nextactor; } if (obj->state != oldstate) break; } obj->state = obj->state->next; if (!obj->state) { RemoveObj (obj); goto nextactor; } if (!obj->state->tictime) { obj->ticcount = 0; goto nextactor; } if (obj->state->tictime>0) obj->ticcount += obj->state->tictime; } } think = obj->state->thinkptr; if (think) { think (obj); if (!obj->state) RemoveObj (obj); } nextactor:; } // keep a list of objects around the player for radar updates // if (obj == player) { px = player->x; py = player->y; psin = sintable[player->angle]; pcos = costable[player->angle]; xl = px-((id0_long_t)RADAR_WIDTH<<TILESHIFT)/2; xh = px+((id0_long_t)RADAR_WIDTH<<TILESHIFT)/2-1; yl = py-((id0_long_t)RADAR_HEIGHT<<TILESHIFT)/2; yh = py+((id0_long_t)RADAR_HEIGHT<<TILESHIFT)/2; } if (objnum > MAX_RADAR_BLIPS-2) objnum = MAX_RADAR_BLIPS-2; ox = obj->x; oy = obj->y; if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh)) { norm_dx = (dx = px-ox)>>TILESHIFT; norm_dy = (dy = oy-py)>>TILESHIFT; id0_int_t IntSqrt(id0_long_t va); o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy)); if (o_radius < RADAR_RADIUS) { newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin); newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos); RadarXY[objnum][0]=newx>>TILESHIFT; RadarXY[objnum][1]=newy>>TILESHIFT; // Define color to use for this object... // switch (obj->obclass) { // NO GEM NEEDED // // THE WIZARD! (YOU) // case playerobj: RadarXY[objnum++][2]=15; break; // WIZARD'S SHOTS // case pshotobj: case bigpshotobj: RadarXY[objnum++][2]=shot_color[screenpage]; break; // BATS (DK GRAY) // case batobj: if (obj->active == always) RadarXY[objnum++][2]=8; break; // RABBITS (LT GRAY) // case bunnyobj: if (obj->active == always) RadarXY[objnum++][2]=7; break; // RED GEM // // EYE, RED DEMON (DK RED) // case eyeobj: case reddemonobj: if (gamestate.gems[B_RGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=4; break; // RED MAGE (LT RED) // case mageobj: if (gamestate.gems[B_RGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=12; break; // BLUE GEM // // SUCCUBUS (LT BLUE) // case succubusobj: if (gamestate.gems[B_BGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=9; break; // WATER DRAGON (DK BLUE) // case wetobj: if (gamestate.gems[B_GGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=1; break; // GREEN GEM // // GREEN TROLL (LT GREEN) // case fatdemonobj: if (gamestate.gems[B_GGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=10; break; // GODESS (DK GREEN) // case godessobj: if (gamestate.gems[B_GGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=2; break; // YELLOW GEM // // ANT (BROWN) // case antobj: case treeobj: if (gamestate.gems[B_YGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=6; break; // SKELETON (YELLOW) // case skeletonobj: if (gamestate.gems[B_YGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=14; break; // PURPLE GEM // // ZOMBIE // case zombieobj: if (gamestate.gems[B_PGEM-B_RGEM]) if (obj->active == always) RadarXY[objnum++][2]=13; break; // ALL GEMS NEEDED // // NEMESIS // case grelmobj: if (!memcmp(gamestate.gems,allgems,sizeof(gamestate.gems))) if (obj->active == always) RadarXY[objnum++][2]=15; break; } } } }
void CheckKeys (void) { //extern id0_boolean_t autofire; if (screenfaded) // don't do anything with a faded screen return; #if 0 // // pause key wierdness can't be checked as a scan code // if (Paused) { CenterWindow (8,3); US_PrintCentered ("PAUSED"); VW_UpdateScreen (); // SD_MusicOff(); IN_Ack(); // SD_MusicOn(); Paused = false; // (REFKEEN) Minor difference from vanilla Catacomb if (MousePresent) BE_ST_GetEmuAccuMouseMotion(NULL, NULL); // Clear accumulated mouse movement //if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement } else if (Keyboard[sc_Enter]) // P = pause with no screen disruptioon { // SD_MusicOff(); DisplaySMsg("PAUSED",NULL); IN_Ack(); // SD_MusicOn(); // (REFKEEN) Minor difference from vanilla Catacomb if (MousePresent) BE_ST_GetEmuAccuMouseMotion(NULL, NULL); // Clear accumulated mouse movement //if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement } else if (Keyboard[sc_S]) { id0_char_t *Text[] = {{"Slow Mode ON"},{"Slow Mode OFF"}}; SlowMode ^= 1; extravbls = SlowMode << 3; CenterWindow (8,3); US_PrintCentered (Text[SlowMode]); VW_UpdateScreen (); // SD_MusicOff(); IN_Ack(); // SD_MusicOn(); // (REFKEEN) Minor difference from vanilla Catacomb if (MousePresent) BE_ST_GetEmuAccuMouseMotion(NULL, NULL); // Clear accumulated mouse movement //if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement } #endif // F2 - SOUND OPTIONS // if (Keyboard[sc_F2]) { id0_int_t height=7; id0_boolean_t ChoiceMade = false; if (AdLibPresent) height++; VW_FixRefreshBuffer(); CenterWindow(22,height); US_Print( "\n 1 ) NO SOUND \n"); US_Print( " 2 ) PC AUDIO \n"); if (AdLibPresent) US_Print(" 3 ) ADLIB AUDIO\n"); US_Print( "\n ESC) EXIT "); VW_UpdateScreen(); // REFKEEN - Alternative controllers support extern BE_ST_ControllerMapping g_ingame_altcontrol_mapping_soundoptions; g_ingame_altcontrol_mapping_soundoptions.buttons[BE_ST_CTRL_BUT_X].mapClass = AdLibPresent ? BE_ST_CTRL_MAP_KEYSCANCODE : BE_ST_CTRL_MAP_NONE; // A bit of patching BE_ST_AltControlScheme_Push(); BE_ST_AltControlScheme_PrepareControllerMapping(&g_ingame_altcontrol_mapping_soundoptions); // Switch audio device ON/OFF & load sounds if there // was a change in the device. do { if (Keyboard[1]) // ESC - Exit ChoiceMade = true; else if (Keyboard[2]) // 1 - No Sound { SD_SetSoundMode(sdm_Off); ChoiceMade = true; } else if (Keyboard[3]) // 2 - PC Audio { SD_SetSoundMode(sdm_PC); // if (oldsoundmode != sdm_PC) CA_LoadAllSounds(); ChoiceMade = true; } else if ((Keyboard[4]) && AdLibPresent) // 3 - AdLib Audio { SD_SetSoundMode(sdm_AdLib); // if (oldsoundmode != sdm_AdLib) CA_LoadAllSounds(); ChoiceMade = true; } BE_ST_ShortSleep(); } while (!ChoiceMade); // REFKEEN - Alternative controllers support BE_ST_AltControlScheme_Pop(); tics = realtics = 1; IN_ClearKeysDown(); } // F5 - CALIBRATE JOYSTICK // if (Keyboard[sc_F5]) { CalibrateJoystick(0); tics = realtics = 1; IN_ClearKeysDown(); } deadloop:; // ESCAPE - quits game // if ((Keyboard[sc_Escape]) || (Flags & FL_DEAD)) { id0_char_t ch; DisplaySMsg("Options", NULL); status_flag = S_NONE; if (Flags & FL_DEAD) { id0_char_t choices[] = {sc_Escape,sc_R,sc_N,sc_Q,0}; ch = DisplayMsg("Restore New Quit",choices); } else { id0_char_t choices[] = {sc_Escape,sc_S,sc_R,sc_N,sc_Q,0}; ch = DisplayMsg("Save Restore New Quit",choices); } DrawText(true); switch (ch) { case sc_S: if (!(Flags & FL_DEAD)) Keyboard[sc_F3] = true; break; case sc_R: Keyboard[sc_F4] = true; break; case sc_N: DisplaySMsg("Starting anew", NULL); VW_WaitVBL(60); playstate = ex_resetgame; Flags &= ~FL_DEAD; break; case sc_Q: // REFKEEN - Alternative controllers support { extern BE_ST_ControllerMapping g_ingame_altcontrol_mapping_inackback; BE_ST_AltControlScheme_Push(); BE_ST_AltControlScheme_PrepareControllerMapping(&g_ingame_altcontrol_mapping_inackback); // REFKEEN - We don't pop this since we quit... } DisplaySMsg("FARE THEE WELL!", NULL); VW_WaitVBL(120); if (!Flags & FL_QUICK) VW_FadeOut(); NormalScreen(); FreeUpMemory(); Quit(NULL); break; } tics = realtics = 1; } // F1 - DISPLAY HELP // if (Keyboard[sc_F1]) { PrintHelp(); #ifdef TEXT_PRESENTER extern PresenterInfo MainHelpText; VW_FadeOut(); FreeUpMemory(); if (!LoadPresenterScript("HELP.TXT",&MainHelpText)) { VW_FadeIn(); CenterWindow(30,5); US_CPrint("\nError loading HELP file.\n"); US_CPrint("Press any key."); IN_Ack(); VW_FadeOut(); } else { VW_SetSplitScreen(200); bufferofs = displayofs = screenloc[0]; VW_Bar(0,0,320,200,0); Display640(); Presenter(&MainHelpText); Display320(); } FreePresenterScript(&MainHelpText); #endif VW_SetSplitScreen(120); VW_SetScreen(screenloc[0],0); screenpage = 0; CacheScaleds(); bufferofs = 0; RedrawStatusWindow(); ThreeDRefresh(); VW_FadeIn(); Keyboard[sc_F1] = false; tics = realtics = 1; IN_ClearKeysDown(); } // F3 - SAVE GAME // if ((Keyboard[sc_F3]) && (!(Flags & FL_DEAD))) { PreFullDisplay(); GE_SaveGame(); PostFullDisplay(true); tics = realtics = 1; IN_ClearKeysDown(); } // F4 - LOAD GAME // if (Keyboard[sc_F4]) { PreFullDisplay(); if (GE_LoadGame()) { loadedgame = true; playstate = ex_loadedgame; Flags &= ~FL_DEAD; lasttext = -1; PostFullDisplay(false); } else if (playstate == ex_victorious) { PostFullDisplay(false); Victory(false); IN_Ack(); // gamestate.mapon++; } else PostFullDisplay(true); Keyboard[sc_F5] = false; tics = realtics = 1; IN_ClearKeysDown(); } if (Flags & FL_DEAD) goto deadloop; // // F10-? debug keys // if (Keyboard[sc_BackSpace]) { DebugKeys(); // (REFKEEN) Minor difference from vanilla Catacomb if (MousePresent) BE_ST_GetEmuAccuMouseMotion(NULL, NULL); // Clear accumulated mouse movement //if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement lasttimecount = SD_GetTimeCount(); } }
bool US_LineInput(uint16_t x, uint16_t y, char *buf, char *def, bool escok, uint16_t maxchars, uint16_t maxwidth) { bool redraw, cursorvis, cursormoved, done, result; IN_ScanCode sc; char c, s[128], olds[128]; uint16_t i, cursor, w, h, len/*, temp*/; uint32_t lasttime; if (def) strcpy(s, def); else *s = '\0'; *olds = '\0'; cursor = strlen(s); cursormoved = redraw = true; cursorvis = done = false; lasttime = SD_GetTimeCount(); IN_SetLastASCII(IN_KP_None); IN_SetLastScan(IN_SC_None); while (!done) { // TODO/FIXME: Handle this in a possibly better way // (no busy loop, updating gfx if required, etc..) IN_PumpEvents(); //CK_SetTicsPerFrame(); if (cursorvis) USL_XORICursor(x, y, s, cursor); sc = IN_GetLastScan(); IN_SetLastScan(IN_SC_None); c = IN_GetLastASCII(); IN_SetLastASCII(IN_KP_None); switch (sc) { case IN_SC_LeftArrow: if (cursor) cursor--; c = 0; cursormoved = true; break; case IN_SC_RightArrow: if (s[cursor]) cursor++; c = 0; cursormoved = true; break; case IN_SC_Home: cursor = 0; c = 0; cursormoved = true; break; case IN_SC_End: cursor = strlen(s); c = 0; cursormoved = true; break; case IN_SC_Enter: strcpy(buf, s); done = true; result = true; c = 0; break; case IN_SC_Escape: if (escok) { done = true; result = false; } c = 0; break; case IN_SC_Backspace: if (cursor) { strcpy(s + cursor - 1, s + cursor); cursor--; redraw = true; } c = 0; cursormoved = true; break; case IN_SC_Delete: if (s[cursor]) { strcpy(s + cursor, s + cursor + 1); redraw = true; } c = 0; cursormoved = true; break; case 0x4c: // Keypad 5 case IN_SC_UpArrow: case IN_SC_DownArrow: case IN_SC_PgUp: case IN_SC_PgDown: case IN_SC_Insert: c = 0; break; } if (c) { len = strlen(s); VH_MeasurePropString(s, &w, &h, US_GetPrintFont()); if ( isprint(c) && (len < 128 - 1) && ((!maxchars) || (len < maxchars)) && ((!maxwidth) || (w < maxwidth)) ) { for (i = len + 1; i > cursor; i--) s[i] = s[i - 1]; s[cursor++] = c; redraw = true; } } if (redraw) { /* px = x; py = y; */ //temp = us_printColour; //us_printColour = us_backColour; VH_DrawPropString(olds, x, y, us_printFont, us_printColour); //us_printColour = temp; strcpy(olds, s); /* px = x; py = y; */ VH_DrawPropString(s, x, y, us_printFont, us_printColour); redraw = false; } if (cursormoved) { cursorvis = false; lasttime = SD_GetTimeCount() - 70 /*TimeCount - TickBase*/; cursormoved = false; } if (SD_GetTimeCount()-lasttime > 35 /*TimeCount - lasttime > TickBase / 2*/) { lasttime = SD_GetTimeCount();//TimeCount; cursorvis ^= true; } if (cursorvis) USL_XORICursor(x, y, s, cursor); //VW_UpdateScreen(); VL_Present(); } if (cursorvis) USL_XORICursor(x, y, s, cursor); if (!result) { /* px = x; py = y; */ VH_DrawPropString(olds, x, y, us_printFont, us_printColour); } //VW_UpdateScreen(); VL_Present(); IN_ClearKeysDown(); return (result); }
void PlayLoop (void) { id0_int_t give; void (*think)(struct objstruct *); // REFKEEN: C++ patch ingame = true; SD_SetTimeCount(0); playstate = (exittype)0; //playstate = TimeCount = 0; gamestate.shotpower = handheight = 0; pointcount = pointsleft = 0; DrawLevelNumber (gamestate.mapon); DrawBars (); #ifndef PROFILE fizzlein = true; // fizzle fade in the first refresh #endif /*TimeCount = */lasttimecount = lastnuke = 0; PollControls (); // center mouse StartMusic (); do { #ifndef PROFILE PollControls(); #else c.xaxis = 1; // if (++TimeCount == 300) // return; SD_SetTimeCount(SD_GetTimeCount()+1); if (SD_GetTimeCount() == 300) return; #endif for (obj = player;obj;obj = obj->next) if (obj->active) { if (obj->ticcount) { obj->ticcount-=tics; while ( obj->ticcount <= 0) { think = obj->state->thinkptr; if (think) { think (obj); if (!obj->state) { RemoveObj (obj); goto nextactor; } } obj->state = obj->state->next; if (!obj->state) { RemoveObj (obj); goto nextactor; } if (!obj->state->tictime) { obj->ticcount = 0; goto nextactor; } if (obj->state->tictime>0) obj->ticcount += obj->state->tictime; } } think = obj->state->thinkptr; if (think) { think (obj); if (!obj->state) RemoveObj (obj); } nextactor:; } if (bordertime) { bordertime -= tics; if (bordertime<=0) { bordertime = 0; VW_ColorBorder (3); } } if (pointcount) { pointcount -= tics; if (pointcount <= 0) { pointcount += POINTTICS; give = (pointsleft > 1000)? 1000 : ( (pointsleft > 100)? 100 : ((pointsleft < 20)? pointsleft : 20) ); SD_PlaySound (GETPOINTSSND); AddPoints (give); pointsleft -= give; if (!pointsleft) pointcount = 0; } } ThreeDRefresh (); CheckKeys(); // (REFKEEN) SPECIAL - Without this the game // can run very fast, even if it's not noticeable // (a lot of PlayLoop iterations and consumed CPU power) // // Notes: // 1. Should NOT be called from ThreeDRefresh/CalcTics, // because we don't always want that to be done // (e.g., FizzleFade effect right after loading C4 saved game). // 2. SHOULD be called AFTER CheckKeys. That function resets // lasttimecount (just like CalcTics) if the debug key modifier // (F10 in Cat. 3-D/Abyss, Backspace in Armageddon/Apocalypse) // is held. As a consequence, if the wait is done before the // call to CheckKeys then the game may seem to get stuck while // the debug key modifier is held. BE_ST_TimeCountWaitFromSrc(SD_GetTimeCount(), 1); // if (singlestep) { VW_WaitVBL(14); lasttimecount = SD_GetTimeCount(); } if (extravbls) VW_WaitVBL(extravbls); }while (!playstate); StopMusic (); ingame = false; if (bordertime) { bordertime = 0; VW_ColorBorder (3); } if (!abortgame) AddPoints (pointsleft); else abortgame = false; }
void CheckKeys (void) { if (screenfaded) // don't do anything with a faded screen return; // // pause key wierdness can't be checked as a scan code // if (Paused) { CenterWindow (8,3); US_PrintCentered ("PAUSED"); VW_UpdateScreen (); SD_MusicOff(); IN_Ack(); SD_MusicOn(); Paused = false; if (MousePresent) BE_ST_GetMouseDelta(NULL, NULL); // Clear accumulated mouse movement //if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement } // // F1-F7/ESC to enter control panel // if ( (LastScan >= sc_F1 && LastScan <= sc_F7) || LastScan == sc_Escape) { StopMusic (); NormalScreen (); FreeUpMemory (); US_CenterWindow (20,8); US_CPrint ("Loading"); VW_UpdateScreen (); US_ControlPanel(); // REFKEEN - Alternative controllers support (maybe user has changed some keys which may currently have an effect) void PrepareGamePlayControllerMapping(void); PrepareGamePlayControllerMapping(); // if (abortgame) { playstate = ex_abort; return; } StartMusic (); IN_ClearKeysDown(); if (restartgame) playstate = ex_resetgame; if (loadedgame) playstate = ex_loadedgame; DrawPlayScreen (); CacheScaleds (); lasttimecount = SD_GetTimeCount(); if (MousePresent) BE_ST_GetMouseDelta(NULL, NULL); // Clear accumulated mouse movement //if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement } // // F10-? debug keys // if (Keyboard[sc_F10]) { DebugKeys(); if (MousePresent) BE_ST_GetMouseDelta(NULL, NULL); // Clear accumulated mouse // if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement lasttimecount = SD_GetTimeCount(); } }