retrograph 0.5-x86-mswin32 → 0.5.1-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -6,8 +6,22 @@ console. It is similar in capability to the Sega Master
6
6
  System's VDP, with some additional features and direct
7
7
  support for text modes.
8
8
 
9
- Retrograph currently supports Ruby/SDL for output; other
10
- output targets may be added in the future.
9
+ Retrograph doesn't do its own screen output but rather
10
+ works with other libraries. Currently, it supports
11
+ Ruby/SDL, but other output targets are planned for the
12
+ future.
13
+
14
+ == Where can I get it? ==
15
+
16
+ Retrograph is available via RubyGems, or via Rubyforge
17
+ downloads:
18
+
19
+ http://rubyforge.org/frs/?group_id=8410
20
+
21
+ Cursory documentation is available on the
22
+ corresponding github wiki:
23
+
24
+ http://wiki.github.com/mental/retrograph
11
25
 
12
26
  == Feature Overview ==
13
27
 
@@ -52,12 +66,16 @@ of the display, we could write:
52
66
 
53
67
  require 'retrograph/sdl'
54
68
 
69
+ vdu = Retrograph::VDU.new
70
+ vdu.write_byte(0x7f00, 0x03)
55
71
  output = vdu.render_frame_sdl do
56
- vdu.write_byte(0x7f00, 0x03)
57
72
  vdu.wait_scanlines(Retrograph::DISPLAY_HEIGHT/2)
58
73
  vdu.write_byte(0x7f00, 0x30)
59
74
  end
60
75
 
76
+ (It is still necessary at this point to copy output to the
77
+ screen.)
78
+
61
79
  == Important Notes ==
62
80
 
63
81
  Nothing is displayed by default. To be shown, the
data/Rakefile CHANGED
@@ -16,7 +16,7 @@ rescue LoadError
16
16
  end
17
17
  require 'rake/clean'
18
18
 
19
- GEM_VERSION = '0.5'
19
+ GEM_VERSION = '0.5.1'
20
20
 
21
21
  CLEAN.include("spec/**/*-output.bmp")
22
22
  CLOBBER.include("lib/1.8")
@@ -36,10 +36,6 @@
36
36
  #define RSTRING_PTR(str) RSTRING(str)->ptr
37
37
  #endif
38
38
 
39
- #define UPSCALE_FACTOR 2
40
- #define UPSCALE_REPEAT(stmts) stmts; stmts;
41
- #define UPSCALE_REPEAT_MINUS1(stmts) stmts;
42
-
43
39
  /* First few fields of SDL_Surface */
44
40
  typedef struct surface_header_tag {
45
41
  uint32_t flags;
@@ -57,7 +53,6 @@ typedef struct rubysdl2_surface_tag {
57
53
  typedef struct vdu_wrapper_tag {
58
54
  retrograph_vdu_t vdu;
59
55
  VALUE surface;
60
- retrograph_pixel_t buffer[RETROGRAPH_DISPLAY_WIDTH];
61
56
  int scanline;
62
57
  } vdu_wrapper_t;
63
58
 
@@ -142,8 +137,8 @@ void alloc_sdl_surface(vdu_wrapper_t *vdu) {
142
137
  VALUE surface;
143
138
  surface = rb_funcall(cSurface, SYM2ID(CREATE_SURFACE_METHOD_NAME), 8,
144
139
  INT2FIX(0), /* flags */
145
- INT2FIX(RETROGRAPH_DISPLAY_WIDTH * UPSCALE_FACTOR),
146
- INT2FIX(RETROGRAPH_DISPLAY_HEIGHT * UPSCALE_FACTOR),
140
+ INT2FIX(RETROGRAPH_DISPLAY_WIDTH * 2),
141
+ INT2FIX(RETROGRAPH_DISPLAY_HEIGHT * 2),
147
142
  INT2FIX(RETROGRAPH_BITS_PER_PIXEL),
148
143
  INT2FIX(RETROGRAPH_RED_MASK),
149
144
  INT2FIX(RETROGRAPH_GREEN_MASK),
@@ -152,6 +147,19 @@ void alloc_sdl_surface(vdu_wrapper_t *vdu) {
152
147
  vdu->surface = surface;
153
148
  }
154
149
 
150
+ static VALUE vdu_initialize_copy(VALUE self, VALUE from) {
151
+ vdu_wrapper_t *vdu;
152
+ vdu_wrapper_t *from_vdu;
153
+ if (CLASS_OF(self) != CLASS_OF(from)) {
154
+ rb_raise(rb_eTypeError, "Mismatched class for copy");
155
+ }
156
+ Data_Get_Struct(self, vdu_wrapper_t, vdu);
157
+ Data_Get_Struct(from, vdu_wrapper_t, from_vdu);
158
+ retrograph_clone(vdu->vdu, from_vdu->vdu);
159
+ check_errors(vdu->vdu);
160
+ return Qnil;
161
+ }
162
+
155
163
  static VALUE vdu_write(VALUE self, VALUE start_address_r, VALUE data_r) {
156
164
  vdu_wrapper_t *vdu;
157
165
  retrograph_addr_t start_address;
@@ -160,6 +168,7 @@ static VALUE vdu_write(VALUE self, VALUE start_address_r, VALUE data_r) {
160
168
  start_address = (retrograph_addr_t)NUM2INT(start_address_r);
161
169
  retrograph_write(vdu->vdu, start_address, RSTRING_PTR(data_r),
162
170
  (size_t)RSTRING_LEN(data_r));
171
+ check_errors(vdu->vdu);
163
172
  return Qnil;
164
173
  }
165
174
 
@@ -171,19 +180,10 @@ static VALUE vdu_write_byte(VALUE self, VALUE start_address_r, VALUE byte_r) {
171
180
  start_address = (retrograph_addr_t)NUM2INT(start_address_r);
172
181
  byte = (uint8_t)NUM2INT(byte_r);
173
182
  retrograph_write(vdu->vdu, start_address, &byte, 1);
183
+ check_errors(vdu->vdu);
174
184
  return Qnil;
175
185
  }
176
186
 
177
- static inline copy_upscale(uint8_t *output, uint8_t const * input, size_t count) {
178
- for (; count; count--) {
179
- UPSCALE_REPEAT(
180
- memcpy(output, input, RETROGRAPH_BYTES_PER_PIXEL);
181
- output += RETROGRAPH_BYTES_PER_PIXEL;
182
- )
183
- input += RETROGRAPH_BYTES_PER_PIXEL;
184
- }
185
- }
186
-
187
187
  static VALUE vdu_render_scanlines(VALUE self, VALUE n_scanlines_r) {
188
188
  vdu_wrapper_t *vdu;
189
189
  surface_header_t *surface;
@@ -203,21 +203,18 @@ static VALUE vdu_render_scanlines(VALUE self, VALUE n_scanlines_r) {
203
203
  max_scanline = RETROGRAPH_DISPLAY_HEIGHT;
204
204
  }
205
205
 
206
- current_line = (uint8_t *)surface->pixels + vdu->scanline * surface->pitch * UPSCALE_FACTOR;
206
+ current_line = (uint8_t *)surface->pixels +
207
+ vdu->scanline * surface->pitch * 2;
207
208
  for (; vdu->scanline < max_scanline; vdu->scanline++) {
208
209
  uint8_t *output;
209
210
  uint8_t const *input;
210
- retrograph_render_scanline(vdu->vdu, vdu->buffer, sizeof(vdu->buffer));
211
+ retrograph_render_scanline_2x(vdu->vdu, current_line,
212
+ RETROGRAPH_DISPLAY_WIDTH *
213
+ RETROGRAPH_BYTES_PER_PIXEL * 2);
211
214
  check_errors(vdu->vdu);
212
- copy_upscale(current_line, (uint8_t const *)vdu->buffer,
213
- RETROGRAPH_DISPLAY_WIDTH);
214
- current_line += surface->pitch;
215
- UPSCALE_REPEAT_MINUS1(
216
- memcpy(current_line, current_line - surface->pitch,
217
- RETROGRAPH_DISPLAY_WIDTH * RETROGRAPH_BYTES_PER_PIXEL *
218
- UPSCALE_FACTOR);
219
- current_line += surface->pitch;
220
- )
215
+ memcpy(current_line + surface->pitch, current_line,
216
+ RETROGRAPH_DISPLAY_WIDTH * RETROGRAPH_BYTES_PER_PIXEL * 2);
217
+ current_line += surface->pitch * 2;
221
218
  }
222
219
 
223
220
  return Qnil;
@@ -304,9 +301,9 @@ void Init_retrograph(void) {
304
301
  #undef DEFINE_CONSTANT
305
302
 
306
303
  rb_const_set(mRetrograph, rb_intern("OUTPUT_WIDTH"),
307
- INT2FIX(RETROGRAPH_DISPLAY_WIDTH * UPSCALE_FACTOR));
304
+ INT2FIX(RETROGRAPH_DISPLAY_WIDTH * 2));
308
305
  rb_const_set(mRetrograph, rb_intern("OUTPUT_HEIGHT"),
309
- INT2FIX(RETROGRAPH_DISPLAY_HEIGHT * UPSCALE_FACTOR));
306
+ INT2FIX(RETROGRAPH_DISPLAY_HEIGHT * 2));
310
307
 
311
308
  rb_global_variable(&cVDU);
312
309
  cVDU = rb_define_class_under(mRetrograph, "VDU", rb_cObject);
@@ -316,6 +313,7 @@ void Init_retrograph(void) {
316
313
  rb_eRuntimeError);
317
314
 
318
315
  rb_define_alloc_func(cVDU, alloc_vdu);
316
+ rb_define_method(cVDU, "initialize_copy", vdu_initialize_copy, 1);
319
317
  rb_define_method(cVDU, "write", vdu_write, 2);
320
318
  rb_define_method(cVDU, "write_byte", vdu_write_byte, 2);
321
319
  rb_define_method(cVDU, "wait_scanlines", vdu_render_scanlines, 1);
data/lib/retrograph.so CHANGED
Binary file
@@ -82,7 +82,7 @@ module ImageTests
82
82
  SDL::Surface.blit(raw_image, 0, 0, 0, 0, reference_image, 0, 0)
83
83
  raw_image = nil
84
84
  if output_image.pixels != reference_image.pixels
85
- raise "Output does not match."
85
+ raise "Output file #{output_file} does not match."
86
86
  end
87
87
  end
88
88
  end
@@ -114,6 +114,12 @@ describe Retrograph::VDU do
114
114
  @vdu.write_byte(0x0001, 42)
115
115
  end
116
116
 
117
+ it "should clone VDU state when dup-ed" do
118
+ @vdu.write_byte(0x7f00, 0x33);
119
+ vdu2 = @vdu.dup
120
+ @vdu.render_frame_sdl.pixels.should == vdu2.render_frame_sdl.pixels
121
+ end
122
+
117
123
  it "should not allow nested calls to #render_frame_sdl" do
118
124
  lambda {
119
125
  @vdu.render_frame_sdl { @vdu.render_frame_sdl }
data/src/retrograph.c CHANGED
@@ -143,6 +143,28 @@ retrograph_vdu_t retrograph_new() {
143
143
  return vdu;
144
144
  }
145
145
 
146
+ void retrograph_clone(retrograph_vdu_t vdu, retrograph_vdu_t from_vdu) {
147
+ if (!vdu || vdu->error) {
148
+ return;
149
+ }
150
+ if (from_vdu->error) {
151
+ /* XXX is this desirable? */
152
+ vdu->error = from_vdu->error;
153
+ return;
154
+ }
155
+ memcpy(vdu->vram, from_vdu->vram, sizeof(vdu->vram));
156
+ memcpy(vdu->sprites, from_vdu->sprites, sizeof(vdu->sprites));
157
+ memcpy(vdu->palette, from_vdu->palette, sizeof(vdu->palette));
158
+ vdu->enable_bg = from_vdu->enable_bg;
159
+ vdu->enable_sprites = from_vdu->enable_sprites;
160
+ vdu->mode = from_vdu->mode;
161
+ vdu->text_pattern_base = from_vdu->text_pattern_base;
162
+ vdu->bg_pattern_base = from_vdu->bg_pattern_base;
163
+ vdu->name_base = from_vdu->name_base;
164
+ vdu->bg_scroll_x = from_vdu->bg_scroll_x;
165
+ vdu->bg_scroll_y = from_vdu->bg_scroll_y;
166
+ }
167
+
146
168
  void retrograph_ref(retrograph_vdu_t vdu) {
147
169
  if (vdu && !is_singleton_vdu(vdu)) {
148
170
  vdu->refcount++;
@@ -574,7 +596,8 @@ static void render_line_graphics_b(retrograph_pixel_t *out_buffer, uint8_t const
574
596
  }
575
597
  }
576
598
 
577
- static void render_line(retrograph_vdu_t vdu, unsigned scanline, uint8_t *dest)
599
+ static void render_line(retrograph_vdu_t vdu, unsigned scanline,
600
+ retrograph_pixel_t *row_buffer)
578
601
  {
579
602
  uint8_t const *name_row;
580
603
  uint8_t bg_x_coarse;
@@ -618,8 +641,6 @@ static void render_line(retrograph_vdu_t vdu, unsigned scanline, uint8_t *dest)
618
641
  bg_y_fine = (uint8_t)(bg_y % 8);
619
642
  }
620
643
 
621
- update_palette_cache(vdu);
622
-
623
644
  switch (vdu->mode) {
624
645
  case TEXT_A:
625
646
  /* stride is 40 2-byte cells */
@@ -630,25 +651,25 @@ static void render_line(retrograph_vdu_t vdu, unsigned scanline, uint8_t *dest)
630
651
  name_row = vdu->vram + vdu->name_base + bg_y_coarse * (32 * 2);
631
652
  }
632
653
 
633
- clear_row_buffer(vdu->row_buffer, vdu->palette_cache[0]);
654
+ clear_row_buffer(row_buffer, vdu->palette_cache[0]);
634
655
  switch (vdu->mode) {
635
656
  case TEXT_A:
636
657
  /* 12px padding above and below display */
637
658
  if (scanline >= 12 ||
638
659
  scanline < RETROGRAPH_DISPLAY_HEIGHT - 12)
639
660
  {
640
- render_line_text_a(vdu->row_buffer, name_row, bg_y_fine,
661
+ render_line_text_a(row_buffer, name_row, bg_y_fine,
641
662
  vdu->vram + vdu->text_pattern_base,
642
663
  vdu->palette_cache, vdu->enable_bg);
643
664
  }
644
665
  break;
645
666
  case TEXT_B:
646
- render_line_text_b(vdu->row_buffer, name_row, bg_y_fine,
667
+ render_line_text_b(row_buffer, name_row, bg_y_fine,
647
668
  vdu->vram + vdu->text_pattern_base,
648
669
  vdu->palette_cache, vdu->enable_bg);
649
670
  break;
650
671
  case GRAPHICS_A:
651
- render_line_graphics_a(vdu->row_buffer, name_row,
672
+ render_line_graphics_a(row_buffer, name_row,
652
673
  bg_x_coarse, bg_x_fine, bg_y_fine,
653
674
  scanline, vdu->vram,
654
675
  vdu->bg_pattern_base,
@@ -657,7 +678,7 @@ static void render_line(retrograph_vdu_t vdu, unsigned scanline, uint8_t *dest)
657
678
  vdu->enable_bg, vdu->enable_sprites);
658
679
  break;
659
680
  case GRAPHICS_B:
660
- render_line_graphics_b(vdu->row_buffer, name_row,
681
+ render_line_graphics_b(row_buffer, name_row,
661
682
  bg_x_coarse, bg_x_fine, bg_y_fine,
662
683
  scanline, vdu->vram,
663
684
  vdu->bg_pattern_base,
@@ -666,7 +687,6 @@ static void render_line(retrograph_vdu_t vdu, unsigned scanline, uint8_t *dest)
666
687
  vdu->enable_bg, vdu->enable_sprites);
667
688
  break;
668
689
  }
669
- memcpy(dest, vdu->row_buffer, ROW_BYTES);
670
690
  }
671
691
 
672
692
  void retrograph_begin_frame(retrograph_vdu_t vdu) {
@@ -676,6 +696,30 @@ void retrograph_begin_frame(retrograph_vdu_t vdu) {
676
696
  vdu->current_scanline = 0;
677
697
  }
678
698
 
699
+ static void retrograph_render_scanline_inner(retrograph_vdu_t vdu,
700
+ retrograph_pixel_t *row_buffer)
701
+ {
702
+ update_palette_cache(vdu);
703
+ if (vdu->current_scanline < RETROGRAPH_DISPLAY_HEIGHT) {
704
+ render_line(vdu, vdu->current_scanline, row_buffer);
705
+ vdu->current_scanline++;
706
+ } else {
707
+ clear_row_buffer(row_buffer, vdu->palette_cache[0]);
708
+ }
709
+ }
710
+
711
+ static inline void copy_line_2x(uint8_t *output, uint8_t const *input,
712
+ size_t count)
713
+ {
714
+ for (; count; count--) {
715
+ memcpy(output, input, RETROGRAPH_BYTES_PER_PIXEL);
716
+ output += RETROGRAPH_BYTES_PER_PIXEL;
717
+ memcpy(output, input, RETROGRAPH_BYTES_PER_PIXEL);
718
+ output += RETROGRAPH_BYTES_PER_PIXEL;
719
+ input += RETROGRAPH_BYTES_PER_PIXEL;
720
+ }
721
+ }
722
+
679
723
  void retrograph_render_scanline(retrograph_vdu_t vdu, void *dest,
680
724
  size_t dest_size)
681
725
  {
@@ -686,12 +730,21 @@ void retrograph_render_scanline(retrograph_vdu_t vdu, void *dest,
686
730
  return;
687
731
  }
688
732
 
689
- if (vdu->current_scanline < RETROGRAPH_DISPLAY_HEIGHT) {
690
- render_line(vdu, vdu->current_scanline, (uint8_t *)dest);
691
- vdu->current_scanline++;
692
- } else {
693
- update_palette_cache(vdu);
694
- clear_row_buffer(vdu->row_buffer, vdu->palette_cache[0]);
695
- memcpy(dest, vdu->row_buffer, ROW_BYTES);
733
+ retrograph_render_scanline_inner(vdu, vdu->row_buffer);
734
+ memcpy(dest, vdu->row_buffer, ROW_BYTES);
735
+ }
736
+
737
+ void retrograph_render_scanline_2x(retrograph_vdu_t vdu, void *dest,
738
+ size_t dest_size)
739
+ {
740
+ if (!vdu || vdu->error) {
741
+ return;
742
+ }
743
+ if (dest_size < ROW_BYTES * 2) {
744
+ return;
696
745
  }
746
+
747
+ retrograph_render_scanline_inner(vdu, vdu->row_buffer);
748
+ copy_line_2x(dest, (uint8_t const *)vdu->row_buffer,
749
+ ROW_BYTES / RETROGRAPH_BYTES_PER_PIXEL);
697
750
  }
data/src/retrograph.h CHANGED
@@ -58,10 +58,13 @@ void retrograph_destroy(retrograph_vdu_t vdu);
58
58
 
59
59
  retrograph_error_t retrograph_get_error(retrograph_vdu_t vdu);
60
60
 
61
+ void retrograph_clone(retrograph_vdu_t vdu, retrograph_vdu_t from_vdu);
61
62
  void retrograph_write(retrograph_vdu_t vdu, retrograph_addr_t start_address,
62
63
  void const *data, size_t n_bytes);
63
64
  void retrograph_begin_frame(retrograph_vdu_t vdu);
64
65
  void retrograph_render_scanline(retrograph_vdu_t vdu, void *dest,
65
66
  size_t dest_size);
67
+ void retrograph_render_scanline_2x(retrograph_vdu_t vdu, void *dest,
68
+ size_t dest_size);
66
69
 
67
70
  #endif
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retrograph
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.5"
4
+ version: 0.5.1
5
5
  platform: x86-mswin32
6
6
  authors:
7
7
  - MenTaLguY <mental@rydia.net>
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-24 00:00:00 -04:00
12
+ date: 2009-07-26 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15