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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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