bup
BIN
asset/clippy-bubble.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
asset/groove-gauge.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
asset/jacket.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
asset/song-data.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
asset/taskbar.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
asset/time-container.png
Normal file
|
After Width: | Height: | Size: 212 B |
BIN
asset/window.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
customize/bg/clear/Clouds.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
customize/bg/clear/Gold_Weave.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
customize/bg/clear/Red_Bricks.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
customize/bg/clear/_Default.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
customize/bg/fail/bsod.png
Normal file
|
After Width: | Height: | Size: 432 KiB |
0
customize/clippy/320x320px-png.txt
Normal file
BIN
customize/clippy/ASIO.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
customize/clippy/Bonzi.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
customize/clippy/Clipenger.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
customize/clippy/Clippy.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
customize/clippy/Penger.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
70
dst/clippy.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
local function getClippy(speechBubbleX, speechBubbleY, speechBubbleFontHeight)
|
||||
return {
|
||||
-- clippy
|
||||
{
|
||||
id = "clippy_character",
|
||||
filter = 0, -- nearest neigbour
|
||||
dst = {
|
||||
{ x = speechBubbleX - 10, y = 66, w = 300, h = 300, a = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "clippy_speechbubble",
|
||||
dst = {
|
||||
{ x = speechBubbleX, y = speechBubbleY, w = 300, h = 300, a = 255 }
|
||||
}
|
||||
},
|
||||
-- clippy speech text
|
||||
{
|
||||
id = "clippy_rank",
|
||||
dst = {
|
||||
{ x = speechBubbleX + 10, y = speechBubbleY + 220, w = 300, h = 60, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "clippy_rank_best",
|
||||
dst = {
|
||||
{ x = speechBubbleX + 190, y = speechBubbleY + 230, w = 100, h = speechBubbleFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
-- gauge type
|
||||
{
|
||||
id = "clippy_clear_type",
|
||||
dst = {
|
||||
{ x = speechBubbleX + 10, y = speechBubbleY + 160, w = 300, h = speechBubbleFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "clippy_clear_type_best",
|
||||
dst = {
|
||||
{ x = speechBubbleX + 190, y = speechBubbleY + 160, w = 100, h = speechBubbleFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
-- ir display
|
||||
{
|
||||
id = "clippy_ir_unavailable",
|
||||
op = { 50 },
|
||||
dst = {
|
||||
{ x = speechBubbleX + 10, y = speechBubbleY + 100, w = 300, h = speechBubbleFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "clippy_ir_rank",
|
||||
op = { 51 },
|
||||
dst = {
|
||||
{ x = speechBubbleX + 10, y = speechBubbleY + 100, w = 300, h = speechBubbleFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
-- rate
|
||||
{
|
||||
id = "clippy_rate",
|
||||
dst = {
|
||||
{ x = speechBubbleX + 10, y = speechBubbleY + 40, w = 300, h = speechBubbleFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
getClippy = getClippy
|
||||
}
|
||||
37
dst/gauge.lua
Normal file
@@ -0,0 +1,37 @@
|
||||
local function getGauge(grooveX, grooveY)
|
||||
return {
|
||||
-- gauge graph
|
||||
{
|
||||
id = "bg_groove",
|
||||
loop = 200,
|
||||
dst = {
|
||||
{ time = 0, x = grooveX, y = grooveY, w = 600, h = 300, a = 0, filter = 1 },
|
||||
{ time = 200, a = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "text_groove_title",
|
||||
loop = 200,
|
||||
dst = {
|
||||
{ time = 0, x = grooveX + 70, y = grooveY + 240, w = 400, h = 40, a = 0, r = 255, g = 255, b = 255, filter = 1 },
|
||||
{ time = 200, a = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "gauge_line",
|
||||
dst = {
|
||||
{ x = grooveX + 4, y = grooveY + 4, w = 592, h = 230, a = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "gauge_bg",
|
||||
dst = {
|
||||
{ x = grooveX + 4, y = grooveY + 4, w = 592, h = 230, a = 192 }
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
getGauge = getGauge
|
||||
}
|
||||
42
dst/jacket.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
local function getJacket(jacketWindowX, jacketWindowY)
|
||||
-- jacket image
|
||||
return {
|
||||
{
|
||||
id = "jacket_window",
|
||||
dst = {
|
||||
{ x = jacketWindowX, y = jacketWindowY, w = 408, h = 372, a = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "text_jacket_title",
|
||||
dst = {
|
||||
{ x = jacketWindowX + 68, y = jacketWindowY + 314, w = 130, h = 40, a = 255, r = 255, g = 255, b = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = -110, -- black image for the black bars in the jacket window
|
||||
dst = {
|
||||
{ x = jacketWindowX + 6, y = jacketWindowY + 6, w = 396, h = 296, a = 255 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = -100, -- stage file (music select image)
|
||||
op = { 191 },
|
||||
dst = {
|
||||
{ x = jacketWindowX + 6, y = jacketWindowY + 6, w = 396, h = 296, a = 255 }
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
id = "jacket_no_jacket",
|
||||
op = { 190 },
|
||||
dst = { -- text is centered so the draw origin is shifted by 200 px
|
||||
{ x = jacketWindowX + 206, y = jacketWindowY + 120, w = 400, h = 52, a = 255, r = 255, g = 255, b = 255 }
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
getJacket = getJacket
|
||||
}
|
||||
105
dst/songdata.lua
Normal file
@@ -0,0 +1,105 @@
|
||||
local game = require("main_state")
|
||||
|
||||
local function getDiffColor(op)
|
||||
local diff = tonumber(game.number(op))
|
||||
if diff < 0 then
|
||||
return 192
|
||||
end
|
||||
return 10
|
||||
end
|
||||
|
||||
local function getSongData(judgeX, judgeY, judgeFontHeight, judgeOffset)
|
||||
return {
|
||||
-- song data + playdata
|
||||
{
|
||||
id = "bg_song",
|
||||
dst = {
|
||||
{ x = judgeX - 10, y = judgeY - 305, w = 1220, h = 376, a = 255, filter = 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "text_title",
|
||||
dst = {
|
||||
{ x = judgeX + 60, y = judgeY + 12, w = 960, h = 40, a = 255, r = 255, g = 255, b = 255, filter = 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "text_level",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 7 - 20, w = 150, h = 40, a = 255, r = 10, g = 10, b = 10, filter = 1 }
|
||||
}
|
||||
},
|
||||
-- playdata
|
||||
{
|
||||
id = "pgreat",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 1, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "great",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 2, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "good",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 3, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "bad",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 4, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "poor",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 5, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "expoor",
|
||||
dst = {
|
||||
{ x = judgeX, y = judgeY - judgeOffset * 6, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "exscore",
|
||||
dst = {
|
||||
{ x = judgeX + 275, y = judgeY - judgeOffset * 1, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "exscore_diff",
|
||||
dst = {
|
||||
{ x = judgeX + 275, y = judgeY - judgeOffset * 2, w = 300, h = judgeFontHeight, a = 255, r = getDiffColor(172), g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "exscore_diff_target",
|
||||
dst = {
|
||||
{ x = judgeX + 275, y = judgeY - judgeOffset * 3, w = 300, h = judgeFontHeight, a = 255, r = getDiffColor(153), g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
-- fastslow
|
||||
{
|
||||
id = "total_fast",
|
||||
dst = {
|
||||
{ x = judgeX + 275, y = judgeY - judgeOffset * 5, w = 300, h = judgeFontHeight, a = 255, r = 10, g = 140, b = 180 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "total_slow",
|
||||
dst = {
|
||||
{ x = judgeX + 275, y = judgeY - judgeOffset * 6, w = 300, h = judgeFontHeight, a = 255, r = 140, g = 10, b = 10 }
|
||||
}
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
getSongData = getSongData
|
||||
}
|
||||
27
dst/taskbar.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
local function getTaskbar()
|
||||
return {
|
||||
-- task bar
|
||||
{ -- todo(boons): extract start button icon so we can use it to toggle the leaderboard
|
||||
id = "taskbar",
|
||||
dst = {
|
||||
{ x = 0, y = 0, w = 1920, h = 63, a = 255, filter = 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "taskbar_time",
|
||||
dst = {
|
||||
{ x = 1455, y = 7, w = 460, h = 50, a = 255, filter = 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "taskbar_time_text",
|
||||
dst = {
|
||||
{ x = 1463, y = 8, w = 444, h = 40, a = 255, r = 0, g = 0, b = 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
getTaskbar = getTaskbar
|
||||
}
|
||||
BIN
font/SarasaMonoCL-Regular.ttf
Normal file
BIN
font/Windows_Regular.ttf
Normal file
16
readme.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# win95 skin for \*oraja
|
||||
|
||||
what it says on the tin
|
||||
|
||||
fully lua, i dont know json
|
||||
|
||||
tested with vanilla 0.8.8 and ED 0.3
|
||||
|
||||
## contents
|
||||
|
||||
1. result (wip)
|
||||
1. course result (soon)
|
||||
|
||||
## customizing
|
||||
|
||||
drop things into the folders, then choose in the config window or ingame
|
||||
6
result.luaskin
Normal file
@@ -0,0 +1,6 @@
|
||||
local result_skin = require("win95-main")
|
||||
if skin_config then
|
||||
return result_skin.main()
|
||||
else
|
||||
return result_skin.header
|
||||
end
|
||||
45
util/index.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="win95.css" />
|
||||
<title>Document</title>
|
||||
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- my first idea was to use this win95 css shit, but it sucked and was bad. -->
|
||||
<div id="card" class="card w95" style="height: 1076px; width: 1918px">
|
||||
<div class="card-header" style="height: 60px"></div>
|
||||
</div>
|
||||
<div
|
||||
id="wallpaper"
|
||||
style="
|
||||
background-image: url('tiles/Clouds_\(Windows_95\).png');
|
||||
background-repeat: repeat;
|
||||
height: 360px;
|
||||
width: 640px;
|
||||
"
|
||||
></div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
html2canvas(card, {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
windowWidth: 1920,
|
||||
windowHeight: 1080,
|
||||
}).then((canvas) => {
|
||||
document.body.appendChild(canvas);
|
||||
});
|
||||
|
||||
html2canvas(wallpaper, {
|
||||
width: 640,
|
||||
height: 360,
|
||||
windowWidth: 1920,
|
||||
windowHeight: 1080,
|
||||
}).then((canvas) => {
|
||||
document.body.appendChild(canvas);
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
13
util/table-folder-icons.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
U+25BD : WHITE DOWN-POINTING TRIANGLE {Hamilton operator}
|
||||
U+25BC : BLACK DOWN-POINTING TRIANGLE
|
||||
U+2606 : WHITE STAR
|
||||
U+2605 : BLACK STAR
|
||||
U+25C6 : BLACK DIAMOND
|
||||
U+25CE : BULLSEYE
|
||||
|
||||
▽
|
||||
▼
|
||||
☆
|
||||
★
|
||||
◆
|
||||
◎
|
||||
BIN
util/tiles/Clouds_(Windows_95).png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
util/tiles/Gold_Weave.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
util/tiles/Red_Blocks.png
Normal file
|
After Width: | Height: | Size: 380 B |
BIN
util/tiles/Stitches.png
Normal file
|
After Width: | Height: | Size: 268 B |
1
util/tiles/i.txt
Normal file
@@ -0,0 +1 @@
|
||||
from https://windowswallpaper.miraheze.org/wiki/Windows_95
|
||||
498
util/win95.css
Normal file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
|
||||
WIN95.CSS
|
||||
https://github.com/AlexBSoft/win95.css
|
||||
Author: Alex B (alex-b.me)
|
||||
License: MIT
|
||||
|
||||
Version: 1.2.0
|
||||
06.12.2020
|
||||
|
||||
*/
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
/*
|
||||
|
||||
Body styles
|
||||
|
||||
*/
|
||||
body {
|
||||
font-family: "Windows Regular", monospace;
|
||||
background: teal;
|
||||
color: white;
|
||||
padding-bottom: 28px;
|
||||
}
|
||||
/*
|
||||
|
||||
Button styles
|
||||
|
||||
*/
|
||||
.btn {
|
||||
border-width: 2px;
|
||||
border-style: outset;
|
||||
border-color: buttonface;
|
||||
border-right-color: #424242;
|
||||
border-bottom-color: #424242;
|
||||
background: silver;
|
||||
color: black;
|
||||
padding: 0 0 4px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.btn:hover {
|
||||
border: 2px inset #fff;
|
||||
background: silver;
|
||||
color: #424242;
|
||||
box-shadow: -1px -1px #000;
|
||||
}
|
||||
.btn:focus {
|
||||
border: 2px inset #fff !important;
|
||||
background: silver;
|
||||
color: #424242;
|
||||
box-shadow: -1px -1px #000 !important;
|
||||
outline: 0 !important;
|
||||
background: url(background.bmp);
|
||||
}
|
||||
.btn:active {
|
||||
border: 2px inset #fff !important;
|
||||
color: #424242;
|
||||
box-shadow: -1px -1px #000 !important;
|
||||
outline: 0 !important;
|
||||
background: url(background.bmp);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
.btn.disabled,
|
||||
.btn:disabled {
|
||||
cursor: default;
|
||||
background-color: silver;
|
||||
border-style: outset;
|
||||
border-color: buttonface;
|
||||
border-right-color: #424242;
|
||||
border-bottom-color: #424242;
|
||||
color: grey;
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
CARDS
|
||||
|
||||
*/
|
||||
.card {
|
||||
border: solid;
|
||||
border-width: 2px;
|
||||
border-bottom-color: #424242;
|
||||
border-right-color: #424242;
|
||||
border-left-color: #fff;
|
||||
border-top-color: #fff;
|
||||
background: silver;
|
||||
color: #212529;
|
||||
}
|
||||
.card.square {
|
||||
border-radius: 0px;
|
||||
}
|
||||
.card.square .card-header {
|
||||
border-radius: 0px;
|
||||
}
|
||||
.card.w95 .card-header {
|
||||
background: #08216b;
|
||||
/* OR #000082 is better?*/
|
||||
}
|
||||
.card-header {
|
||||
background: -webkit-linear-gradient(left, #08216b, #a5cef7);
|
||||
color: #fff;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 1px;
|
||||
text-align: left;
|
||||
}
|
||||
.card-header.icon {
|
||||
padding-left: 4px;
|
||||
}
|
||||
.header-inactive {
|
||||
background: gray !important;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
LIST GROUPS
|
||||
|
||||
*/
|
||||
.list-group {
|
||||
border: solid;
|
||||
border-width: 2px;
|
||||
border-bottom-color: #424242;
|
||||
border-right-color: #424242;
|
||||
border-left-color: #fff;
|
||||
border-top-color: #fff;
|
||||
background: silver;
|
||||
color: #212529;
|
||||
}
|
||||
.list-group-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
background: transparent;
|
||||
color: #212529;
|
||||
}
|
||||
.list-group-item-primary {
|
||||
color: white;
|
||||
background: -webkit-linear-gradient(left, #08216b, #a5cef7);
|
||||
}
|
||||
.list-group-item-action:hover {
|
||||
color: #08216b;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
NAVBAR
|
||||
|
||||
*/
|
||||
.navbar-95 {
|
||||
background: silver;
|
||||
margin: 0;
|
||||
border: 1px outset #fff;
|
||||
min-height: 40px;
|
||||
padding: 0 6px;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
color: #212529;
|
||||
padding: 0 6px;
|
||||
}
|
||||
.nav-link {
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
padding: 0 9px;
|
||||
color: #212529;
|
||||
}
|
||||
.dropdown-menu {
|
||||
display: none;
|
||||
min-width: 119px;
|
||||
padding: 0 0 2px;
|
||||
margin-left: 12px;
|
||||
font-size: 12px;
|
||||
list-style-type: none;
|
||||
background: silver;
|
||||
border: 1.8px outset #fff;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: 1.5px 1.5px #000;
|
||||
box-shadow: 1.5px 1.5px #000;
|
||||
}
|
||||
.dropdown-item {
|
||||
padding: 1px 0 1px 2px;
|
||||
}
|
||||
.dropdown-item:hover {
|
||||
color: #08216b;
|
||||
}
|
||||
.navbar-light .navbar-toggler.collapsed .navbar-toggler-icon {
|
||||
width: 32px;
|
||||
background: url(icons/directory_closed_cool-5.png);
|
||||
}
|
||||
.navbar-light .navbar-toggler .navbar-toggler-icon {
|
||||
width: 32px;
|
||||
background: url(icons/directory_open_cool-5.png);
|
||||
}
|
||||
.navbar-toggler {
|
||||
width: auto;
|
||||
}
|
||||
/*
|
||||
|
||||
FOOTER
|
||||
|
||||
*/
|
||||
.taskbar {
|
||||
cursor: default;
|
||||
background-color: silver;
|
||||
margin: 16px 0 0 0;
|
||||
padding: 0 8px;
|
||||
position: static;
|
||||
bottom: 0;
|
||||
border-top: 2px outset #fff;
|
||||
z-index: 228;
|
||||
width: 100%;
|
||||
margin-right: 0px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
.taskbar .start-button {
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
border: 1px outset #fff;
|
||||
padding: 0 0 0 2px;
|
||||
box-shadow: 1px 1px #000;
|
||||
margin-bottom: 2px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.taskbar .time {
|
||||
color: #212529;
|
||||
margin-top: 2px;
|
||||
|
||||
text-align: right;
|
||||
font-size: 14px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
#page-content {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
/*
|
||||
|
||||
ICONS
|
||||
|
||||
*/
|
||||
.icon-16 {
|
||||
margin-bottom: 2px;
|
||||
max-height: 16px;
|
||||
}
|
||||
.icon-16-4 {
|
||||
margin-bottom: 4px;
|
||||
max-height: 16px;
|
||||
}
|
||||
/*
|
||||
|
||||
FORMS
|
||||
|
||||
*/
|
||||
.form-95 {
|
||||
width: 100%;
|
||||
border: 2px inset #d5d5d5;
|
||||
color: #424242;
|
||||
background: #fff;
|
||||
box-shadow: -1px -1px 0 0 #828282;
|
||||
margin-top: 4px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
.bootstrap-select,
|
||||
textarea:focus,
|
||||
textarea.form-control:focus,
|
||||
input.form-control:focus,
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
input[type="number"]:focus,
|
||||
[type="text"].form-control:focus,
|
||||
[type="password"].form-control:focus,
|
||||
[type="email"].form-control:focus,
|
||||
[type="tel"].form-control:focus,
|
||||
[contenteditable].form-control:focus {
|
||||
outline: 0 !important;
|
||||
}
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
.form-check-label::before,
|
||||
.form-check-label::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.form-check-label {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
input[type="radio"] + .form-check-label::before,
|
||||
input[type="radio"] + .form-check-label::after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.form-check-label::before {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
top: 3px;
|
||||
padding-right: 2px;
|
||||
border: 2px inset #d5d5d5;
|
||||
background: white;
|
||||
box-shadow: -1px -1px 0 0 #828282;
|
||||
}
|
||||
input[type="radio"] + .form-check-label::after {
|
||||
display: none;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin: 6px;
|
||||
top: 3px;
|
||||
background: black;
|
||||
}
|
||||
input[type="checkbox"] + .form-check-label::after {
|
||||
display: none;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23000' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 4px;
|
||||
top: 3px;
|
||||
}
|
||||
input:checked + .form-check-label::after {
|
||||
display: block;
|
||||
}
|
||||
/*
|
||||
|
||||
Progress bar
|
||||
|
||||
*/
|
||||
.progress {
|
||||
height: 1rem;
|
||||
overflow: hidden;
|
||||
font-size: 0.75rem;
|
||||
background-color: silver;
|
||||
border-radius: 0rem;
|
||||
border: 1px inset #d5d5d5;
|
||||
color: #424242;
|
||||
}
|
||||
.progress-bar {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #1a0094;
|
||||
transition: width 0.6s ease;
|
||||
}
|
||||
.progress-bar-blocks {
|
||||
background-image: linear-gradient(90deg, transparent 75%, #d5d5d5 25%);
|
||||
background-size: 1rem 1rem;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
TABS
|
||||
|
||||
*/
|
||||
.tab-content {
|
||||
background: silver;
|
||||
border: solid;
|
||||
border-width: 2px;
|
||||
border-bottom-color: #424242;
|
||||
border-right-color: #424242;
|
||||
border-left-color: #fff;
|
||||
border-top-color: silver;
|
||||
padding: 1rem 1.4rem;
|
||||
}
|
||||
.nav-tabs {
|
||||
border-bottom: 2px solid white;
|
||||
}
|
||||
.nav-tabs .nav-item {
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
background: #c0c0c0;
|
||||
color: black;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-right: 1px solid #5a5a5a;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link {
|
||||
color: black;
|
||||
padding: 0.2rem 1.8rem;
|
||||
box-sizing: border-box;
|
||||
transform: none;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active {
|
||||
position: relative;
|
||||
background: #c0c0c0;
|
||||
}
|
||||
.nav-tabs .nav-item:not(:first-child) .nav-link.active {
|
||||
border-left: 1px solid #5a5a5a;
|
||||
}
|
||||
.nav-tabs .nav-item:first-child {
|
||||
border-left: 2px solid white;
|
||||
}
|
||||
.nav-tabs .nav-item .nav-link.active:after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -2px;
|
||||
background: #c0c0c0;
|
||||
}
|
||||
.nav-tabs .nav-link {
|
||||
border: 0;
|
||||
padding: 1rem 1rem;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
MODAL
|
||||
TODO: make it draggable;
|
||||
|
||||
*/
|
||||
.modal-content {
|
||||
box-shadow: 1px 1px 0 0 #424242;
|
||||
border: 1px solid #fff;
|
||||
border-right-color: #848484;
|
||||
border-bottom-color: #848484;
|
||||
background: silver;
|
||||
padding: 2px;
|
||||
}
|
||||
.modal-header {
|
||||
height: 32px;
|
||||
background: -webkit-linear-gradient(left, #08216b, #a5cef7) !important;
|
||||
color: white;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
.modal-header .btn {
|
||||
margin-top: 5px;
|
||||
padding-bottom: 10px;
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
.modal-header .btn span {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 14px;
|
||||
}
|
||||
.modal-title {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
.modal-footer {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
TABLES
|
||||
|
||||
*/
|
||||
.table {
|
||||
background: white;
|
||||
border-color: #c0c0c0;
|
||||
}
|
||||
.table-bordered {
|
||||
border: 1px solid #c0c0c0;
|
||||
}
|
||||
.table-bordered td,
|
||||
.table-bordered th {
|
||||
border: 1px solid #c0c0c0;
|
||||
}
|
||||
.table td,
|
||||
.table th {
|
||||
padding: 0.75rem;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid #c0c0c0;
|
||||
}
|
||||
277
win95-main.lua
Normal file
@@ -0,0 +1,277 @@
|
||||
-- get raja state
|
||||
local game = require("main_state")
|
||||
local timer_util = require("timer_util")
|
||||
|
||||
local judgeY = 992
|
||||
local judgeX = 30
|
||||
local judgeOffset = 40
|
||||
local judgeFontHeight = 36
|
||||
|
||||
local grooveX = 660
|
||||
local grooveY = 650
|
||||
|
||||
local speechBubbleX = 1600
|
||||
local speechBubbleY = 374
|
||||
local speechBubbleFontHeight = 30
|
||||
|
||||
local jacketWindowY = 200
|
||||
local jacketWindowX = 1000
|
||||
|
||||
|
||||
function Append(list, t)
|
||||
if t then
|
||||
for i, v in pairs(t) do
|
||||
table.insert(list, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function getDiff(op)
|
||||
local diff = tonumber(game.number(op))
|
||||
if diff < 0 then
|
||||
return diff
|
||||
end
|
||||
return "+" .. diff
|
||||
end
|
||||
|
||||
-- thanks mr mary
|
||||
local function getClearType()
|
||||
local cleartype = {
|
||||
[0] = "PASSED",
|
||||
[1] = "FAILED",
|
||||
[2] = "A-CLEAR",
|
||||
[3] = "LA-CLEAR",
|
||||
[4] = "EASY CLEAR",
|
||||
[5] = "CLEAR",
|
||||
[6] = "HARD CLEAR",
|
||||
[7] = "EXH CLEAR",
|
||||
[8] = "FC",
|
||||
[9] = "PERFECT",
|
||||
[10] = "MAX"
|
||||
}
|
||||
-- clear id
|
||||
return cleartype[game.number(370)]
|
||||
end
|
||||
|
||||
local function isBestClear()
|
||||
-- target clear < current clear
|
||||
if game.number(371) < game.number(370) then
|
||||
return "(BEST)"
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
-- thanks mr mary
|
||||
local function getRank()
|
||||
local rank = {
|
||||
[1] = "AAA",
|
||||
[2] = "AA",
|
||||
[3] = "A",
|
||||
[4] = "B",
|
||||
[5] = "C",
|
||||
[6] = "D",
|
||||
[7] = "E",
|
||||
[8] = "F"
|
||||
}
|
||||
local gradeOptionIdx = 0
|
||||
repeat
|
||||
gradeOptionIdx = gradeOptionIdx + 1
|
||||
until game.option(299 + gradeOptionIdx)
|
||||
return rank[gradeOptionIdx]
|
||||
end
|
||||
|
||||
local function isBestRank()
|
||||
local nowRank = 0
|
||||
local bestRank = 0
|
||||
repeat
|
||||
nowRank = nowRank + 1
|
||||
until game.option(299 + nowRank)
|
||||
repeat
|
||||
bestRank = bestRank + 1
|
||||
until game.option(319 + bestRank)
|
||||
|
||||
-- counter-intuitive, but AAA is 0, and F is 8
|
||||
-- so whichever stops earlier is win
|
||||
if bestRank > nowRank then
|
||||
return "(BEST)"
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function getIrRank()
|
||||
return game.number(179)
|
||||
end
|
||||
|
||||
local function getIrTotal()
|
||||
return game.number(180)
|
||||
end
|
||||
|
||||
local function constructIrRankDisplay()
|
||||
return game.text(1020) .. ": " .. getIrRank() .. " / " .. getIrTotal()
|
||||
end
|
||||
|
||||
local header = {
|
||||
-- type = result
|
||||
type = 7,
|
||||
name = "win95 result",
|
||||
-- skin size
|
||||
w = 1920,
|
||||
h = 1080,
|
||||
-- scene timer
|
||||
scene = 3600000,
|
||||
-- time until inputs are active
|
||||
input = 500,
|
||||
-- time it takes to fade out
|
||||
fadeout = 100,
|
||||
|
||||
-- me :D
|
||||
author = "boons",
|
||||
|
||||
-- config options
|
||||
filepath = {
|
||||
{ name = "CLEAR", path = "customize/bg/clear/*.png", def = "_Default.png", category = "CLEAR" },
|
||||
{ name = "FAIL", path = "customize/bg/fail/*.png", def = "BSOD.png", category = "FAIL" },
|
||||
{ name = "CLIPPY", path = "customize/clippy/*.png", def = "Clippy.png", category = "CLIPPY" }
|
||||
},
|
||||
category = {
|
||||
{
|
||||
name = "RESULT BG",
|
||||
item =
|
||||
{
|
||||
"CLEAR",
|
||||
"FAIL"
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "CLIPPY",
|
||||
item =
|
||||
{
|
||||
"CLIPPY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local function main()
|
||||
local skin = {}
|
||||
|
||||
-- add header properties into skin
|
||||
for k, v in pairs(header) do
|
||||
skin[k] = v
|
||||
end
|
||||
|
||||
-- tell raja where to look for assets
|
||||
skin.source = {
|
||||
{ id = 0, path = "customize/bg/fail/*.png" },
|
||||
{ id = 1, path = "customize/bg/clear/*.png" },
|
||||
{ id = 2, path = "asset/song-data.png" },
|
||||
{ id = 3, path = "asset/groove-gauge.png" },
|
||||
{ id = 4, path = "asset/clippy-bubble.png" },
|
||||
{ id = 5, path = "customize/clippy/*.png" },
|
||||
{ id = 6, path = "asset/jacket.png" },
|
||||
{ id = 7, path = "asset/taskbar.png" },
|
||||
{ id = 8, path = "asset/time-container.png" }
|
||||
-- todo: taskbar items
|
||||
}
|
||||
|
||||
skin.font = {
|
||||
{ id = 0, path = "font/SarasaMonoCL-Regular.ttf" }, -- CJK monospace
|
||||
{ id = 1, path = "font/Windows_Regular.ttf" } -- clippy speech
|
||||
}
|
||||
|
||||
skin.image = {
|
||||
{ id = "bg_clear", src = 1, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "bg_failed", src = 0, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "bg_song", src = 2, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "bg_groove", src = 3, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "clippy_speechbubble", src = 4, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "clippy_character", src = 5, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "jacket_window", src = 6, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "taskbar", src = 7, x = 0, y = 0, w = -1, h = -1 },
|
||||
{ id = "taskbar_time", src = 8, x = 0, y = 0, w = -1, h = -1 }
|
||||
}
|
||||
|
||||
skin.text = {
|
||||
{ id = "text_groove_title", font = 0, size = 40, align = 0, overflow = 1, constantText = "GAUGE: " .. game.number(107) .. "." .. game.number(407) .. "%" }, -- gauge
|
||||
{ id = "text_title", font = 0, size = 40, align = 0, overflow = 2, ref = 12 }, -- shrink
|
||||
{ id = "text_level", font = 0, size = 40, align = 0, overflow = 1, ref = 1002 },
|
||||
{ id = "pgreat", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "PERFECT: " .. game.number(110) },
|
||||
{ id = "great", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "GREAT : " .. game.number(111) },
|
||||
{ id = "good", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "GOOD : " .. game.number(112) },
|
||||
{ id = "bad", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "BAD : " .. game.number(113) },
|
||||
{ id = "poor", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "POOR : " .. game.number(114) },
|
||||
{ id = "expoor", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "EXPOOR : " .. game.number(420) },
|
||||
{ id = "exscore", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "SCORE : " .. game.number(171) },
|
||||
{ id = "exscore_diff", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "BEST : " .. getDiff(172) },
|
||||
{ id = "exscore_diff_target", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "TARGET : " .. getDiff(153) },
|
||||
-- judge rank
|
||||
{ id = "total_fast", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "FAST : " .. game.number(423) },
|
||||
{ id = "total_slow", font = 0, size = judgeFontHeight, align = 0, overflow = 1, constantText = "SLOW : " .. game.number(424) },
|
||||
-- clippy
|
||||
{ id = "clippy_rank", font = 1, size = 60, align = 0, overflow = 1, constantText = getRank() },
|
||||
{ id = "clippy_rank_best", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = isBestRank() },
|
||||
{ id = "clippy_clear_type", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = getClearType() },
|
||||
{ id = "clippy_clear_type_best", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = isBestClear() },
|
||||
{ id = "clippy_rate", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = "RATE: " .. game.number(155) .. "." .. game.number(156) .. "%" },
|
||||
-- ir
|
||||
{
|
||||
id = "clippy_ir_rank",
|
||||
font = 1,
|
||||
size = speechBubbleFontHeight,
|
||||
align = 0,
|
||||
overflow = 1,
|
||||
value = constructIrRankDisplay
|
||||
},
|
||||
{ id = "clippy_ir_unavailable", font = 1, size = speechBubbleFontHeight, align = 0, overflow = 1, constantText = "IR OFFLINE (^^);" },
|
||||
--jacket
|
||||
{ id = "text_jacket_title", font = 0, size = 40, align = 0, overflow = 1, constantText = "JACKET" },
|
||||
{ id = "jacket_no_jacket", font = 0, size = 52, align = 1, overflow = 1, constantText = "NO JACKET (^^);" },
|
||||
-- task bar
|
||||
{ id = "taskbar_time_text", font = 1, size = 40, align = 0, overflow = 1, constantText = os.date("%c") }
|
||||
}
|
||||
|
||||
-- gauge graph
|
||||
skin.gaugegraph = {
|
||||
{ id = "gauge_line", assistClearLineColor = "FF00FF00", assistAndEasyFailLineColor = "00ff0000", grooveFailLineColor = "00ffff00", grooveClearAndHardLineColor = "ff000000", exHardLineColor = "ffff0000", hazardLineColor = "cccccc00", borderlineColor = "ff000000" },
|
||||
{ id = "gauge_bg", assistClearBGColor = "ff00ff00", assistAndEasyFailBGColor = "00ff0000", grooveFailBGColor = "00ffff00", grooveClearAndHardBGColor = "ff000000", exHardBGColor = "ffff0000", hazardBGColor = "44444400", borderColor = "eeeeee00" },
|
||||
}
|
||||
|
||||
-- put it all to use
|
||||
skin.destination = {
|
||||
{
|
||||
id = "bg_clear",
|
||||
op = { 90 }, -- cleared
|
||||
dst = {
|
||||
{ x = 0, y = 0, w = 1920, h = 1080, a = 255, filter = 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "bg_failed",
|
||||
op = { 91 }, -- failed
|
||||
dst = {
|
||||
{ x = 0, y = 0, w = 1920, h = 1080, a = 255, filter = 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local songdata = require("dst.songdata")
|
||||
local clippy = require("dst.clippy")
|
||||
local gauge = require("dst.gauge")
|
||||
local jacket = require("dst.jacket")
|
||||
local taskbar = require("dst.taskbar")
|
||||
|
||||
Append(skin.destination, songdata.getSongData(judgeX, judgeY, judgeFontHeight, judgeOffset))
|
||||
Append(skin.destination, clippy.getClippy(speechBubbleX, speechBubbleY, speechBubbleFontHeight))
|
||||
Append(skin.destination, gauge.getGauge(grooveX, grooveY))
|
||||
Append(skin.destination, jacket.getJacket(jacketWindowX, jacketWindowY))
|
||||
Append(skin.destination, taskbar.getTaskbar())
|
||||
|
||||
return skin
|
||||
end
|
||||
|
||||
return {
|
||||
header = header,
|
||||
main = main
|
||||
}
|
||||