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 +21 -3
- data/Rakefile +1 -1
- data/ext/retrograph/retrograph.c +28 -30
- data/lib/retrograph.so +0 -0
- data/spec/retrograph_spec.rb +7 -1
- data/src/retrograph.c +69 -16
- data/src/retrograph.h +3 -0
- metadata +2 -2
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
|
10
|
-
|
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
data/ext/retrograph/retrograph.c
CHANGED
@@ -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 *
|
146
|
-
INT2FIX(RETROGRAPH_DISPLAY_HEIGHT *
|
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 +
|
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
|
-
|
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
|
-
|
213
|
-
|
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 *
|
304
|
+
INT2FIX(RETROGRAPH_DISPLAY_WIDTH * 2));
|
308
305
|
rb_const_set(mRetrograph, rb_intern("OUTPUT_HEIGHT"),
|
309
|
-
INT2FIX(RETROGRAPH_DISPLAY_HEIGHT *
|
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
|
data/spec/retrograph_spec.rb
CHANGED
@@ -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,
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
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:
|
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-
|
12
|
+
date: 2009-07-26 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|