mirror of
https://github.com/themitosan/fpPS4-Temmie-s-Launcher.git
synced 2024-06-23 14:43:17 -04:00
Push project files
This commit is contained in:
parent
ae65a19fc0
commit
6f610687c2
188
App/css/style.css
Normal file
188
App/css/style.css
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
Styles.css
|
||||||
|
*/
|
||||||
|
html, body {
|
||||||
|
color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
font-family: monospace;
|
||||||
|
background-color: #000;
|
||||||
|
text-shadow: 2px 2px 4px #000;
|
||||||
|
}
|
||||||
|
input[type='button'], input[type='checkbox'] {
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
input[disabled="disabled"], input[disabled] {
|
||||||
|
cursor: no-drop;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 6px 0px 6px 0px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #e7e7e7;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:active {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Divs
|
||||||
|
*/
|
||||||
|
.DIV_LIST {
|
||||||
|
top: 38px;
|
||||||
|
left: 0px;
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% - 280px);
|
||||||
|
height: calc(100% - 286px);
|
||||||
|
background-image: linear-gradient(146deg, #090f1b, #162a50);
|
||||||
|
}
|
||||||
|
.DIV_LOG {
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 248px;
|
||||||
|
position: absolute;
|
||||||
|
background-size: auto 50%;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-image: url('../img/logo.png');
|
||||||
|
}
|
||||||
|
.DIV_ACTIONS {
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 22px;
|
||||||
|
padding: 8px;
|
||||||
|
position: absolute;
|
||||||
|
background-image: linear-gradient(45deg, #28467f, #1c325f);
|
||||||
|
}
|
||||||
|
.DIV_OPTIONS {
|
||||||
|
top: 38px;
|
||||||
|
right: 0px;
|
||||||
|
padding: 6px;
|
||||||
|
width: 268px;
|
||||||
|
position: absolute;
|
||||||
|
height: calc(100% - 298px);
|
||||||
|
background-image: linear-gradient(0deg, #162a50, #2a4a86);
|
||||||
|
}
|
||||||
|
.DIV_TITLE {
|
||||||
|
font-size: 28px;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.DIV_LIST_INTERNAL {
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
transition: 0.4s;
|
||||||
|
position: absolute;
|
||||||
|
background-size: cover;
|
||||||
|
background-color: #0000;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
.GAME_ENTRY {
|
||||||
|
margin: 6px;
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 92px;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
border-radius: 6px;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
width: calc(100% - 12px);
|
||||||
|
backdrop-filter: blur(4px) invert(0.1);
|
||||||
|
background-image: linear-gradient(90deg, #3a4b6b82, #0000);
|
||||||
|
}
|
||||||
|
.GAME_ENTRY:hover {
|
||||||
|
box-shadow: 0px 0px 10px #0006;
|
||||||
|
background-image: linear-gradient(90deg, #3a4b6b82, #3a4b6b82);
|
||||||
|
}
|
||||||
|
.GAME_ENTRY:active {
|
||||||
|
box-shadow: 0px 0px 10px #0006 inset;
|
||||||
|
backdrop-filter: invert(0.68) blur(6px);
|
||||||
|
}
|
||||||
|
.GAME_DETAILS {
|
||||||
|
cursor: pointer;
|
||||||
|
width: calc(100% - 88px);
|
||||||
|
}
|
||||||
|
.DIV_RUN_BTN {
|
||||||
|
bottom: 4px;
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% - 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Images
|
||||||
|
*/
|
||||||
|
.GAME_ICON {
|
||||||
|
width: 66px;
|
||||||
|
margin: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input
|
||||||
|
*/
|
||||||
|
.APP_LOG {
|
||||||
|
color: #0f0;
|
||||||
|
height: 100%;
|
||||||
|
resize: none;
|
||||||
|
border: none;
|
||||||
|
cursor: text;
|
||||||
|
outline: none;
|
||||||
|
width: calc(100% - 4px);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
text-shadow: 2px 2px 2px #000;
|
||||||
|
background-image: linear-gradient(180deg, #000000db, #090f1b);
|
||||||
|
}
|
||||||
|
.BTN_RUN {
|
||||||
|
left: 8px;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 18px;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Labels
|
||||||
|
*/
|
||||||
|
.LABEL_checkbox {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.LABEL_emuColor {
|
||||||
|
color: #fffb8e;
|
||||||
|
}
|
||||||
|
.LABEL_gameTtitle {
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Misc
|
||||||
|
*/
|
||||||
|
.none {
|
||||||
|
display: none;
|
||||||
|
}
|
BIN
App/img/404.png
Normal file
BIN
App/img/404.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
BIN
App/img/404_BG.png
Normal file
BIN
App/img/404_BG.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
App/img/logo.png
Normal file
BIN
App/img/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
70
App/index.htm
Normal file
70
App/index.htm
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>fpPS4 Temmie's Launcher</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Top Menu -->
|
||||||
|
<div class="DIV_ACTIONS">
|
||||||
|
|
||||||
|
<input type="button" class="APP_btn" onclick="APP.gameList.selectPath();" value="Select game path">
|
||||||
|
<input type="button" class="APP_btn" onclick="APP.gameList.openFolder();" value="Open game folder">
|
||||||
|
<input type="button" class="APP_btn" onclick="APP.gameList.load();" value="Refresh game list">
|
||||||
|
<input type="button" class="APP_btn" onclick="APP.about();" value="About">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- fpPS4 Options -->
|
||||||
|
<div class="DIV_OPTIONS" id="DIV_OPTIONS">
|
||||||
|
|
||||||
|
<div class="DIV_TITLE"><label class="LABEL_emuColor">fp</label>PS4 Options</div>
|
||||||
|
|
||||||
|
<div id="DIV_HACK_LIST">
|
||||||
|
<!-- Hacks goes here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Run fpPS4 -->
|
||||||
|
<div class="DIV_RUN_BTN">
|
||||||
|
<input type="button" class="BTN_RUN" id="BTN_KILL" onclick="APP.emuManager.killEmu();" disabled="disabled" value="Stop fpPS4">
|
||||||
|
<input type="button" class="BTN_RUN" id="BTN_RUN" onclick="APP.emuManager.runGame();" disabled="disabled" value="Run fpPS4">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Game List -->
|
||||||
|
<div class="DIV_LIST" id="DIV_LIST">
|
||||||
|
<div class="DIV_LIST_INTERNAL" id="DIV_LIST_INTERNAL">
|
||||||
|
<!-- Games goes here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Log -->
|
||||||
|
<div class="DIV_LOG" id="DIV_LOG">
|
||||||
|
<textarea class="APP_LOG" id="APP_LOG" disabled="disabled"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hidden Stuff -->
|
||||||
|
<div class="none">
|
||||||
|
|
||||||
|
<!-- Folder loader -->
|
||||||
|
<input type="file" id="APP_FOLDER_LOADER" nwdirectory/>
|
||||||
|
|
||||||
|
<!-- Scripts -->
|
||||||
|
<script type="text/javascript" src="js/TMS.js"></script>
|
||||||
|
<script type="text/javascript" src="js/filemanager.js"></script>
|
||||||
|
<script type="text/javascript" src="js/gamelist.js"></script>
|
||||||
|
<script type="text/javascript" src="js/settings.js"></script>
|
||||||
|
<script type="text/javascript" src="js/design.js"></script>
|
||||||
|
<script type="text/javascript" src="js/emumanager.js"></script>
|
||||||
|
<script type="text/javascript" src="js/main.js"></script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
308
App/js/TMS.js
Normal file
308
App/js/TMS.js
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
*******************************************************************************
|
||||||
|
TMS.js - By @TheMitoSan
|
||||||
|
|
||||||
|
This file is an original replacement - Because I don't want to deal with jQuery
|
||||||
|
anymore!
|
||||||
|
|
||||||
|
Original source / motivation: http://youmightnotneedjquery.com/
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
tmsTemp = {};
|
||||||
|
tmsTemp['logWarnings'] = false;
|
||||||
|
/*
|
||||||
|
Warn if something goes wrong
|
||||||
|
*/
|
||||||
|
tmsTemp['warn'] = function(warnText){
|
||||||
|
if (TMS.logWarnings === true){
|
||||||
|
console.warn(warnText);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
CSS
|
||||||
|
*/
|
||||||
|
tmsTemp['css'] = function(elementId, cssChanges){
|
||||||
|
var canStart = true, eReason = '';
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId === null){
|
||||||
|
canStart = false;
|
||||||
|
eReason = eReason + '\nDOM does not exist! (' + elementId + ')';
|
||||||
|
};
|
||||||
|
if (typeof cssChanges !== 'object'){
|
||||||
|
canStart = false;
|
||||||
|
eReason = eReason + '\nYou must insert an object for CSS data (Current type: ' + typeof cssChanges + ')';
|
||||||
|
};
|
||||||
|
// End
|
||||||
|
if (canStart === true){
|
||||||
|
Object.keys(cssChanges).forEach(function(cItem){
|
||||||
|
elId.style[cItem] = cssChanges[cItem];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to apply CSS data!' + eReason);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Animate
|
||||||
|
|
||||||
|
elementId = HTML DOM id
|
||||||
|
cssChanges = Object {width: x, height, y}
|
||||||
|
animationTime = Number (Min: 0)
|
||||||
|
animationEase = CSS for transition option, like cubic-bezier
|
||||||
|
*/
|
||||||
|
tmsTemp['animate'] = function(elementId, cssChanges, animationTime, animationEase){
|
||||||
|
var canStart = true, eReason = transitionString = '';
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId === null){
|
||||||
|
canStart = false;
|
||||||
|
eReason = eReason + '\nDOM does not exist! (' + elementId + ')';
|
||||||
|
}
|
||||||
|
if (typeof cssChanges !== 'object'){
|
||||||
|
canStart = false;
|
||||||
|
eReason = eReason + '\nYou must insert an object for CSS data (Current type: ' + typeof cssChanges + ')';
|
||||||
|
}
|
||||||
|
if (typeof animationTime !== 'number'){
|
||||||
|
canStart = false;
|
||||||
|
eReason = eReason + '\nYou must insert a number on animation time (Current type: ' + typeof animationTime + ')';
|
||||||
|
}
|
||||||
|
// End
|
||||||
|
if (canStart === true){
|
||||||
|
if (animationEase === undefined){
|
||||||
|
animationEase = '';
|
||||||
|
}
|
||||||
|
if (animationTime < 0){
|
||||||
|
animationTime = 0;
|
||||||
|
}
|
||||||
|
Object.keys(cssChanges).forEach(function(cItem){
|
||||||
|
elId.style[cItem] = cssChanges[cItem];
|
||||||
|
transitionString = transitionString + cItem + ' ' + (animationTime / 1000) + 's ';
|
||||||
|
elId.style['transition'] = transitionString + animationEase;
|
||||||
|
});
|
||||||
|
setTimeout(function(){
|
||||||
|
elId.style['transition'] = 'none 0s';
|
||||||
|
}, (animationTime + 1));
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to animate!' + eReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Focus Element
|
||||||
|
sTimeout = time [ms]
|
||||||
|
*/
|
||||||
|
tmsTemp['focus'] = function(elementId, sTimeout){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
if (sTimeout !== undefined && parseInt(sTimeout) !== NaN){
|
||||||
|
setTimeout(function(){
|
||||||
|
elId.focus();
|
||||||
|
}, sTimeout);
|
||||||
|
} else {
|
||||||
|
elId.focus();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to focus element because it does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Disable Element
|
||||||
|
*/
|
||||||
|
tmsTemp['disableElement'] = function(idList){
|
||||||
|
var disableList = [];
|
||||||
|
if (typeof idList === 'object'){
|
||||||
|
disableList = idList;
|
||||||
|
} else {
|
||||||
|
disableList.push(idList);
|
||||||
|
};
|
||||||
|
// End
|
||||||
|
disableList.forEach(function(cItem){
|
||||||
|
const elId = document.getElementById(cItem);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.disabled = 'disabled';
|
||||||
|
// If is <input>
|
||||||
|
if (elId.type === 'button'){
|
||||||
|
TMS.css(cItem, {'filter': 'grayscale(1) blur(0.8px)', 'cursor': 'not-allowed', 'opacity': '0.6'});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to disable element because it does not exist! (' + cItem + ')');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Enable Element
|
||||||
|
*/
|
||||||
|
tmsTemp['enableElement'] = function(elementId){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.disabled = '';
|
||||||
|
// If is <input>
|
||||||
|
if (elId.type === 'button'){
|
||||||
|
TMS.css(elementId, {'filter': 'grayscale(0) blur(0px)', 'cursor': 'pointer', 'opacity': '1'});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to enable element because it does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Get CSS data
|
||||||
|
Returns the attr value from CSS propriety
|
||||||
|
*/
|
||||||
|
tmsTemp['getCssData'] = function(elementId, cssAttrName){
|
||||||
|
var elId = document.getElementById(elementId),
|
||||||
|
result = '';
|
||||||
|
if (elId !== null){
|
||||||
|
result = elId.style[cssAttrName];
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to get element because it does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Scroll top
|
||||||
|
Usage: elementObjects = {HTML_DOM_ID_0: scrollInt, HTML_DOM_ID_1: scrollInt2} and goes on
|
||||||
|
*/
|
||||||
|
tmsTemp['scrollTop'] = function(elementObjects){
|
||||||
|
Object.keys(elementObjects).forEach(function(cItem){
|
||||||
|
const elId = document.getElementById(cItem);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.scrollTop = elementObjects[cItem];
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to scroll element because it does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Append data
|
||||||
|
*/
|
||||||
|
tmsTemp['append'] = function(elementId, newData){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
var pHTML = elId.innerHTML;
|
||||||
|
elId.innerHTML = pHTML + newData;
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to append element data because parent DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Add Class
|
||||||
|
*/
|
||||||
|
tmsTemp['addClass'] = function(elementId, className){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.classList.add(className);
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to add class because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Add Class
|
||||||
|
*/
|
||||||
|
tmsTemp['removeClass'] = function(elementId, className){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.classList.remove(className);
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to remove class because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Clear
|
||||||
|
Removes all HTML inside
|
||||||
|
*/
|
||||||
|
tmsTemp['clear'] = function(elementId){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.innerHTML = '';
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to clear inner data because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
triggerClick
|
||||||
|
*/
|
||||||
|
tmsTemp['triggerClick'] = function(elementId){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
elId.click();
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to clear inner data because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
fadeIn
|
||||||
|
*/
|
||||||
|
tmsTemp['fadeIn'] = function(elementId, animationTime){
|
||||||
|
const elId = document.getElementById(elementId), tagType = {
|
||||||
|
'DIV': 'block',
|
||||||
|
'IMG': 'inline'
|
||||||
|
};
|
||||||
|
if (elId !== null){
|
||||||
|
var dTime = 1000, dMode = 'block', finalOpacity = 1, eStyles = getComputedStyle(elId);
|
||||||
|
if (animationTime !== undefined && animationTime !== NaN){
|
||||||
|
dTime = parseInt(animationTime);
|
||||||
|
if (dTime < 0){
|
||||||
|
dTime = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (tagType[elId.tagType] !== undefined){
|
||||||
|
dMode = tagType[elId.tagType];
|
||||||
|
};
|
||||||
|
if (eStyles.opacity !== ''){
|
||||||
|
finalOpacity = eStyles.opacity;
|
||||||
|
};
|
||||||
|
TMS.css(elementId, {'display': dMode, 'opacity': finalOpacity, 'transition': 'opacity ' + dTime + 'ms'});
|
||||||
|
setTimeout(function(){
|
||||||
|
TMS.css(elementId, {'transition': 'none'});
|
||||||
|
}, (dTime + 1));
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to fade in because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
fadeOut
|
||||||
|
*/
|
||||||
|
tmsTemp['fadeOut'] = function(elementId, animationTime){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
var dTime = 1000;
|
||||||
|
if (animationTime !== undefined && animationTime !== NaN){
|
||||||
|
dTime = parseInt(animationTime);
|
||||||
|
if (dTime < 0){
|
||||||
|
dTime = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
TMS.css(elementId, {'opacity': '0', 'transition': 'opacity ' + dTime + 'ms'});
|
||||||
|
setTimeout(function(){
|
||||||
|
TMS.css(elementId, {'transition': 'none', 'display': 'none'});
|
||||||
|
}, (dTime + 1));
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to fade out because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
scrollCenter
|
||||||
|
*/
|
||||||
|
tmsTemp['scrollCenter'] = function(elementId){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
var parentDom = elId.parentElement,
|
||||||
|
parentHeight = parentDom.offsetHeight;
|
||||||
|
parentDom.scrollTo(0, (elId.offsetTop - (parentHeight / 2)))
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to fade out because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
setInnerHtml
|
||||||
|
*/
|
||||||
|
tmsTemp['setInnerHtml'] = function(elementId, htmlData){
|
||||||
|
const elId = document.getElementById(elementId);
|
||||||
|
if (elId !== null){
|
||||||
|
document.getElementById(elementId).innerHTML = htmlData;
|
||||||
|
} else {
|
||||||
|
TMS.warn('TMS - Unable to set innerHTML because DOM does not exist! (' + elementId + ')');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
END
|
||||||
|
*/
|
||||||
|
const TMS = tmsTemp;
|
||||||
|
delete(tmsTemp);
|
123
App/js/design.js
Normal file
123
App/js/design.js
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
design.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_DESIGN = {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Hack List
|
||||||
|
*/
|
||||||
|
hackList: [
|
||||||
|
'DEPTH_DISABLE_HACK',
|
||||||
|
'COMPUTE_DISABLE_HACK',
|
||||||
|
'MEMORY_BOUND_HACK',
|
||||||
|
'IMAGE_TEST_HACK',
|
||||||
|
'IMAGE_LOAD_HACK',
|
||||||
|
'DISABLE_SRGB_HACK'
|
||||||
|
],
|
||||||
|
|
||||||
|
// Process checkbox status
|
||||||
|
processCheckbox: function(domName){
|
||||||
|
|
||||||
|
var res = !1,
|
||||||
|
domId = document.getElementById(domName).checked;
|
||||||
|
|
||||||
|
if (domId === !1){
|
||||||
|
res = !0;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById(domName).checked = res;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Render hack list
|
||||||
|
renderHacklist: function(){
|
||||||
|
|
||||||
|
var htmlTemp = '';
|
||||||
|
|
||||||
|
this.hackList.forEach(function(hackName){
|
||||||
|
htmlTemp = htmlTemp + '<input type="checkbox" id="CHECK_' + hackName + '"><label class="LABEL_checkbox" onclick="APP.design.processCheckbox(\'CHECK_' + hackName +
|
||||||
|
'\');">Enable ' + hackName + '</label><br>';
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('DIV_HACK_LIST').innerHTML = htmlTemp;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Render game list
|
||||||
|
renderGameList: function(){
|
||||||
|
|
||||||
|
var gList = APP.gameList.list,
|
||||||
|
tempHtml = '';
|
||||||
|
|
||||||
|
Object.keys(gList).forEach(function(cGame){
|
||||||
|
tempHtml = tempHtml + '<div class="GAME_ENTRY" onclick="APP.design.selectGame(\'' + cGame + '\');"><img class="GAME_ICON" src="' +
|
||||||
|
gList[cGame].icon + '"><div class="GAME_DETAILS"><label class="LABEL_gameTtitle">' + gList[cGame].name +
|
||||||
|
'</label><br>' + 'Path: ' + gList[cGame].eboot + '</div></div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert HTML
|
||||||
|
document.getElementById('DIV_LIST_INTERNAL').innerHTML = tempHtml;
|
||||||
|
|
||||||
|
// Clear BG image
|
||||||
|
TMS.css('DIV_LIST_INTERNAL', {'background-image': 'none'});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Select game
|
||||||
|
selectGame: function(gameName){
|
||||||
|
|
||||||
|
if (APP.gameList.list[gameName] !== void 0){
|
||||||
|
|
||||||
|
const cGame = APP.gameList.list[gameName];
|
||||||
|
TMS.css('DIV_LIST_INTERNAL', {
|
||||||
|
'background-image': 'url("' + cGame.bg + '")'
|
||||||
|
});
|
||||||
|
|
||||||
|
APP.gameList.selectedGame = gameName;
|
||||||
|
APP.design.updateRunButtons();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Enable or Disable Run / Stop buttons
|
||||||
|
updateRunButtons: function(){
|
||||||
|
|
||||||
|
// Check if emu is present before allowing to run
|
||||||
|
if (APP.fs.existsSync(APP.settings.data.emuPath) === !0){
|
||||||
|
|
||||||
|
var btnRun = '',
|
||||||
|
logHeight = '248px',
|
||||||
|
btnKill = 'disabled',
|
||||||
|
hackDisplay = 'inline',
|
||||||
|
listHeight = 'calc(100% - 286px)',
|
||||||
|
optionsHeight = 'calc(100% - 298px)';
|
||||||
|
|
||||||
|
// If emu is running
|
||||||
|
if (APP.emuManager.emuRunning === !0){
|
||||||
|
|
||||||
|
btnKill = '';
|
||||||
|
btnRun = 'disabled';
|
||||||
|
listHeight = '172px';
|
||||||
|
hackDisplay = 'none';
|
||||||
|
optionsHeight = '160px';
|
||||||
|
logHeight = 'calc(100% - 210px)';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update GUI
|
||||||
|
TMS.css('DIV_LOG', {'height': logHeight});
|
||||||
|
TMS.css('DIV_LIST', {'height': listHeight});
|
||||||
|
TMS.css('DIV_OPTIONS', {'height': optionsHeight});
|
||||||
|
TMS.css('DIV_HACK_LIST', {'display': hackDisplay});
|
||||||
|
|
||||||
|
// Update Buttons
|
||||||
|
document.getElementById('BTN_RUN').disabled = btnRun;
|
||||||
|
document.getElementById('BTN_KILL').disabled = btnKill;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
App/js/emumanager.js
Normal file
51
App/js/emumanager.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
emumanager.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_EMUMANAGER = {
|
||||||
|
|
||||||
|
// Emulator is running
|
||||||
|
emuRunning: !1,
|
||||||
|
|
||||||
|
// Run emu
|
||||||
|
runGame: function(){
|
||||||
|
|
||||||
|
// If user selected a game
|
||||||
|
if (APP.gameList.list[APP.gameList.selectedGame] !== void 0){
|
||||||
|
|
||||||
|
// Set main variables
|
||||||
|
var ebootPath = APP.gameList.list[APP.gameList.selectedGame].eboot,
|
||||||
|
emuArgs = ['-e', ebootPath],
|
||||||
|
hList = APP.design.hackList;
|
||||||
|
|
||||||
|
// Get enabled hacks
|
||||||
|
hList.forEach(function(hackName){
|
||||||
|
if (document.getElementById('CHECK_' + hackName).checked === !0){
|
||||||
|
emuArgs.push('-h');
|
||||||
|
emuArgs.push(hackName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log emu args
|
||||||
|
APP.log('\nINFO - Running fpPS4 with args: ' + emuArgs.toString().replace(RegExp(',', 'gi'), ' ') + '\n\n');
|
||||||
|
|
||||||
|
// Run fpPS4
|
||||||
|
APP.runExec(APP.settings.data.emuPath, emuArgs);
|
||||||
|
this.emuRunning = !0;
|
||||||
|
|
||||||
|
// Update GUI
|
||||||
|
APP.design.updateRunButtons();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Kill emu process
|
||||||
|
killEmu: function(){
|
||||||
|
|
||||||
|
process.kill(APP.execProcess.pid);
|
||||||
|
this.emuRunning = !1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
App/js/filemanager.js
Normal file
30
App/js/filemanager.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
filemanager.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_FILEMANAGER = {
|
||||||
|
|
||||||
|
// Select path
|
||||||
|
selectPath: function(postAction){
|
||||||
|
|
||||||
|
if (postAction !== void 0){
|
||||||
|
|
||||||
|
document.getElementById('APP_FOLDER_LOADER').onchange = function(){
|
||||||
|
|
||||||
|
const cFile = document.getElementById('APP_FOLDER_LOADER').files[0];
|
||||||
|
|
||||||
|
if (cFile.path !== null && cFile.path !== void 0 && cFile.path !== ''){
|
||||||
|
postAction(cFile.path.replace(RegExp('\\\\', 'gi'), '/'));
|
||||||
|
document.getElementById('APP_FOLDER_LOADER').value = '';
|
||||||
|
document.getElementById('APP_FOLDER_LOADER').accept = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('APP_FOLDER_LOADER').click();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
125
App/js/gamelist.js
Normal file
125
App/js/gamelist.js
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
gamelist.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_GAMELIST = {
|
||||||
|
|
||||||
|
// Game List
|
||||||
|
list: {},
|
||||||
|
|
||||||
|
// Selected game
|
||||||
|
selectedGame: '',
|
||||||
|
|
||||||
|
// Select game path
|
||||||
|
selectPath: function(){
|
||||||
|
|
||||||
|
APP.fileManager.selectPath(function(newGamePath){
|
||||||
|
APP.settings.data.gamePath = newGamePath;
|
||||||
|
APP.settings.save();
|
||||||
|
APP.gameList.load();
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Load list
|
||||||
|
load: function(){
|
||||||
|
|
||||||
|
// Check if path exists
|
||||||
|
if (APP.fs.existsSync(APP.settings.data.gamePath) === !0){
|
||||||
|
|
||||||
|
// Reset game list
|
||||||
|
APP.gameList.list = {};
|
||||||
|
|
||||||
|
// Get game list
|
||||||
|
const gList = APP.fs.readdirSync(APP.settings.data.gamePath);
|
||||||
|
|
||||||
|
if (gList.length > 0){
|
||||||
|
|
||||||
|
// Process game list
|
||||||
|
gList.forEach(function(gPath){
|
||||||
|
|
||||||
|
var addGame = !0,
|
||||||
|
elfName = '',
|
||||||
|
ebootName = '',
|
||||||
|
pathBase = APP.settings.data.gamePath + '/' + gPath,
|
||||||
|
|
||||||
|
appBg0 = pathBase + '/pic0.png',
|
||||||
|
appBg1 = pathBase + '/pic1.png',
|
||||||
|
appIcon = pathBase + '/icon.png',
|
||||||
|
|
||||||
|
finalBg = appBg0,
|
||||||
|
finalIcon = appIcon,
|
||||||
|
|
||||||
|
ebootFile = pathBase + '/eboot.bin';
|
||||||
|
|
||||||
|
if (APP.fs.existsSync(ebootFile) === !0){
|
||||||
|
ebootName = 'eboot.bin';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If eboot.bin doesn't exists, look for any .elf file
|
||||||
|
if (APP.fs.existsSync(ebootFile) !== !0){
|
||||||
|
|
||||||
|
var fList = APP.fs.readdirSync(pathBase),
|
||||||
|
execName = fList.filter(function(fName){
|
||||||
|
if (fName.toLowerCase().indexOf('.elf') !== -1){
|
||||||
|
return fName;
|
||||||
|
}
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
ebootName = execName;
|
||||||
|
|
||||||
|
// If not found (undefined), skip
|
||||||
|
if (execName === void 0){
|
||||||
|
addGame = !1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set icon
|
||||||
|
if (APP.fs.existsSync(appIcon) === !1){
|
||||||
|
finalIcon = APP.settings.data.nwPath + '/app/img/404.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set BG image
|
||||||
|
if (APP.fs.existsSync(appBg0) === !1){
|
||||||
|
finalBg = appBg1;
|
||||||
|
if (APP.fs.existsSync(appBg1) === !1){
|
||||||
|
finalBg = APP.settings.data.nwPath + '/app/img/404_BG.png';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If executable exists, set data
|
||||||
|
if (addGame === !0){
|
||||||
|
APP.gameList.list[gPath] = {
|
||||||
|
bg: finalBg,
|
||||||
|
name: gPath,
|
||||||
|
icon: finalIcon,
|
||||||
|
eboot: APP.settings.data.gamePath + '/' + gPath + '/' + ebootName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// No games / homebrew found
|
||||||
|
APP.log('INFO - No games / homebrew were detected on current path (' + APP.settings.data.gamePath + ')');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render game list
|
||||||
|
APP.design.renderGameList();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Open game folder
|
||||||
|
openFolder: function(){
|
||||||
|
|
||||||
|
// Spawn explorer
|
||||||
|
APP.childProcess.exec('start "" "' + APP.settings.data.gamePath + '"');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
124
App/js/main.js
Normal file
124
App/js/main.js
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
main.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
var APP = {
|
||||||
|
|
||||||
|
// App version
|
||||||
|
version: '1.0.0',
|
||||||
|
|
||||||
|
// Import nw modules
|
||||||
|
fs: require('fs'),
|
||||||
|
path: require('path'),
|
||||||
|
childProcess: require('child_process'),
|
||||||
|
|
||||||
|
// Import app modules
|
||||||
|
design: temp_DESIGN,
|
||||||
|
gameList: temp_GAMELIST,
|
||||||
|
settings: temp_SETTINGS,
|
||||||
|
emuManager: temp_EMUMANAGER,
|
||||||
|
fileManager: temp_FILEMANAGER,
|
||||||
|
|
||||||
|
// Log function and variables
|
||||||
|
logData: '',
|
||||||
|
log: function(text, skipLog){
|
||||||
|
|
||||||
|
if (text !== '' && text !== void 0){
|
||||||
|
|
||||||
|
var textarea = document.getElementById('APP_LOG'),
|
||||||
|
previousLog = textarea.value,
|
||||||
|
newLog = previousLog + '\n' + text;
|
||||||
|
|
||||||
|
if (previousLog == ''){
|
||||||
|
newLog = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousLog.slice(previousLog.length - 1, previousLog.length) === '\n'){
|
||||||
|
newLog = previousLog + text;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.value = newLog;
|
||||||
|
APP.logData = newLog;
|
||||||
|
|
||||||
|
// If true, skip internal log
|
||||||
|
if (skipLog !== !0){
|
||||||
|
console.log(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll log
|
||||||
|
textarea.scrollTop = textarea.scrollHeight;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Run external software
|
||||||
|
execProcess: void 0,
|
||||||
|
runExec: function(exe, args){
|
||||||
|
|
||||||
|
if (exe !== void 0 && exe !== ''){
|
||||||
|
|
||||||
|
/*
|
||||||
|
Spawn process
|
||||||
|
It will change running dir to current exe location
|
||||||
|
*/
|
||||||
|
process.chdir(APP.path.parse(exe).dir);
|
||||||
|
APP.execProcess = APP.childProcess.spawn(exe, args);
|
||||||
|
|
||||||
|
// Log on stdout and stderr
|
||||||
|
APP.execProcess.stdout.on('data', function(data){
|
||||||
|
APP.log(data.toString(), !0);
|
||||||
|
});
|
||||||
|
APP.execProcess.stderr.on('data', function(data){
|
||||||
|
APP.log(data.toString(), !0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log on close
|
||||||
|
APP.execProcess.on('close', function(code){
|
||||||
|
process.chdir(APP.settings.data.nwPath);
|
||||||
|
APP.emuManager.emuRunning = !1;
|
||||||
|
APP.log('INFO - ' + APP.path.parse(exe).base + ' was closed returning code ' + code);
|
||||||
|
APP.design.updateRunButtons();
|
||||||
|
return code;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// About screen
|
||||||
|
about: function(){
|
||||||
|
window.alert('fpPS4 Temmie\'s Launcher - Version: ' + this.version + '\nCreated by TemmieHeartz\n(https://twitter.com/themitosan)\n\nfpPS4 main emulator is created by red-prig\n(https://github.com/red-prig/fpPS4)');
|
||||||
|
},
|
||||||
|
|
||||||
|
// Reload app
|
||||||
|
reload: function(){
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete modules
|
||||||
|
delete temp_DESIGN;
|
||||||
|
delete temp_SETTINGS;
|
||||||
|
delete temp_GAMELIST;
|
||||||
|
delete temp_EMUMANAGER;
|
||||||
|
delete temp_FILEMANAGER;
|
||||||
|
|
||||||
|
// Start
|
||||||
|
window.onload = function(){
|
||||||
|
|
||||||
|
// Main log
|
||||||
|
APP.log('fpPS4 Temmie\'s Launcher - Version: ' + APP.version + '\nRunning on nw.js (node-webkit) version ' + process.versions.nw);
|
||||||
|
|
||||||
|
// Load settings
|
||||||
|
APP.settings.load();
|
||||||
|
APP.settings.checkPaths();
|
||||||
|
|
||||||
|
// Load game list
|
||||||
|
APP.gameList.load();
|
||||||
|
|
||||||
|
// Rener hack list
|
||||||
|
APP.design.renderHacklist();
|
||||||
|
|
||||||
|
}
|
69
App/js/settings.js
Normal file
69
App/js/settings.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
settings.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
temp_SETTINGS = {
|
||||||
|
|
||||||
|
// Settings list
|
||||||
|
data: {
|
||||||
|
nwPath: '',
|
||||||
|
emuPath: '',
|
||||||
|
gamePath: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
// Load settings
|
||||||
|
load: function() {
|
||||||
|
|
||||||
|
// Create save
|
||||||
|
if (localStorage.getItem('settings') === null){
|
||||||
|
APP.settings.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
const settings = localStorage.getItem('settings');
|
||||||
|
this.data = JSON.parse(settings);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Save settings
|
||||||
|
save: function() {
|
||||||
|
localStorage.setItem('settings', JSON.stringify(this.data));
|
||||||
|
},
|
||||||
|
|
||||||
|
// Check paths
|
||||||
|
checkPaths: function(){
|
||||||
|
|
||||||
|
// Fix path
|
||||||
|
this.data.nwPath = nw.__dirname.replace(RegExp('\\\\', 'gi'), '/');
|
||||||
|
|
||||||
|
const mainPath = this.data.nwPath,
|
||||||
|
pathList = [
|
||||||
|
'/Emu',
|
||||||
|
'/Games'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Try create required paths
|
||||||
|
pathList.forEach(function(cPath){
|
||||||
|
if (APP.fs.existsSync(mainPath + cPath) !== !0){
|
||||||
|
try {
|
||||||
|
APP.fs.mkdirSync(mainPath + cPath);
|
||||||
|
} catch (err) {
|
||||||
|
APP.log('Unable to create path!\n(' + mainPath + cPath + ')\n' + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set Games / Emu paths and check if fpPS4 exe is present
|
||||||
|
this.data.gamePath = mainPath + '/Games';
|
||||||
|
this.data.emuPath = mainPath + '/Emu/fpPS4.exe';
|
||||||
|
|
||||||
|
if (APP.fs.existsSync(this.data.emuPath) === !0){
|
||||||
|
APP.log('INFO - Main fpPS4 was found!');
|
||||||
|
} else {
|
||||||
|
const errMsg = 'ERROR - Unable to locate main fpPS4 executable!\nMake sure to insert it on \"Emu\" folder and click on ok.';
|
||||||
|
window.alert(errMsg);
|
||||||
|
APP.log(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
package.json
Normal file
25
package.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "GPL-2",
|
||||||
|
"main": "App/index.htm",
|
||||||
|
"author": "TemmieHeartz",
|
||||||
|
"name": "fpPS4 Temmie's Launcher",
|
||||||
|
"description": "A simple launcher for fpPS4 project",
|
||||||
|
"repository": "https://github.com/themitosan/fpPS4-Temmie-s-Launcher",
|
||||||
|
"window": {
|
||||||
|
"frame": true,
|
||||||
|
"width": 1180,
|
||||||
|
"height": 710,
|
||||||
|
"toolbar": true,
|
||||||
|
"min_width": 1180,
|
||||||
|
"min_height": 710,
|
||||||
|
"fullscreen": false,
|
||||||
|
"position": "center",
|
||||||
|
"theme-color": "#000",
|
||||||
|
"icon": "App/img/logo.png",
|
||||||
|
"title": "fpPS4 Temmie's Launcher"
|
||||||
|
},
|
||||||
|
"webkit": {
|
||||||
|
"plugin": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue