commit aca5cd42f1165771f76c7543952281bae70e1f00 Author: boonsboos Date: Mon Sep 8 22:59:59 2025 +0200 bup diff --git a/asset/clippy-bubble.png b/asset/clippy-bubble.png new file mode 100644 index 0000000..7b492f2 Binary files /dev/null and b/asset/clippy-bubble.png differ diff --git a/asset/groove-gauge.png b/asset/groove-gauge.png new file mode 100644 index 0000000..4a73d84 Binary files /dev/null and b/asset/groove-gauge.png differ diff --git a/asset/jacket.png b/asset/jacket.png new file mode 100644 index 0000000..6696b18 Binary files /dev/null and b/asset/jacket.png differ diff --git a/asset/song-data.png b/asset/song-data.png new file mode 100644 index 0000000..6cfa429 Binary files /dev/null and b/asset/song-data.png differ diff --git a/asset/taskbar.png b/asset/taskbar.png new file mode 100644 index 0000000..f4ca890 Binary files /dev/null and b/asset/taskbar.png differ diff --git a/asset/time-container.png b/asset/time-container.png new file mode 100644 index 0000000..f5d21d2 Binary files /dev/null and b/asset/time-container.png differ diff --git a/asset/window.png b/asset/window.png new file mode 100644 index 0000000..c2bf278 Binary files /dev/null and b/asset/window.png differ diff --git a/customize/bg/clear/Clouds.png b/customize/bg/clear/Clouds.png new file mode 100644 index 0000000..b8eb3b3 Binary files /dev/null and b/customize/bg/clear/Clouds.png differ diff --git a/customize/bg/clear/Gold_Weave.png b/customize/bg/clear/Gold_Weave.png new file mode 100644 index 0000000..75a70b6 Binary files /dev/null and b/customize/bg/clear/Gold_Weave.png differ diff --git a/customize/bg/clear/Red_Bricks.png b/customize/bg/clear/Red_Bricks.png new file mode 100644 index 0000000..1c4f4be Binary files /dev/null and b/customize/bg/clear/Red_Bricks.png differ diff --git a/customize/bg/clear/_Default.png b/customize/bg/clear/_Default.png new file mode 100644 index 0000000..86f6891 Binary files /dev/null and b/customize/bg/clear/_Default.png differ diff --git a/customize/bg/fail/bsod.png b/customize/bg/fail/bsod.png new file mode 100644 index 0000000..85a71df Binary files /dev/null and b/customize/bg/fail/bsod.png differ diff --git a/customize/clippy/320x320px-png.txt b/customize/clippy/320x320px-png.txt new file mode 100644 index 0000000..e69de29 diff --git a/customize/clippy/ASIO.png b/customize/clippy/ASIO.png new file mode 100644 index 0000000..ca0494e Binary files /dev/null and b/customize/clippy/ASIO.png differ diff --git a/customize/clippy/Bonzi.png b/customize/clippy/Bonzi.png new file mode 100644 index 0000000..1e0efd4 Binary files /dev/null and b/customize/clippy/Bonzi.png differ diff --git a/customize/clippy/Clipenger.png b/customize/clippy/Clipenger.png new file mode 100644 index 0000000..5337e95 Binary files /dev/null and b/customize/clippy/Clipenger.png differ diff --git a/customize/clippy/Clippy.png b/customize/clippy/Clippy.png new file mode 100644 index 0000000..4727bcd Binary files /dev/null and b/customize/clippy/Clippy.png differ diff --git a/customize/clippy/Penger.png b/customize/clippy/Penger.png new file mode 100644 index 0000000..0793e3e Binary files /dev/null and b/customize/clippy/Penger.png differ diff --git a/dst/clippy.lua b/dst/clippy.lua new file mode 100644 index 0000000..6f9a30f --- /dev/null +++ b/dst/clippy.lua @@ -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 +} diff --git a/dst/gauge.lua b/dst/gauge.lua new file mode 100644 index 0000000..63e3f0d --- /dev/null +++ b/dst/gauge.lua @@ -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 +} diff --git a/dst/jacket.lua b/dst/jacket.lua new file mode 100644 index 0000000..9a72d0b --- /dev/null +++ b/dst/jacket.lua @@ -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 +} diff --git a/dst/songdata.lua b/dst/songdata.lua new file mode 100644 index 0000000..dcaeccc --- /dev/null +++ b/dst/songdata.lua @@ -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 +} diff --git a/dst/taskbar.lua b/dst/taskbar.lua new file mode 100644 index 0000000..c3cc085 --- /dev/null +++ b/dst/taskbar.lua @@ -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 +} diff --git a/font/SarasaMonoCL-Regular.ttf b/font/SarasaMonoCL-Regular.ttf new file mode 100644 index 0000000..10828ba Binary files /dev/null and b/font/SarasaMonoCL-Regular.ttf differ diff --git a/font/Windows_Regular.ttf b/font/Windows_Regular.ttf new file mode 100644 index 0000000..26abb3d Binary files /dev/null and b/font/Windows_Regular.ttf differ diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..71c8e73 --- /dev/null +++ b/readme.md @@ -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 diff --git a/result.luaskin b/result.luaskin new file mode 100644 index 0000000..8845f57 --- /dev/null +++ b/result.luaskin @@ -0,0 +1,6 @@ +local result_skin = require("win95-main") +if skin_config then + return result_skin.main() +else + return result_skin.header +end \ No newline at end of file diff --git a/util/index.html b/util/index.html new file mode 100644 index 0000000..6341ad4 --- /dev/null +++ b/util/index.html @@ -0,0 +1,45 @@ + + + + + + + Document + + + + +
+
+
+
+ + + + diff --git a/util/table-folder-icons.txt b/util/table-folder-icons.txt new file mode 100644 index 0000000..fdfb5f4 --- /dev/null +++ b/util/table-folder-icons.txt @@ -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 + +▽ +▼ +☆ +★ +◆ +◎ \ No newline at end of file diff --git a/util/tiles/Clouds_(Windows_95).png b/util/tiles/Clouds_(Windows_95).png new file mode 100644 index 0000000..d5e058e Binary files /dev/null and b/util/tiles/Clouds_(Windows_95).png differ diff --git a/util/tiles/Gold_Weave.png b/util/tiles/Gold_Weave.png new file mode 100644 index 0000000..f949153 Binary files /dev/null and b/util/tiles/Gold_Weave.png differ diff --git a/util/tiles/Red_Blocks.png b/util/tiles/Red_Blocks.png new file mode 100644 index 0000000..0dfb87f Binary files /dev/null and b/util/tiles/Red_Blocks.png differ diff --git a/util/tiles/Stitches.png b/util/tiles/Stitches.png new file mode 100644 index 0000000..1c93f1f Binary files /dev/null and b/util/tiles/Stitches.png differ diff --git a/util/tiles/i.txt b/util/tiles/i.txt new file mode 100644 index 0000000..9a52afc --- /dev/null +++ b/util/tiles/i.txt @@ -0,0 +1 @@ +from https://windowswallpaper.miraheze.org/wiki/Windows_95 \ No newline at end of file diff --git a/util/win95.css b/util/win95.css new file mode 100644 index 0000000..686e749 --- /dev/null +++ b/util/win95.css @@ -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; +} diff --git a/win95-main.lua b/win95-main.lua new file mode 100644 index 0000000..d41f62a --- /dev/null +++ b/win95-main.lua @@ -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 +}