This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#576 2010-10-28 17:35:20

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Lets make a new Scratch viewer!

midnightleopard wrote:

gosh I thought I knew something about canvas- then I read these posts.

XD, I hardly know anything about it, but I knew that drawing a sprite pixel by pixel would be slow.


http://block.site90.net/scratch.mit/text.php?size=30&text=%20A%20signature!&color=333333

Offline

 

#577 2010-10-28 20:35:21

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Lets make a new Scratch viewer!

johnnydean1 wrote:

Remember rotation. It can be hard to do with PHP and JScript and HTML4

Not with save(), restore(), and transformations!  smile
(at least I think that's what they're called...they let you pop transformations onto a stack, then restore them later)


nXIII

Offline

 

#578 2010-10-28 20:40:10

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Lets make a new Scratch viewer!

nXIII wrote:

johnnydean1 wrote:

Remember rotation. It can be hard to do with PHP and JScript and HTML4

Not with save(), restore(), and transformations!  smile
(at least I think that's what they're called...they let you pop transformations onto a stack, then restore them later)

Wow! You're a living dictionary... Uh, I mean API!


http://block.site90.net/scratch.mit/text.php?size=30&text=%20A%20signature!&color=333333

Offline

 

#579 2010-10-28 20:42:30

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Lets make a new Scratch viewer!

MathWizz wrote:

nXIII wrote:

johnnydean1 wrote:

Remember rotation. It can be hard to do with PHP and JScript and HTML4

Not with save(), restore(), and transformations!  smile
(at least I think that's what they're called...they let you pop transformations onto a stack, then restore them later)

Wow! You're a living dictionary... Uh, I mean API!

LOL, I think I've used canvases like three times... I just remembered that from reading a tutorial  tongue
I would HIGHLY recommend MDC to everyone. They have tons of tutorials and reference for everything you'd ever want to know.  big_smile
EDIT: Well, apparently it's called MDN on their front page...but it's MDC everywhere else  tongue

Last edited by nXIII (2010-10-28 20:42:59)


nXIII

Offline

 

#580 2010-10-28 20:57:14

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Lets make a new Scratch viewer!

nXIII wrote:

MathWizz wrote:

nXIII wrote:


Not with save(), restore(), and transformations!  smile
(at least I think that's what they're called...they let you pop transformations onto a stack, then restore them later)

Wow! You're a living dictionary... Uh, I mean API!

LOL, I think I've used canvases like three times... I just remembered that from reading a tutorial  tongue
I would HIGHLY recommend MDC to everyone. They have tons of tutorials and reference for everything you'd ever want to know.  big_smile
EDIT: Well, apparently it's called MDN on their front page...but it's MDC everywhere else  tongue

I've seen that site before! Very handy.

BTW: How far have you gotten reading a Scratch file with php?


http://block.site90.net/scratch.mit/text.php?size=30&text=%20A%20signature!&color=333333

Offline

 

#581 2010-10-28 21:44:34

midnightleopard
Scratcher
Registered: 2007-09-13
Posts: 1000+

Re: Lets make a new Scratch viewer!

yeah. Canvas is amazing, you can have it draw the text from the entire harry potter series several times, then make it scroll around without a lag.


http://pwp.wizards.com/5103673563/Scorecards/Landscape.png

Offline

 

#582 2010-10-28 21:50:07

midnightleopard
Scratcher
Registered: 2007-09-13
Posts: 1000+

Re: Lets make a new Scratch viewer!

okay. I am learning how to control canvas with JavaScript, while I wait for some of you to finish the decoding in PHP, perhaps I can make us a website? (better)


http://pwp.wizards.com/5103673563/Scorecards/Landscape.png

Offline

 

#583 2010-10-29 03:44:54

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

^ hang on for a second. Someones doing a template.


You can now reach me on Twitter @johnnydean1_

Offline

 

#584 2010-10-29 05:28:18

Daffy22
Scratcher
Registered: 2008-12-15
Posts: 500+

Re: Lets make a new Scratch viewer!

Yeah, I've made a template!  big_smile


http://img201.imageshack.us/img201/1784/logosmalle.png
"Spectacular - 5 Star" -  CNET.com Editor.

Offline

 

#585 2010-10-29 09:35:02

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Lets make a new Scratch viewer!

Uhg... Can someone else please finish the PHP reader? I just can't fix it! It's here.

Last edited by MathWizz (2010-10-29 12:54:50)


http://block.site90.net/scratch.mit/text.php?size=30&text=%20A%20signature!&color=333333

Offline

 

#586 2010-10-29 12:07:17

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

How do I get the code?


You can now reach me on Twitter @johnnydean1_

Offline

 

#587 2010-10-29 12:28:23

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Lets make a new Scratch viewer!

I could try.


/* No comment */

Offline

 

#588 2010-10-29 12:51:26

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Lets make a new Scratch viewer!

johnnydean1 wrote:

How do I get the code?

Use FTP... Oh, you don't have the FTP details do you.

Code:

<?php
$class_id = array(1 => "UndefinedObject", 2 => "True", 3 => "False", 4 => "SmallInteger", 5 => "SmallInteger16", 6 => "LargePositiveInteger", 7 => "LargeNegativeInteger", 8 => "Float", 9 => "String", 10 => "Symbol", 11 => "ByteArray", 12 => "SoundBuffer", 13 => "Bitmap", 14 => "UTF8", 20 => "Array", 21 => "OrderedCollection", 22 => "Set", 23 => "IdentitySet", 24 => "Dictionary", 25 => "IdentityDictionary", 30 => "Color", 31 => "TranslucentColor", 32 => "Point", 33 => "Rectangle", 34 => "Form", 35 => "ColorForm", 99 => "ObjectRef", 100 => "Morph", 101 => "BorderedMorph", 102 => "RectangleMorph", 103 => "EllipseMorph", 104 => "AlignmentMorph", 105 => "StringMorph", 106 => "UpdatingStringMorph", 107 => "SimpleSliderMorph", 108 => "SimpleButtonMorph", 109 => "SampledSound", 110 => "ImageMorph", 111 => "SketchMorph", 123 => "SensorBoardMorph", 124 => "ScratchSpriteMorph", 125 => "ScratchStageMorph", 140 => "ChoiceArgMorph", 141 => "ColorArgMorph", 142 => "ExpressionArgMorph", 145 => "SpriteArgMorph", 147 => "BlockMorph", 148 => "CommandBlockMorph", 149 => "CBlockMorph", 151 => "HatBlockMorph", 153 => "ScratchScriptsMorph", 154 => "ScratchSliderMorph", 155 => "WatcherMorph", 157 => "SetterBlockMorph", 158 => "EventHatMorph", 160 => "VariableBlockMorph", 162 => "ImageMedia", 163 => "MovieMedia", 164 => "SoundMedia", 165 => "KeyEventHatMorph", 166 => "BooleanArgMorph", 167 => "EventTitleMorph", 168 => "MouseClickEventHatMorph", 169 => "ExpressionArgMorphWithMenu", 170 => "ReporterBlockMorph", 171 => "MultilineStringMorph", 172 => "ToggleButton", 173 => "WatcherReadoutFrameMorph", 174 => "WatcherSliderMorph");
$file = array();
$objects = array();

foreach (str_split(file_get_contents($_FILES["sbfile"]["tmp_name"])) as $byte)
{
    array_push($file, ord($byte));
}

if (read_header())
{
    if (next_string(2) == 0)
    {
        die("This project is too old!");
    }
    else
    {
        next_uint(4);
        read_object();
        $object = read_object();
        //print_objects($object);
        
        //echo "<hr>";
        
        $object = fix_object(0);
        print_r($object);
    }
}
else
{
    die("This file is not a Scratch file!");
}

function next_byte()
{
    static $i = 0;
    $n = $GLOBALS["file"][$i];
    $i++;
    return $n;
}

function next_length($length)
{
    $array = array();
    for ($i = 1; $i <= $length; $i++)
    {
        array_push($array, next_byte());
    }
    return $array;
}

function read_header()
{
    return next_string(8) == "ScratchV";
}

function next_string($length)
{
    $string = "";
    foreach (next_length($length) as $byte)
    {
        $string = $string . chr($byte);
    }
    return $string;
}

function next_uint($length)
{
    $int = 0;
    $i = 1;
    foreach (array_reverse(next_length($length)) as $byte)
    {
        $int += $byte * $i;
        $i *= 256;
    }
    return $int;
}

function next_int($length)
{
    $int = 0;
    $i = 1;
    foreach (next_length($length) as $byte)
    {
        $int += $byte * $i;
        $i *= 256;
    }
    return $int;
}

function read_obj_header()
{
    return next_string(4) == 'ObjS' && next_byte() == 1 && next_string(4) == 'Stch' && next_byte() == 1;
}

function read_object()
{
    if (read_obj_header())
    {
        $size = next_uint(4);
        
        $fields = array();
        for ($i = 1; $i <= $size; $i++)
        {
            $field = read_field();
            array_push($fields, $field);
        }
        return $fields;
    }
    else
    {
        die("Not an Object!");
    }
}

function read_field()
{
    $class_ID = next_byte();
    $class_name = $GLOBALS["class_id"][$class_ID];
    switch ($class_name)
    {    
        case "ObjectRef":
            $result = array(next_uint(3));
            break;
        case "UndefinedObject":
            $result = array();
            break;
        case "True":
            $result = array();
            break;
        case "False":
            $result = array();
            break;
        case "SmallInteger":
            $result = array(next_uint(4));
            break;
        case "SmallInteger16":
            $result = array(next_uint(2));
            break;
        case "Float":
            $result = array(next_uint(4), next_uint(4));
            break;
        case "String":
            $result = array(next_string(next_uint(4)));
            break;
        case "Symbol":
            $result = array(next_string(next_uint(4)));
            break;
        case "ByteArray":
            $result = array(next_length(next_uint(4)));
            break;
        /*case "SoundBuffer":
            $size = next_uint(4);
            $result = array();
            for ($i = 1; $i <= $size; $i++)
            {
                array_push($result, read_field());
            }
            $result = array("SoundBuffer", $result, false, false);
            break;*/
        case "UTF8":
            $result = array(next_string(next_uint(4)));
            break;
        case "Array":
            $size = next_uint(4);
            $result = array();
            for ($i = 1; $i <= $size; $i++)
            {
                array_push($result, read_field());
            }
            break;
        case "OrderedCollection":
            $size = next_uint(4);
            $result = array();
            for ($i = 1; $i <= $size; $i++)
            {
                array_push($result, read_field());
            }
            break;
        case "Dictionary":
            $size = next_uint(4);
            $result = array();
            for ($i = 1; $i <= $size; $i++)
            {
                $key = read_field();
                $value = read_field();
                array_push($result, $key, $value);
            }
            break;
        case "Color":
            $result = array(next_uint(4));
            break;
        case "TranslucentColor":
            $result = array(next_uint(4), next_byte());
            break;
        case "Point":
            $result = array(read_field(), read_field());
            break;
        case "Rectangle":
            $result = array(read_field(), read_field(), read_field(), read_field());
            break;
        case "Form":
            $width = read_field();
            $height = read_field();
            $depth = read_field();
            $offset = read_field();
            $bits = read_field();
            $result = array($width, $height, $depth, $offset, $bits);
            break;
        case "ColorForm":
            $width = read_field();
            $height = read_field();
            $depth = read_field();
            $offset = read_field();
            $bits = read_field();
            $colors = read_field();
            $result = array($width, $height, $depth, $offset, $bits, $colors);
            break;
        default:
            if($class_ID >= 100 && $class_ID <= 174)
            {
                $version = next_byte();
                $size = next_byte();
                $result = array();
                for ($i = 1; $i <= $size; $i++)
                {
                    $value = read_field();
                    array_push($result, $value);
                }
                return array($class_name, $result, true, false);
            }
            else
            {
                die("Unknown classID: " . $class_ID . "<br/>");
            }
    }
    return array($class_name, $result, false, false);
}

function fix_object($object_num)
{
    global $object;
    print_r($object);
    $class_name = $object[$object_num][0];
    if($object[$object_num][3])
    {
        return $object[$object_num];
    }
    switch ($class_name)
    {
        case "Array":
            $result = array();
            for ($i = 0; $i < count($object[$object_num][1]); $i++)
            {
                $value = object_from($object[$object_num][1][$i]);
                array_push($result, $value);
            }
            break;
        case "OrderedCollection":
            $result = array();
            for ($i = 0; $i < count($object[$object_num][1]); $i++)
            {
                $value = object_from($object[$object_num][1][$i]);
                array_push($result, $value);
            }
            break;
        case "Dictionary":
            $result = array();
            for ($i = 0; $i < count($object[$object_num][1]); $i++)
            {
                $value = object_from($object[$object_num][1][$i]);
                array_push($result, $value);
            }
            break;
        case "Form":
            $width = object_from($object[$object_num][1][0]);
            $height = object_from($object[$object_num][1][1]);
            $depth = object_from($object[$object_num][1][2]);
            $offset = object_from($object[$object_num][1][3]);
            $bits = object_from($object[$object_num][1][4]);
            $result = array($width, $height, $depth, $offset, $bits);
            break;
        case "ColorForm":
            $width = object_from($object[$object_num][1][0]);
            $height = object_from($object[$object_num][1][1]);
            $depth = object_from($object[$object_num][1][2]);
            $offset = object_from($object[$object_num][1][3]);
            $bits = object_from($object[$object_num][1][4]);
            $colors = object_from($object[$object_num][1][5]);
            $result = array($width, $height, $depth, $offset, $bits, $colors);
            break;
        default:
            if($object[$object_num][2])
            {
                $result = array();
                for ($i = 0; $i < count($object[$object_num][1]); $i++)
                {
                    $value = object_from($object[$object_num][1][$i]);
                    array_push($result, $value);
                    //print_r($object[$object_num][1][$i] = $value);
                }
                $result = array($object[$object_num][0], $result);
            }
            else
            {
                $result = $object[$object_num];
            }
    }
    $object[$object_num][3] = true;
    print_r($object);
    exit;
    //print_object($result);
    return array($class_name, $result, $object[$object_num][2], true);
}

function object_from($object_ref)
{
    global $object;
    if ($object_ref[0] != "ObjectRef")
    {
        return $object_ref;
    }
    $temp = fix_object($object_ref[1][0] - 1);
    $object[$object_ref[1][0] - 1] = $temp;
    return $temp;
}

function print_objects($objects)
{
    for ($i = 0; $i < count($objects); $i++)
    {
        echo "[" . $i . "] => " . $objects[$i][0] . "(";
        foreach ($objects[$i][1] as $item) {
            echo $item[0];
            if($item[0] == "ObjectRef")
            {
                echo "(" . $item[1][0] . ")";
            }
            echo ", ";
        }
        echo ")<br/>";
    }
}
?>

XD


http://block.site90.net/scratch.mit/text.php?size=30&amp;text=%20A%20signature!&amp;color=333333

Offline

 

#589 2010-10-29 13:13:00

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

Thanks!


You can now reach me on Twitter @johnnydean1_

Offline

 

#590 2010-10-29 16:10:09

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Lets make a new Scratch viewer!

MathWizz wrote:

How far have you gotten reading a Scratch file with php?

I did it in JS. I forget how, though...lemme check. Ah. That's it. What I did was use unpack("H*") to get the binary of the file in PHP,

EDIT: There's a hexdec() somewhere in there, too.

then echoed that to the JS with

Code:

"var raw = [" . implode(",", $raw) . "];"

I then made a new ByteArray JS class:

Code:

function ByteArray(value) {...}
ByteArray.prototype.read = function(length) {...}
ByteArray.prototype.next = function(length) {...}
ByteArray.prototype.uint32 = function() {...}
ByteArray.prototype.uint16 = function() {...}
ByteArray.prototype.asString = function() {...}
ByteArray.prototype.asInt = function() {...}

So I could convert between raw byte data (next(...)), string data (read(...) or next(...).asString()), and integers (next(...).asInt() or the uint32() and uint16() functions).
I then just used really big switch statements copied from a decompiled version of the Java player source code. For images, I got the byte data and drew it pixel-by-pixel on a new canvas element (dynamically created and never added to the page), then used the toDataURL() to get a faster version.

Last edited by nXIII (2010-10-29 16:12:25)


nXIII

Offline

 

#591 2010-10-29 16:26:24

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

^ so it works?


You can now reach me on Twitter @johnnydean1_

Offline

 

#592 2010-10-29 16:27:15

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Lets make a new Scratch viewer!

johnnydean1 wrote:

^ so it works?

What do you mean?


nXIII

Offline

 

#593 2010-10-29 16:28:36

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

So have you made a working viewer?


You can now reach me on Twitter @johnnydean1_

Offline

 

#594 2010-10-29 16:39:15

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Lets make a new Scratch viewer!

johnnydean1 wrote:

So have you made a working viewer?

That was going to be my question.

Any progress on the reader JD1?


http://block.site90.net/scratch.mit/text.php?size=30&amp;text=%20A%20signature!&amp;color=333333

Offline

 

#595 2010-10-29 17:08:26

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Lets make a new Scratch viewer!

MathWizz wrote:

johnnydean1 wrote:

So have you made a working viewer?

That was going to be my question.

No, I was mostly working on the UI and dragging engine right now:
http://i54.tinypic.com/16k4zgm.jpg
[+] click to enlarge

Last edited by nXIII (2010-10-29 17:09:12)


nXIII

Offline

 

#596 2010-10-29 17:57:27

midnightleopard
Scratcher
Registered: 2007-09-13
Posts: 1000+

Re: Lets make a new Scratch viewer!

nXIII wrote:

MathWizz wrote:

johnnydean1 wrote:

So have you made a working viewer?

That was going to be my question.

No, I was mostly working on the UI and dragging engine right now:
http://i54.tinypic.com/16k4zgm.jpg
[+] click to enlarge

HOLY FRIJOLES


http://pwp.wizards.com/5103673563/Scorecards/Landscape.png

Offline

 

#597 2010-10-30 05:36:21

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

^ MathWizz
I have the same problem as you. I cant see the error!


You can now reach me on Twitter @johnnydean1_

Offline

 

#598 2010-10-30 06:28:56

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Lets make a new Scratch viewer!

You could try my PHP debugging trick of echoing the dodgy variables and seeing what they are.


/* No comment */

Offline

 

#599 2010-10-30 06:42:03

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Lets make a new Scratch viewer!

Can you do that Successor?


You can now reach me on Twitter @johnnydean1_

Offline

 

#600 2010-10-30 06:50:33

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Lets make a new Scratch viewer!

I'll try.


/* No comment */

Offline

 

Board footer