Debugger can now connect. AngularJS: I have no idea what I'm doing.

This commit is contained in:
Ben Vanik 2013-12-21 11:53:49 -08:00
parent da340891c4
commit a9378eb7eb
22 changed files with 1086 additions and 466 deletions

3
.gitignore vendored
View File

@ -32,6 +32,9 @@ tmtags
.project .project
.metadata .metadata
# WebStorm
.idea
# ============================================================================== # ==============================================================================
# Temp generated code # Temp generated code
# ============================================================================== # ==============================================================================

View File

@ -0,0 +1,255 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
.full-width {
width: 100%;
}
body {
margin: 0;
}
.app-main {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: hidden;
min-width: 900px;
min-height: 350px;
display: flex;
flex-flow: column nowrap;
}
.app-header {
order: 1;
flex: 0 0 auto;
align-self: auto;
}
.app-header .navbar {
border-radius: 0;
min-height: 0;
margin-bottom: 0;
}
.app-body {
order: 2;
flex: 1 1 auto;
align-self: auto;
position: relative;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.tab-pane {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.app-console {
order: 3;
flex: 0 0 auto;
align-self: auto;
border-top-width: 2px;
border-top-style: solid;
}
.console {
display: flex;
flex-flow: column nowrap;
padding: 5px;
}
.console-part-log {
order: 1;
flex: 1 1 auto;
align-self: auto;
}
.console-log-outer {
position: relative;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 1px solid #ddd;
overflow-y: scroll;
height: 100px;
}
.console-part-input {
order: 2;
flex: 0 0 auto;
align-self: auto;
display: flex;
flex-flow: row nowrap;
padding-top: 5px;
}
.console-input-left {
order: 1;
flex: 0 0 auto;
min-width: 0;
}
.console-input-middle {
order: 2;
flex: 1 1 auto;
}
.console-input-right {
order: 3;
flex: 0 0 auto;
padding-left: 10px;
}
.debugger-main {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: flex;
flex-flow: column nowrap;
}
.debugger-header {
order: 1;
flex: 0 0 auto;
align-self: auto;
border-bottom: 1px solid #ddd;
padding: 5px;
}
.debugger-body {
order: 2;
flex: 1 1 auto;
align-self: auto;
display: flex;
flex-flow: row nowrap;
}
.debugger-fnlist {
order: 1;
flex: 0 0 auto;
display: flex;
flex-flow: column nowrap;
max-width: 200px;
}
.debugger-fnlist-header {
order: 1;
flex: 0 0 auto;
padding: 5px;
}
.debugger-fnlist-body {
order: 2;
flex: 1 1 auto;
padding: 5px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
position: relative;
}
.debugger-fnlist-list {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
padding: 5px;
overflow: scroll;
}
.debugger-fnlist-footer {
order: 3;
flex: 0 0 auto;
padding: 5px;
}
.debugger-fnview {
order: 2;
flex: 1 1 auto;
display: flex;
flex-flow: column nowrap;
border-left: 2px solid #ddd;
border-right: 2px solid #ddd;
}
.debugger-fnview-header {
order: 1;
flex: 0 0 auto;
padding: 5px;
display: flex;
flex-flow: row nowrap;
}
.debugger-fnview-header-left {
order: 1;
flex: 1 1 auto;
padding: 5px;
}
.debugger-fnview-header-name {
font-size: 21px;
font-family: monospace;
}
.debugger-fnview-header-address {
font-family: monospace;
}
.debugger-fnview-header-right {
order: 2;
flex: 0 0 auto;
padding: 5px;
}
.debugger-fnview-body {
order: 2;
flex: 1 1 auto;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
display: flex;
flex-flow: row nowrap;
}
.debugger-fnview-codeview {
order: 1;
flex: 1 1 auto;
position: relative;
}
.debugger-fnview-codeview .CodeMirror {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
height: 100%;
}
.debugger-fnview-graphview {
order: 2;
flex: 0 0 auto;
position: relative;
border-left: 1px solid #ddd;
min-width: 100px;
}
.debugger-fnview-footer {
order: 3;
flex: 0 0 auto;
padding: 5px;
}
.debugger-tools {
order: 3;
flex: 0 0 auto;
display: flex;
flex-flow: column nowrap;
min-width: 200px;
}
.debugger-tools-threads {
order: 1;
flex: 0 0 auto;
padding: 5px;
}
.debugger-tools-callstack {
order: 2;
flex: 1 1 auto;
padding: 5px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
position: relative;
}
.debugger-tools-registers {
order: 3;
flex: 1 1 auto;
padding: 5px;
}

View File

@ -0,0 +1 @@
TODO: APU

View File

@ -0,0 +1,93 @@
<div class="debugger-main">
<div class="debugger-header">
debug header/toolbar/etc
<div ui-view></div>
</div>
<div class="debugger-body">
<div class="debugger-fnlist">
<div class="debugger-fnlist-header">
<div class="btn-group btn-group-xs full-width">
<button type="button" class="btn btn-default dropdown-toggle full-width" data-toggle="dropdown">
module_name.xex <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">module 1</a></li>
<li><a href="#">module 2</a></li>
</ul>
</div>
</div>
<div class="debugger-fnlist-body">
<div class="debugger-fnlist-list">
fn<br/>fn<br/>fn
</div>
</div>
<div class="debugger-fnlist-footer">
<div class="input-group input-group-sm">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Filter">
</div>
</div>
</div>
<div class="debugger-fnview">
<div class="debugger-fnview-header">
<div class="debugger-fnview-header-left">
<span class="debugger-fnview-header-name">function name</span>
<span class="debugger-fnview-header-address">(0x80000000-0x80000000)</span>
</div>
<div class="debugger-fnview-header-right">
<div class="btn-toolbar" role="toolbar">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default" ng-model="radioModel" btn-radio="'PPC'">PPC</button>
<button type="button" class="btn btn-default" ng-model="radioModel" btn-radio="'HIR'">HIR</button>
<button type="button" class="btn btn-default" ng-model="radioModel" btn-radio="'LIR'">LIR</button>
</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default">1</button>
<button type="button" class="btn btn-default">2</button>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Dropdown link</a></li>
<li><a href="#">Dropdown link</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="debugger-fnview-body">
<div class="debugger-fnview-codeview">
<textarea class="debugger-fnview-textarea"></textarea>
</div>
<div class="debugger-fnview-graphview">
graph!
</div>
</div>
<div class="debugger-fnview-footer">
footer
</div>
</div>
<div class="debugger-tools">
<div class="debugger-tools-threads">
<div class="btn-group btn-group-xs full-width">
<button type="button" class="btn btn-default dropdown-toggle full-width" data-toggle="dropdown">
thread 0 <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">thread 1</a></li>
<li><a href="#">thread 2</a></li>
</ul>
</div>
</div>
<div class="debugger-tools-callstack">
callstack
</div>
<div class="debugger-tools-registers">
registers
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,2 @@
TODO: function
<div ui-view></div>

View File

@ -0,0 +1,26 @@
<div class="console" ng-controller="ConsoleController">
<div class="console-part-log">
<div class="console-log-outer">
<ul>
<li ng-repeat="line in log.lines track by $index">{{line}}</li>
</ul>
</div>
</div>
<div class="console-part-input">
<div class="console-input-left">
</div>
<div class="console-input-middle">
<div class="input-group input-group-sm">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Command" ng-model="commandText" ui-enter="issueCommand()">
</div>
</div>
<div class="console-input-right">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default">A</button>
<button type="button" class="btn btn-default">B</button>
<button type="button" class="btn btn-default">C</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,34 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.ui.console', [
'xe.log'
]);
module.controller('ConsoleController', function($scope, log) {
$scope.log = log;
$scope.commandText = '';
$scope.issueCommand = function() {
var command = $scope.commandText;
$scope.commandText = '';
if (!command) {
return;
}
log.appendLine('@' + command);
// TODO(benvanik): execute.
console.log(command);
};
});

View File

@ -0,0 +1 @@
TODO: GPU

View File

@ -0,0 +1 @@
TODO: kernel

View File

@ -0,0 +1 @@
TODO: memory

View File

@ -0,0 +1,37 @@
<nav class="navbar navbar-default" role="navigation" ng-controller="NavbarController">
<div class="navbar-header">
<a class="navbar-brand" href="http://xenia.jp/" target="_blank">Xenia</a>
</div>
<ul class="nav navbar-nav" ng-show="app.session">
<li ui-sref-active="active"><a ui-sref="session.code">Code</a></li>
<li ui-sref-active="active"><a ui-sref="session.memory">Memory</a></li>
<li ui-sref-active="active"><a ui-sref="session.kernel">Kernel</a></li>
<li ui-sref-active="active"><a ui-sref="session.gpu">GPU</a></li>
<li ui-sref-active="active"><a ui-sref="session.apu">APU</a></li>
</ul>
<p class="navbar-text navbar-right"></p>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<div class="btn-group navbar-btn">
<button type="button" class="btn btn-default" ng-click="connectClicked()" ng-disabled="app.loading">
<span class="glyphicon glyphicon-link"></span> Connect
</button>
<button type="button" class="btn btn-default" ng-click="openClicked()" ng-disabled="app.loading">
<span class="glyphicon glyphicon-file"></span> Open
</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" ng-disabled="app.loading">
<span class="glyphicon glyphicon-cog"></span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
</li>
</ul>
<p class="navbar-text navbar-right"></p>
<p class="navbar-text navbar-right" ng-show="app.session">{{app.session.source}}</p>
</nav>

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.ui.navbar', []);
module.controller('NavbarController', function(
$scope, $state, app, log) {
$scope.connectClicked = function() {
// TODO(benvanik): show a fancy dialog or something.
var oldSession = app.session;
app.connect().then(function(session) {
if (!oldSession || oldSession.id != session.id) {
$state.go('session', {
'sessionId': session.id
}, {
notify: true
});
}
}, function(e) {
$state.go('/', {
}, {
notify: true
});
});
};
$scope.openClicked = function() {
var inputEl = document.createElement('input');
inputEl.type = 'file';
inputEl.accept = '.xe-trace,application/x-extension-xe-trace';
inputEl.onchange = function(e) {
$scope.$apply(function() {
if (inputEl.files.length) {
//app.open(inputEl.files[0]);
log.info('Not implemented yet');
}
});
};
inputEl.click();
};
});

View File

@ -0,0 +1 @@
<div ui-view></div>

View File

@ -7,41 +7,7 @@
****************************************************************************** ******************************************************************************
*/ */
// TODO(benvanik): closure or something fancy /*
var DebugClient = function(endpoint) {
/**
* Target websocket endpoint.
* @type {string}
* @private
*/
this.endpoint_ = endpoint;
/**
* Connected socket.
* @type {!WebSocket}
* @private
*/
this.socket_ = new WebSocket(endpoint, []);
this.socket_.onopen = (function() {
console.log('opened');
}).bind(this);
this.socket_.onerror = (function(e) {
console.log('error', e);
}).bind(this);
this.socket_.onmessage = (function(e) {
console.log('message', e.data);
}).bind(this);
}
var client = new DebugClient('ws://127.0.0.1:6200');
var myTextArea = document.querySelector('.debugger-fnview-textarea'); var myTextArea = document.querySelector('.debugger-fnview-textarea');
var myCodeMirror = CodeMirror.fromTextArea(myTextArea, { var myCodeMirror = CodeMirror.fromTextArea(myTextArea, {
mode: 'javascript', mode: 'javascript',
@ -58,3 +24,4 @@ var myCodeMirror = CodeMirror.fromTextArea(myTextArea, {
//readOnly: true, //readOnly: true,
}); });
*/

View File

@ -1,445 +1,36 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html ng-app="app">
<head> <head>
<title>Xenia Debugger</title> <title>Xenia Debugger</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.7.0.js"></script>
<script src="//angular-ui.github.io/ui-router/build/angular-ui-router.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<link rel="stylesheet" href="http://codemirror.net/lib/codemirror.css"> <!--<link rel="stylesheet" href="//codemirror.net/lib/codemirror.css">-->
<link rel="stylesheet" href="assets/styles/app.css">
<style> <style>
.full-width {
width: 100%;
}
body {
margin: 0;
}
.app-main {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: hidden;
min-width: 900px;
min-height: 350px;
display: flex;
flex-flow: column nowrap;
}
.app-header {
order: 1;
flex: 0 0 auto;
align-self: auto;
}
.app-header .navbar {
border-radius: 0;
min-height: 0;
margin-bottom: 0;
}
.app-body {
order: 2;
flex: 1 1 auto;
align-self: auto;
position: relative;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.tab-pane {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.app-console {
order: 3;
flex: 0 0 auto;
align-self: auto;
border-top-width: 2px;
border-top-style: solid;
display: flex;
flex-flow: column nowrap;
padding: 5px;
}
.console-part-log {
order: 1;
flex: 1 1 auto;
align-self: auto;
}
.console-log-outer {
position: relative;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 1px solid #ddd;
overflow-y: scroll;
}
.console-part-input {
order: 2;
flex: 0 0 auto;
align-self: auto;
display: flex;
flex-flow: row nowrap;
padding-top: 5px;
}
.console-input-left {
order: 1;
flex: 0 0 auto;
min-width: 0;
}
.console-input-middle {
order: 2;
flex: 1 1 auto;
}
.console-input-right {
order: 3;
flex: 0 0 auto;
padding-left: 10px;
}
.debugger-main {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: flex;
flex-flow: column nowrap;
}
.debugger-header {
order: 1;
flex: 0 0 auto;
align-self: auto;
border-bottom: 1px solid #ddd;
padding: 5px;
}
.debugger-body {
order: 2;
flex: 1 1 auto;
align-self: auto;
display: flex;
flex-flow: row nowrap;
}
.debugger-fnlist {
order: 1;
flex: 0 0 auto;
display: flex;
flex-flow: column nowrap;
max-width: 200px;
}
.debugger-fnlist-header {
order: 1;
flex: 0 0 auto;
padding: 5px;
}
.debugger-fnlist-body {
order: 2;
flex: 1 1 auto;
padding: 5px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
position: relative;
}
.debugger-fnlist-list {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
padding: 5px;
overflow: scroll;
}
.debugger-fnlist-footer {
order: 3;
flex: 0 0 auto;
padding: 5px;
}
.debugger-fnview {
order: 2;
flex: 1 1 auto;
display: flex;
flex-flow: column nowrap;
border-left: 2px solid #ddd;
border-right: 2px solid #ddd;
}
.debugger-fnview-header {
order: 1;
flex: 0 0 auto;
padding: 5px;
display: flex;
flex-flow: row nowrap;
}
.debugger-fnview-header-left {
order: 1;
flex: 1 1 auto;
padding: 5px;
}
.debugger-fnview-header-name {
font-size: 21px;
font-family: monospace;
}
.debugger-fnview-header-address {
font-family: monospace;
}
.debugger-fnview-header-right {
order: 2;
flex: 0 0 auto;
padding: 5px;
}
.debugger-fnview-body {
order: 2;
flex: 1 1 auto;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
display: flex;
flex-flow: row nowrap;
}
.debugger-fnview-codeview {
order: 1;
flex: 1 1 auto;
position: relative;
}
.debugger-fnview-codeview .CodeMirror {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
height: 100%;
}
.debugger-fnview-graphview {
order: 2;
flex: 0 0 auto;
position: relative;
border-left: 1px solid #ddd;
min-width: 100px;
}
.debugger-fnview-footer {
order: 3;
flex: 0 0 auto;
padding: 5px;
}
.debugger-tools {
order: 3;
flex: 0 0 auto;
display: flex;
flex-flow: column nowrap;
min-width: 200px;
}
.debugger-tools-threads {
order: 1;
flex: 0 0 auto;
padding: 5px;
}
.debugger-tools-callstack {
order: 2;
flex: 1 1 auto;
padding: 5px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
position: relative;
}
.debugger-tools-registers {
order: 3;
flex: 1 1 auto;
padding: 5px;
}
</style> </style>
</head> </head>
<body> <body ng-controller="AppController">
<div class="app-main"> <div class="app-main">
<div class="app-header"> <div class="app-header" ng-include="'assets/ui/navbar.html'"></div>
<nav class="navbar navbar-default" role="navigation"> <div class="app-body tab-content" ui-view></div>
<div class="navbar-header"> <div class="app-console navbar-default" ng-include="'assets/ui/console/console.html'"></div>
<a class="navbar-brand" href="http://xenia.jp/" target="_blank">Xenia</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a href="#tab-debugger" data-toggle="tab">Debugger</a></li>
<li><a href="#tab-memory" data-toggle="tab">Memory</a></li>
<li><a href="#tab-kernel" data-toggle="tab">Kernel</a></li>
<li><a href="#tab-gpu" data-toggle="tab">GPU</a></li>
<li><a href="#tab-apu" data-toggle="tab">APU</a></li>
</ul>
<p class="navbar-text navbar-right"></p>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<div class="btn-group navbar-btn">
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-link"></span> Connect
</button>
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-file"></span> Open
</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-cog"></span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
</li>
</ul>
<p class="navbar-text navbar-right"></p>
<p class="navbar-text navbar-right">(status text)</p>
</nav>
</div>
<div class="app-body tab-content">
<div class="tab-pane active" id="tab-debugger">
<div class="debugger-main">
<div class="debugger-header">
debug header/toolbar/etc
</div>
<div class="debugger-body">
<div class="debugger-fnlist">
<div class="debugger-fnlist-header">
<div class="btn-group btn-group-xs full-width">
<button type="button" class="btn btn-default dropdown-toggle full-width" data-toggle="dropdown">
module_name.xex <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">module 1</a></li>
<li><a href="#">module 2</a></li>
</ul>
</div>
</div>
<div class="debugger-fnlist-body">
<div class="debugger-fnlist-list">
fn<br/>fn<br/>fn
</div>
</div>
<div class="debugger-fnlist-footer">
<div class="input-group input-group-sm">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Filter">
</div>
</div>
</div>
<div class="debugger-fnview">
<div class="debugger-fnview-header">
<div class="debugger-fnview-header-left">
<span class="debugger-fnview-header-name">function name</span>
<span class="debugger-fnview-header-address">(0x80000000-0x80000000)</span>
</div>
<div class="debugger-fnview-header-right">
<div class="btn-toolbar" role="toolbar">
<div class="btn-group btn-group-sm" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="options" id="option1"> PPC
</label>
<label class="btn btn-default">
<input type="radio" name="options" id="option2"> HIR
</label>
<label class="btn btn-default">
<input type="radio" name="options" id="option3"> x64
</label>
</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default">1</button>
<button type="button" class="btn btn-default">2</button>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Dropdown link</a></li>
<li><a href="#">Dropdown link</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="debugger-fnview-body">
<div class="debugger-fnview-codeview">
<textarea class="debugger-fnview-textarea"></textarea>
</div>
<div class="debugger-fnview-graphview">
graph!
</div>
</div>
<div class="debugger-fnview-footer">
footer
</div>
</div>
<div class="debugger-tools">
<div class="debugger-tools-threads">
<div class="btn-group btn-group-xs full-width">
<button type="button" class="btn btn-default dropdown-toggle full-width" data-toggle="dropdown">
thread 0 <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">thread 1</a></li>
<li><a href="#">thread 2</a></li>
</ul>
</div>
</div>
<div class="debugger-tools-callstack">
callstack
</div>
<div class="debugger-tools-registers">
registers
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab-memory">
TODO: memory
</div>
<div class="tab-pane" id="tab-kernel">
TODO: kernel
</div>
<div class="tab-pane" id="tab-gpu">
TODO: GPU
</div>
<div class="tab-pane" id="tab-apu">
TODO: APU
</div>
</div>
<div class="app-console navbar-default">
<div class="console-part-log">
<div class="console-log-outer">
log<br/>log<br/>log
</div>
</div>
<div class="console-part-input">
<div class="console-input-left">
</div>
<div class="console-input-middle">
<div class="input-group input-group-sm">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Command">
</div>
</div>
<div class="console-input-right">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default">A</button>
<button type="button" class="btn btn-default">B</button>
<button type="button" class="btn btn-default">C</button>
</div>
</div>
</div>
</div>
</div> </div>
<script src="https://code.jquery.com/jquery.js"></script> <!--<script src="http://codemirror.net/lib/codemirror.js"></script>-->
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script src="http://codemirror.net/lib/codemirror.js"></script> <script src="src/base.js"></script>
<script src="src/app.js"></script>
<script src="src/datasources.js"></script>
<script src="src/directives.js"></script>
<script src="src/log.js"></script>
<script src="src/router.js"></script>
<script src="src/session.js"></script>
<script src="assets/ui/navbar.js"></script>
<script src="assets/ui/console/console.js"></script>
<script src="debugger.js"></script> <script src="debugger.js"></script>
</body> </body>

107
debugger/src/app.js Normal file
View File

@ -0,0 +1,107 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('app', [
'ui.bootstrap',
'ui.router',
'xe.datasources',
'xe.directives',
'xe.log',
'xe.router',
'xe.session',
'xe.ui.console',
'xe.ui.navbar'
]);
module.controller('AppController', function($scope, app) {
this.app = app;
});
module.service('app', function(
$rootScope, $q, $state, log, Session) {
var App = function() {
this.loading = false;
this.session = null;
};
App.prototype.setSession = function(session) {
this.close();
this.session = session;
};
App.prototype.close = function() {
this.loading = false;
if (this.session) {
this.session.dispose();
this.session = null;
}
};
App.prototype.open = function(sessionId) {
this.close();
var d = $q.defer();
this.loading = true;
log.info('Opening session ' + sessionId);
var session = new Session(sessionId);
this.loading = false;
this.setSession(session);
d.resolve(session);
return d.promise;
};
App.prototype.connect = function(opt_host) {
this.close();
var d = $q.defer();
this.loading = true;
Session.query(opt_host).then((function(infos) {
var info = infos[0];
var id = info.titleId;
if (id == '00000000') {
id = info.name;
}
var session = new Session(id);
var p = session.connect(opt_host);
p.then((function(session) {
this.loading = false;
this.setSession(session);
d.resolve(session);
}).bind(this), (function(e) {
this.loading = false;
d.reject(e);
}).bind(this), function(update) {
d.notify(update);
});
}).bind(this), (function(e) {
this.loading = false;
log.info('No sessions found at ' + Session.getHost(opt_host));
d.reject(e);
}).bind(this));
return d.promise;
};
return new App();
});
module.run(function($rootScope, app, log) {
$rootScope.app = app;
$rootScope.log = log;
});

19
debugger/src/base.js Normal file
View File

@ -0,0 +1,19 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
function inherits(childCtor, parentCtor) {
function tempCtor() {};
tempCtor.prototype = parentCtor.prototype;
childCtor.superClass_ = parentCtor.prototype;
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};

122
debugger/src/datasources.js Normal file
View File

@ -0,0 +1,122 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.datasources', []);
var DataSource = function(source) {
this.source = source;
this.online = false;
this.status = 'disconnected';
};
DataSource.prototype.open = function() {};
DataSource.prototype.dispose = function() {};
module.service('RemoteDataSource', function($q) {
var RemoteDataSource = function(url) {
DataSource.call(this, url);
this.url = url;
this.socket = null;
};
inherits(RemoteDataSource, DataSource);
RemoteDataSource.prototype.open = function() {
var url = this.url;
this.online = false;
this.status = 'connecting';
var d = $q.defer();
this.socket = new WebSocket(url, []);
this.socket.onopen = (function() {
// TODO(benvanik): handshake
this.online = true;
this.status = 'connected';
d.resolve();
}).bind(this);
this.socket.onclose = (function(e) {
this.online = false;
if (this.status == 'connecting') {
this.status = 'disconnected';
d.reject(e.code + ' ' + e.reason);
} else {
this.status = 'disconnected';
}
}).bind(this);
this.socket.onerror = (function(e) {
// ?
}).bind(this);
this.socket.onmessage = (function(e) {
console.log('message', e.data);
}).bind(this);
return d.promise;
};
RemoteDataSource.prototype.dispose = function() {
this.online = false;
this.status = 'disconnected';
if (this.socket) {
this.socket.close();
this.socket = null;
}
DataSource.prototype.dispose.call(this);
};
return RemoteDataSource;
});
module.service('FileDataSource', function($q) {
var FileDataSource = function(file) {
DataSource.call(this, file.name);
this.file = file;
};
inherits(FileDataSource, DataSource);
FileDataSource.prototype.open = function() {
this.status = 'connecting';
var d = $q.defer();
var self = this;
window.setTimeout(function() {
$scope.$apply((function() {
// TODO(benvanik): scan/load trace
this.online = true;
this.status = 'connected';
d.resolve();
}).bind(self));
});
return d.promise;
};
FileDataSource.prototype.dispose = function() {
this.online = false;
if (this.file) {
if (this.file.close) {
this.file.close();
}
this.file = null;
}
DataSource.prototype.dispose.call(this);
};
return FileDataSource;
});

View File

@ -0,0 +1,26 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.directives', []);
module.directive('uiEnter', function() {
return function($scope, element, attrs) {
element.bind("keydown keypress", function(e) {
if(e.which === 13) {
$scope.$apply(function(){
$scope.$eval(attrs.uiEnter);
});
e.preventDefault();
}
});
};
});

45
debugger/src/log.js Normal file
View File

@ -0,0 +1,45 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.log', []);
module.service('log', function($rootScope) {
var Log = function() {
this.lines = [];
this.progressActive = false;
this.progress = 0;
};
Log.prototype.appendLine = function(line) {
this.lines.push(line);
};
Log.prototype.info = function(line) {
this.appendLine('I ' + line);
};
Log.prototype.error = function(line) {
this.appendLine('E ' + line);
};
Log.prototype.setProgress = function(value) {
this.progressActive = true;
this.progress = value;
};
Log.prototype.clearProgress = function() {
this.progressActive = false;
};
return new Log();
});

144
debugger/src/router.js Normal file
View File

@ -0,0 +1,144 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.router', [
'ui.router',
]);
module.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('/', {
template: 'empty'
});
$stateProvider.state('session', {
url: '/:sessionId',
templateUrl: 'assets/ui/session.html',
resolve: {
app: 'app',
session: function($stateParams, $urlRouter, $state, $q, $timeout,
Session, app) {
// If we are given a session we assume the user is trying to connect to
// it. Attempt that now. If we fail we redirect to home, otherwise we
// check whether it's the same game down below.
var d = $q.defer();
if ($stateParams.sessionId) {
if (!app.session ||
app.session.id != $stateParams.sessionId) {
Session.query().then(function(infos) {
var id = (infos[0].titleId == '00000000') ?
infos[0].name : infos[0].titleId;
if (!app.session || app.session.id == id) {
// Same session, continue.
var p = app.connect();
p.then(function(session) {
d.resolve(session);
}, function(e) {
$state.go('session', {
'sessionId': session.id
}, {
notify: true
});
d.reject(e);
})
} else {
// Different session. Create without connection.
var p = app.open(id);
p.then(function(session) {
d.resolve(session);
}, function(e) {
d.reject(e);
});
}
}, function(e) {
var p = app.open($stateParams.sessionId);
p.then(function(session) {
d.resolve(session);
}, function(e) {
d.reject(e);
});
});
} else {
var p = app.open($stateParams.sessionId);
p.then(function(session) {
d.resolve(session);
}, function(e) {
d.reject(e);
});
}
} else {
d.resolve(null);
}
return d.promise;
}
},
controller: function($scope, $stateParams, $q, app, session) {
},
onEnter: function() {
},
onExit: function() {}
});
$stateProvider.state('session.code', {
url: '/code',
templateUrl: 'assets/ui/code/code-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.code.function', {
url: '/:module/:function',
templateUrl: 'assets/ui/code/function-view.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.memory', {
url: '/memory',
templateUrl: 'assets/ui/memory/memory-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.kernel', {
url: '/kernel',
templateUrl: 'assets/ui/kernel/kernel-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.gpu', {
url: '/gpu',
templateUrl: 'assets/ui/gpu/gpu-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.apu', {
url: '/apu',
templateUrl: 'assets/ui/apu/apu-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
});

92
debugger/src/session.js Normal file
View File

@ -0,0 +1,92 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.session', []);
module.service('Session', function(
$q, $http, log, FileDataSource, RemoteDataSource) {
var Session = function(id, opt_dataSource) {
this.id = id;
this.dataSource = opt_dataSource || null;
};
Session.prototype.dispose = function() {
this.disconnect();
};
Session.DEFAULT_HOST = '127.0.0.1:6200';
Session.getHost = function(opt_host) {
return opt_host || Session.DEFAULT_HOST;
};
Session.query = function(opt_host) {
var url = 'http://' + Session.getHost(opt_host);
var p = $http({
method: 'GET',
url: url + '/sessions',
cache: false,
timeout: 500,
responseType: 'json'
});
var d = $q.defer();
p.then(function(response) {
if (!response.data || !response.data.length) {
d.reject(new Error('No session data'));
return;
}
d.resolve(response.data);
}, function(e) {
d.reject(e);
});
return d.promise;
};
Session.prototype.connect = function(opt_host) {
this.disconnect();
var url = 'ws://' + Session.getHost(opt_host);
log.info('Connecting to ' + url + '...');
log.setProgress(0);
var d = $q.defer();
var dataSource = new RemoteDataSource(url);
var p = dataSource.open();
p.then((function() {
log.info('Connected!');
log.clearProgress();
this.dataSource = dataSource;
d.resolve(this);
}).bind(this), (function(e) {
log.error('Unable to connect: ' + e);
log.clearProgress();
d.reject(e);
}).bind(this), function(update) {
log.setProgress(update.progress);
d.notify(update);
});
return d.promise;
};
Session.prototype.disconnect = function() {
if (this.dataSource) {
this.dataSource.dispose();
this.dataSource = null;
}
};
return Session;
});