DieHard Wolfers Forum Index DieHard Wolfers
A Wolfenstein 3d Fan Community


  Hosted by: MCS & Areyep.com - Designed by: BrotherTank

Original Yahoo Forum - Die Hard Archives

AReyeP HomepageAreyep Homepage DieHard Wolfenstein BunkerDieHard Wolfenstein Bunker Log inLog in RegisterRegister Banlist FAQFAQ Search ForumsSearch

  Username:    Password:      Remember me       

[Tutorial] Map Controls
Page 1 of 1
DieHard Wolfers Forum Index -> SDL Code Crackers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page BottomView Next Topic
Post new topicReply to topic
Author Message
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Fri Dec 25, 2009 9:03 pm
   Subject: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Next PostGoto Bottom of Posts

PART 1: Map Controlled Music

Here's my tutorial that allows you to set the level music, by simply defining what tile you'd be placing in a map. The tile that has been set in this tutorial is 1,0...

So here goes:

Firstly open VERSION.H and any where inside add #define MAPCONTROLLEDMUSIC

Now open WL_PLAY.CPP and make the following changes in red:
::: CODE :::
exit_t playstate;

#ifndef MAPCONTROLLEDMUSIC
static musicnames lastmusicchunk = (musicnames) 0;
#else
static musicnames lastmusicchunk;
#endif


static int DebugOk;


Replace the StopMusic method with:
::: CODE :::
int StopMusic (void)
{
    #ifdef MAPCONTROLLEDMUSIC
    int lastoffs = SD_MusicOff ();
    //static musicnames lastmusicchunk;
    int holder;
   
    holder = tilemap[1][0];
    if (holder < 0 || holder >LASTMUSIC)
        holder=0;

    UNCACHEAUDIOCHUNK (STARTMUSIC + holder);

    return lastoffs;
    #else
    int lastoffs = SD_MusicOff ();

    UNCACHEAUDIOCHUNK (STARTMUSIC + lastmusicchunk);

    return lastoffs;
    #endif
}


Replace the startMusic function with:
::: CODE :::
void StartMusic ()
{
    #ifdef MAPCONTROLLEDMUSIC
    int holder;
    //static musicnames lastmusicchunk;
    #endif
    SD_MusicOff ();
    #ifdef MAPCONTROLLEDMUSIC
    holder = tilemap[1][0];
    if (holder < 0 || holder >LASTMUSIC)
        holder=0;
    lastmusicchunk = (musicnames) songs[holder];
    #else
    lastmusicchunk = (musicnames) songs[gamestate.mapon + gamestate.episode * 10];
    #endif
    SD_StartMusic(STARTMUSIC + lastmusicchunk);
}


And finally replace the ContinueMusic function with:
::: CODE :::
void ContinueMusic (int offs)
{
    #ifdef MAPCONTROLLEDMUSIC
    int holder;
    //static musicnames lastmusicchunk;
    #endif
    SD_MusicOff ();
    #ifdef MAPCONTROLLEDMUSIC
    holder = tilemap[1][0];
    if (holder < 0 || holder >LASTMUSIC)
        holder=0;
    lastmusicchunk = (musicnames) songs[holder];
    #else
    lastmusicchunk = (musicnames) songs[gamestate.mapon + gamestate.episode * 10];
    #endif
    SD_ContinueMusic(STARTMUSIC + lastmusicchunk, offs);
}


Now compile, and remember that the tile that allows you to set the music on a level is 1,0...

There should be tutorials coming out on other options that can be controlled by editing the maps...

_________________
Haasboy Engine - Currently under construction (To be used with future mods - F.A.D.E.D. - Mansion X - Rising Evil Series)


Last edited by Haasboy on Fri Dec 25, 2009 9:26 pm; edited 1 time in total
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Fri Dec 25, 2009 9:23 pm
   Subject: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

PART 2: BrotherTank's Par time Map control

Credit for this goes to BT, as it is from his Bunker SDL source...

In VERSION.H add #define MAPCONTROLPARTIME

Next open WL_DEF.H and add the following in gamestate section:
::: CODE :::
    boolean     victoryflag;            // set during victory animations

#ifdef MAPCONTROLPARTIME
    float       partime;
#endif


Open WL_GAME.CPP and add the red in the GameLoop function:
::: CODE :::
            gamestate.keys |= 1;
            DrawKeys ();
        }
#endif
#ifdef MAPCONTROLPARTIME
      gamestate.partime = 2.0;
      if (tilemap[61][0]>=1 && tilemap[61][0] <=20)
      {
         gamestate.partime = tilemap[62][0];
         if (tilemap[62][0]>=1 && tilemap[62][0] <=3)
         {
            switch(tilemap[62][0])
            {
               case 1: gamestate.partime += .25; break;
               case 2: gamestate.partime += .5; break;
               case 3: gamestate.partime += .75; break;
            }
         }
      }
      gamestate.partime = (gamestate.partime * 4200)/70;
#endif


        ingame = true;


In WL_INTER.CPP change the LevelCompleted function to:
::: CODE :::
void
LevelCompleted (void)
{
#ifdef MAPCONTROLPARTIME
   float times_time;
   int t;
#else
   typedef struct {
         float time;
         char timestr[6];
         } times;
#endif

    int x, i, min, sec, ratio, kr, sr, tr;
    char tempstr[10];
    int32_t bonus, timeleft = 0;

#ifdef MAPCONTROLPARTIME

   char   times_timestr[6] = "02:00 ";
   times_time = 2.0;
   t = 2;   
   if(tilemap[61][0] >= 1 && tilemap[61][0]<=20)
   {
      t = tilemap[61][0];
      times_time = t;
      times_timestr[0] = '0' + t/10;
      times_timestr[1] = '0' + t%10;
   }
   switch (tilemap[62][0]>=1 && tilemap[62][0] <=3)
   {
      case 1: // 15
         times_time += .25;
         times_timestr[3] = '1';
         times_timestr[4] = '5';
         break;
      case 2: // 30
         times_time += .5;
         times_timestr[3] = '3';
         break;
      case 3: // 45
         times_time += .75;
         times_timestr[3] = '4';
         times_timestr[4] = '5';
         break;
   }   
#else   

    times parTimes[] = {
#ifndef SPEAR
        //
        // Episode One Par Times
        //
        {1.5, "01:30"},
        {2, "02:00"},
        {2, "02:00"},
        {3.5, "03:30"},
        {3, "03:00"},
        {3, "03:00"},
        {2.5, "02:30"},
        {2.5, "02:30"},
        {0, "??:??"},           // Boss level
        {0, "??:??"},           // Secret level

        //
        // Episode Two Par Times
        //
        {1.5, "01:30"},
        {3.5, "03:30"},
        {3, "03:00"},
        {2, "02:00"},
        {4, "04:00"},
        {6, "06:00"},
        {1, "01:00"},
        {3, "03:00"},
        {0, "??:??"},
        {0, "??:??"},

        //
        // Episode Three Par Times
        //
        {1.5, "01:30"},
        {1.5, "01:30"},
        {2.5, "02:30"},
        {2.5, "02:30"},
        {3.5, "03:30"},
        {2.5, "02:30"},
        {2, "02:00"},
        {6, "06:00"},
        {0, "??:??"},
        {0, "??:??"},

        //
        // Episode Four Par Times
        //
        {2, "02:00"},
        {2, "02:00"},
        {1.5, "01:30"},
        {1, "01:00"},
        {4.5, "04:30"},
        {3.5, "03:30"},
        {2, "02:00"},
        {4.5, "04:30"},
        {0, "??:??"},
        {0, "??:??"},

        //
        // Episode Five Par Times
        //
        {2.5, "02:30"},
        {1.5, "01:30"},
        {2.5, "02:30"},
        {2.5, "02:30"},
        {4, "04:00"},
        {3, "03:00"},
        {4.5, "04:30"},
        {3.5, "03:30"},
        {0, "??:??"},
        {0, "??:??"},

        //
        // Episode Six Par Times
        //
        {6.5, "06:30"},
        {4, "04:00"},
        {4.5, "04:30"},
        {6, "06:00"},
        {5, "05:00"},
        {5.5, "05:30"},
        {5.5, "05:30"},
        {8.5, "08:30"},
        {0, "??:??"},
        {0, "??:??"}
#else
        //
        // SPEAR OF DESTINY TIMES
        //
        {1.5, "01:30"},
        {3.5, "03:30"},
        {2.75, "02:45"},
        {3.5, "03:30"},
        {0, "??:??"},           // Boss 1
        {4.5, "04:30"},
        {3.25, "03:15"},
        {2.75, "02:45"},
        {4.75, "04:45"},
        {0, "??:??"},           // Boss 2
        {6.5, "06:30"},
        {4.5, "04:30"},
        {2.75, "02:45"},
        {4.5, "04:30"},
        {6, "06:00"},
        {0, "??:??"},           // Boss 3
        {6, "06:00"},
        {0, "??:??"},           // Boss 4
        {0, "??:??"},           // Secret level 1
        {0, "??:??"},           // Secret level 2
#endif
    };
#endif

    CacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
    ClearSplitVWB ();           // set up for double buffering in split screen
    VWB_Bar (0, 0, 320, screenHeight / scaleFactor - STATUSLINES + 1, VIEWCOLOR);

    if (bordercol != VIEWCOLOR)
        DrawStatusBorder (VIEWCOLOR);

    StartCPMusic (ENDLEVEL_MUS);

//
// do the intermission
//
    IN_ClearKeysDown ();
    IN_StartAck ();

#ifdef JAPAN
    CA_CacheGrChunk (C_INTERMISSIONPIC);
    VWB_DrawPic (0, 0, C_INTERMISSIONPIC);
    UNCACHEGRCHUNK (C_INTERMISSIONPIC);
#endif
    VWB_DrawPic (0, 16, L_GUYPIC);

#ifndef SPEAR
    if (mapon < 8)
#else
    if (mapon != 4 && mapon != 9 && mapon != 15 && mapon < 17)
#endif
    {
#ifndef JAPAN
#ifdef SPANISH
        Write (14, 2, "piso\ncompletado");
#else
        Write (14, 2, "floor\ncompleted");
#endif

        Write (14, 7, STR_BONUS "     0");
        Write (16, 10, STR_TIME);
        Write (16, 12, STR_PAR);

#ifdef SPANISH
        Write (11, 14, STR_RAT2KILL);
        Write (11, 16, STR_RAT2SECRET);
        Write (11, 18, STR_RAT2TREASURE);
#else
        Write (9, 14, STR_RAT2KILL);
        Write (5, 16, STR_RAT2SECRET);
        Write (1, 18, STR_RAT2TREASURE);
#endif

        Write (26, 2, itoa (gamestate.mapon + 1, tempstr, 10));
#endif

#ifdef MAPCONTROLPARTIME
    #ifndef SPANISH
    Write (26, 12, times_timestr);
    #else
    Write (30, 12, times_timestr);
    #endif
#else
    #ifdef SPANISH
    Write(30,12,parTimes[gamestate.episode*10+mapon].timestr);
    #else
    Write(26,12,parTimes[gamestate.episode*10+mapon].timestr);
    #endif
#endif



        //
        // PRINT TIME
        //
        sec = gamestate.TimeCount / 70;

        if (sec > 99 * 60)      // 99 minutes max
            sec = 99 * 60;

#ifdef MAPCONTROLPARTIME
        if (gamestate.TimeCount<times_time*4200)
          timeleft=(fixed)(times_time*4200)/70-sec;
#else   
        if (gamestate.TimeCount<parTimes[gamestate.episode*10+mapon].time*4200)
          timeleft=(fixed)(parTimes[gamestate.episode*10+mapon].time*4200)/70-sec;
#endif
        min = sec / 60;
        sec %= 60;

#ifdef SPANISH
        i = 30 * 8;
#else
        i = 26 * 8;
#endif
        VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (min / 10));
        i += 2 * 8;
        VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (min % 10));
        i += 2 * 8;
        Write (i / 8, 10, ":");
        i += 1 * 8;
        VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (sec / 10));
        i += 2 * 8;
        VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (sec % 10));

        VW_UpdateScreen ();
        VW_FadeIn ();


        //
        // FIGURE RATIOS OUT BEFOREHAND
        //
        kr = sr = tr = 0;
        if (gamestate.killtotal)
            kr = (gamestate.killcount * 100) / gamestate.killtotal;
        if (gamestate.secrettotal)
            sr = (gamestate.secretcount * 100) / gamestate.secrettotal;
        if (gamestate.treasuretotal)
            tr = (gamestate.treasurecount * 100) / gamestate.treasuretotal;


        //
        // PRINT TIME BONUS
        //
        bonus = timeleft * PAR_AMOUNT;
        if (bonus)
        {
            for (i = 0; i <= timeleft; i++)
            {
                ltoa ((int32_t) i * PAR_AMOUNT, tempstr, 10);
                x = 36 - (int) strlen(tempstr) * 2;
                Write (x, 7, tempstr);
                if (!(i % (PAR_AMOUNT / 10)))
                    SD_PlaySound (ENDBONUS1SND);
                VW_UpdateScreen ();
                while (SD_SoundPlaying ())
                    BJ_Breathe ();
                if (IN_CheckAck ())
                    goto done;
            }

            VW_UpdateScreen ();

            SD_PlaySound (ENDBONUS2SND);
            while (SD_SoundPlaying ())
                BJ_Breathe ();
        }


#ifdef SPANISH
#define RATIOXX                33
#else
#define RATIOXX                37
#endif
        //
        // KILL RATIO
        //
        ratio = kr;
        for (i = 0; i <= ratio; i++)
        {
            itoa (i, tempstr, 10);
            x = RATIOXX - (int) strlen(tempstr) * 2;
            Write (x, 14, tempstr);
            if (!(i % 10))
                SD_PlaySound (ENDBONUS1SND);
            VW_UpdateScreen ();
            while (SD_SoundPlaying ())
                BJ_Breathe ();

            if (IN_CheckAck ())
                goto done;
        }
        if (ratio >= 100)
        {
            VW_WaitVBL (VBLWAIT);
            SD_StopSound ();
            bonus += PERCENT100AMT;
            ltoa (bonus, tempstr, 10);
            x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
            Write (x, 7, tempstr);
            VW_UpdateScreen ();
            SD_PlaySound (PERCENT100SND);
        }
        else if (!ratio)
        {
            VW_WaitVBL (VBLWAIT);
            SD_StopSound ();
            SD_PlaySound (NOBONUSSND);
        }
        else
            SD_PlaySound (ENDBONUS2SND);

        VW_UpdateScreen ();
        while (SD_SoundPlaying ())
            BJ_Breathe ();

        //
        // SECRET RATIO
        //
        ratio = sr;
        for (i = 0; i <= ratio; i++)
        {
            itoa (i, tempstr, 10);
            x = RATIOXX - (int) strlen(tempstr) * 2;
            Write (x, 16, tempstr);
            if (!(i % 10))
                SD_PlaySound (ENDBONUS1SND);
            VW_UpdateScreen ();
            while (SD_SoundPlaying ())
                BJ_Breathe ();
            BJ_Breathe ();

            if (IN_CheckAck ())
                goto done;
        }
        if (ratio >= 100)
        {
            VW_WaitVBL (VBLWAIT);
            SD_StopSound ();
            bonus += PERCENT100AMT;
            ltoa (bonus, tempstr, 10);
            x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
            Write (x, 7, tempstr);
            VW_UpdateScreen ();
            SD_PlaySound (PERCENT100SND);
        }
        else if (!ratio)
        {
            VW_WaitVBL (VBLWAIT);
            SD_StopSound ();
            SD_PlaySound (NOBONUSSND);
        }
        else
            SD_PlaySound (ENDBONUS2SND);
        VW_UpdateScreen ();
        while (SD_SoundPlaying ())
            BJ_Breathe ();

        //
        // TREASURE RATIO
        //
        ratio = tr;
        for (i = 0; i <= ratio; i++)
        {
            itoa (i, tempstr, 10);
            x = RATIOXX - (int) strlen(tempstr) * 2;
            Write (x, 18, tempstr);
            if (!(i % 10))
                SD_PlaySound (ENDBONUS1SND);
            VW_UpdateScreen ();
            while (SD_SoundPlaying ())
                BJ_Breathe ();
            if (IN_CheckAck ())
                goto done;
        }
        if (ratio >= 100)
        {
            VW_WaitVBL (VBLWAIT);
            SD_StopSound ();
            bonus += PERCENT100AMT;
            ltoa (bonus, tempstr, 10);
            x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
            Write (x, 7, tempstr);
            VW_UpdateScreen ();
            SD_PlaySound (PERCENT100SND);
        }
        else if (!ratio)
        {
            VW_WaitVBL (VBLWAIT);
            SD_StopSound ();
            SD_PlaySound (NOBONUSSND);
        }
        else
            SD_PlaySound (ENDBONUS2SND);
        VW_UpdateScreen ();
        while (SD_SoundPlaying ())
            BJ_Breathe ();


        //
        // JUMP STRAIGHT HERE IF KEY PRESSED
        //
done:   itoa (kr, tempstr, 10);
        x = RATIOXX - (int) strlen(tempstr) * 2;
        Write (x, 14, tempstr);

        itoa (sr, tempstr, 10);
        x = RATIOXX - (int) strlen(tempstr) * 2;
        Write (x, 16, tempstr);

        itoa (tr, tempstr, 10);
        x = RATIOXX - (int) strlen(tempstr) * 2;
        Write (x, 18, tempstr);

        bonus = (int32_t) timeleft *PAR_AMOUNT +
            (PERCENT100AMT * (kr >= 100)) +
            (PERCENT100AMT * (sr >= 100)) + (PERCENT100AMT * (tr >= 100));

        GivePoints (bonus);
        ltoa (bonus, tempstr, 10);
        x = 36 - (int) strlen(tempstr) * 2;
        Write (x, 7, tempstr);

        //
        // SAVE RATIO INFORMATION FOR ENDGAME
        //
        LevelRatios[mapon].kill = kr;
        LevelRatios[mapon].secret = sr;
        LevelRatios[mapon].treasure = tr;
        LevelRatios[mapon].time = min * 60 + sec;
    }
    else
    {
#ifdef SPEAR
#ifndef SPEARDEMO
        switch (mapon)
        {
            case 4:
                Write (14, 4, " trans\n" " grosse\n" STR_DEFEATED);
                break;
            case 9:
                Write (14, 4, "barnacle\n" "wilhelm\n" STR_DEFEATED);
                break;
            case 15:
                Write (14, 4, "ubermutant\n" STR_DEFEATED);
                break;
            case 17:
                Write (14, 4, " death\n" " knight\n" STR_DEFEATED);
                break;
            case 18:
                Write (13, 4, "secret tunnel\n" "    area\n" "  completed!");
                break;
            case 19:
                Write (13, 4, "secret castle\n" "    area\n" "  completed!");
                break;
        }
#endif
#else
        Write (14, 4, "secret floor\n completed!");
#endif

        Write (10, 16, "15000 bonus!");

        VW_UpdateScreen ();
        VW_FadeIn ();

        GivePoints (15000);
    }


    DrawScore ();
    VW_UpdateScreen ();

    lastBreathTime = GetTimeCount();
    IN_StartAck ();
    while (!IN_CheckAck ())
        BJ_Breathe ();

//
// done
//
#ifdef SPEARDEMO
    if (gamestate.mapon == 1)
    {
        SD_PlaySound (BONUS1UPSND);

        CA_CacheGrChunk (STARTFONT + 1);
        Message ("This concludes your demo\n"
                 "of Spear of Destiny! Now,\n" "go to your local software\n" "store and buy it!");
        UNCACHEGRCHUNK (STARTFONT + 1);

        IN_ClearKeysDown ();
        IN_Ack ();
    }
#endif

#ifdef JAPDEMO
    if (gamestate.mapon == 3)
    {
        SD_PlaySound (BONUS1UPSND);

        CA_CacheGrChunk (STARTFONT + 1);
        Message ("This concludes your demo\n"
                 "of Wolfenstein 3-D! Now,\n" "go to your local software\n" "store and buy it!");
        UNCACHEGRCHUNK (STARTFONT + 1);

        IN_ClearKeysDown ();
        IN_Ack ();
    }
#endif

    VW_FadeOut ();
    DrawPlayBorder();

    UnCacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
}


That's it...

The tilemaps used in this tutorial are:
61,0 for the minutes, and 62,0 for the seconds...For the seconds placing wall 1 would give 15 seconds, wall 2 - 30 seconds, and wall 3 - 45 seconds...

The minimum allowed for the minutes is 2, so using anything below wall 2, will automatic set it to 2 minutes...


Last edited by Haasboy on Sat Dec 26, 2009 10:47 pm; edited 1 time in total
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Sat Dec 26, 2009 7:35 am
   Subject: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

PART 3: Shading Map Control

In VERSION.H add #define MAPCONTROLLEDSHADE

Next open WL_SHADE.CPP and make the following changes (changes appear in red):

::: CODE :::
#ifndef MAPCONTROLLEDSHADE
#ifdef USE_FEATUREFLAGS

// The lower 8-bit of the upper left tile of every map determine
// the used shading definition of shadeDefs.
static inline int GetShadeDefID()
{
    int shadeID = ffDataTopLeft & 0x00ff;
    assert(shadeID >= 0 && shadeID < lengthof(shadeDefs));
    return shadeID;
}

#else

static int GetShadeDefID()
{
    int shadeID;
    switch(gamestate.episode * 10 + mapon)
    {
        case  0: shadeID = 4; break;
        case  1:
        case  2:
        case  6: shadeID = 1; break;
        case  3: shadeID = 0; break;
        case  5: shadeID = 2; break;
        default: shadeID = 3; break;
    }
    assert(shadeID >= 0 && shadeID < lengthof(shadeDefs));
    return shadeID;
}

#endif
#endif


::: CODE :::
void InitLevelShadeTable()
{
#ifdef MAPCONTROLLEDSHADE
    int rlevel, glevel, blevel;
    int fstrength;
    fstrength = tilemap[3][0];
    rlevel = tilemap[4][0];
    glevel = tilemap[5][0];
    blevel = tilemap[6][0];
    if (fstrength == 0) {
        NoShading();
    } else if (fstrength == 1) {
        GenerateShadeTable(rlevel, glevel, blevel, gamepal, LSHADE_NORMAL);
    } else if (fstrength >= 2) {
        GenerateShadeTable(rlevel, glevel, blevel, gamepal, LSHADE_FOG);
    }
#else

    shadedef_t *shadeDef = &shadeDefs[GetShadeDefID()];
    if(shadeDef->fogStrength == LSHADE_NOSHADING)
        NoShading();
    else
        GenerateShadeTable(shadeDef->destRed, shadeDef->destGreen, shadeDef->destBlue, gamepal, shadeDef->fogStrength);
#endif
}

int GetShade(int scale)
{
#ifdef MAPCONTROLLEDSHADE
    if (tilemap[2][0]) return 0; // Turns shading or fog off
#endif

    int shade = (scale >> 1) / (((viewwidth * 3) >> 8) + 1 + LSHADE_flag);  // TODO: reconsider this...
    if(shade > 32) shade = 32;
    else if(shade < 1) shade = 1;
    shade = 32 - shade;

    return shade;
}


Now hows this works:

This feature uses the tiles 2,0; 3,0; 4,0; 5,0; and 6,0...
[2][0] - Allows you to turn the shading on or off (The 0 tile shading is on; 1 and higher shading is off)
[3][0] - Shading Strength (0 no shading; 1 normal shading; 2 and higher fog)
[4][0] - Red Shading level
[5][0] - Green Shading level
[6][0] - Blue Shading level
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Sat Dec 26, 2009 12:39 pm
   Subject: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

PART 4: Player Level Settings

This feature allows you to determine whether the player will start the next level with what they finished with in the previous level, or start a with particular status (e.g. machine gun, 20 ammo and 25% health). This feature uses the tiles 63,0; 63,1; 63,2; and 63,3....

Firstly open VERSION.H and add #define MAPCONTROLLEDPLSETT

Next open WL_GAME.CPP and in the GameLoop function add the lines in red:
::: CODE :::
        if (!loadedgame)
            SetupGameLevel ();
#ifdef MAPCONTROLLEDPLSETT
        if (!loadedgame) {
            if (tilemap[63][0]) {
                ResetPlayer();
            }
        }
#endif


WL_DEF.H
::: CODE :::
void            NewGame (int difficulty,int episode);
void            ResetPlayer (void);
void            CalcProjection (int32_t focal);


WL_MAIN.C after the NewGame function add:
::: CODE :::
#ifdef MAPCONTROLLEDPLSETT
/********
**
** ResetPlayer
**
***************/

void ResetPlayer (void)
{
     int ammoAmount, healthAmount;
     if (tilemap[63][1] == 0) { // Start with a specific weapon
         gamestate.weapon = gamestate.bestweapon = gamestate.chosenweapon = wp_knife;
     } else if (tilemap[63][1] == 1) {
         gamestate.weapon = gamestate.bestweapon = gamestate.chosenweapon = wp_pistol;
     } else if (tilemap[63][1] == 2) {
         gamestate.weapon = gamestate.bestweapon = gamestate.chosenweapon = wp_machinegun;
     } else if (tilemap[63][1] >= 3) {
         gamestate.weapon = gamestate.bestweapon = gamestate.chosenweapon = wp_chaingun;
     }
     ammoAmount = tilemap[63][2]; //Start with a specific amount of ammo
     if (ammoAmount > 99) {
         gamestate.ammo = 99;
     } else {
         gamestate.ammo = ammoAmount;
     }
     if (tilemap[63][3] == 0) {   // Start with a certain percentage of health
         healthAmount = 25;
     } else if (tilemap[63][3] == 1) {
         healthAmount = 50;
     } else if (tilemap[63][3] == 2) {
         healthAmount = 75;
     } else if (tilemap[63][3] >= 3) {
         healthAmount = 100;
     }
     gamestate.health = healthAmount;
}
#endif


How this feature works:

[63][0] - Any tile greater than 0 changes what the player starts with...
[63][1] - Player starts with a specific weapon (knife, pistol, machine gun, or chaingun)...
[63][2] - Player starts with a specific amount of ammo (0-99)...
[63][3] - Player starts with a specific amount of health (tile 0 - 25%; tile 1 - 50%; tile 2 - 75%; tile 3 and higher - 100%)...

This feature can be used if to add some sort of challenge during play (e.g player being caught)...
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Sat Dec 26, 2009 10:43 pm
   Subject: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

PART 5: Timed Levels

Another feature that'll add strategy to the game...This particular feature allows to set whether level will be timed or not...

Firstly open VERSION.H and add #define MAPCONTROLLEDLTIME

Next open WL_PLAY.CPP and before the PlayLoop function add:
::: CODE :::
#ifdef MAPCONTROLLEDLTIME
float leveltime;
int32_t scoreticcount;
int scorebonusAmount;
#endif


Next bit goes within the PlayLoop function, after the following code:
::: CODE :::
        //
        // MAKE FUNNY FACE IF BJ DOESN'T MOVE FOR AWHILE
        //
#ifdef SPEAR
        funnyticount += tics;
        if (funnyticount > 30l * 70)
        {
            funnyticount = 0;
            if(viewsize != 21)
                StatusDrawFace(BJWAITING1PIC + (US_RndT () & 1));
            facecount = 0;
        }
#endif

add:
::: CODE :::
#ifdef MAPCONTROLLEDLTIME
        if (tilemap[63][4]) {
            leveltime = 2.0;
            if (tilemap[63][5] >= 1 && tilemap[63][5] <= 5) {
                leveltime = tilemap[63][5];
                if (tilemap[63][6] >= 1 && tilemap[63][6] <= 3) {
                    switch(tilemap[63][6]) {
                         case 1:
                              leveltime += .25;
                              break;
                         case 2:
                              leveltime += .50;
                              break;
                         case 3:
                              leveltime += .75;
                              break;
                    }
                }
            }
            leveltime = (leveltime * 4200)/70;
            if (tilemap[63][7] <= 1) {
                scorebonusAmount = (tilemap[63][7])*1000;
            } else if (tilemap[63][7] == 0) {
                scorebonusAmount = 500;
            }
            scoreticcount += tics;
            if (scoreticcount > 1l*70) {
                GivePoints(scorebonusAmount);
                scoreticcount = 0;
            }
            if (gamestate.TimeCount == leveltime*70)
                playstate = ex_completed;
        }
       
#endif


UPDATED
Next open WL_AGENT.CPP and add the red lines into the TakeDamage function:
::: CODE :::
    if (!godmode)
        gamestate.health -= points;

    if (gamestate.health<=0) {
#ifdef MAPCONTROLLEDLTIME
        if (tilemap[63][4]) {
            gamestate.health = 0;
            playstate = ex_completed;
        } else {
#endif

            gamestate.health = 0;
            playstate = ex_died;
            killerobj = attacker;
#ifdef MAPCONTROLLEDLTIME
        }
#endif

    }

    if (godmode != 2)
        StartDamageFlash (points);


ADDITIONAL
Next open WL_INTER.CPP and add red lines into the LevelCompleted function:
::: CODE :::
//
// do the intermission
//
    IN_ClearKeysDown ();
    IN_StartAck ();

#ifdef JAPAN
    CA_CacheGrChunk (C_INTERMISSIONPIC);
    VWB_DrawPic (0, 0, C_INTERMISSIONPIC);
    UNCACHEGRCHUNK (C_INTERMISSIONPIC);
#endif
    VWB_DrawPic (0, 16, L_GUYPIC);

#ifdef MAPCONTROLLEDLTIME
    if (tilemap[63][4] >= 1) {
        Write (14, 2, "Level\ncompleted");
       
        if (gamestate.health<=0) {
            Write (8, 15, "Sorry you died!");
            Write (8, 18, "50 bonus!");
            GivePoints (50);
        } else {
            Write (8, 15, "Congratulations");
            Write (8, 18, "15000 bonus!");
            GivePoints (15000);
        }

        gamestate.health = 100;
        VW_UpdateScreen ();
        VW_FadeIn ();

    } else {
#endif

#ifndef SPEAR
    if (mapon < 8)
#else
    if (mapon != 4 && mapon != 9 && mapon != 15 && mapon < 17)
#endif


::: CODE :::
        GivePoints (15000);
    }

#ifdef MAPCONTROLLEDLTIME
    }
#endif


    DrawScore ();
    VW_UpdateScreen ();


Now the point of this feature allows you to set a particular level to be timed...

After the time runs, the player goes to the next level with 100% health...

Tilemap Attributes
[63][4] - Any tile enables this feature; 0 disables it...
[63][5] - The amount of playable minutes allowed (default is 2; minimum is 1; maximum is 5)...
[63][6] - The amount of playable seconds allowed(15 seconds; 30 seconds; or 45 seconds)...
[63][7] - Bonus points achieved after each second (0 is 500 points; 1 and higher is 1*1000)...

UPDATED - 31 Dec 09
Code has been update so that if the mapper sets the level to a timed level then, a different intermission screen appears, and a bonus depending on whether they survived the level or not...

I might still update this step even further to allow the mapper to set certain parameters (e.g killing all enemies on the level, etc) that the player must obtain for extra bonuses...


Last edited by Haasboy on Thu Dec 31, 2009 6:06 am; edited 5 times in total
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 5:42 ago.

Topics: 160
Posts: 7935
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Sun Dec 27, 2009 7:08 pm
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Thanks for posting this, Haasboy. It's a big help to have this code isolated; now WolfDX and other WIP mods can benefit. Thumbs Up Too Cool Beer Party Beer
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Sun Dec 27, 2009 9:03 pm
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Thanks...there's still plenty to come...

_________________
Haasboy Engine - Currently under construction (To be used with future mods - F.A.D.E.D. - Mansion X - Rising Evil Series)
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Mon Dec 28, 2009 9:25 am
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Part 6: Parallaxed Sky (Improvement from the feature flags)

I know you're all probably saying that if you enable feature flags in the SDL code, you'll be able to control what parallaxed sky you want, well I've had problems with that as it doesn't show the parallaxed sky at all, even with the parallaxed sky and feature flags enabled, so here's my solution:

Firstly open VERSION.H and add #define MAPCONTROLLEDSKY

Then open WL_PARALLAX.CPP and make the following modifications (changes are in red):
::: CODE :::
#ifdef MAPCONTROLLEDSKY
static int GetParallaxStartTexture()
{
    int startTex = tilemap[7][0];
    return startTex;
}

#else

#ifdef USE_FEATUREFLAGS

// The lower left tile of every map determines the start texture of the parallax sky.
static int GetParallaxStartTexture()
{
    int startTex = ffDataBottomLeft;
    assert(startTex >= 0 && startTex < PMSpriteStart);
    return startTex;
}

#else

static int GetParallaxStartTexture()
{
    int startTex;
    switch(gamestate.episode * 10 + mapon)
    {
        case  0: startTex =  1; break;
        default: startTex =  0; break;
    }
    assert(startTex >= 0 && startTex < PMSpriteStart);
    return startTex;
}

#endif
#endif


Then open WL_DRAW.CPP and make the following changes in the ThreeDRefresh function (changes are in red):
::: CODE :::
    WallRefresh ();

#if defined(MAPCONTROLLEDSKY) && defined(USE_PARALLAX)
    DrawParallax(vbuf, vbufPitch);
#else

#if defined(USE_FEATUREFLAGS) && defined(USE_PARALLAX)
    if(GetFeatureFlags() & FF_PARALLAXSKY)
        DrawParallax(vbuf, vbufPitch);
#endif
#endif

#if defined(USE_FEATUREFLAGS) && defined(USE_CLOUDSKY)
    if(GetFeatureFlags() & FF_CLOUDSKY)
        DrawClouds(vbuf, vbufPitch, min_wallheight);
#endif


Now you can define what wall tile the parallaxed sky will be used from, by setting wall tile on the map with the map tile [7][0]...

_________________
Haasboy Engine - Currently under construction (To be used with future mods - F.A.D.E.D. - Mansion X - Rising Evil Series)
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Tue Dec 29, 2009 8:02 am
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Part 7: Floor and Ceiling colours

Now to make mapping even easier, by allowing the mapper to set the floor and ceiling colour without restricting the mapper...

Firstly open VERSION.H and add the following two lines:
::: CODE :::
#define MAPCONTROLLEDCEILING// Map Controlled Ceiling colour (8,0)
#define MAPCONTROLLEDFLOOR    // Map Controlled Floor colour (9,0)


Next, open WL_DRAW.CPP and make your way to the VGAClearScreen function, and change it to look like this:
::: CODE :::
void VGAClearScreen (void)
{
    #ifdef MAPCONTROLLEDFLOOR
    byte floor;
    floor=tilemap[9][0];
    #endif
   
    byte ceiling;
    #ifdef MAPCONTROLLEDCEILING
    ceiling=tilemap[8][0];
    #else
    ceiling=vgaCeiling[gamestate.episode*10+mapon];
    #endif

    int y;
    byte *ptr = vbuf;
#ifdef USE_SHADING
    for(y = 0; y < viewheight / 2; y++, ptr += vbufPitch)
        memset(ptr, shadetable[GetShade((viewheight / 2 - y) << 3)][ceiling], viewwidth);
    for(; y < viewheight; y++, ptr += vbufPitch)
        #ifndef MAPCONTROLLEDFLOOR
        memset(ptr, shadetable[GetShade((y - viewheight / 2) << 3)][0x19], viewwidth);
        #else
        memset(ptr, shadetable[GetShade((y - viewheight / 2) << 3)][floor], viewwidth);
        #endif
#else
    for(y = 0; y < viewheight / 2; y++, ptr += vbufPitch)
        memset(ptr, ceiling, viewwidth);
    for(; y < viewheight; y++, ptr += vbufPitch)
        #ifndef MAPCONTROLLEDFLOOR
        memset(ptr, 0x19, viewwidth);
        #else
        memset(ptr, floor, viewwidth);
        #endif
#endif
}


This code allows you to set the floor and ceiling colours by putting the appropriate wall tile in the required map tile:
[8][0] - Ceiling colour
[9][0] - Floor colour

_________________
Haasboy Engine - Currently under construction (To be used with future mods - F.A.D.E.D. - Mansion X - Rising Evil Series)
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Thu Dec 31, 2009 5:02 am
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Part 5 timed levels feature has been updated...check it out!!!

_________________
Haasboy Engine - Currently under construction (To be used with future mods - F.A.D.E.D. - Mansion X - Rising Evil Series)
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 5:42 ago.

Topics: 160
Posts: 7935
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Thu Dec 31, 2009 8:29 pm
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

How would one go about controlling what level you're sent to on a Floor 6B elevator? What code should be used there? Thank you for your time. Smile
Haasboy
DieHard Officer
DieHard Officer


Joined: 23 Jul 2003
Last Visit: 17 Jul 2017

Topics: 58
Posts: 581
Location: South Africa, Johannesburg
southafrica.gif

PostPosted: Thu Dec 31, 2009 10:45 pm
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

That would be an interest feature (elevator level control), I'll look into it!!!

_________________
Haasboy Engine - Currently under construction (To be used with future mods - F.A.D.E.D. - Mansion X - Rising Evil Series)
BrotherTank
Forum Administrator
<B>Forum Administrator</B>


Joined: 01 Mar 2003
Last Visit: 14 Sep 2016

Topics: 153
Posts: 2256
Location: Ontario
canada.gif

PostPosted: Fri Jan 01, 2010 12:44 am
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

You might want to check out Map Control - By BrotherTank - Jan 04, 2005

It lists many of the features listed and more...
For what it is worth, the map can control just about anything.
Using any point on the map with:

Mapspot (x,y,plane)

You can set any place on the map as a control. That function works both ways... You can use: x = Mapspot..... or Mapspot... = x. Both are valid. And for further ideas that I already did... see the Map of the Month threads where I discussed all the settings that I was using.. Map of the Month Discussion...

And there are a couple of downloads in the download section that by the looks of things, most have overlooked....

BT

_________________

The probability of someone watching you is directly related to the Stupidity of your actions
&
The two most abundant things in the Universe are Hydrogen & Stupidity - H.Ellison

Which of those is more relevant to you??


Last edited by BrotherTank on Fri Jan 01, 2010 3:22 pm; edited 1 time in total
Merthsoft
Bring 'em On
Bring 'em On


Joined: 12 May 2004
Last Visit: 28 Jan 2016

Topics: 5
Posts: 97
Location: Wisconsin
usa.gif

PostPosted: Fri Jan 01, 2010 1:58 pm
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

The Mapspot(x,y,plane) can be useful with actors as well, say for a tile that causes actors to spawn in certain places based on the actor at a tile.
Like, say you put an SS walking forward in (1,1), then at spot (45, 24) there's a "Spawn Trigger" pickup that causes all the "Spawn Tile" spots associated with (1,1) to spawn an SS walking forward. Make some neat traps that way.

_________________
Shaun
BrotherTank
Forum Administrator
<B>Forum Administrator</B>


Joined: 01 Mar 2003
Last Visit: 14 Sep 2016

Topics: 153
Posts: 2256
Location: Ontario
canada.gif

PostPosted: Fri Jan 01, 2010 3:17 pm
   Subject: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

For the Specifics on using the map to control the secret levels...

Just look in the Map of the Month Source Code Download SDL & Dos. It's not hard to find as you already know the places in the source where the Secret Level Control is taken care of... And the source changes that I made aren't that difficult to follow either.

BT
Chris
DieHard Wolfer
DieHard Wolfer


Joined: 11 Mar 2003
Last Visit: 11 Jul 2017

Topics: 55
Posts: 2106
Location: Canada
blank.gif

PostPosted: Tue Jul 04, 2017 9:28 am
   Subject: Re: [Tutorial] Map Controls
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Bottom of Posts

Officer-Michael John found an interesting issue with "PART 1: Map Controlled Music". The songs[] array is not the order of the songs in the Audiot file, but the order they are arranged in the Levels (ie. 0 and 4 are the same, GETTHEM_MUS for E1L1 and E1L5). When he used 32 for his Jazzing the Nazis slot, it instead played POW which I'm guessing is because it corresponds to the E4L3 in songs[]:

https://github.com/AlumiuN/Wolf4SDL/blob/master/WL_PLAY.CPP#L164

One quick way to change/fix it is to use this:

::: CODE :::
#ifndef MAPCONTROLLEDMUSIC
musicnames      lastmusicchunk = (musicnames) -1;
#endif

::: CODE :::
void StartMusic()
{
       #ifdef MAPCONTROLLEDMUSIC
       int holder;
        #endif
        SD_MusicOff();
        #ifdef MAPCONTROLLEDMUSIC
        holder = tilemap[1][0];
        CA_CacheAudioChunk(STARTMUSIC + holder);
        SD_StartMusic((MusicGroup *)audiosegs[STARTMUSIC + holder]);
        #else
        lastmusicchunk = (musicnames) songs[gamestate.mapon+gamestate.episode*10];
        CA_CacheAudioChunk(STARTMUSIC + lastmusicchunk);
        if(audiosegs[STARTMUSIC + lastmusicchunk])
                SD_StartMusic((MusicGroup *)audiosegs[STARTMUSIC + lastmusicchunk]);
        #endif
}

::: CODE :::
void ContinueMusic(int offs)
{
       #ifdef MAPCONTROLLEDMUSIC
       int holder;
        #endif
        SD_MusicOff();
        #ifdef MAPCONTROLLEDMUSIC
        holder = tilemap[1][0];
        CA_CacheAudioChunk(STARTMUSIC + holder);
        SD_ContinueMusic((MusicGroup *) audiosegs[STARTMUSIC + holder],offs);
        #else
        lastmusicchunk = (musicnames) songs[gamestate.mapon+gamestate.episode*10];
        CA_CacheAudioChunk(STARTMUSIC + lastmusicchunk);
        if(audiosegs[STARTMUSIC + lastmusicchunk])
                SD_ContinueMusic((MusicGroup *) audiosegs[STARTMUSIC + lastmusicchunk],
                        offs);
        #endif
}

StopMusic already had holder set up correctly for this so that one didn't have to be adjusted.
Display posts from previous:   
Post new topicReply to topic Time synchronized with the forum server time
DieHard Wolfers Forum Index -> SDL Code Crackers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page TopView Next Topic
Page 1 of 1
Jump to:  

Related topics
 Topics   Replies   Views   Last Post 
No new posts Sticky: [Tutorial] Compiling Wolf4SDL with Code::Blocks
Author: dcbasic
90 14551 Wed May 24, 2017 7:53 pm
Falcon*93 View latest post
No new posts [help] adding music and seamless levels, textured ceilings
Author: lilmanjs
34 3366 Fri Aug 22, 2008 1:12 pm
lilmanjs View latest post
No new posts SDL Tutorials available on Haasboy Software
Author: Haasboy
4 1520 Tue Aug 12, 2008 10:11 pm
Haasboy View latest post
No new posts [Help] Problem with Checkweaponchange function (wolf4sdl)
Author: Mortimer
4 2003 Sat May 17, 2008 11:26 am
Mortimer View latest post
No new posts [help] Wolf4sdl's implemented tutorials
Author: Mortimer
6 2171 Tue May 06, 2008 1:15 pm
Ripper View latest post
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
   You cannot delete your posts in this forum
You cannot vote in polls in this forum


Copyright ©2003-2008 DieHard Wolfers
A Modified subBunker Theme by BrotherTank
Powered by phpBB © 2001, 2005 phpBB Group