Tweaks from SB2 importer audit (#137)

* Fix SB2 variable imports!

* Fix expectedArg field types

* motion_pointindirection uses math_angle

* Fix "think for secs" expected input

* Add handling for empty input case (empty if-else, for example)

* Fix opcodes for if_else, repeat_until, set tempo

* Specialized number fields for SB2 import

* Convert color picker numbers to hex in SB2 import

* KEY_OPTIONS -> KEY_OPTION

* Backdrop blocks get BACKDROP

* Update toolbox XML to match naming changes

* Merge in math_angle case

* Move color converter to its own utility

* Fix merge conflicts

* Add negative color check.

* Fix keyoptions naming

* Pen JSON tweak post-scratch-blocks update
This commit is contained in:
Tim Mickel 2016-09-06 11:46:10 -04:00 committed by GitHub
parent 9a8b68643a
commit 3dbfc3fdb6
4 changed files with 65 additions and 38 deletions

View file

@ -205,12 +205,12 @@
<block type="looks_nextcostume"></block> <block type="looks_nextcostume"></block>
<block type="looks_nextbackdrop"></block> <block type="looks_nextbackdrop"></block>
<block type="looks_switchbackdropto"> <block type="looks_switchbackdropto">
<value name="COSTUME"> <value name="BACKDROP">
<shadow type="looks_backdrops"></shadow> <shadow type="looks_backdrops"></shadow>
</value> </value>
</block> </block>
<block type="looks_switchbackdroptoandwait"> <block type="looks_switchbackdroptoandwait">
<value name="COSTUME"> <value name="BACKDROP">
<shadow type="looks_backdrops"></shadow> <shadow type="looks_backdrops"></shadow>
</value> </value>
</block> </block>
@ -503,7 +503,7 @@
</block> </block>
<block type="sensing_answer"></block> <block type="sensing_answer"></block>
<block type="sensing_keypressed"> <block type="sensing_keypressed">
<value name="KEY_OPTIONS"> <value name="KEY_OPTION">
<shadow type="sensing_keyoptions"></shadow> <shadow type="sensing_keyoptions"></shadow>
</value> </value>
</block> </block>

View file

@ -5,9 +5,9 @@
* scratch-vm runtime structures. * scratch-vm runtime structures.
*/ */
var Sprite = require('../sprites/sprite');
var Blocks = require('../engine/blocks'); var Blocks = require('../engine/blocks');
var Sprite = require('../sprites/sprite');
var Color = require('../util/color.js');
var uid = require('../util/uid'); var uid = require('../util/uid');
var specMap = require('./sb2specmap'); var specMap = require('./sb2specmap');
@ -204,10 +204,10 @@ function parseBlock (sb2block) {
block: null, block: null,
shadow: null shadow: null
}; };
if (typeof providedArg == 'object') { if (typeof providedArg == 'object' && providedArg) {
// Block or block list occupies the input. // Block or block list occupies the input.
var innerBlocks; var innerBlocks;
if (typeof providedArg[0] == 'object') { if (typeof providedArg[0] == 'object' && providedArg[0]) {
// Block list occupies the input. // Block list occupies the input.
innerBlocks = parseBlockList(providedArg); innerBlocks = parseBlockList(providedArg);
} else { } else {
@ -224,7 +224,6 @@ function parseBlock (sb2block) {
); );
} }
// Generate a shadow block to occupy the input. // Generate a shadow block to occupy the input.
// The shadow block is either visible or obscured.
if (!expectedArg.inputOp) { if (!expectedArg.inputOp) {
// No editable shadow input; e.g., for a boolean. // No editable shadow input; e.g., for a boolean.
continue; continue;
@ -234,7 +233,11 @@ function parseBlock (sb2block) {
var fieldValue = providedArg; var fieldValue = providedArg;
// Shadows' field names match the input name, except for these: // Shadows' field names match the input name, except for these:
var fieldName = expectedArg.inputName; var fieldName = expectedArg.inputName;
if (expectedArg.inputOp == 'math_number') { if (expectedArg.inputOp == 'math_number' ||
expectedArg.inputOp == 'math_whole_number' ||
expectedArg.inputOp == 'math_positive_number' ||
expectedArg.inputOp == 'math_integer' ||
expectedArg.inputOp == 'math_angle') {
fieldName = 'NUM'; fieldName = 'NUM';
// Fields are given Scratch 2.0 default values if obscured. // Fields are given Scratch 2.0 default values if obscured.
if (shadowObscured) { if (shadowObscured) {
@ -246,7 +249,9 @@ function parseBlock (sb2block) {
fieldValue = ''; fieldValue = '';
} }
} else if (expectedArg.inputOp == 'colour_picker') { } else if (expectedArg.inputOp == 'colour_picker') {
fieldName = 'COLOR'; // Convert SB2 color to hex.
fieldValue = Color.scratchColorToHex(providedArg);
fieldName = 'COLOUR';
if (shadowObscured) { if (shadowObscured) {
fieldValue = '#990000'; fieldValue = '#990000';
} }
@ -266,7 +271,7 @@ function parseBlock (sb2block) {
shadow: true shadow: true
}); });
activeBlock.inputs[expectedArg.inputName].shadow = inputUid; activeBlock.inputs[expectedArg.inputName].shadow = inputUid;
// If no block occupying the input, alias the block to the shadow. // If no block occupying the input, alias to the shadow.
if (!activeBlock.inputs[expectedArg.inputName].block) { if (!activeBlock.inputs[expectedArg.inputName].block) {
activeBlock.inputs[expectedArg.inputName].block = inputUid; activeBlock.inputs[expectedArg.inputName].block = inputUid;
} }

View file

@ -44,7 +44,7 @@ var specMap = {
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_angle',
'inputName':'DIRECTION' 'inputName':'DIRECTION'
} }
] ]
@ -210,7 +210,7 @@ var specMap = {
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_number',
'inputName':'MESSAGE' 'inputName':'SECS'
} }
] ]
}, },
@ -255,7 +255,7 @@ var specMap = {
{ {
'type':'input', 'type':'input',
'inputOp':'looks_backdrops', 'inputOp':'looks_backdrops',
'inputName':'COSTUME' 'inputName':'BACKDROP'
} }
] ]
}, },
@ -324,7 +324,7 @@ var specMap = {
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_integer',
'inputName':'NUM' 'inputName':'NUM'
} }
] ]
@ -350,7 +350,7 @@ var specMap = {
{ {
'type':'input', 'type':'input',
'inputOp':'looks_backdrops', 'inputOp':'looks_backdrops',
'inputName':'COSTUME' 'inputName':'BACKDROP'
} }
] ]
}, },
@ -475,7 +475,7 @@ var specMap = {
] ]
}, },
'setTempoTo:':{ 'setTempoTo:':{
'opcode':'sound_settempoto', 'opcode':'sound_settempotobpm',
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
@ -545,12 +545,12 @@ var specMap = {
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_number',
'inputName':'XXXNAME' 'inputName':'SHADE'
} }
] ]
}, },
'setPenShadeTo:':{ 'setPenShadeTo:':{
'opcode':'pen_changepenshadeto', 'opcode':'pen_changepenshadeby',
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
@ -653,7 +653,7 @@ var specMap = {
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_positive_number',
'inputName':'DURATION' 'inputName':'DURATION'
} }
] ]
@ -663,7 +663,7 @@ var specMap = {
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_whole_number',
'inputName':'TIMES' 'inputName':'TIMES'
}, },
{ {
@ -695,7 +695,7 @@ var specMap = {
] ]
}, },
'doIfElse':{ 'doIfElse':{
'opcode':'control_ifelse', 'opcode':'control_if_else',
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
@ -712,7 +712,7 @@ var specMap = {
] ]
}, },
'doWaitUntil':{ 'doWaitUntil':{
'opcode':'control_waituntil', 'opcode':'control_wait_until',
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
@ -721,7 +721,7 @@ var specMap = {
] ]
}, },
'doUntil':{ 'doUntil':{
'opcode':'control_repeatuntil', 'opcode':'control_repeat_until',
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
@ -829,7 +829,7 @@ var specMap = {
{ {
'type':'input', 'type':'input',
'inputOp':'sensing_keyoptions', 'inputOp':'sensing_keyoptions',
'inputName':'KEY_OPTIONS' 'inputName':'KEY_OPTION'
} }
] ]
}, },
@ -1108,7 +1108,7 @@ var specMap = {
'argMap':[ 'argMap':[
{ {
'type':'input', 'type':'input',
'inputOp':'math_number', 'inputOp':'math_whole_number',
'inputName':'LETTER' 'inputName':'LETTER'
}, },
{ {
@ -1169,11 +1169,12 @@ var specMap = {
] ]
}, },
'readVariable':{ 'readVariable':{
'opcode':'data_getvariable', 'opcode':'data_variable',
'argMap':[ 'argMap':[
{ {
'type':'field', 'type':'input',
'fieldName':'VARIABLE' 'inputOp':'data_variablemenu',
'inputName':'VARIABLE'
} }
] ]
}, },
@ -1181,8 +1182,9 @@ var specMap = {
'opcode':'data_setvariableto', 'opcode':'data_setvariableto',
'argMap':[ 'argMap':[
{ {
'type':'field', 'type':'input',
'fieldName':'VARIABLE' 'inputOp':'data_variablemenu',
'inputName':'VARIABLE'
}, },
{ {
'type':'input', 'type':'input',
@ -1195,8 +1197,9 @@ var specMap = {
'opcode':'data_changevariableby', 'opcode':'data_changevariableby',
'argMap':[ 'argMap':[
{ {
'type':'field', 'type':'input',
'fieldName':'VARIABLE' 'inputOp':'data_variablemenu',
'inputName':'VARIABLE'
}, },
{ {
'type':'input', 'type':'input',
@ -1209,8 +1212,9 @@ var specMap = {
'opcode':'data_showvariable', 'opcode':'data_showvariable',
'argMap':[ 'argMap':[
{ {
'type':'field', 'type':'input',
'fieldName':'VARIABLE' 'inputOp':'data_variablemenu',
'inputName':'VARIABLE'
} }
] ]
}, },
@ -1218,8 +1222,9 @@ var specMap = {
'opcode':'data_hidevariable', 'opcode':'data_hidevariable',
'argMap':[ 'argMap':[
{ {
'type':'field', 'type':'input',
'fieldName':'VARIABLE' 'inputOp':'data_variablemenu',
'inputName':'VARIABLE'
} }
] ]
}, },

17
src/util/color.js Normal file
View file

@ -0,0 +1,17 @@
function Color () {}
/**
* Convert a Scratch color number to a hex string, #RRGGBB.
* @param {number} color RGB color as a decimal.
* @return {string} RGB color as #RRGGBB hex string.
*/
Color.scratchColorToHex = function (color) {
if (color < 0) {
color += 0xFFFFFF + 1;
}
var hex = Number(color).toString(16);
hex = '#' + '000000'.substr(0, 6 - hex.length) + hex;
return hex;
};
module.exports = Color;