//------------------------------------------------------------------------- /* Copyright (C) 1996, 2003 - 3D Realms Entertainment Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements) Copyright (C) 2004, 2007 - EDuke32 developers This file is part of EDuke32 EDuke32 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //------------------------------------------------------------------------- #include "duke3d.h" #include "osd.h" #ifdef RENDERTYPEWIN #define WIN32_LEAN_AND_MEAN #include #endif extern char pow2char[]; extern int everyothertime; static int which_palookup = 9; int g_NumPalettes; short spritecache[MAXTILES][3]; static char precachehightile[2][MAXTILES>>3]; static int precachecount; extern char *duke3dgrpstring; extern int leveltexttime; static void tloadtile(int tilenume, int type) { if ((picanm[tilenume]&63) < 1) { if (!(gotpic[tilenume>>3] & pow2char[tilenume&7])) precachecount++; gotpic[tilenume>>3] |= pow2char[tilenume&7]; precachehightile[(unsigned char)type][tilenume>>3] |= pow2char[tilenume&7]; return; } { int i,j; if ((picanm[tilenume]&192)==192) { i = tilenume - (picanm[tilenume]&63); j = tilenume; } else { i = tilenume; j = tilenume + (picanm[tilenume]&63); } for (;i<=j;i++) { if (!(gotpic[i>>3] & pow2char[i&7])) precachecount++; gotpic[i>>3] |= pow2char[i&7]; precachehightile[(unsigned char)type][i>>3] |= pow2char[i&7]; } } } static void cachespritenum(int i) { char maxc; int j; if (ud.monsters_off && badguy(&sprite[i])) return; maxc = 1; if (spritecache[PN][0] == PN) for (j = PN; j <= spritecache[PN][1]; j++) tloadtile(j,1); switch (dynamictostatic[PN]) { case HYDRENT__STATIC: tloadtile(BROKEFIREHYDRENT,1); for (j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1); break; case TOILET__STATIC: tloadtile(TOILETBROKE,1); for (j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1); break; case STALL__STATIC: tloadtile(STALLBROKE,1); for (j = TOILETWATER; j < (TOILETWATER+4); j++) tloadtile(j,1); break; case RUBBERCAN__STATIC: maxc = 2; break; case TOILETWATER__STATIC: maxc = 4; break; case FEMPIC1__STATIC: maxc = 44; break; case LIZTROOP__STATIC: case LIZTROOPRUNNING__STATIC: case LIZTROOPSHOOT__STATIC: case LIZTROOPJETPACK__STATIC: case LIZTROOPONTOILET__STATIC: case LIZTROOPDUCKING__STATIC: for (j = LIZTROOP; j < (LIZTROOP+72); j++) tloadtile(j,1); for (j=HEADJIB1;j 1) { maxc = 5; for (j = 1420;j < 1420+106; j++) tloadtile(j,1); } break; case ATOMICHEALTH__STATIC: maxc = 14; break; case DRONE__STATIC: maxc = 10; break; case EXPLODINGBARREL__STATIC: case SEENINE__STATIC: case OOZFILTER__STATIC: maxc = 3; break; case NUKEBARREL__STATIC: case CAMERA1__STATIC: maxc = 5; break; // caching of HUD sprites for weapons that may be in the level case CHAINGUNSPRITE__STATIC: for (j=CHAINGUN; j<=CHAINGUN+7; j++) tloadtile(j,1); break; case RPGSPRITE__STATIC: for (j=RPGGUN; j<=RPGGUN+2; j++) tloadtile(j,1); break; case FREEZESPRITE__STATIC: for (j=FREEZE; j<=FREEZE+5; j++) tloadtile(j,1); break; case GROWSPRITEICON__STATIC: case SHRINKERSPRITE__STATIC: for (j=SHRINKER-2; j<=SHRINKER+5; j++) tloadtile(j,1); break; case HBOMBAMMO__STATIC: case HEAVYHBOMB__STATIC: for (j=HANDREMOTE; j<=HANDREMOTE+5; j++) tloadtile(j,1); break; case TRIPBOMBSPRITE__STATIC: for (j=HANDHOLDINGLASER; j<=HANDHOLDINGLASER+4; j++) tloadtile(j,1); break; case SHOTGUNSPRITE__STATIC: tloadtile(SHOTGUNSHELL,1); for (j=SHOTGUN; j<=SHOTGUN+6; j++) tloadtile(j,1); break; case DEVISTATORSPRITE__STATIC: for (j=DEVISTATOR; j<=DEVISTATOR+1; j++) tloadtile(j,1); break; } for (j = PN; j < (PN+maxc); j++) tloadtile(j,1); } static void cachegoodsprites(void) { int i,j; for (i=0;i 1) tloadtile(FRAGBAR,1); tloadtile(VIEWSCREEN,1); for (i=STARTALPHANUM;i= MAXSOUNDS || ud.config.SoundToggle == 0) return 0; if (ud.config.FXDevice < 0) return 0; if (!g_sounds[num].filename && !g_sounds[num].filename1) return 0; if (g_sounds[num].filename1) fp = kopen4loadfrommod(g_sounds[num].filename1,loadfromgrouponly); if (fp == -1) fp = kopen4loadfrommod(g_sounds[num].filename,loadfromgrouponly); if (fp == -1) { initprintf("Sound '%s' not found\n",g_sounds[num].filename); return 0; } l = kfilelength(fp); g_sounds[num].soundsiz = l; if ((ud.level_number == 0 && ud.volume_number == 0 && (num == 189 || num == 232 || num == 99 || num == 233 || num == 17)) || (l < 12288)) { g_sounds[num].lock = 199; allocache((intptr_t *)&g_sounds[num].ptr,l,(char *)&g_sounds[num].lock); if (g_sounds[num].ptr != NULL) kread(fp, g_sounds[num].ptr , l); } kclose(fp); return 1; } static void precachenecessarysounds(void) { int i, j; if (ud.config.FXDevice < 0) return; j = 0; for (i=0;ipalette = palette; setgamepalette(g_player[myconnectindex].ps, palette, 1); // JBF 20040308 fadepal(0,0,0, 0,64,7); i = ud.screen_size; ud.screen_size = 0; vscrn(); clearview(0L); } SetGameVarID(g_iReturnVarID,LOADSCREEN, -1, -1); OnEvent(EVENT_GETLOADTILE, -1, myconnectindex, -1); j = GetGameVarID(g_iReturnVarID, -1, -1); rotatesprite(320<<15,200<<15,65536L,0,j > MAXTILES-1?j-MAXTILES:j,0,0,2+8+64,0,0,xdim-1,ydim-1); if (j > MAXTILES-1) { nextpage(); return; } if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0) { menutext(160,90,0,0,"LOADING USER MAP"); gametextpal(160,90+10,boardfilename,14,2); } else { menutext(160,90,0,0,"LOADING"); if (map[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) menutext(160,90+16+8,0,0,map[(ud.volume_number*MAXLEVELS) + ud.level_number].name); } if (statustext) gametext(160,180,statustext,0,2+8+16); OnEvent(EVENT_DISPLAYLOADINGSCREEN, g_player[screenpeek].ps->i, screenpeek, -1); nextpage(); if (!statustext) { fadepal(0,0,0, 63,0,-7); KB_FlushKeyboardQueue(); ud.screen_size = i; } } else { if (!statustext) { clearview(0L); //g_player[myconnectindex].ps->palette = palette; //palto(0,0,0,0); setgamepalette(g_player[myconnectindex].ps, palette, 0); // JBF 20040308 } SetGameVarID(g_iReturnVarID,LOADSCREEN, -1, -1); OnEvent(EVENT_GETLOADTILE, -1, myconnectindex, -1); j = GetGameVarID(g_iReturnVarID, -1, -1); rotatesprite(320<<15,200<<15,65536L,0,j > MAXTILES-1?j-MAXTILES:j,0,0,2+8+64,0,0,xdim-1,ydim-1); if (j > MAXTILES-1) { nextpage(); return; } menutext(160,105,0,0,"LOADING..."); if (statustext) gametext(160,180,statustext,0,2+8+16); OnEvent(EVENT_DISPLAYLOADINGSCREEN, g_player[screenpeek].ps->i, screenpeek, -1); nextpage(); } } extern void SetCrosshairColor(int r, int g, int b); extern palette_t crosshair_colors; void cacheit(void) { int i,j,pc=0; int tc; unsigned int starttime, endtime; if (ud.recstat == 2) return; MUSIC_Pause(); if (map[MAXVOLUMES*MAXLEVELS+2].musicfn1) { MUSIC_StopSong(); playmusic(&env_music_fn[2][0],MAXVOLUMES*MAXLEVELS+2); // loadmus } starttime = getticks(); precachenecessarysounds(); cachegoodsprites(); for (i=0;i= 0) { tloadtile(wall[i].overpicnum, 0); } } for (i=0;i= 0) { if (sprite[j].xrepeat != 0 && sprite[j].yrepeat != 0 && (sprite[j].cstat&32768) == 0) cachespritenum(j); j = nextspritesect[j]; } } tc = totalclock; j = 0; for (i=0;i>3]) { i+=7; continue; } if (gotpic[i>>3] & pow2char[i&7]) { if (waloff[i] == 0) loadtile((short)i); #if defined(POLYMOST) && defined(USE_OPENGL) if (ud.config.useprecache) { int k; if (precachehightile[0][i>>3] & pow2char[i&7]) for (k=0; k>3] & pow2char[i&7]) for (k=0; k TICRATE/4) { sprintf(tempbuf,"Loading resources... %d%%\n",min(100,100*pc/precachecount)); dofrontscreens(tempbuf); tc = totalclock; } } clearbufbyte(gotpic,sizeof(gotpic),0L); endtime = getticks(); OSD_Printf("Cache time: %dms\n", endtime-starttime); } void xyzmirror(int i,int wn) { //if (waloff[wn] == 0) loadtile(wn); setviewtotile(wn,tilesizy[wn],tilesizx[wn]); drawrooms(SX,SY,SZ,SA,100+sprite[i].shade,SECT); display_mirror = 1; animatesprites(SX,SY,SA,65536L); display_mirror = 0; drawmasks(); setviewback(); squarerotatetile(wn); invalidatetile(wn,-1,255); } void vscrn(void) { int i, j, ss, x1, x2, y1, y2; if (ud.screen_size < 0) ud.screen_size = 0; if (ud.screen_size > 64) ud.screen_size = 64; if (ud.screen_size == 0) flushperms(); ss = max(ud.screen_size-8,0); x1 = scale(ss,xdim,160); x2 = xdim-x1; y1 = ss; y2 = 200; if (ud.screen_size > 0 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_FRAGBAR) && ud.multimode > 1) { j = 0; for (i=connecthead;i>=0;i=connectpoint2[i]) if (i > j) j = i; if (j >= 1) y1 += 8; if (j >= 4) y1 += 8; if (j >= 8) y1 += 8; if (j >= 12) y1 += 8; } if (ud.screen_size >= 8 && !(getrendermode() >= 3 && ud.screen_size == 8 && ud.statusbarmode)) y2 -= (ss+scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100)); y1 = scale(y1,ydim,200); y2 = scale(y2,ydim,200); setview(x1,y1,x2-1,y2-1); GetCrosshairColor(); SetCrosshairColor(crosshair_colors.r, crosshair_colors.g, crosshair_colors.b); pub = NUMPAGES; pus = NUMPAGES; } void pickrandomspot(int snum) { player_struct *p = g_player[snum].ps; int i=snum,j,k; unsigned int dist,pdist = -1; if (ud.multimode > 1 && !(gametype_flags[ud.coop] & GAMETYPE_FLAG_FIXEDRESPAWN)) { i = TRAND%numplayersprites; if (gametype_flags[ud.coop] & GAMETYPE_FLAG_TDMSPAWN) { for (j=0;jteam == p->team && sprite[g_player[j].ps->i].extra > 0) { for (k=0;kposx-g_PlayerSpawnPoints[k].ox,g_player[j].ps->posy-g_PlayerSpawnPoints[k].oy); if (dist < pdist) i = k, pdist = dist; } break; } } } } p->bobposx = p->oposx = p->posx = g_PlayerSpawnPoints[i].ox; p->bobposy = p->oposy = p->posy = g_PlayerSpawnPoints[i].oy; p->oposz = p->posz = g_PlayerSpawnPoints[i].oz; p->ang = g_PlayerSpawnPoints[i].oa; p->cursectnum = g_PlayerSpawnPoints[i].os; } static void resetplayerstats(int snum) { player_struct *p = g_player[snum].ps; ud.show_help = 0; ud.showallmap = 0; p->dead_flag = 0; p->wackedbyactor = -1; p->falling_counter = 0; p->quick_kick = 0; p->subweapon = 0; p->last_full_weapon = 0; p->ftq = 0; p->fta = 0; p->tipincs = 0; p->buttonpalette = 0; p->actorsqu =-1; p->invdisptime = 0; p->refresh_inventory= 0; p->last_pissed_time = 0; p->holster_weapon = 0; p->pycount = 0; p->pyoff = 0; p->opyoff = 0; p->loogcnt = 0; p->angvel = 0; p->weapon_sway = 0; // p->select_dir = 0; p->extra_extra8 = 0; p->show_empty_weapon= 0; p->dummyplayersprite=-1; p->crack_time = 0; p->hbomb_hold_delay = 0; p->transporter_hold = 0; p->wantweaponfire = -1; p->hurt_delay = 0; p->footprintcount = 0; p->footprintpal = 0; p->footprintshade = 0; p->jumping_toggle = 0; p->ohoriz = p->horiz= 140; p->horizoff = 0; p->bobcounter = 0; p->on_ground = 0; p->player_par = 0; p->return_to_center = 9; p->airleft = 15*26; p->rapid_fire_hold = 0; p->toggle_key_flag = 0; p->access_spritenum = -1; if (ud.multimode > 1 && (gametype_flags[ud.coop] & GAMETYPE_FLAG_ACCESSATSTART)) p->got_access = 7; else p->got_access = 0; p->random_club_frame= 0; pus = 1; p->on_warping_sector = 0; p->spritebridge = 0; p->sbs = 0; p->palette = (char *) &palette[0]; if (p->steroids_amount < 400) { p->steroids_amount = 0; p->inven_icon = 0; } p->heat_on = 0; p->jetpack_on = 0; p->holoduke_on = -1; p->look_ang = 512 - ((ud.level_number&1)<<10); p->rotscrnang = 0; p->orotscrnang = 1; // JBF 20031220 p->newowner =-1; p->jumping_counter = 0; p->hard_landing = 0; p->posxv = 0; p->posyv = 0; p->poszv = 0; fricxv = 0; fricyv = 0; p->somethingonplayer =-1; p->one_eighty_count = 0; p->cheat_phase = 0; p->on_crane = -1; if ((aplWeaponWorksLike[p->curr_weapon][snum] == PISTOL_WEAPON) && (aplWeaponReload[p->curr_weapon][snum] > aplWeaponTotalTime[p->curr_weapon][snum])) p->kickback_pic = aplWeaponTotalTime[p->curr_weapon][snum]+1; else p->kickback_pic = 0; p->weapon_pos = 6; p->walking_snd_toggle= 0; p->weapon_ang = 0; p->knuckle_incs = 1; p->fist_incs = 0; p->knee_incs = 0; p->jetpack_on = 0; p->reloading = 0; p->movement_lock = 0; setpal(p); OnEvent(EVENT_RESETPLAYER, p->i, snum, -1); } void resetweapons(int snum) { int weapon; player_struct *p = g_player[snum].ps; for (weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++) p->gotweapon[weapon] = 0; for (weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++) p->ammo_amount[weapon] = 0; p->weapon_pos = 6; p->kickback_pic = 5; p->curr_weapon = PISTOL_WEAPON; p->gotweapon[PISTOL_WEAPON] = 1; p->gotweapon[KNEE_WEAPON] = 1; p->ammo_amount[PISTOL_WEAPON] = 48; p->gotweapon[HANDREMOTE_WEAPON] = 1; p->last_weapon = -1; p->show_empty_weapon= 0; p->last_pissed_time = 0; p->holster_weapon = 0; OnEvent(EVENT_RESETWEAPONS, p->i, snum, -1); } void resetinventory(int snum) { player_struct *p = g_player[snum].ps; p->inven_icon = 0; p->boot_amount = 0; p->scuba_on = 0; p->scuba_amount = 0; p->heat_amount = 0; p->heat_on = 0; p->jetpack_on = 0; p->jetpack_amount = 0; p->shield_amount = start_armour_amount; p->holoduke_on = -1; p->holoduke_amount = 0; p->firstaid_amount = 0; p->steroids_amount = 0; p->inven_icon = 0; OnEvent(EVENT_RESETINVENTORY, p->i, snum, -1); } static void resetprestat(int snum,int g) { player_struct *p = g_player[snum].ps; int i; spriteqloc = 0; for (i=0;ihbomb_on = 0; p->cheat_phase = 0; p->pals_time = 0; p->toggle_key_flag = 0; p->secret_rooms = 0; p->max_secret_rooms = 0; p->actors_killed = 0; p->max_actors_killed = 0; p->lastrandomspot = 0; p->weapon_pos = 6; p->kickback_pic = 5; p->last_weapon = -1; p->weapreccnt = 0; p->interface_toggle_flag = 0; p->show_empty_weapon= 0; p->holster_weapon = 0; p->last_pissed_time = 0; p->one_parallax_sectnum = -1; p->visibility = ud.const_visibility; screenpeek = myconnectindex; numanimwalls = 0; numcyclers = 0; animatecnt = 0; parallaxtype = 0; randomseed = 17L; ud.pause_on = 0; ud.camerasprite =-1; ud.eog = 0; tempwallptr = 0; camsprite =-1; earthquaketime = 0; numinterpolations = 0; startofdynamicinterpolations = 0; if (((g&MODE_EOL) != MODE_EOL && numplayers < 2) || (!(gametype_flags[ud.coop]&GAMETYPE_FLAG_PRESERVEINVENTORYDEATH) && numplayers > 1)) { resetweapons(snum); resetinventory(snum); } else if (p->curr_weapon == HANDREMOTE_WEAPON) { p->ammo_amount[HANDBOMB_WEAPON]++; p->curr_weapon = HANDBOMB_WEAPON; } p->timebeforeexit = 0; p->customexitsound = 0; } static void setupbackdrop(short sky) { short i; for (i=0;i sector[i].ceilingz) sector[i].lotag |= 32768; continue; } if (sector[i].ceilingstat&1) { if (waloff[sector[i].ceilingpicnum] == 0) { if (sector[i].ceilingpicnum == LA) for (j=0;j<5;j++) tloadtile(sector[i].ceilingpicnum+j, 0); } setupbackdrop(sector[i].ceilingpicnum); if (sector[i].ceilingpicnum == CLOUDYSKIES && numclouds < 127) clouds[numclouds++] = i; if (g_player[0].ps->one_parallax_sectnum == -1) g_player[0].ps->one_parallax_sectnum = i; } if (sector[i].lotag == 32767) //Found a secret room { g_player[0].ps->max_secret_rooms++; continue; } if (sector[i].lotag == -1) { g_player[0].ps->exitx = wall[sector[i].wallptr].x; g_player[0].ps->exity = wall[sector[i].wallptr].y; continue; } } i = headspritestat[0]; while (i >= 0) { nexti = nextspritestat[i]; ResetActorGameVars(i); LoadActor(i); OnEvent(EVENT_LOADACTOR, i, -1, -1); if (sprite[i].lotag == -1 && (sprite[i].cstat&16)) { g_player[0].ps->exitx = SX; g_player[0].ps->exity = SY; } else switch (dynamictostatic[PN]) { case GPSPEED__STATIC: sector[SECT].extra = SLT; deletesprite(i); break; case CYCLER__STATIC: if (numcyclers >= MAXCYCLERS) { Bsprintf(tempbuf,"\nToo many cycling sectors (%d max).",MAXCYCLERS); gameexit(tempbuf); } cyclers[numcyclers][0] = SECT; cyclers[numcyclers][1] = SLT; cyclers[numcyclers][2] = SS; cyclers[numcyclers][3] = sector[SECT].floorshade; cyclers[numcyclers][4] = SHT; cyclers[numcyclers][5] = (SA == 1536); numcyclers++; deletesprite(i); break; case SECTOREFFECTOR__STATIC: case ACTIVATOR__STATIC: case TOUCHPLATE__STATIC: case ACTIVATORLOCKED__STATIC: case MUSICANDSFX__STATIC: case LOCATORS__STATIC: case MASTERSWITCH__STATIC: case RESPAWN__STATIC: sprite[i].cstat = 0; break; } i = nexti; } for (i=0;i < MAXSPRITES;i++) { if (sprite[i].statnum < MAXSTATUS) { if (PN == SECTOREFFECTOR && SLT == 14) continue; spawn(-1,i); } } for (i=0;i < MAXSPRITES;i++) if (sprite[i].statnum < MAXSTATUS) { if (PN == SECTOREFFECTOR && SLT == 14) spawn(-1,i); } lotaglist = 0; i = headspritestat[0]; while (i >= 0) { switch (dynamictostatic[PN-1]) { case DIPSWITCH__STATIC: case DIPSWITCH2__STATIC: case PULLSWITCH__STATIC: case HANDSWITCH__STATIC: case SLOTDOOR__STATIC: case LIGHTSWITCH__STATIC: case SPACELIGHTSWITCH__STATIC: case SPACEDOORSWITCH__STATIC: case FRANKENSTINESWITCH__STATIC: case LIGHTSWITCH2__STATIC: case POWERSWITCH1__STATIC: case LOCKSWITCH1__STATIC: case POWERSWITCH2__STATIC: for (j=0;j MAXSPRITES-1) gameexit("\nToo many switches."); j = headspritestat[3]; while (j >= 0) { if (sprite[j].lotag == 12 && sprite[j].hitag == SLT) hittype[j].temp_data[0] = 1; j = nextspritestat[j]; } } break; } i = nextspritestat[i]; } mirrorcnt = 0; for (i = 0; i < numwalls; i++) { walltype *wal; wal = &wall[i]; if (wal->overpicnum == MIRROR && (wal->cstat&32) != 0) { j = wal->nextsector; if (mirrorcnt > 63) gameexit("\nToo many mirrors (64 max.)"); if ((j >= 0) && sector[j].ceilingpicnum != MIRROR) { sector[j].ceilingpicnum = MIRROR; sector[j].floorpicnum = MIRROR; mirrorwall[mirrorcnt] = i; mirrorsector[mirrorcnt] = j; mirrorcnt++; continue; } } if (numanimwalls >= MAXANIMWALLS) { Bsprintf(tempbuf,"\nToo many 'anim' walls (%d max).",MAXANIMWALLS); gameexit(tempbuf); } animwall[numanimwalls].tag = 0; animwall[numanimwalls].wallnum = 0; switchpicnum = wal->overpicnum; if ((wal->overpicnum > W_FORCEFIELD)&&(wal->overpicnum <= W_FORCEFIELD+2)) { switchpicnum = W_FORCEFIELD; } switch (dynamictostatic[switchpicnum]) { case FANSHADOW__STATIC: case FANSPRITE__STATIC: wall->cstat |= 65; animwall[numanimwalls].wallnum = i; numanimwalls++; break; case W_FORCEFIELD__STATIC: if (wal->overpicnum==W_FORCEFIELD__STATIC) for (j=0;j<3;j++) tloadtile(W_FORCEFIELD+j, 0); if (wal->shade > 31) wal->cstat = 0; else wal->cstat |= 85+256; if (wal->lotag && wal->nextwall >= 0) wall[wal->nextwall].lotag = wal->lotag; case BIGFORCE__STATIC: animwall[numanimwalls].wallnum = i; numanimwalls++; continue; } wal->extra = -1; switch (dynamictostatic[wal->picnum]) { case WATERTILE2__STATIC: for (j=0;j<3;j++) tloadtile(wal->picnum+j, 0); break; case TECHLIGHT2__STATIC: case TECHLIGHT4__STATIC: tloadtile(wal->picnum, 0); break; case W_TECHWALL1__STATIC: case W_TECHWALL2__STATIC: case W_TECHWALL3__STATIC: case W_TECHWALL4__STATIC: animwall[numanimwalls].wallnum = i; // animwall[numanimwalls].tag = -1; numanimwalls++; break; case SCREENBREAK6__STATIC: case SCREENBREAK7__STATIC: case SCREENBREAK8__STATIC: for (j=SCREENBREAK6;jextra = wal->picnum; animwall[numanimwalls].tag = -1; if (ud.lockout) { if (wal->picnum == FEMPIC1) wal->picnum = BLANKSCREEN; else wal->picnum = SCREENBREAK6; } animwall[numanimwalls].wallnum = i; animwall[numanimwalls].tag = wal->picnum; numanimwalls++; break; case SCREENBREAK1__STATIC: case SCREENBREAK2__STATIC: case SCREENBREAK3__STATIC: case SCREENBREAK4__STATIC: case SCREENBREAK5__STATIC: case SCREENBREAK9__STATIC: case SCREENBREAK10__STATIC: case SCREENBREAK11__STATIC: case SCREENBREAK12__STATIC: case SCREENBREAK13__STATIC: case SCREENBREAK14__STATIC: case SCREENBREAK15__STATIC: case SCREENBREAK16__STATIC: case SCREENBREAK17__STATIC: case SCREENBREAK18__STATIC: case SCREENBREAK19__STATIC: animwall[numanimwalls].wallnum = i; animwall[numanimwalls].tag = wal->picnum; numanimwalls++; break; } } //Invalidate textures in sector behind mirror for (i=0;i= 0 && ud.config.FXDevice >= 0 && ud.config.SoundToggle) { while (issoundplaying(-1,globalskillsound)) { handleevents(); getpackets(); } } globalskillsound = -1; waitforeverybody(); ready2send = 0; if (ud.m_recstat != 2 && ud.last_level >= 0 && ud.multimode > 1 && (ud.coop&GAMETYPE_FLAG_SCORESHEET)) dobonus(1); if (ln == 0 && vn == 3 && ud.multimode < 2 && ud.lockout == 0) { playmusic(&env_music_fn[1][0],MAXVOLUMES*MAXLEVELS+1); flushperms(); setview(0,0,xdim-1,ydim-1); clearview(0L); nextpage(); playanm("vol41a.anm",6); clearview(0L); nextpage(); playanm("vol42a.anm",7); playanm("vol43a.anm",9); clearview(0L); nextpage(); FX_StopAllSounds(); } show_shareware = 26*34; ud.level_number = ln; ud.volume_number = vn; ud.player_skill = sk; ud.secretlevel = 0; ud.from_bonus = 0; parallaxyscale = 0; ud.last_level = -1; lastsavedpos = -1; p->zoom = 768; p->gm = 0; //AddLog("Newgame"); ResetGameVars(); InitGameVarPointers(); ResetSystemDefaults(); for (i=0;i<(MAXVOLUMES*MAXLEVELS);i++) if (map[i].savedstate) { Bfree(map[i].savedstate); map[i].savedstate = NULL; } if (ud.m_coop != 1) { for (i=0;icurr_weapon = i; p->gotweapon[i] = 1; p->ammo_amount[i] = 48; } else if (aplWeaponWorksLike[i][0]==KNEE_WEAPON) p->gotweapon[i] = 1; else if (aplWeaponWorksLike[i][0]==HANDREMOTE_WEAPON) p->gotweapon[i] = 1; } p->last_weapon = -1; } display_mirror = 0; if (ud.multimode > 1) { if (numplayers < 2) { connecthead = 0; for (i=0;ii, screenpeek, -1); } int getteampal(int team) { switch (team) { case 0: return 3; case 1: return 10; case 2: return 11; case 3: return 12; } return 0; } static void resetpspritevars(char g) { short i, j, nexti,circ; // int firstx,firsty; spritetype *s; char aimmode[MAXPLAYERS],autoaim[MAXPLAYERS],weaponswitch[MAXPLAYERS]; STATUSBARTYPE tsbar[MAXPLAYERS]; EGS(g_player[0].ps->cursectnum,g_player[0].ps->posx,g_player[0].ps->posy,g_player[0].ps->posz, APLAYER,0,0,0,g_player[0].ps->ang,0,0,0,10); if (ud.recstat != 2) for (i=0;iaim_mode; autoaim[i] = g_player[i].ps->auto_aim; weaponswitch[i] = g_player[i].ps->weaponswitch; if (ud.multimode > 1 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_PRESERVEINVENTORYDEATH) && ud.last_level >= 0) { for (j=0;jammo_amount[j]; tsbar[i].gotweapon[j] = g_player[i].ps->gotweapon[j]; } tsbar[i].shield_amount = g_player[i].ps->shield_amount; tsbar[i].curr_weapon = g_player[i].ps->curr_weapon; tsbar[i].inven_icon = g_player[i].ps->inven_icon; tsbar[i].firstaid_amount = g_player[i].ps->firstaid_amount; tsbar[i].steroids_amount = g_player[i].ps->steroids_amount; tsbar[i].holoduke_amount = g_player[i].ps->holoduke_amount; tsbar[i].jetpack_amount = g_player[i].ps->jetpack_amount; tsbar[i].heat_amount = g_player[i].ps->heat_amount; tsbar[i].scuba_amount = g_player[i].ps->scuba_amount; tsbar[i].boot_amount = g_player[i].ps->boot_amount; } } resetplayerstats(0); for (i=1;iaim_mode = aimmode[i]; g_player[i].ps->auto_aim = autoaim[i]; g_player[i].ps->weaponswitch = weaponswitch[i]; if (ud.multimode > 1 && (gametype_flags[ud.coop]&GAMETYPE_FLAG_PRESERVEINVENTORYDEATH) && ud.last_level >= 0) { for (j=0;jammo_amount[j] = tsbar[i].ammo_amount[j]; g_player[i].ps->gotweapon[j] = tsbar[i].gotweapon[j]; } g_player[i].ps->shield_amount = tsbar[i].shield_amount; g_player[i].ps->curr_weapon = tsbar[i].curr_weapon; g_player[i].ps->inven_icon = tsbar[i].inven_icon; g_player[i].ps->firstaid_amount = tsbar[i].firstaid_amount; g_player[i].ps->steroids_amount= tsbar[i].steroids_amount; g_player[i].ps->holoduke_amount = tsbar[i].holoduke_amount; g_player[i].ps->jetpack_amount = tsbar[i].jetpack_amount; g_player[i].ps->heat_amount = tsbar[i].heat_amount; g_player[i].ps->scuba_amount= tsbar[i].scuba_amount; g_player[i].ps->boot_amount = tsbar[i].boot_amount; } } numplayersprites = 0; circ = 2048/ud.multimode; which_palookup = 9; j = connecthead; i = headspritestat[10]; while (i >= 0) { nexti = nextspritestat[i]; s = &sprite[i]; if (numplayersprites == MAXPLAYERS) gameexit("\nToo many player sprites (max 16.)"); /* if (numplayersprites == 0) { firstx = g_player[0].ps->posx; firsty = g_player[0].ps->posy; }*/ g_PlayerSpawnPoints[(unsigned char)numplayersprites].ox = s->x; g_PlayerSpawnPoints[(unsigned char)numplayersprites].oy = s->y; g_PlayerSpawnPoints[(unsigned char)numplayersprites].oz = s->z; g_PlayerSpawnPoints[(unsigned char)numplayersprites].oa = s->ang; g_PlayerSpawnPoints[(unsigned char)numplayersprites].os = s->sectnum; numplayersprites++; if (j >= 0) { s->owner = i; s->shade = 0; s->xrepeat = 42; s->yrepeat = 36; s->cstat = 1+256; s->xoffset = 0; s->clipdist = 64; if ((g&MODE_EOL) != MODE_EOL || g_player[j].ps->last_extra == 0) { g_player[j].ps->last_extra = g_player[j].ps->max_player_health; s->extra = g_player[j].ps->max_player_health; g_player[j].ps->runspeed = dukefriction; } else s->extra = g_player[j].ps->last_extra; s->yvel = j; if (!g_player[j].pcolor && ud.multimode > 1 && !(gametype_flags[ud.coop] & GAMETYPE_FLAG_TDM)) { if (s->pal == 0) { int k = 0; for (;kpalookup) { which_palookup++; if (which_palookup >= 17) which_palookup = 9; k=0; } } g_player[j].pcolor = s->pal = g_player[j].ps->palookup = which_palookup++; if (which_palookup >= 17) which_palookup = 9; } else g_player[j].pcolor = g_player[j].ps->palookup = s->pal; } else { int k = g_player[j].pcolor; if (gametype_flags[ud.coop] & GAMETYPE_FLAG_TDM) { k = getteampal(g_player[j].pteam); g_player[j].ps->team = g_player[j].pteam; } s->pal = g_player[j].ps->palookup = k; } g_player[j].ps->i = i; g_player[j].ps->frag_ps = j; hittype[i].owner = i; hittype[i].bposx = g_player[j].ps->bobposx = g_player[j].ps->oposx = g_player[j].ps->posx = s->x; hittype[i].bposy = g_player[j].ps->bobposy = g_player[j].ps->oposy = g_player[j].ps->posy = s->y; hittype[i].bposz = g_player[j].ps->oposz = g_player[j].ps->posz = s->z; g_player[j].ps->oang = g_player[j].ps->ang = s->ang; updatesector(s->x,s->y,&g_player[j].ps->cursectnum); j = connectpoint2[j]; } else deletesprite(i); i = nexti; } } static inline void clearfrags(void) { int i = 0; while (ifrag = g_player[i].ps->fraggedself = 0, i++; clearbufbyte(&g_player[i].frags[0],MAXPLAYERS<<1,0L); } } void resettimevars(void) { vel = svel = angvel = horiz = 0; totalclock = 0L; cloudtotalclock = 0L; ototalclock = 0L; lockclock = 0L; ready2send = 1; leveltexttime = 85; MoveThingsCount = 0; } void waitforeverybody() { int i; if (numplayers < 2) return; packbuf[0] = 250; g_player[myconnectindex].playerreadyflag++; if ((networkmode == 1) || (!networkmode && (myconnectindex != connecthead))) for (i=connecthead;i>=0;i=connectpoint2[i]) { if (i != myconnectindex) sendpacket(i,packbuf,1); if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master } if (ud.multimode > 1) { setgamepalette(g_player[myconnectindex].ps, titlepal, 11); rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1); rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1); rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1); if (PLUTOPAK) // JBF 20030804 rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1); gametext(160,190,"WAITING FOR PLAYERS",14,2); nextpage(); } while (1) { idle(); /* sampletimer(); handleevents(); AudioUpdate(); */ if (quitevent || keystatus[1]) gameexit(""); getpackets(); for (i=connecthead;i>=0;i=connectpoint2[i]) { if (g_player[i].playerreadyflag < g_player[myconnectindex].playerreadyflag) break; if ((!networkmode) && (myconnectindex != connecthead)) { i = -1; break; } //slaves in M/S mode only wait for master } if (i < 0) { if (!networkmode && myconnectindex == connecthead) for (i=connecthead;i>=0;i=connectpoint2[i]) { packbuf[0] = 250; if (i != myconnectindex) sendpacket(i,packbuf,1); } setgamepalette(g_player[myconnectindex].ps, palette, 11); return; } } } extern int jump_input; void clearfifo(void) { int i = 0; syncvaltail = 0L; syncvaltottail = 0L; memset(&syncstat, 0, sizeof(syncstat)); bufferjitter = 1; mymaxlag = otherminlag = 0; jump_input = 0; movefifoplc = movefifosendplc = fakemovefifoplc = 0; avgfvel = avgsvel = avgavel = avghorz = avgbits = avgextbits = 0; otherminlag = mymaxlag = 0; clearbufbyte(&loc,sizeof(input_t),0L); clearbufbyte(&inputfifo,sizeof(input_t)*MOVEFIFOSIZ*MAXPLAYERS,0L); for (;iposx; myy = omyy = g_player[myconnectindex].ps->posy; myz = omyz = g_player[myconnectindex].ps->posz; myxvel = myyvel = myzvel = 0; myang = omyang = g_player[myconnectindex].ps->ang; myhoriz = omyhoriz = g_player[myconnectindex].ps->horiz; myhorizoff = omyhorizoff = g_player[myconnectindex].ps->horizoff; mycursectnum = g_player[myconnectindex].ps->cursectnum; myjumpingcounter = g_player[myconnectindex].ps->jumping_counter; myjumpingtoggle = g_player[myconnectindex].ps->jumping_toggle; myonground = g_player[myconnectindex].ps->on_ground; myhardlanding = g_player[myconnectindex].ps->hard_landing; myreturntocenter = g_player[myconnectindex].ps->return_to_center; } extern int voting, vote_map, vote_episode; void getlevelfromfilename(const char *fn, char *volume, char *level) { for (*volume=0;*volumeposx, &g_player[0].ps->posy, &g_player[0].ps->posz, &g_player[0].ps->ang,&g_player[0].ps->cursectnum) == -1) { OSD_Printf(OSD_ERROR "Map '%s' not found!\n",boardfilename); //gameexit(tempbuf); return 1; } { char *p; strcpy(levname, boardfilename); p = Bstrrchr(levname,'.'); if (!p) strcat(levname,".mhk"); else { p[1]='m'; p[2]='h'; p[3]='k'; p[4]=0; } if (!loadmaphack(levname)) initprintf("Loaded map hack file '%s'\n",levname); // usermap music based on map filename Bcorrectfilename(levname,0); p = Bstrrchr(levname,'.'); if (p) { int fil; p[1]='o'; p[2]='g'; p[3]='g'; p[4]=0; fil = kopen4loadfrommod(levname,0); if (fil > -1) { kclose(fil); if (map[ud.m_level_number].musicfn1 == NULL) map[ud.m_level_number].musicfn1 = Bcalloc(Bstrlen(levname)+1,sizeof(char)); else if ((Bstrlen(levname)+1) > sizeof(map[ud.m_level_number].musicfn1)) map[ud.m_level_number].musicfn1 = Brealloc(map[ud.m_level_number].musicfn1,(Bstrlen(levname)+1)); Bstrcpy(map[ud.m_level_number].musicfn1,levname); } else if (map[ud.m_level_number].musicfn1 != NULL) { Bfree(map[ud.m_level_number].musicfn1); map[ud.m_level_number].musicfn1 = NULL; } p[1]='m'; p[2]='i'; p[3]='d'; p[4]=0; fil = kopen4loadfrommod(levname,0); if (fil == -1) Bsprintf(levname,"dethtoll.mid"); else kclose(fil); if (map[ud.m_level_number].musicfn == NULL) map[ud.m_level_number].musicfn = Bcalloc(Bstrlen(levname)+1,sizeof(char)); else if ((Bstrlen(levname)+1) > sizeof(map[ud.m_level_number].musicfn)) map[ud.m_level_number].musicfn = Brealloc(map[ud.m_level_number].musicfn,(Bstrlen(levname)+1)); Bstrcpy(map[ud.m_level_number].musicfn,levname); } } } else if (loadboard(map[(ud.volume_number*MAXLEVELS)+ud.level_number].filename,0,&g_player[0].ps->posx, &g_player[0].ps->posy, &g_player[0].ps->posz, &g_player[0].ps->ang,&g_player[0].ps->cursectnum) == -1) { OSD_Printf(OSD_ERROR "Map %s not found!\n",map[(ud.volume_number*MAXLEVELS)+ud.level_number].filename); //gameexit(tempbuf); return 1; } else { char *p; strcpy(levname, map[(ud.volume_number*MAXLEVELS)+ud.level_number].filename); p = Bstrrchr(levname,'.'); if (!p) strcat(levname,".mhk"); else { p[1]='m'; p[2]='h'; p[3]='k'; p[4]=0; } if (!loadmaphack(levname)) initprintf("Loaded map hack file '%s'\n",levname); } } else { i = strlen(map[(ud.volume_number*MAXLEVELS)+ud.level_number].filename); copybufbyte(map[(ud.volume_number*MAXLEVELS)+ud.level_number].filename,&levname[0],i); levname[i] = 255; levname[i+1] = 0; if (loadboard(levname,1,&g_player[0].ps->posx, &g_player[0].ps->posy, &g_player[0].ps->posz, &g_player[0].ps->ang,&g_player[0].ps->cursectnum) == -1) { OSD_Printf(OSD_ERROR "Map '%s' not found!\n",map[(ud.volume_number*MAXLEVELS)+ud.level_number].filename); //gameexit(tempbuf); return 1; } else { char *p; p = Bstrrchr(levname,'.'); if (!p) strcat(levname,".mhk"); else { p[1]='m'; p[2]='h'; p[3]='k'; p[4]=0; } if (!loadmaphack(levname)) initprintf("Loaded map hack file '%s'\n",levname); } } precachecount = 0; clearbufbyte(gotpic,sizeof(gotpic),0L); clearbufbyte(precachehightile, sizeof(precachehightile), 0l); //clearbufbyte(hittype,sizeof(hittype),0l); // JBF 20040531: yes? no? prelevel(g); allignwarpelevators(); resetpspritevars(g); cachedebug = 0; automapping = 0; cacheit(); if (ud.recstat != 2) { music_select = (ud.volume_number*MAXLEVELS) + ud.level_number; if (map[(unsigned char)music_select].musicfn != NULL) playmusic(&map[(unsigned char)music_select].musicfn[0],music_select); } if ((g&MODE_GAME) || (g&MODE_EOL)) g_player[myconnectindex].ps->gm = MODE_GAME; else if (g&MODE_RESTART) { if (ud.recstat == 2) g_player[myconnectindex].ps->gm = MODE_DEMO; else g_player[myconnectindex].ps->gm = MODE_GAME; } if ((ud.recstat == 1) && (g&MODE_RESTART) != MODE_RESTART) opendemowrite(); if (VOLUMEONE) { if (ud.level_number == 0 && ud.recstat != 2) FTA(40,g_player[myconnectindex].ps); } for (i=connecthead;i>=0;i=connectpoint2[i]) switch (dynamictostatic[sector[sprite[g_player[i].ps->i].sectnum].floorpicnum]) { case HURTRAIL__STATIC: case FLOORSLIME__STATIC: case FLOORPLASMA__STATIC: resetweapons(i); resetinventory(i); g_player[i].ps->gotweapon[PISTOL_WEAPON] = 0; g_player[i].ps->ammo_amount[PISTOL_WEAPON] = 0; g_player[i].ps->curr_weapon = KNEE_WEAPON; g_player[i].ps->kickback_pic = 0; break; } //PREMAP.C - replace near the my's at the end of the file resetmys(); //g_player[myconnectindex].ps->palette = palette; //palto(0,0,0,0); setgamepalette(g_player[myconnectindex].ps, palette, 0); // JBF 20040308 setpal(g_player[myconnectindex].ps); flushperms(); everyothertime = 0; global_random = 0; ud.last_level = ud.level_number+1; clearfifo(); for (i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i]; restorepalette = 1; flushpackets(); waitforeverybody(); palto(0,0,0,0); vscrn(); clearview(0L); drawbackground(); displayrooms(myconnectindex,65536); for (i=0;iover_shoulder_on = 0; clearfrags(); resettimevars(); // Here we go //Bsprintf(g_szBuf,"ENTERLEVEL L=%d V=%d",ud.level_number, ud.volume_number); //AddLog(g_szBuf); // variables are set by pointer... Bmemcpy(¤tboardfilename[0],&boardfilename[0],BMAX_PATH); OnEvent(EVENT_ENTERLEVEL, -1, -1, -1); OSD_Printf(OSDTEXT_YELLOW "E%dL%d: %s\n",ud.volume_number+1,ud.level_number+1,map[(ud.volume_number*MAXLEVELS)+ud.level_number].name); return 0; } void FreeMapState(int mapnum) { int j; for (j=0;jvars[j]) Bfree(map[mapnum].savedstate->vars[j]); } else if (aGameVars[j].dwFlags & GAMEVAR_FLAG_PERACTOR) { if (map[mapnum].savedstate->vars[j]) Bfree(map[mapnum].savedstate->vars[j]); } } Bfree(map[mapnum].savedstate); map[mapnum].savedstate = NULL; }