// ... splice this page with the previous ... of chapter 20.
// We have to overload the resize method for diamonds
// (unlike the other objects) because diamond shapes
// have to be symmetrical. That is, the width and
// the height have to be the same. This code enforces
// this restriction by setting both parameters to the
// minimum of the width/height parameters and then it
// calls shape.resize to do the dirty work.
method diamond.resize( width:uns32; height:uns32 ); @nodisplay;
begin resize;
// Diamonds are symmetrical shapes, so the width and
// height must be the same. Force that here:
push( eax );
mov( width, eax );
if( eax > height ) then
mov( height, eax );
endif;
// Call the shape.resize method to do the actual work:
push( eax ); // Pass the minimum value as the width.
push( eax ); // Also pass the minimum value as the height.
call( shape._VMT_[ @offset( shape.resize ) ] );
pop( eax );
end resize;
// Here's the code to draw the diamond.
method diamond.draw; @nodisplay;
var
startR: uns32;
endR: uns32;
startC: uns32;
endC: uns32;
begin draw;
push( eax );
push( ebx );
push( ecx );
push( edx );
if
(#{
cmp( this.width, 2 );
jb true;
cmp( this.height, 2 );
jae false;
}#) then
// Special cases for small diamonds.
// Resizing prevents most of these from ever appearing.
// However, if someone pokes around directly in the
// width and height fields this code will save us:
cmp( this.width, 1 );
ja D2x1;
cmp( this.height, 1 );
ja D1x2;
// At this point we must have a 1x1 diamond
console.gotorc( this.R, this.C );
stdout.putc( '+' );
jmp SmallDiamondDone;
D2x1:
// Okay, we have a 2x1 (WxH) diamond here:
console.gotorc( this.R, this.C );
stdout.puts( "<>" );
jmp SmallDiamondDone;
D1x2:
// We have a 1x2 (WxH) diamond here:
mov( this.R, eax );
console.gotorc( eax, this.C );
stdout.putc( '^' );
inc( eax );
console.gotorc( eax, this.C );
stdout.putc( 'V' );
SmallDiamondDone:
else
// Okay, we're drawing a reasonable sized diamond.
// There is still a minor problem. The best looking
// diamonds always have a width and height that is an
// even integer. We need to do something special if
// the height or width is odd.
//
// Odd Odd
// Height Width
// . <- That's a period
// /\ / \
// < > \ /
// \/ ' <- That's an apostrophe
//
// Both
// .
// / \
// < >
// \ /
// '
//
// Step one: determine if we have an odd width. If so,
// output the period and quote at the appropriate points.
mov( this.width, eax );
mov( this.R, ecx );
test( 1, al );
if( @nz ) then
shr( 1, eax );
add( this.C, eax );
console.gotorc( ecx, eax );
stdout.putc( '.' );
inc( ecx );
mov( ecx, startR );
add( this.height, ecx );
sub( 2, ecx );
console.gotorc( ecx, eax );
stdout.putc( '''' );
dec( ecx );
mov( ecx, endR );
else
mov( this.R, eax );
mov( eax, startR );
add( this.height, eax );
dec( eax );
mov( eax, endR );
endif;
// Step two: determine if we have an odd height. If so,
// output the less than and greater than symbols at the
// appropriate spots (in the center of the diamond).
mov( this.height, eax );
mov( this.C, ecx );
test( 1, al );
if( @nz ) then
shr( 1, eax );
add( this.R, eax );
console.gotorc( eax, ecx );
stdout.putc( '<' );
inc( ecx );
mov( ecx, startC );
// Write spaces across the center if fillShape is true.
if( this.fillShape ) then
console.setAttrs( this.textCol, this.backCol );
lea( ebx, [ecx+1] );
mov( this.C, edx );
add( this.width, edx );
dec( edx );
while( ebx < edx ) do
stdout.putc( ' ' );
inc( ebx );
endwhile;
endif;
add( this.width, ecx );
sub( 2, ecx );
console.gotorc( eax, ecx );
stdout.putc( '>' );
dec( ecx );
mov( ecx, endC );
else
mov( this.C, eax );
mov( eax, startC );
add( this.width, eax );
dec( eax );
mov( eax, endC );
endif;
// Step three: fill in the sides of the diamond
//
// /\ '
// / \ O / \ (or something inbetween these two).
// \ / R < >
// \/ \ /
// '
// We've already drawn the points if there was an odd height
// or width, now we've just got to fill in the sides with
// "/" and "\" characters.
//
// Compute the middle two (or three) lines beginning with
// the "/" (decY) and "\" (incY) symbols:
//
// decY = (( startR + endR - 1 ) and $FFFE )/2
// incY = ( startR + endR )/2 + 1
mov( startR, eax );
add( endR, eax );
mov( eax, ebx );
dec( eax );
and( $FFFF_FFFE, eax ); // Force value to be even.
shr( 1, eax );
shr( 1, ebx );
inc( ebx );
// Fill in pairs of rows as long as we don't hit the bottom/top
// of the diamond:
while( (type int32 eax) >= (type int32 startR) ) do
// Draw the sides on the upper half of the diamond:
mov( startC, ecx );
mov( endC, edx );
console.gotorc( eax, ecx );
stdout.putc( '/' );
if( this.fillShape ) then
console.setAttrs( this.textCol, this.backCol );
inc( ecx );
while( ecx < edx ) do
stdout.putc( ' ' );
inc( ecx );
endwhile;
endif;
console.gotorc( eax, edx );
stdout.putc( '\' );
// Draw the sides on the lower half of the diamond:
mov( startC, ecx );
mov( endC, edx );
console.gotorc( ebx, ecx );
stdout.putc( '\' );
if( this.fillShape ) then
console.setAttrs( this.textCol, this.backCol );
inc( ecx );
while( ecx < edx ) do
stdout.putc( ' ' );
inc( ecx );
endwhile;
endif;
console.gotorc( ebx, edx );
stdout.putc( '/' );
inc( ebx );
dec( eax );
inc( startC );
dec( endC );
endwhile;
endif;
pop( edx );
pop( ecx );
pop( ebx );
pop( eax );
end draw;
end Shapes;
This is a big chapter to swallow ...take it in little steps.
We started off with little steps like mov( 3, eax ); add( 7, eax ); mov( eax, my_u32 ) ...
We have built up from primitive machine level instructions to some very sophisticated coding tools ... like OOP ...
After we, (mostly Randall here), put these last two shapes programs together ... With just the following 3 simple lines, we can put a very large number of distinct and precisely designed objects on the screen ... in almost instantaneous succession.
Recall this simple loop ...
// Now ... for the real fun, draw all of the objects
// on the screen using the following simple loop.
for( mov( 0, ebx ); ebx < 9; inc( ebx ) ) do
DrawList.draw[ ebx*4 ]();
endfor;
You may do well to read as much of Randy's material as possible if you are keen on being a Computer Scientist. I have already provided several links to HLA/Randy. But here is a good place to start: http://webster.cs.ucr.edu/
Google for others too. Also, take a look at C and C++. There are many free compilers, e-texts and tutorials. Here is a free tutorial for C
http://mindview.net/CDs/ThinkingInC/beta3 ... and a free DEV C/C++ compiler at
http://www.bloodshed.net/Same is true for Python. (Google for it or try here: http://www.python.org/~guido/ ) Also... take a look at HTML ... Hyper Text Markup Language ... the language of the WWW ... and see some of the more uptodate modifications. Try here: http://www.w3schools.com/
Remember the process, putting little things together ... until we end up with some amazingly big and powerful packages. But this one thing ... should be obvious ... but it is not so obvious today ...
Here it is.
It took somebody ... (many somebodies to put it all <the first computer> together.) ...
And so ... In the beginning God created the heavens and the earth ... it didn't just all happen by itself.
Even a beginner can see that it took a lot of intelligence, work, material ... to put together the first CPU ... and it took materials, energy, planning, work, design, purpose, language, coding, decoding ...etc ...to get it to do anything purposeful ... get the drift ... And look at all the work, planning, thinking ... since then to get to OOP ... and INTEL and LINUX !!!
Shalom shalom,
David
P.S. Take a further look at Chapter 17 ... and the program there. It is just a little French and English intro to the good news of our Creator ... and soon coming King of Kings. Try this link too ...
http://sites.google.com/site/andeveryeyeshallseehim/Yes ... it may NOT be that much longer until this most awesome event transpires:
* Behold, he cometh with clouds;
* and every eye shall see him,
* and they also which pierced him:
* and all kindreds of the earth shall wail because of him.
* Even so,
* Amen.
* (Revelation 1:7)