Recommended for you
Scrummble's avatar
Osaka Underground 1.1.1 for foobar2000
By Scrummble   |   Watch
42 111 15K (3 Today)
Published: August 15, 2015
© 2015 - 2019 Scrummble
# foobar2000 Osaka Underground
1.1.1: Fixed the bug of wikipedia button
New in 1.1:
  • Playlist and information panel added to the right bar 
  • JS Smooth Browser added to the main panel 
  • Changed the cover panel in the lower-left corner 
  • Improved banner and scroll bar 
  • Bugs fixed 
Please check the readme file for the setup guide.
Alternative download link: drive.google.com/file/d/0B8nAo…

Required Fonts: Source Han Sans; InputMono; FontAwesome.
Fonts Lazy Pack: drive.google.com/open?id=0B8nA… Note that it's not full sets; only containing need files.
MacType needed for font aa.

Other Credits:
  • "CoverFlow View", "JS Smooth Browser" and "WSH Tabbed Playlist Manager" are created by [Br3tt aka Falstaff](br3tt.deviantart.com); modifications by me. 
  • Cover Panel is from [marc_2003](www.hydrogenaud.io/forums/inde…). 
  • Some codes of ELPlaylist were from dreamix 3.3 by dreamawake. 
  • Components belong to each own authors.
If you would please, leave comments / questions / advises / bug reports, thank you.
I do not login on deviantart frequently, so you could email me at frankzhao0912@qq.com.
Please attach full credit when taking out, shaing or modifying.
Recommended for you
Comments111
anonymous's avatar
Join the community to add your comment. Already a deviant? Sign In
Ahimenes's avatar
Hi. Pretty cool skin...on screens. On my foobar2k:
Screenshot 2018-11-30 001 by Ahimenes  
No buttons. No control panel. No mercy.
petteri-pasila's avatar
Well you didn't install any of the fonts, bro.

Neither did I, cuz it's laggy, and I wanna keep looking.
ifelix's avatar
three years gone =(
Reikawa's avatar
two years gone, still waiting the new version :)
ifelix's avatar
Hello Scrummble,

do you have any plans for the next Version? e.g. with some visualization or something :)

Thanks and Greetings !
Scrummble's avatar
Hopefully some new version will be released soon......
Jdotpeacock's avatar
Hello,

Could you help me modify this skin to work better on a smaller tablet.

I'd like to cut the 'Now Playing' right hand column and also increase the size slightly of the left hand library tree.

Also I would like to increase font size slightly.

Thanks in advanced.

Here is an example of what I'm looking to achieve.
i.gyazo.com/cbabee484f89a56553…
Scrummble's avatar
The feature of hiding columns will be released with the next version.

It's pretty hard for me to add a function modifying font size... With brightest intention it will be in the 3rd update from now, with DPI modifications.
MShidare's avatar
great but buttom left albumart option

what is cd jewel case use of? when i switch to this, it shows some error like that

File: C:\Users\User\Desktop\foobar2000\skins\OsakaUnderground\wsh_marc2003\js\albumart.js
Line: 9, Col: 6
<source text only available at compile time>

Thank you
Scrummble's avatar
Please just ignore that option. The panel was a plug-in and will be replaced in the next version.
enSHtEIN's avatar
Hello, can you give any tips of how to add rating to the main playlist (instead of codec or bitrate info for example)? Didn't knew i will miss the rating so much :/
Scrummble's avatar
$puts(w,$sub($get(w),10)) $drawtextex($if2(%rating%,-),$get(xOffset),1,$get(w),$get(texth),$if(%rating%,$get(trackc),$get(darkc)),vcenter right) $font(FontAwesome,8,) $puts(w,$sub($get(w),10)) $drawtextex($if(%loved%,$char(61444),$char(61445)),$get(xOffset),2,$get(w),$get(texth),$if(%loved%,$get(trackc),$get(darkc)),vcenter right) $puts(w,$sub($get(w),12)) $font(%NUM_FONT%,%size8%,italic)

Right click > Settings, and try putting this before //Count.
enSHtEIN's avatar
Looks a bit weird, but works i guess.
ifelix's avatar
How did you added the Visualisation? =)
enSHtEIN's avatar
It's the Waveform seekbar panel. Here are the settings for it (i think):

texture tex : WAVEFORMDATA;

sampler sTex = sampler_state
{
Texture = (tex);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Clamp;
};

struct VS_IN
{
float2 pos : POSITION;
float2 tc : TEXCOORD0;
};

struct PS_IN
{
float4 pos : SV_POSITION;
float2 tc : TEXCOORD0;
};

float4 panelBackgroundColor : BACKGROUNDCOLOR; // 'Background color' - whole panel background
float4 waveHighlightColor   : HIGHLIGHTCOLOR;  // 'Highlight color' - for played part
float4 selectionColor       : SELECTIONCOLOR;  // Not used
float4 waveUnplayedColor    : TEXTCOLOR;       // 'Foreground color' - for unplayed part
float cursorPos             : CURSORPOSITION;
bool cursorVisible          : CURSORVISIBLE;
float seekPos               : SEEKPOSITION;
bool seeking                : SEEKING;
float4 replayGain           : REPLAYGAIN;
float2 viewportSize         : VIEWPORTSIZE;
bool horizontal             : ORIENTATION;
bool flipped                : FLIPPED;
bool shadePlayed            : SHADEPLAYED;

float4 colorDodge(float4 baseColor, float4 blendColor)
{
return saturate(baseColor / (1 - blendColor));
}

float4 linearDodge(float4 baseColor, float4 blendColor)
{
return saturate(baseColor + blendColor);
}

float4 multiply(float4 baseColor, float4 blendColor)
{
return saturate(baseColor * blendColor);
}

float4 getSeekAheadColor()
{
float4 color = colorDodge(waveHighlightColor, 0.4);
color.a = 0.5;

return color;
}

float4 getSeekBackColor()
{
return float4(1.0, 1.0, 1.0, 0.5);
}

float4 getWaveTopColor()
{
return colorDodge(waveHighlightColor, 0.57);
}

float4 getReflectionHightlightColor()
{
float4 color = waveHighlightColor;
color = multiply(color, 0.75);
color = linearDodge(color, 0.6);

return color;
}

float2 getPixelSize()
{
float2 pixelSize = horizontal
? 1 / viewportSize.xy
: 1 / viewportSize.yx;

return pixelSize;
}

/*
  Split waveform into bars.

  Waveform texture contains upper half-waves (positive peaks) in Green channel
  and negative ones in Red. Negative values are ignored to make reflection later.
*/
float4 rmsSampling(float2 tc, float2 pixelSize, inout bool isGap)
{
float rmsData;
float mainAxisLength = (horizontal ? viewportSize.x : viewportSize.y);

if (ceil(mainAxisLength * tc.x) % 3 < 0.1)
{
rmsData = tex1D(sTex, tc.x).g;
}
else if (ceil(mainAxisLength * tc.x) % 3 < 1.1)
{
rmsData = tex1D(sTex, tc.x - pixelSize.x).g;
}
else
{
isGap = true;

// Height of a gap equals to height of the smallest neighbour bar
float leftPeak = tex1D(sTex, tc.x - (2 * pixelSize.x)).g;
float rightPeak = tex1D(sTex, tc.x + pixelSize.x).g;
rmsData = min(leftPeak, rightPeak);
}

return rmsData;
}

float4 getWaveColor(float2 tc, float2 pixelSize, int pixelBar, int cursorBar, float barCoverage, float4 bgColor, bool isGap)
{
bool isBeyondSeek = tc.x > seekPos;
float4 seekAheadColor = getSeekAheadColor();
float4 seekBackColor = getSeekBackColor();
float4 seekColor = isBeyondSeek ? seekBackColor : seekAheadColor;

float4 waveTop = getWaveTopColor();
float4 waveBottom = waveHighlightColor;

float4 color = (cursorBar < pixelBar ? waveUnplayedColor : lerp(waveBottom, waveTop, tc.y));

if (pixelBar == cursorBar)
{
if (seeking)
{
if (isBeyondSeek)
{
color = lerp(color, seekColor, seekColor.a);
color = lerp(color, waveUnplayedColor, barCoverage);
}
else
{
color = lerp(color, lerp(waveUnplayedColor, seekColor, seekColor.a), barCoverage);
}
}
else
{
color = lerp(color, waveUnplayedColor, barCoverage);
}
}
else if (seeking)
{
bool afterCursor = tc.x + pixelSize.x > cursorPos;
float4 seekColor = isBeyondSeek ? seekBackColor : seekAheadColor;

if ((afterCursor + isBeyondSeek) == 1)
{
color = lerp(color, seekColor, seekColor.a);
}
}

if (isGap)
{
color = lerp(color, bgColor, tc.y * 0.35 + 0.5);
}

return color;
}

float4 getReflectionColor(float2 tc, float2 pixelSize, int pixelBar, int cursorBar, float barCoverage, float4 bgColor, bool isGap)
{
float4 color;

float4 reflectionUnplayedColor = multiply(waveUnplayedColor, 0.8980);
float4 reflectionHighlightColor = getReflectionHightlightColor();

if (isGap)
{
color = bgColor;
}
else if (pixelBar == cursorBar)
{
color = lerp(reflectionHighlightColor, reflectionUnplayedColor, barCoverage);
}
else
{
color = cursorPos < tc.x + pixelSize.x ? reflectionUnplayedColor : reflectionHighlightColor;
}

return color;
}

float4 evaluate(float2 tc)
{
float mainAxisLength = (horizontal ? viewportSize.x : viewportSize.y);
float2 pixelSize = getPixelSize();

bool isGap = false;
float rmsData = rmsSampling(tc, pixelSize, isGap);

tc.y += 0.5;

// Reflection
if (tc.y < 0)
{
// Invert upper half-waves to imitate reflection
rmsData = 1 - rmsData;

// Squeeze reflection
tc.y *= 3.5;
}

rmsData -= 0.5;
rmsData *= 2.5;

bool above = abs(tc.y) > abs(rmsData);
float4 bgColor = panelBackgroundColor * ((0.93 - (tc.x * 0.08)) + ((tc.y * 0.1) - 0.07));

if (above || abs(tc.y) < 1.33 * pixelSize.y)
{
return bgColor;
}

int pixelBar = ceil(mainAxisLength * (tc.x + pixelSize.x) / 3.0);
int cursorBar = ceil(mainAxisLength * cursorPos / 3.0);
float barCoverage = (cursorBar * 3.0 - (mainAxisLength * cursorPos)) / 3.0;

float4 color = tc.y > 0
? getWaveColor(tc, pixelSize, pixelBar, cursorBar, barCoverage, bgColor, isGap)
: getReflectionColor(tc, pixelSize, pixelBar, cursorBar, barCoverage, bgColor, isGap);

return color;
}

PS_IN VS(VS_IN input)
{
    float pixelWidth = horizontal
        ? 1 / viewportSize.x
        : 1 / viewportSize.y;

    PS_IN output = (PS_IN)0;
    
    // Move left to fill 1st empty pixel
    output.pos = float4(input.pos - float2(pixelWidth, 0), 0, 1);

    if (horizontal)
    {
    float firstBarAlignment = (flipped ? 2*pixelWidth : -2*pixelWidth);
        output.tc = float4((input.tc.xy + float2(1.0 + firstBarAlignment, 0)) * float2(0.5, 1.0), 0, 1);
    }
    else
    {
    float firstBarAlignment = (flipped ? 3*pixelWidth : -1*pixelWidth);
        output.tc = float4((-input.pos.yx + float2(1.0 + firstBarAlignment, 0)) * float2(0.5, 1.0), 0, 1);
    }

    if (flipped)
    {
        output.tc.x = 1.0 - output.tc.x;
    }

return output;
}

float4 PS(PS_IN input) : SV_Target
{
float4 color = evaluate(input.tc);

return color;
}

technique Render9
{
pass
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_3_0 PS();
}
}

technique10 Render10
{
pass P0
{
SetGeometryShader(0);
SetVertexShader(CompileShader(vs_4_0, VS()));
SetPixelShader(CompileShader(ps_4_0, PS()));
}
}
Scrummble's avatar
Ooh I forgot some variables are not defined in the published old version...
Try to change this: "$if(%loved%,$get(trackc),$get(darkc))" (excluding "") to: "$get(trackc)(excluding "" too).
Hope that works.
enSHtEIN's avatar
I figured out what's it all about ;) (Wink)  I leveled the text a little...and with my customdb settings it looks like this. Better than i wanted at first time.

$puts(w,$sub($get(w),5))
$drawtextex($if2(%rating%,-),$get(xOffset),0,$get(w),$get(texth),$get(trackc),vcenter right)
$font(FontAwesome,8,)
$puts(w,$sub($get(w),17))
$drawtextex($if(%LASTFM_LOVED_DB%,$char(61444),$char(61445)),$get(xOffset),0,$get(w),$get(texth),$get(trackc),vcenter right)
$puts(w,$sub($get(w),10))
$font(%NUM_FONT%,%size8%,italic)

p.s. You're a magician.
Scrummble's avatar
Glad to see you enjoying it!
enSHtEIN's avatar
Great skin! Still using it! But a lot modified. Untitled by enSHtEIN  
laboccia's avatar
Ciao, le copertine si aggiornano solista DOPO Aver cliccato su Una seconda canzone e non immediatamente. Anche se si cambia La Scelta tra "preferiscono ora playng" e "seguire traccia selezionata"
Scrummble's avatar
Sorry I cannot read Italian, and google translate did not give me information specific enough. Would you mind using some language that I know...? Thank you...
laboccia's avatar
Hello, the covers are upgraded solo after getting clicked A second song and not immediately. Even if you change the choice between "now prefer playng" and "follow the selected track"
Scrummble's avatar
Have you tried right-clicking on the cover itself? If yes, it may be a bug of the panel... The next version will remove the problematic add-ons. Sorry for the inconvenience. 
anonymous's avatar
Join the community to add your comment. Already a deviant? Sign In
©2019 DeviantArt
All Rights reserved