2014-07-09 23:04:22 +00:00
using System ;
using System.Drawing ;
2014-07-28 16:43:47 +00:00
using System.Linq ;
2014-07-09 23:04:22 +00:00
using System.Windows.Forms ;
using BizHawk.Client.Common ;
2014-07-28 16:43:47 +00:00
using BizHawk.Client.EmuHawk.WinFormExtensions ;
2014-07-09 23:04:22 +00:00
namespace BizHawk.Client.EmuHawk
{
public partial class TAStudio
{
2014-07-11 16:08:47 +00:00
// Input Painting
2014-07-11 16:26:19 +00:00
private string _startBoolDrawColumn = string . Empty ;
private string _startFloatDrawColumn = string . Empty ;
2014-07-11 16:08:47 +00:00
private bool _boolPaintState ;
2014-07-11 16:26:19 +00:00
private float _floatPaintState ;
2014-07-11 16:08:47 +00:00
private bool _startMarkerDrag ;
private bool _startFrameDrag ;
2014-07-21 02:23:47 +00:00
public static Color CurrentFrame_FrameCol = Color . FromArgb ( 0xCFEDFC ) ;
public static Color CurrentFrame_InputLog = Color . FromArgb ( 0xB5E7F7 ) ;
2014-07-16 00:10:37 +00:00
2014-07-21 02:23:47 +00:00
public static Color GreenZone_FrameCol = Color . FromArgb ( 0xDDFFDD ) ;
2014-08-22 16:05:06 +00:00
public static Color GreenZone_Invalidated_FrameCol = Color . FromArgb ( 0xFFFFFF ) ;
2014-07-21 02:23:47 +00:00
public static Color GreenZone_InputLog = Color . FromArgb ( 0xC4F7C8 ) ;
2014-08-22 16:05:06 +00:00
public static Color GreenZone_Invalidated_InputLog = Color . FromArgb ( 0xE0FBE0 ) ;
2014-07-16 00:10:37 +00:00
2014-07-21 02:23:47 +00:00
public static Color LagZone_FrameCol = Color . FromArgb ( 0xFFDCDD ) ;
2014-08-22 16:05:06 +00:00
public static Color LagZone_Invalidated_FrameCol = Color . FromArgb ( 0xFFE9E9 ) ;
2014-07-21 02:23:47 +00:00
public static Color LagZone_InputLog = Color . FromArgb ( 0xF0D0D2 ) ;
2014-08-22 16:05:06 +00:00
public static Color LagZone_Invalidated_InputLog = Color . FromArgb ( 0xF7E5E5 ) ;
2014-07-16 00:10:37 +00:00
2014-07-21 02:23:47 +00:00
public static Color NoState_GreenZone_FrameCol = Color . FromArgb ( 0xF9FFF9 ) ;
public static Color NoState_GreenZone_InputLog = Color . FromArgb ( 0xE0FBE0 ) ;
2014-07-16 00:10:37 +00:00
2014-07-21 02:23:47 +00:00
public static Color NoState_LagZone_FrameCol = Color . FromArgb ( 0xFFE9E9 ) ;
public static Color NoState_LagZone_InputLog = Color . FromArgb ( 0xF0D0D2 ) ;
2014-07-16 00:10:37 +00:00
2014-07-21 02:23:47 +00:00
public static Color Marker_FrameCol = Color . FromArgb ( 0xF7FFC9 ) ;
2014-07-16 00:10:37 +00:00
2014-07-09 23:04:22 +00:00
#region Query callbacks
private void TasView_QueryItemBkColor ( int index , int column , ref Color color )
{
2014-07-11 19:58:24 +00:00
var columnName = TasView . Columns [ column ] . Name ;
2014-07-16 00:10:37 +00:00
2014-07-16 23:04:56 +00:00
// Marker Column is white regardless
2014-07-16 00:10:37 +00:00
if ( columnName = = MarkerColumnName )
2014-07-09 23:04:22 +00:00
{
2014-07-16 00:10:37 +00:00
color = Color . White ;
2014-07-16 23:04:56 +00:00
return ;
}
// "pending" frame logic
2014-08-19 19:24:17 +00:00
if ( index = = Global . Emulator . Frame & & index = = _currentTasMovie . InputLogLength )
2014-07-16 23:04:56 +00:00
{
if ( columnName = = FrameColumnName )
{
color = CurrentFrame_FrameCol ;
}
color = CurrentFrame_InputLog ;
return ;
2014-07-09 23:04:22 +00:00
}
2014-07-16 23:04:56 +00:00
2014-08-19 19:24:17 +00:00
var record = _currentTasMovie [ index ] ;
2014-07-16 23:04:56 +00:00
2014-08-31 14:58:44 +00:00
if ( ! ( record . Lagged ? ? false ) )
{
int zzz = 0 ;
}
2014-07-16 23:04:56 +00:00
if ( columnName = = FrameColumnName )
2014-07-09 23:04:22 +00:00
{
2014-07-16 00:10:37 +00:00
if ( Global . Emulator . Frame = = index )
{
color = CurrentFrame_FrameCol ;
}
2014-08-19 19:24:17 +00:00
else if ( _currentTasMovie . Markers . IsMarker ( index ) )
2014-07-16 00:10:37 +00:00
{
color = Marker_FrameCol ;
}
else if ( record . Lagged . HasValue )
2014-07-10 19:24:21 +00:00
{
if ( record . Lagged . Value )
{
2014-08-31 14:58:44 +00:00
color = record . HasState ? LagZone_FrameCol : NoState_LagZone_InputLog ;
2014-07-10 19:24:21 +00:00
}
else
{
2014-08-31 14:58:44 +00:00
color = record . HasState ? GreenZone_FrameCol : NoState_GreenZone_FrameCol ;
2014-07-10 19:24:21 +00:00
}
}
else
{
2014-07-16 00:10:37 +00:00
color = Color . White ;
}
}
else
{
if ( Global . Emulator . Frame = = index )
{
color = CurrentFrame_InputLog ;
}
else
{
if ( record . Lagged . HasValue )
{
if ( record . Lagged . Value )
{
2014-08-31 14:58:44 +00:00
color = record . HasState ? LagZone_InputLog : NoState_LagZone_InputLog ;
2014-07-16 00:10:37 +00:00
}
else
{
2014-08-31 14:58:44 +00:00
color = record . HasState ? GreenZone_InputLog : NoState_GreenZone_InputLog ;
2014-07-16 00:10:37 +00:00
}
}
else
{
color = ( columnName = = MarkerColumnName | | columnName = = FrameColumnName ) ?
Color . White :
SystemColors . ControlLight ;
}
2014-07-10 19:24:21 +00:00
}
2014-07-09 23:04:22 +00:00
}
}
private void TasView_QueryItemText ( int index , int column , out string text )
{
try
{
2014-07-16 23:04:56 +00:00
text = string . Empty ;
2014-07-09 23:04:22 +00:00
var columnName = TasView . Columns [ column ] . Name ;
if ( columnName = = MarkerColumnName )
{
2014-07-10 20:15:46 +00:00
text = Global . Emulator . Frame = = index ? ">" : string . Empty ;
2014-07-09 23:04:22 +00:00
}
else if ( columnName = = FrameColumnName )
{
2014-07-10 20:15:46 +00:00
text = ( index ) . ToString ( ) . PadLeft ( 5 , '0' ) ;
2014-07-09 23:04:22 +00:00
}
else
{
2014-08-19 19:24:17 +00:00
if ( index < _currentTasMovie . InputLogLength )
2014-07-16 23:04:56 +00:00
{
2014-08-19 19:24:17 +00:00
text = _currentTasMovie . DisplayValue ( index , columnName ) ;
2014-07-16 23:04:56 +00:00
}
2014-08-19 19:24:17 +00:00
else if ( Global . Emulator . Frame = = _currentTasMovie . InputLogLength ) // In this situation we have a "pending" frame for the user to click
2014-07-16 23:04:56 +00:00
{
2014-08-29 01:59:08 +00:00
text = _currentTasMovie . CreateDisplayValueForButton (
2014-07-16 23:04:56 +00:00
Global . ClickyVirtualPadController ,
columnName ) ;
}
2014-07-09 23:04:22 +00:00
}
}
catch ( Exception ex )
{
text = string . Empty ;
MessageBox . Show ( "oops\n" + ex ) ;
}
}
#endregion
#region Events
2014-07-28 16:43:47 +00:00
private void TasView_ColumnClick ( object sender , ColumnClickEventArgs e )
{
2014-08-30 18:42:14 +00:00
if ( TasView . SelectedRows . Any ( ) )
2014-07-28 16:43:47 +00:00
{
var columnName = TasView . Columns [ e . Column ] . Name ;
if ( columnName = = FrameColumnName )
{
// TODO: add marker to LastSelectedIndex
}
else if ( columnName ! = MarkerColumnName ) // TODO: what about float?
{
2014-08-30 18:42:14 +00:00
foreach ( var index in TasView . SelectedRows )
2014-07-28 16:43:47 +00:00
{
ToggleBoolState ( index , columnName ) ;
}
RefreshDialog ( ) ;
}
}
}
2014-07-09 23:04:22 +00:00
private void TasView_MouseDown ( object sender , MouseEventArgs e )
{
2014-07-17 20:35:12 +00:00
if ( e . Button = = MouseButtons . Middle )
{
TogglePause ( ) ;
return ;
}
2014-08-31 17:15:21 +00:00
if ( TasView . CurrentCell ! = null & & TasView . CurrentCell . RowIndex . HasValue & & TasView . CurrentCell . Column ! = null )
2014-07-09 23:04:22 +00:00
{
2014-07-14 01:49:37 +00:00
if ( e . Button = = MouseButtons . Left )
2014-07-09 23:04:22 +00:00
{
2014-08-23 15:19:48 +00:00
if ( TasView . CurrentCell . Column . Name = = MarkerColumnName )
2014-07-10 20:40:50 +00:00
{
2014-07-14 01:49:37 +00:00
_startMarkerDrag = true ;
2014-08-23 13:14:25 +00:00
GoToFrame ( TasView . CurrentCell . RowIndex . Value ) ;
2014-07-14 01:49:37 +00:00
}
2014-08-23 15:19:48 +00:00
else if ( TasView . CurrentCell . Column . Name = = FrameColumnName )
2014-07-14 01:49:37 +00:00
{
_startFrameDrag = true ;
2014-07-10 20:40:50 +00:00
}
2014-08-22 14:42:31 +00:00
else //User changed input
2014-07-11 16:26:19 +00:00
{
2014-08-23 13:14:25 +00:00
var frame = TasView . CurrentCell . RowIndex . Value ;
2014-08-23 15:19:48 +00:00
var buttonName = TasView . CurrentCell . Column . Name ;
2014-07-14 01:49:37 +00:00
if ( Global . MovieSession . MovieControllerAdapter . Type . BoolButtons . Contains ( buttonName ) )
{
2014-08-23 15:19:48 +00:00
ToggleBoolState ( TasView . CurrentCell . RowIndex . Value , buttonName ) ;
2014-08-23 13:14:25 +00:00
GoToLastEmulatedFrameIfNecessary ( TasView . CurrentCell . RowIndex . Value ) ;
2014-07-14 01:49:37 +00:00
TasView . Refresh ( ) ;
2014-08-23 15:19:48 +00:00
_startBoolDrawColumn = buttonName ;
2014-08-19 19:24:17 +00:00
_boolPaintState = _currentTasMovie . BoolIsPressed ( frame , buttonName ) ;
2014-07-14 01:49:37 +00:00
}
else
{
2014-08-23 15:19:48 +00:00
_startFloatDrawColumn = buttonName ;
2014-08-19 19:24:17 +00:00
_floatPaintState = _currentTasMovie . GetFloatValue ( frame , buttonName ) ;
2014-07-14 01:49:37 +00:00
}
2014-07-11 16:26:19 +00:00
}
2014-07-09 23:04:22 +00:00
}
2014-08-23 01:18:05 +00:00
else if ( e . Button = = MouseButtons . Right )
{
2014-08-23 13:14:25 +00:00
var frame = TasView . CurrentCell . RowIndex . Value ;
2014-08-23 15:19:48 +00:00
var buttonName = TasView . CurrentCell . Column . Name ;
2014-08-30 18:42:14 +00:00
if ( TasView . SelectedRows . IndexOf ( frame ) ! = - 1 & & ( buttonName = = MarkerColumnName | | buttonName = = FrameColumnName ) )
2014-08-23 01:18:05 +00:00
{
2014-08-23 02:51:52 +00:00
//Disable the option to remove markers if no markers are selected (FCUEX does this).
2014-08-30 18:42:14 +00:00
RemoveMarkersContextMenuItem . Enabled = _currentTasMovie . Markers . Any ( m = > TasView . SelectedRows . Contains ( m . Frame ) ) ;
2014-08-23 01:18:05 +00:00
RightClickMenu . Show ( TasView , e . X , e . Y ) ;
}
}
2014-07-09 23:04:22 +00:00
}
}
private void TasView_MouseUp ( object sender , MouseEventArgs e )
{
_startMarkerDrag = false ;
_startFrameDrag = false ;
2014-07-11 16:26:19 +00:00
_startBoolDrawColumn = string . Empty ;
_startFloatDrawColumn = string . Empty ;
_floatPaintState = 0 ;
2014-07-09 23:04:22 +00:00
}
2014-07-16 01:37:50 +00:00
private void TasView_MouseWheel ( object sender , MouseEventArgs e )
{
2014-08-23 13:14:25 +00:00
if ( TasView . RightButtonHeld & & TasView . CurrentCell . RowIndex . HasValue )
2014-07-16 01:37:50 +00:00
{
if ( e . Delta < 0 )
{
2014-07-17 23:55:10 +00:00
GoToFrame ( Global . Emulator . Frame + 1 ) ;
2014-07-16 01:37:50 +00:00
}
else
{
2014-08-31 16:07:11 +00:00
if ( Global . Emulator . Frame > 0 )
{
GoToFrame ( Global . Emulator . Frame - 1 ) ;
}
2014-07-16 01:37:50 +00:00
}
}
}
private void TasView_MouseDoubleClick ( object sender , MouseEventArgs e )
{
2014-08-23 13:14:25 +00:00
if ( TasView . CurrentCell . RowIndex . HasValue & &
2014-08-23 15:19:48 +00:00
TasView . CurrentCell ! = null & &
2014-08-31 18:06:31 +00:00
TasView . CurrentCell . Column . Name = = FrameColumnName & &
e . Button = = MouseButtons . Left )
2014-07-16 01:37:50 +00:00
{
2014-08-23 13:14:25 +00:00
CallAddMarkerPopUp ( TasView . CurrentCell . RowIndex . Value ) ;
2014-07-16 01:37:50 +00:00
}
}
2014-08-23 15:19:48 +00:00
private void TasView_PointedCellChanged ( object sender , InputRoll . CellEventArgs e )
2014-07-09 23:04:22 +00:00
{
2014-08-23 15:19:48 +00:00
// TODO: think about nullability
// For now return if a null because this happens OnEnter which doesn't have any of the below behaviors yet?
// Most of these are stupid but I got annoyed at null crashes
if ( e . OldCell = = null | | e . OldCell . Column = = null | | e . OldCell . RowIndex = = null | |
e . NewCell = = null | | e . NewCell . RowIndex = = null | | e . NewCell . Column = = null )
{
return ;
}
2014-07-11 16:08:47 +00:00
int startVal , endVal ;
2014-08-23 13:14:25 +00:00
if ( e . OldCell . RowIndex . Value < e . NewCell . RowIndex . Value )
2014-07-11 16:08:47 +00:00
{
2014-08-23 13:14:25 +00:00
startVal = e . OldCell . RowIndex . Value ;
endVal = e . NewCell . RowIndex . Value ;
2014-07-11 16:08:47 +00:00
}
else
{
2014-08-23 13:14:25 +00:00
startVal = e . NewCell . RowIndex . Value ;
endVal = e . OldCell . RowIndex . Value ;
2014-07-11 16:08:47 +00:00
}
2014-07-09 23:04:22 +00:00
if ( _startMarkerDrag )
{
2014-08-23 13:14:25 +00:00
if ( e . NewCell . RowIndex . HasValue )
2014-07-09 23:04:22 +00:00
{
2014-08-23 13:14:25 +00:00
GoToFrame ( e . NewCell . RowIndex . Value ) ;
2014-07-09 23:04:22 +00:00
}
}
else if ( _startFrameDrag )
{
2014-08-23 13:14:25 +00:00
if ( e . OldCell . RowIndex . HasValue & & e . NewCell . RowIndex . HasValue )
2014-07-09 23:04:22 +00:00
{
2014-08-29 18:02:23 +00:00
for ( var i = startVal ; i < endVal ; i + + )
2014-07-09 23:04:22 +00:00
{
2014-08-31 15:40:02 +00:00
TasView . SelectRow ( i , true ) ;
2014-08-29 18:02:23 +00:00
TasView . Refresh ( ) ;
2014-07-09 23:04:22 +00:00
}
}
}
2014-08-23 13:14:25 +00:00
else if ( TasView . IsPaintDown & & e . NewCell . RowIndex . HasValue & & ! string . IsNullOrEmpty ( _startBoolDrawColumn ) )
2014-07-11 16:26:19 +00:00
{
2014-08-23 13:14:25 +00:00
if ( e . OldCell . RowIndex . HasValue & & e . NewCell . RowIndex . HasValue )
2014-07-11 16:26:19 +00:00
{
for ( var i = startVal ; i < endVal ; i + + )
{
2014-07-16 23:04:56 +00:00
SetBoolState ( i , _startBoolDrawColumn , _boolPaintState ) ; // Notice it uses new row, old column, you can only paint across a single column
2014-08-23 13:14:25 +00:00
GoToLastEmulatedFrameIfNecessary ( TasView . CurrentCell . RowIndex . Value ) ;
2014-07-11 16:26:19 +00:00
}
TasView . Refresh ( ) ;
}
}
2014-08-23 13:14:25 +00:00
else if ( TasView . IsPaintDown & & e . NewCell . RowIndex . HasValue & & ! string . IsNullOrEmpty ( _startFloatDrawColumn ) )
2014-07-09 23:04:22 +00:00
{
2014-08-23 13:14:25 +00:00
if ( e . OldCell . RowIndex . HasValue & & e . NewCell . RowIndex . HasValue )
2014-07-11 16:08:47 +00:00
{
for ( var i = startVal ; i < endVal ; i + + )
{
2014-08-19 19:24:17 +00:00
if ( i < _currentTasMovie . InputLogLength ) // TODO: how do we really want to handle the user setting the float state of the pending frame?
2014-07-16 23:04:56 +00:00
{
2014-08-19 19:24:17 +00:00
_currentTasMovie . SetFloatState ( i , _startFloatDrawColumn , _floatPaintState ) ; // Notice it uses new row, old column, you can only paint across a single column
2014-08-23 13:14:25 +00:00
GoToLastEmulatedFrameIfNecessary ( TasView . CurrentCell . RowIndex . Value ) ;
2014-07-16 23:04:56 +00:00
}
2014-07-11 16:08:47 +00:00
}
2014-07-11 16:26:19 +00:00
2014-07-11 16:08:47 +00:00
TasView . Refresh ( ) ;
}
2014-07-09 23:04:22 +00:00
}
}
private void TasView_SelectedIndexChanged ( object sender , EventArgs e )
{
SetSplicer ( ) ;
}
2014-07-17 19:57:44 +00:00
private void TasView_KeyDown ( object sender , KeyEventArgs e )
{
if ( e . Control & & ! e . Shift & & ! e . Alt & & e . KeyCode = = Keys . Left ) // Ctrl + Left
{
GoToPreviousMarker ( ) ;
}
else if ( e . Control & & ! e . Shift & & ! e . Alt & & e . KeyCode = = Keys . Right ) // Ctrl + Left
{
GoToNextMarker ( ) ;
}
2014-07-25 01:02:24 +00:00
else if ( e . Control & & ! e . Shift & & ! e . Alt & & e . KeyCode = = Keys . Up ) // Ctrl + Up
{
GoToPreviousFrame ( ) ;
}
else if ( e . Control & & ! e . Shift & & ! e . Alt & & e . KeyCode = = Keys . Down ) // Ctrl + Down
{
GoToNextFrame ( ) ;
}
2014-07-17 19:57:44 +00:00
}
2014-07-09 23:04:22 +00:00
#endregion
}
}