Here's a patch that gets the Minesweeper examine running again. It's not *correct*, in that the field-drawing math appears to do the wrong thing, but I couldn't find the easy way to fix that. Maths is hard.
I cleaned up just enough of the code to get it to do the wrong thing without crashing. That's progress, right? For what it's worth, the cleanup process included finding and fixing a few potentially buggy situations. That seems valuable; the changes to PIR have been improvements for the most part. (The object initialization and parameter passing style is still difficult enough that I really want to port the Perl 6 metaclass stuff. Any objections?) -- c $ diffstat fix_minesweeper.patch examples/sdl/anim_image.pir | 1 examples/sdl/minesweeper/field.pir | 231 ++++++++++--------------------- examples/sdl/minesweeper/mines.pir | 59 +++---- runtime/parrot/library/SDL/Button.pir | 39 ++--- runtime/parrot/library/SDL/LCD.pir | 37 +--- runtime/parrot/library/SDL/Rect.pir | 4 runtime/parrot/library/SDL/StopWatch.pir | 10 - 7 files changed, 145 insertions(+), 236 deletions(-)
=== examples/sdl/anim_image.pir ================================================================== --- examples/sdl/anim_image.pir (revision 22951) +++ examples/sdl/anim_image.pir (local) @@ -19,7 +19,6 @@ load_bytecode "library/SDL/Image.pir" load_bytecode "library/SDL/Sprite.pir" - .local pmc app .local int app_type === examples/sdl/minesweeper/field.pir ================================================================== --- examples/sdl/minesweeper/field.pir (revision 22951) +++ examples/sdl/minesweeper/field.pir (local) @@ -4,18 +4,13 @@ =head1 SYNOPSIS + # create the field + $I0 = find_type "Mines::Field" + field = new $I0 + # setup field properties - $P0 = new .Hash - $P0['width'] = 40 - $P0['height'] = 28 - $P0['mines'] = 0.1075 - $P0['level'] = 123 - $P0['screen'] = screen - $P0['debug'] = debug - # create the field - $I0 = find_type "Mines::Field" - field = new $I0, $P0 + field.'init'( 'width' => 40, 'height' => 28, 'mines' => 0.1075, 'level' => 123, 'screen' => screen, 'debug' => debug ) # draw the field field.'draw'() @@ -71,10 +66,9 @@ .const int STATUS_WON = 4 -=item __init( hash ) +=item init( %args ) -The constructor. You have to pass a hash filled with -the following values: +The constructor. Pass a set of key/value pairs where: =over 4 @@ -107,37 +101,32 @@ =cut -.sub __init method - .param pmc args +.sub 'init' :method + .param int width :named( 'width' ) + .param int height :named( 'height' ) + .param int level :named( 'level' ) + .param pmc screen :named( 'screen' ) + .param num mines :named( 'mines' ) + .param int debug :named( 'debug' ) + .local pmc field - .local pmc screen .local pmc cache - .local int width - .local int height - .local int level - .local num mines .local int val - .local int debug .local pmc lcd .local pmc watch - # get the arguments - width = args['width'] - height = args['height'] - level = args['level'] - mines = args['mines'] - screen = args['screen'] - debug = args['debug'] field = new .ResizablePMCArray cache = new .ResizablePMCArray $I0 = find_type 'SDL::StopWatch' - watch = new $I0, screen + watch = new $I0 + watch.'init'( screen ) watch.'xpos'( 515 ) watch.'ypos'( 5 ) $I0 = find_type 'SDL::LCD' lcd = new $I0 + lcd.'init'() # This seems to call __init() with too many parameters # lcd = 0 lcd.'_digits'( 4 ) @@ -145,63 +134,31 @@ lcd.'ypos'( 5 ) # set the attributes - $I0 = classoffset self, 'Mines::Field' - - # field - setattribute self, $I0, field - - # cache - inc $I0 - setattribute self, $I0, cache - - # screen - inc $I0 - setattribute self, $I0, screen - - # width - inc $I0 + setattribute self, 'field', field + setattribute self, 'cache', cache + setattribute self, 'screen', screen $P0 = new .Integer $P0 = width - setattribute self, $I0, $P0 - - # height - inc $I0 + setattribute self, 'width', $P0 $P0 = new .Integer $P0 = height - setattribute self, $I0, $P0 - - # mines - inc $I0 + setattribute self, 'height', $P0 $P0 = new .Float $P0 = mines - setattribute self, $I0, $P0 - - # markpos - inc $I0 + setattribute self, 'mines', $P0 $P0 = new .Integer $P0 = -1 - setattribute self, $I0, $P0 - - # debug - inc $I0 + setattribute self, 'markpos', $P0 $P0 = new .Integer $P0 = debug - setattribute self, $I0, $P0 + setattribute self, 'debug', $P0 + setattribute self, 'mines_lcd', lcd + setattribute self, 'watch', watch - # lcd - inc $I0 - setattribute self, $I0, lcd - - # watch - inc $I0 - setattribute self, $I0, watch - # button - inc $I0 - $P0 = new .String - $P0 = "examples/sdl/minesweeper/smiley.png" $I1 = find_type "SDL::Button" - $P0 = new $I1, $P0 + $P0 = new $I1 + $P0.'init'( "examples/sdl/minesweeper/smiley.png" ) $P0.'states'( 5 ) $P0.'pos'( 305, 2 ) $P0.'size'( 30, 30 ) @@ -211,7 +168,7 @@ $P0.'setAction'( STATUS_WON, $P1 ) $P0.'setAction'( STATUS_LOST, $P1 ) - setattribute self, $I0, $P0 + setattribute self, 'status_button', $P0 self.'newLevel'( level ) .end @@ -222,7 +179,7 @@ =cut -.sub newLevel method +.sub newLevel :method .param int level .local pmc field .local pmc cache @@ -233,28 +190,13 @@ .local num mines # get the attributes - $I0 = classoffset self, 'Mines::Field' - - # field - field = getattribute self, $I0 - - # cache - inc $I0 - cache = getattribute self, $I0 - - # width - add $I0, 2 - $P0 = getattribute self, $I0 + field = getattribute self, 'field' + cache = getattribute self, 'cache' + $P0 = getattribute self, 'width' width = $P0 - - # height - inc $I0 - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'height' height = $P0 - - # mines - inc $I0 - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'mines' mines = $P0 size = width * height @@ -310,7 +252,7 @@ =cut -.sub draw method +.sub draw :method .local pmc screen .local pmc image .local pmc dest_rect @@ -331,36 +273,29 @@ .local pmc watch .local pmc status - classoffset $I0, self, "Mines::Field" - # field - getattribute field, self, $I0 - field = new Iterator, field + getattribute field, self, 'field' + field = new .Iterator, field field = .ITERATE_FROM_START # cache - inc $I0 - cache = getattribute self, $I0 - cacheit = new Iterator, cache + cache = getattribute self, 'cache' + cacheit = new .Iterator, cache cacheit = .ITERATE_FROM_START # screen - inc $I0 - screen = getattribute self, $I0 + screen = getattribute self, 'screen' # width - inc $I0 - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'width' width = $P0 # height - inc $I0 - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'height' height = $P0 # debug - add $I0, 3 - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'debug' debug = $P0 minx = width * FIELD_WIDTH @@ -375,15 +310,10 @@ image = find_global "Mines::Field", "field_debug" IMAGE_OK: $I0 = find_type "SDL::Rect" - $P0 = new .Hash - $P0['x'] = 0 - $P0['y'] = 0 - $P0['width'] = 0 - $P0['height'] = 0 - dest_rect = new $I0, $P0 - $P0['width'] = FIELD_WIDTH - $P0['height'] = FIELD_HEIGHT - src_rect = new $I0, $P0 + dest_rect = new $I0 + dest_rect.'init'( 'x' => 0, 'y' => 0, 'width' => 0, 'height' => 0 ) + src_rect = new $I0 + src_rect.'init'( 'x' => 0, 'y' => 0, 'width' => FIELD_WIDTH, 'height' => FIELD_HEIGHT ) set size, width mul size, height @@ -468,7 +398,7 @@ $P0.'draw'( screen ) $P0 = getattribute self, "Mines::Field\x0watch" - $P0.'draw'( screen ) + $P0.'draw'() $P0 = getattribute self, "Mines::Field\x0status_button" $P0.'draw'( screen ) @@ -482,7 +412,7 @@ =cut -.sub reveal method +.sub reveal :method .param int x .param int y .local int width @@ -510,7 +440,8 @@ # status inc $I0 $P0 = getattribute self, $I0 - if $P0 > STATUS_CHOOSING goto END + $I1 = $P0 + if $I1 > STATUS_CHOOSING goto END x -= 0 y -= 32 @@ -544,7 +475,7 @@ =cut -.sub setFlag method +.sub setFlag :method .param int x .param int y .local int width @@ -645,7 +576,7 @@ =cut -.sub undo_mark method +.sub undo_mark :method .param int i :optional .param int has_i :opt_flag @@ -653,21 +584,11 @@ .local pmc field .local pmc status - - $I0 = classoffset self, 'Mines::Field' - - # field - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'field' field = $P0 + markpos = getattribute self, 'markpos' + status = getattribute self, 'status_button' - # markpos - add $I0, 6 - markpos = getattribute self, $I0 - - # status - add $I0, 4 - status = getattribute self, $I0 - $I0 = markpos if $I0 == -1 goto UNDO_DONE $I1 = field[$I0] @@ -677,7 +598,8 @@ markpos = -1 if has_i goto END - if status != STATUS_CHOOSING goto END + $I0 = status + if $I0 != STATUS_CHOOSING goto END self."setStatus"( STATUS_PLAYING ) END: .end @@ -691,7 +613,7 @@ =cut -.sub mark method +.sub mark :method .param int x .param int y .local int width @@ -728,7 +650,8 @@ # status inc $I0 $P0 = getattribute self, $I0 - if $P0 >= STATUS_CHOOSING goto END + $I1 = $P0 + if $I1 >= STATUS_CHOOSING goto END if x < 0 goto END if y < 0 goto END @@ -790,7 +713,7 @@ =cut -.sub click method +.sub click :method .param int x .param int y .param int b @@ -822,7 +745,7 @@ =cut -.sub reveal_recursive method +.sub reveal_recursive :method .param int x .param int y .param int width @@ -898,7 +821,7 @@ =cut -.sub lost method +.sub lost :method .local pmc field .local int i .local int max @@ -941,7 +864,7 @@ =cut -.sub won method +.sub won :method self."setStatus"( STATUS_WON ) .end @@ -951,7 +874,7 @@ =cut -.sub check_end method +.sub check_end :method .local pmc field classoffset $I0, self, "Mines::Field" @@ -990,7 +913,7 @@ =cut -.sub setStatus method +.sub setStatus :method .param int s .local pmc screen .local pmc watch @@ -1019,7 +942,7 @@ status = s self."undo_mark"( 1 ) - watch.'draw'( screen ) + watch.'draw'() DONE: .end @@ -1030,7 +953,7 @@ =cut -.sub update_stats method +.sub update_stats :method .local pmc field .local int size .local pmc count @@ -1104,15 +1027,13 @@ # XXX: remove load_bytecode "library/Data/Dumper.pir" - $P0 = new .String - $P0 = "examples/sdl/minesweeper/mines.png" $I0 = find_type "SDL::Image" - image = new $I0, $P0 + image = new $I0 + image.'init'( 'examples/sdl/minesweeper/mines.png' ) store_global "Mines::Field", "field", image - $P0 = new .String - $P0 = "examples/sdl/minesweeper/mines_debug.png" - image = new $I0, $P0 + image = new $I0 + image.'init'( 'examples/sdl/minesweeper/mines_debug.png' ) store_global "Mines::Field", "field_debug", image newclass $P0, "Mines::Field" === examples/sdl/minesweeper/mines.pir ================================================================== --- examples/sdl/minesweeper/mines.pir (revision 22951) +++ examples/sdl/minesweeper/mines.pir (local) @@ -21,8 +21,6 @@ .sub _main :main .param pmc args - .local pmc field - .local pmc screen .local int debug # the debug mode is activated if you pass in any argument @@ -37,46 +35,47 @@ load_bytecode "library/SDL/Color.pir" load_bytecode "library/SDL/Image.pir" load_bytecode "examples/sdl/minesweeper/field.pir" + + .local pmc app + .local int app_type + + # create the SDL object + find_type app_type, "SDL::App" + app = new app_type # setup the screen properties - $P0 = new .Hash - $P0["height"] = 480 - $P0["width"] = 640 - $P0["bpp"] = 32 - $P0["flags"] = 5 + app.'init'( 'height' => 480, 'width' => 640, 'bpp' => 32, 'flags' => 5 ) - # create the SDL object - find_type $I0, "SDL::App" - $P0 = new $I0, $P0 - screen = $P0."surface"() + .local pmc screen + screen = app.'surface'() # choose a "random" field - $I0 = time + .local int level + level = time - # setup field properties - $P0 = new .Hash - $P0['width'] = 40 - $P0['height'] = 28 - $P0['mines'] = 0.1075 -# $P0['mines'] = 0.0075 - $P0['level'] = $I0 - $P0['screen'] = screen - $P0['debug'] = debug - # create the field - $I0 = find_type "Mines::Field" - field = new $I0, $P0 + .local pmc field + .local int mf_type + mf_type = find_type "Mines::Field" + field = new mf_type + + # setup field properties + field.'init'( 'width' => 40, 'height' => 28, 'mines' => 0.1075, 'level' => level, 'screen' => screen, 'debug' => debug ) # draw the field field.'draw'() # runloop - find_type $I0, "SDL::Event" - $P0 = new $I0 - find_type $I0, "Mines::EventHandler" - $P1 = new $I0 - $P0."process_events"( 0.1, $P1, field ) + .local pmc event, event_handler + .local int event_type + find_type event_type, "SDL::Event" + event = new event_type + event.'init'() + .local int eh_type + find_type eh_type, "Mines::EventHandler" + event_handler = new eh_type + event.'process_events'( event_handler, field, 0.1 ) end .end @@ -94,6 +93,6 @@ =head1 COPYRIGHT -Copyright (C) 2004, The Perl Foundation. +Copyright (C) 2004, 2006, The Perl Foundation. =cut === runtime/parrot/library/SDL/Button.pir ================================================================== --- runtime/parrot/library/SDL/Button.pir (revision 22951) +++ runtime/parrot/library/SDL/Button.pir (local) @@ -7,14 +7,13 @@ =head1 SYNOPSIS - # the image to use for the button - $P0 = new .String - $P0 = "filename/to/image.png" - # create the button $I0 = find_type 'SDL::Button' - button = new $I0, $P0 + button = new $I0 + # the image to use for the button + button.'init'( "filename/to/image.png" ) + # set the position button.'xpos'( 10 ) button.'ypos'( 10 ) @@ -59,18 +58,19 @@ END: .end -=item button = new ID, name +=item button.'init'( filename ) =cut -.sub __init :method - .param pmc name +.sub 'init' :method + .param string name $I0 = classoffset self, 'SDL::Button' # image $I1 = find_type 'SDL::Image' - $P0 = new $I1, name + $P0 = new $I1 + $P0.'init'( name ) setattribute self, $I0, $P0 # status @@ -89,6 +89,7 @@ inc $I0 $I1 = find_type 'SDL::Rect' $P0 = new $I1 + $P0.'init'() setattribute self, $I0, $P0 # clicked @@ -208,19 +209,17 @@ $I1 = find_type 'SDL::Rect' srect = new $I1 - $I1 = drect.'height'() - srect.'height'( $I1 ) - $I1 = drect.'width'() - srect.'width'( $I1 ) + .local int x, y, width, height - cmod $I0, status, states - $I0 *= $I1 - srect.'x'( $I0 ) + height = drect.'height'() + width = drect.'width'() + + cmod x, status, states + x *= width - $I1 = drect.'height'() - $I0 = clicked - $I0 *= $I1 - srect.'y'( $I0 ) + y = clicked + y *= height + srect.'init'( 'x' => x, 'y' => y, 'height' => height, 'width' => width ) screen.'blit'( image, srect, drect ) screen.'update_rect'( drect ) === runtime/parrot/library/SDL/LCD.pir ================================================================== --- runtime/parrot/library/SDL/LCD.pir (revision 22951) +++ runtime/parrot/library/SDL/LCD.pir (local) @@ -46,10 +46,9 @@ load_bytecode "library/SDL/Image.pir" load_bytecode "library/SDL/Rect.pir" - $P0 = new .String - $P0 = "runtime/parrot/library/SDL/LCD.png" $I0 = find_type "SDL::Image" - $P0 = new $I0, $P0 + $P0 = new $I0 + $P0.'init'( 'runtime/parrot/library/SDL/LCD.png' ) store_global "SDL::LCD", "digits", $P0 $P0 = newclass 'SDL::LCD' @@ -60,26 +59,21 @@ END: .end -.sub __init :method - $I0 = classoffset self, "SDL::LCD" - +.sub 'init' :method $P0 = new .String - setattribute self, $I0, $P0 + setattribute self, 'value', $P0 - inc $I0 $P0 = new .Integer $P0 = -1 - setattribute self, $I0, $P0 + setattribute self, 'numdigits', $P0 - inc $I0 $P0 = new .Integer $P0 = 0 - setattribute self, $I0, $P0 + setattribute self, 'xpos', $P0 - inc $I0 $P0 = new .Integer $P0 = 0 - setattribute self, $I0, $P0 + setattribute self, 'ypos', $P0 .end =item _digits( count ) @@ -91,9 +85,7 @@ .sub _digits :method .param int val - $I0 = classoffset self, "SDL::LCD" - inc $I0 - $P0 = getattribute self, $I0 + $P0 = getattribute self, 'numdigits' $P0 = val .end @@ -173,16 +165,11 @@ val = $S0 LEN_OK: - rect = new .Hash - rect["width"] = 10 - rect["height"] = 21 $I0 = find_type "SDL::Rect" - rect["x"] = 0 - rect["y"] = 0 - drect = new $I0, rect - rect["x"] = xpos - rect["y"] = ypos - rect = new $I0, rect + drect = new $I0 + drect.'init'( 'x' => 0, 'y' => 0, 'width' => 10, 'height' => 21 ) + rect = new $I0 + rect.'init'( 'x' => xpos, 'y' => ypos, 'width' => 10, 'height' => 21 ) digits = find_global "SDL::LCD", "digits" === runtime/parrot/library/SDL/Rect.pir ================================================================== --- runtime/parrot/library/SDL/Rect.pir (revision 22951) +++ runtime/parrot/library/SDL/Rect.pir (local) @@ -203,7 +203,7 @@ =cut -.sub x :method +.sub 'x' :method .param int new_x :optional .param int has_new_x :opt_flag @@ -228,7 +228,7 @@ =cut -.sub y :method +.sub 'y' :method .param int new_y :optional .param int has_new_y :opt_flag === runtime/parrot/library/SDL/StopWatch.pir ================================================================== --- runtime/parrot/library/SDL/StopWatch.pir (revision 22951) +++ runtime/parrot/library/SDL/StopWatch.pir (local) @@ -58,9 +58,13 @@ =cut -.sub __init :method +.sub 'init' :method .param pmc screen + .local pmc parent + parent = find_global 'SDL::LCD', 'init' + self.parent() + $I0 = classoffset self, 'SDL::StopWatch' $P0 = new .Float @@ -223,7 +227,7 @@ =cut -.sub draw :method +.sub 'draw' :method $I0 = self.'current_time'() cmod $I5, $I0, 10 @@ -261,7 +265,7 @@ add $I0, 3 screen = getattribute self, $I0 $P0 = find_global "SDL::LCD", "draw" - $P0( screen ) + self.$P0( screen ) .end .namespace ["SDL::StopWatch::Timer"]