/[VRac]/Screen.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /Screen.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 75 - (show annotations)
Wed Aug 1 12:40:20 2007 UTC (16 years, 8 months ago) by dpavlin
Original Path: M6502/Screen.pm
File size: 3903 byte(s)
super-fast SDL-based screen renderer
1 package Screen;
2
3 # Dobrica Pavlinusic, <dpavlin@rot13.org> 07/30/07 17:58:55 CEST
4
5 use strict;
6 use warnings;
7
8 use SDL::App;
9 use SDL::Rect;
10 use SDL::Color;
11 use SDL::Constants;
12
13 use Carp qw/confess/;
14 use Data::Dump qw/dump/;
15
16 use base qw(Class::Accessor Prefs);
17 __PACKAGE__->mk_accessors(qw(app));
18
19 =head1 NAME
20
21 Screen - simulated 256*256 pixels monochrome screen using SDL
22
23 =head2 open_screen
24
25 Open simulated screen
26
27 =cut
28
29 our $app;
30
31 sub open_screen {
32 my $self = shift;
33
34 $self->prefs;
35
36 if ( ! $self->scale ) {
37 $self->scale( 1 );
38 warn "using default unscaled display\n";
39 }
40
41 $app = SDL::App->new(
42 -width => 256 * $self->scale + ( $self->show_mem ? 256 : 0 ),
43 -height => 256 * $self->scale,
44 -depth => 16,
45 );
46 #$app->grab_input( SDL_GRAB_QUERY );
47 $app->grab_input( SDL_GRAB_OFF );
48
49 warn "# created SDL::App\n";
50 $self->app( $app );
51 }
52
53 my $white = SDL::Color->new( -r => 0xff, -g => 0xff, -b => 0xff );
54 my $black = SDL::Color->new( -r => 0x80, -g => 0x80, -b => 0x80 );
55
56 my $red = SDL::Color->new( -r => 0xff, -g => 0x00, -b => 0x00 );
57 my $green = SDL::Color->new( -r => 0x00, -g => 0xff, -b => 0x00 );
58 my $blue = SDL::Color->new( -r => 0x00, -g => 0x00, -b => 0xff );
59
60 =head2 p
61
62 $screen->p( $x, $y, 1 );
63
64 =cut
65
66 sub p {
67 my $self = shift;
68
69 my ($x,$y,$w) = (@_);
70
71 warn "p($x,$y,$w)\n" if $self->debug;
72
73 my $scale = $self->scale;
74 my $rect = SDL::Rect->new(
75 -height => $scale,
76 -width => $scale,
77 -x => $x * $scale,
78 -y => $y * $scale,
79 );
80
81 $app->fill( $rect, $w ? $white : $black );
82 $app->update( $rect );
83 }
84
85 =head2 mem_xy
86
87 Helper to return x and y coordinates in memory map
88
89 my ( $x,$y ) = $screen->mem_xy( $address );
90
91 =cut
92
93 sub mem_xy {
94 my $self = shift;
95 my $offset = shift;
96 my $x = $offset & 0xff;
97 $x += 256 * $self->scale;
98 my $y = $offset >> 8;
99 return ($x,$y);
100 }
101
102 =head2 vram
103
104 Push byte to video memory and draw it
105
106 $screen->vram( $offset, $byte );
107
108 =cut
109
110 my $_vram_counter;
111
112 sub vram {
113 my ( $self, $offset, $byte ) = @_;
114 my $x = ( $offset % 32 ) << 3;
115 my $y = $offset >> 5;
116 my $mask = 1;
117 my $scale = $self->scale;
118
119 printf "## vram %04x %02x*%02x %02x\n", $offset, $x, $y, $byte if $self->trace;
120
121 foreach ( 0 .. 7 ) {
122 my $on = $byte & $mask;
123 if ( $scale == 1 ) {
124 $app->pixel( $x + $_, $y, $on ? $white : $black );
125 } else {
126 $self->p($x + $_, $y, $on );
127 }
128 $mask = $mask << 1;
129 }
130
131 $app->sync if ( $_vram_counter++ % 10 == 0 );
132 }
133
134 =head2 mmap_pixel
135
136 Draw pixel in memory map
137
138 $self->mmap_pixel( $addr, $r, $g, $b );
139
140 =cut
141
142 # keep accesses to memory
143 my $_mem_stat;
144
145 sub mmap_pixel {
146 my ( $self, $addr, $r, $g, $b ) = @_;
147 return unless $self->show_mem && $self->app;
148
149 my ( $x, $y ) = $self->mem_xy( $addr );
150 warn sprintf "## mem %04x %02x %02x %02d*%02d\n", $addr, $r, $g, $x, $y if $self->debug;
151
152 my $col = SDL::Color->new( -r => $r, -g => $g, -b => $b );
153 $self->app->pixel( $x, $y, $col );
154
155 $_mem_stat++;
156 if ( $_mem_stat % 1000 == 0 ) {
157 $self->app->sync;
158 }
159 }
160
161
162 =head2 sync
163
164 $self->sync;
165
166 =cut
167
168 sub sync {
169 $app->sync;
170 }
171
172 =head2 render
173
174 $self->render( @video_memory );
175
176 =cut
177
178 sub render {
179 my $self = shift;
180
181 die "this function isn't supported if scale isn't 1" unless $self->scale == 1;
182
183 my $pixels = pack("C*", @_);
184
185 my $vram = SDL::Surface->new(
186 -width => 256,
187 -height => 256,
188 -depth => 1, # 1 bit per pixel
189 -pitch => 32, # bytes per line
190 -from => $pixels,
191 );
192 $vram->set_colors( 0, $black, $white, $red );
193 $vram->display_format;
194
195 my $rect = SDL::Rect->new( -x => 0, -y => 0, -width => 256, -height => 256 );
196 $vram->blit( $rect, $app, $rect );
197
198 $app->sync;
199 }
200
201 =head1 SEE ALSO
202
203 L<Orao> is sample implementation using this module
204
205 =head1 AUTHOR
206
207 Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
208
209 =head1 COPYRIGHT & LICENSE
210
211 Copyright 2007 Dobrica Pavlinusic, All Rights Reserved.
212
213 This program is free software; you can redistribute it and/or modify it
214 under the same terms as Perl itself.
215
216 =cut
217 1;

  ViewVC Help
Powered by ViewVC 1.1.26