/[projet1]/public/pc/tools/osdk/main/pictconv/sources/oric_converter.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/pictconv/sources/oric_converter.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1260 - (show annotations)
Sat Feb 14 20:26:49 2015 UTC (4 years, 7 months ago) by dbug
File size: 21298 byte(s)
PictConv 0.21
- Added support for 32bit picture, to handle things like masking/opacity in the picture formats
- The -a1 mode will generate bytes with null value for blocks of 6 pixels with transparent alpha values (only active in monochrome or AIC conversion modes)
- Added the -f7 conversion mode for Oric pictures using the AIC coloring method.

1
2
3 #include <assert.h>
4 #include <stdio.h>
5 #include <fcntl.h>
6 #include <iostream>
7 #include <string.h>
8
9 #ifndef _WIN32
10 #include <unistd.h>
11 #endif
12
13 #include <sys/types.h>
14 #include <sys/stat.h>
15
16 #include "FreeImage.h"
17
18 #include "defines.h"
19 #include "getpixel.h"
20 #include "hires.h"
21 #include "oric_converter.h"
22 #include "dithering.h"
23
24 #include "common.h"
25
26 #include "image.h"
27
28
29
30 //
31 // dither_riemersma
32 //
33 void dither_riemersma_monochrom(ImageContainer& image,int width,int height);
34 void dither_riemersma_rgb(ImageContainer& image,int width,int height);
35
36
37
38
39 // ============================================================================
40 //
41 // OricRgbColor
42 //
43 // ============================================================================
44
45 class OricRgbColor : public RgbColor
46 {
47 public:
48 ORIC_COLOR GetOricColor()
49 {
50 ORIC_COLOR color=ORIC_COLOR_BLACK;
51 if ((m_red)>128) color|=ORIC_COLOR_RED;
52 if ((m_green)>128) color|=ORIC_COLOR_GREEN;
53 if ((m_blue)>128) color|=ORIC_COLOR_BLUE;
54 return (ORIC_COLOR)color;
55 }
56
57 void SetOricColor(ORIC_COLOR color)
58 {
59 if (color&1) m_red=255;
60 else m_red=0;
61
62 if (color&2) m_green=255;
63 else m_green=0;
64
65 if (color&4) m_blue=255;
66 else m_blue=0;
67
68 m_alpha=255;
69 }
70 };
71
72
73
74 // ============================================================================
75 //
76 // OricPictureConverter
77 //
78 // ============================================================================
79
80 OricPictureConverter::OricPictureConverter() :
81 PictureConverter(MACHINE_ORIC),
82 m_format(FORMAT_MONOCHROM),
83 m_flag_setbit6(true)
84 {
85 m_Buffer.SetBufferSize(240,200); // Default size
86 m_Buffer.ClearBuffer(m_flag_setbit6);
87
88 // Define the default AIC palette (should be possible to override at some point)
89 m_PaletteAIC[0][0]=ORIC_COLOR_BLACK;
90 m_PaletteAIC[0][1]=ORIC_COLOR_CYAN;
91 m_PaletteAIC[1][0]=ORIC_COLOR_BLACK;
92 m_PaletteAIC[1][1]=ORIC_COLOR_YELLOW;
93 }
94
95 OricPictureConverter::~OricPictureConverter()
96 {
97 }
98
99
100
101 ORIC_COLOR OricPictureConverter::convert_pixel_monochrom(const ImageContainer& sourcePicture,unsigned int x,unsigned int y)
102 {
103 RgbColor rgb=sourcePicture.ReadColor(x,y);
104
105 unsigned char r=rgb.m_red;
106 unsigned char g=rgb.m_green;
107 unsigned char b=rgb.m_blue;
108 unsigned char a=rgb.m_alpha;
109
110 ORIC_COLOR alphaMask=ORIC_COLOR_OPAQUE;
111 if ( (m_transparency==TRANSPARENCY_HOLES) && (a<128) )
112 {
113 alphaMask|=ORIC_COLOR_TRANSPARENT;
114 }
115
116 switch (m_dither)
117 {
118 case DITHER_NONE:
119 //
120 // Simple BLACK/WHITE selection
121 // based on the global luminosity.
122 //
123 if ((r+g+b)>127+127+127)
124 {
125 r=255;
126 g=255;
127 b=255;
128 }
129 else
130 {
131 r=0;
132 g=0;
133 b=0;
134 }
135 break;
136
137 case DITHER_ALTERNATE:
138 case DITHER_ALTERNATE_INVERSED:
139 //
140 // Semi dithering :))
141 // BLACK/GREY/WHITE
142 //
143 if ((r+g+b)>170*3)
144 {
145 r=255;
146 g=255;
147 b=255;
148 }
149 else
150 if ((r+g+b)<85*3)
151 {
152 r=0;
153 g=0;
154 b=0;
155 }
156 else
157 {
158 if ((x^y)&1)
159 {
160 if (m_dither==DITHER_ALTERNATE_INVERSED)
161 {
162 r=255;
163 g=255;
164 b=255;
165 }
166 else
167 {
168 r=0;
169 g=0;
170 b=0;
171 }
172 }
173 else
174 {
175 if (m_dither==DITHER_ALTERNATE_INVERSED)
176 {
177 r=0;
178 g=0;
179 b=0;
180 }
181 else
182 {
183 r=255;
184 g=255;
185 b=255;
186 }
187 }
188 }
189 break;
190
191 case DITHER_ORDERED:
192 {
193 //
194 // Use a dithering matrix
195 //
196 int bit=1 << ((x&3) | ((y&3)<<2));
197
198 unsigned char c=(r+g+b)/3;
199 if (DitherMask[(c*8)/255]&bit) c=255;
200 else c=0;
201
202 r=g=b=c;
203 }
204 break;
205
206 default:
207 break;
208 }
209
210 if (r|g|b)
211 return ORIC_COLOR_WHITE|alphaMask;
212 return ORIC_COLOR_BLACK|alphaMask;
213 }
214
215
216
217 ORIC_COLOR OricPictureConverter::convert_pixel_rgb(const ImageContainer& sourcePicture,unsigned int x,unsigned int y)
218 {
219 RgbColor rgb1=sourcePicture.ReadColor(x,y+0);
220 RgbColor rgb2=sourcePicture.ReadColor(x,y+1);
221 RgbColor rgb3=sourcePicture.ReadColor(x,y+2);
222
223 unsigned char r=(rgb1.m_red +rgb2.m_red +rgb3.m_red )/3;
224 unsigned char g=(rgb1.m_green+rgb2.m_green+rgb3.m_green)/3;
225 unsigned char b=(rgb1.m_blue +rgb2.m_blue +rgb3.m_blue )/3;
226
227 int c;
228
229 switch (m_dither)
230 {
231 case DITHER_NONE:
232 //
233 // Simple BLACK/COMPONENT selection
234 // based on the global luminosity.
235 //
236 c=y % 3;
237
238 switch (c)
239 {
240 case 0:
241 if (r>127) r=255;
242 else r=0;
243 g=0;
244 b=0;
245 break;
246 case 1:
247 if (g>127) g=255;
248 else g=0;
249 r=0;
250 b=0;
251 break;
252 case 2:
253 if (b>127) b=255;
254 else b=0;
255 r=0;
256 g=0;
257 break;
258 }
259 if (r|g|b)
260 return ORIC_COLOR_WHITE;
261 return ORIC_COLOR_BLACK;
262 break;
263
264 case DITHER_ALTERNATE:
265 //
266 // Semi dithering :))
267 // BLACK/GREY/WHITE
268 //
269 c=y % 3;
270
271 switch (c)
272 {
273 case 0:
274 if (r>170) r=255;
275 else
276 if (r<85) r=0;
277 else r=(unsigned char)(255*((x^y)&1));
278 g=0;
279 b=0;
280 break;
281 case 1:
282 if (g>170) g=255;
283 else
284 if (g<85) g=0;
285 else g=(unsigned char)(255*((x^y)&1));
286 r=0;
287 b=0;
288 break;
289 case 2:
290 if (b>170) b=255;
291 else
292 if (b<85) b=0;
293 else b=(unsigned char)(255*((x^y)&1));
294 r=0;
295 g=0;
296 break;
297 }
298 if (r|g|b)
299 return ORIC_COLOR_WHITE;
300 return ORIC_COLOR_BLACK;
301 break;
302
303 case DITHER_ORDERED:
304 {
305 //
306 // Use a dithering matrix
307 //
308 int bit=1 << ((x&3) | ((y&3)<<2));
309
310 c=y % 3;
311
312 switch (c)
313 {
314 case 0:
315 if (DitherMask[(r*8)/255]&bit) r=255;
316 else r=0;
317 g=0;
318 b=0;
319 break;
320 case 1:
321 if (DitherMask[(g*8)/255]&bit) g=255;
322 else g=0;
323 r=0;
324 b=0;
325 break;
326 case 2:
327 if (DitherMask[(b*8)/255]&bit) b=255;
328 else b=0;
329 r=0;
330 g=0;
331 break;
332 }
333 if (r|g|b)
334 return ORIC_COLOR_WHITE;
335 return ORIC_COLOR_BLACK;
336 }
337 break;
338
339 case DITHER_FLOYD:
340 break;
341
342 default:
343 break;
344 }
345 return ORIC_COLOR_BLACK;
346 }
347
348
349
350
351
352 ORIC_COLOR OricPictureConverter::convert_pixel_rb(const ImageContainer& sourcePicture,unsigned int x,unsigned int y)
353 {
354 RgbColor rgb1=sourcePicture.ReadColor(x,y+0);
355 RgbColor rgb2=sourcePicture.ReadColor(x,y+1);
356 RgbColor rgb3=sourcePicture.ReadColor(x,y+2);
357
358 unsigned char r=(rgb1.m_red+rgb2.m_red +rgb3.m_red)/3;
359 unsigned char gb=(rgb1.m_green+rgb2.m_green+rgb3.m_green+rgb1.m_blue+rgb2.m_blue +rgb3.m_blue)/6;
360
361 int c;
362 switch (m_dither)
363 {
364 case DITHER_NONE:
365 //
366 // Simple BLACK/COMPONENT selection
367 // based on the global luminosity.
368 //
369 c=y % 2;
370
371 switch (c)
372 {
373 case 0:
374 if (r>127) r=255;
375 else r=0;
376 gb=0;
377 break;
378 case 1:
379 if (gb>127) gb=255;
380 else gb=0;
381 r=0;
382 break;
383 }
384 break;
385
386 case DITHER_ALTERNATE:
387 //
388 // Semi dithering :))
389 // BLACK/GREY/WHITE
390 //
391 c=y % 2;
392
393 switch (c)
394 {
395 case 0:
396 if (r>170) r=255;
397 else
398 if (r<85) r=0;
399 else r=(unsigned char)(255*((x^y)&1));
400 gb=0;
401 break;
402 case 1:
403 if (gb>170) gb=255;
404 else
405 if (gb<85) gb=0;
406 else gb=(unsigned char)(255*((x^y)&1));
407 r=0;
408 break;
409 }
410 break;
411
412 case DITHER_ORDERED:
413 //
414 // Use a dithering matrix
415 //
416 int bit;
417
418 bit=1 << ((x&3) | ((y&3)<<2));
419
420 c=y % 2;
421
422 switch (c)
423 {
424 case 0:
425 if (DitherMask[(r*8)/255]&bit) r=255;
426 else r=0;
427 gb=0;
428 break;
429 case 1:
430 if (DitherMask[(gb*8)/255]&bit) gb=255;
431 else gb=0;
432 r=0;
433 break;
434 }
435 break;
436
437 case DITHER_FLOYD:
438 break;
439
440 default:
441 break;
442 }
443
444 if (r|gb)
445 return ORIC_COLOR_WHITE;
446 return ORIC_COLOR_BLACK;
447 }
448
449
450
451
452
453
454
455 void OricPictureConverter::convert_monochrom(const ImageContainer& sourcePicture)
456 {
457 ImageContainer convertedPicture(sourcePicture);
458
459 //
460 // Perform the global dithering, if required
461 //
462 switch (m_dither)
463 {
464 case DITHER_RIEMERSMA:
465 dither_riemersma_monochrom(convertedPicture,m_Buffer.m_buffer_width,m_Buffer.m_buffer_height);
466 m_dither=DITHER_NONE;
467 break;
468 }
469
470 //
471 // Perform the HIRES conversion
472 //
473 unsigned char* ptr_hires=m_Buffer.m_buffer;
474 for (unsigned int y=0;y<m_Buffer.m_buffer_height;y++)
475 {
476 int x=0;
477 for (int col=0;col<m_Buffer.m_buffer_cols;col++)
478 {
479 unsigned char val=0;
480 unsigned char transparentPixelMask=0;
481 for (int bit=0;bit<6;bit++)
482 {
483 val<<=1;
484 transparentPixelMask<<=1;
485 ORIC_COLOR color=convert_pixel_monochrom(convertedPicture,x,y);
486
487 if ( (m_transparency==TRANSPARENCY_HOLES) && (color & ORIC_COLOR_TRANSPARENT) )
488 {
489 color&=~ORIC_COLOR_TRANSPARENT;
490 transparentPixelMask|=1;
491 }
492
493 if (color!=ORIC_COLOR_BLACK)
494 {
495 val|=1;
496 }
497 x++;
498 }
499 if ( (m_transparency==TRANSPARENCY_HOLES) && (transparentPixelMask==(1+2+4+8+16+32)) )
500 {
501 val=0;
502 }
503 else
504 if (m_flag_setbit6)
505 {
506 // In some cases you don't want to get the bit 6 to be set at all
507 val|=64;
508 }
509 *ptr_hires++=val;
510 }
511 }
512 }
513
514
515
516
517
518
519 class OricImageContainer : public ImageContainer
520 {
521 public:
522 OricImageContainer(const ImageContainer& otherImage)
523 : ImageContainer(otherImage)
524 {}
525
526 OricRgbColor ReadOricColor(int x,int y)
527 {
528 OricRgbColor oricColor;
529 BYTE *ptr_byte=FreeImage_GetBitsRowCol(GetBitmap(),x,y);
530
531 oricColor.m_blue =*ptr_byte++;
532 oricColor.m_green =*ptr_byte++;
533 oricColor.m_red =*ptr_byte++;
534 oricColor.m_alpha =*ptr_byte++;
535
536 return oricColor;
537 }
538
539 };
540
541
542 void OricPictureConverter::convert_aic(const ImageContainer& sourcePicture)
543 {
544 OricImageContainer convertedPicture(sourcePicture);
545
546 //
547 // Perform the global dithering, if required
548 //
549 switch (m_dither)
550 {
551 case DITHER_RIEMERSMA:
552 dither_riemersma_monochrom(convertedPicture,m_Buffer.m_buffer_width,m_Buffer.m_buffer_height);
553 m_dither=DITHER_NONE;
554 break;
555 }
556
557 //
558 // Perform the HIRES conversion
559 //
560 unsigned char* ptr_hires=m_Buffer.m_buffer;
561 for (unsigned int y=0;y<m_Buffer.m_buffer_height;y++)
562 {
563 ORIC_COLOR paper=m_PaletteAIC[y&1][0];
564 ORIC_COLOR ink =m_PaletteAIC[y&1][1];
565
566 int x=0;
567 for (int col=0;col<m_Buffer.m_buffer_cols;col++)
568 {
569 BlocOf6 pixelBloc;
570
571 bool isOpaque=false;
572 for (int bit=0;bit<6;bit++)
573 {
574 // Read the source color
575 OricRgbColor rgb=convertedPicture.ReadOricColor(x,y);
576 if (rgb.m_alpha>128)
577 {
578 isOpaque=true;
579 }
580
581 pixelBloc.AddColor(rgb.GetOricColor());
582 x++;
583 }
584 unsigned char val;
585 if (isOpaque || (m_transparency!=TRANSPARENCY_HOLES))
586 {
587 pixelBloc.UsePalette(paper,ink);
588 val=pixelBloc.value;
589 if (m_flag_setbit6)
590 {
591 // In some cases you don't want to get the bit 6 to be set at all
592 val|=64;
593 }
594 }
595 else
596 {
597 val=0;
598 }
599 *ptr_hires++=val;
600 }
601 }
602 }
603
604
605 void OricPictureConverter::convert_twilighte_mask(const ImageContainer& sourcePicture)
606 {
607 ImageContainer convertedPicture(sourcePicture);
608
609 //
610 // Perform the global dithering, if required
611 //
612 switch (m_dither)
613 {
614 case DITHER_RIEMERSMA:
615 dither_riemersma_monochrom(convertedPicture,m_Buffer.m_buffer_width,m_Buffer.m_buffer_height);
616 m_dither=DITHER_NONE;
617 break;
618 }
619
620 //
621 // Perform the HIRES conversion
622 //
623 unsigned char* ptr_hires=m_Buffer.m_buffer;
624 for (unsigned int y=0;y<m_Buffer.m_buffer_height;y++)
625 {
626 int x=0;
627 for (int col=0;col<m_Buffer.m_buffer_cols;col++)
628 {
629 unsigned char mask=0;
630 unsigned char mask_control=0;
631 unsigned char val=0;
632 for (int bit=0;bit<6;bit++)
633 {
634 val<<=1;
635 mask_control<<=1;
636
637 // Get the original pixel color
638 BYTE *ptr_byte=FreeImage_GetBitsRowCol(convertedPicture.GetBitmap(),x,y);
639 int color=0;
640 if ((*ptr_byte++)>128) color|=4;
641 if ((*ptr_byte++)>128) color|=2;
642 if ((*ptr_byte++)>128) color|=1;
643
644 switch (color)
645 {
646 case ORIC_COLOR_BLACK:
647 // Paper
648 val|=0;
649 mask_control|=1;
650 break;
651
652 case ORIC_COLOR_WHITE:
653 // Ink
654 val|=1;
655 mask_control|=1;
656 break;
657
658 default:
659 // mask
660 if (bit<=2)
661 {
662 mask|=2;
663 }
664 else
665 {
666 mask|=1;
667 }
668 break;
669 }
670 x++;
671 }
672
673 //
674 // Test if we have mask/pixels conflicts
675 //
676 /*
677 if ( ((mask&1) && (mask_control&(1+2+4))) ||
678 ((mask&2) && (mask_control&(8+16+32))) )
679 {
680 printf("\r\nMask/Ink/Paper problem Line %d Bloc %d",y,col);
681 }
682 */
683
684 //
685 // Write the value
686 //
687 *ptr_hires++=val|(mask<<6);
688 }
689 }
690 }
691
692
693
694 void OricPictureConverter::convert_rgb(const ImageContainer& sourcePicture)
695 {
696 ImageContainer convertedPicture(sourcePicture);
697
698 //
699 // Perform the global dithering, if required
700 //
701 switch (m_dither)
702 {
703 case DITHER_RIEMERSMA:
704 dither_riemersma_rgb(convertedPicture,m_Buffer.m_buffer_width,m_Buffer.m_buffer_height);
705 m_dither=DITHER_NONE;
706 break;
707 }
708
709 //
710 // Perform the HIRES conversion
711 //
712 unsigned char* ptr_hires=m_Buffer.m_buffer;
713 for (unsigned int y=0;y<m_Buffer.m_buffer_height;y++)
714 {
715 //
716 // Write RgbColor attrib
717 //
718 switch (y%3)
719 {
720 case 0:
721 *ptr_hires++=ORIC_COLOR_RED;
722 break;
723 case 1:
724 *ptr_hires++=ORIC_COLOR_GREEN;
725 break;
726 case 2:
727 *ptr_hires++=ORIC_COLOR_BLUE;
728 break;
729 }
730
731 int x=0;
732 for (int col=1;col<m_Buffer.m_buffer_cols;col++)
733 {
734 unsigned char val=0;
735 for (int bit=0;bit<6;bit++)
736 {
737 val<<=1;
738 ORIC_COLOR color=convert_pixel_rgb(convertedPicture,x,y);
739 if (color!=ORIC_COLOR_BLACK)
740 {
741 val|=1;
742 }
743 x++;
744 }
745 if (m_flag_setbit6)
746 {
747 // In some cases you don't want the bit 6 to be set at all
748 val|=64;
749 }
750 *ptr_hires++=val;
751 }
752 }
753 }
754
755
756
757
758
759
760
761
762
763 void OricPictureConverter::convert_rb(const ImageContainer& sourcePicture)
764 {
765 ImageContainer convertedPicture(sourcePicture);
766
767 //
768 // Perform the global dithering, if required
769 //
770 switch (m_dither)
771 {
772 case DITHER_RIEMERSMA:
773 dither_riemersma_rgb(convertedPicture,m_Buffer.m_buffer_width,m_Buffer.m_buffer_height);
774 m_dither=DITHER_NONE;
775 break;
776 }
777
778 //
779 // Perform the HIRES conversion
780 //
781 unsigned char *ptr_hires=m_Buffer.m_buffer;
782 for (unsigned int y=0;y<m_Buffer.m_buffer_height;y++)
783 {
784 //
785 // Write RgbColor attrib
786 //
787 switch (y%2)
788 {
789 case 0:
790 *ptr_hires++=ORIC_COLOR_RED;
791 break;
792 case 1:
793 *ptr_hires++=ORIC_COLOR_WHITE;
794 break;
795 }
796
797 int x=0;
798 for (int col=0;col<39;col++)
799 {
800 unsigned char val=0;
801 for (int bit=0;bit<6;bit++)
802 {
803 val<<=1;
804 ORIC_COLOR color=convert_pixel_rb(convertedPicture,x,y);
805 if (color!=ORIC_COLOR_BLACK)
806 {
807 val|=1;
808 }
809 x++;
810 }
811 if (m_flag_setbit6)
812 {
813 // In some cases you don't want the bit 6 to be set at all
814 val|=64;
815 }
816 *ptr_hires++=val;
817 }
818 }
819 }
820
821
822
823
824
825 bool OricPictureConverter::Convert(const ImageContainer& sourcePicture)
826 {
827 if (m_blockmode==BLOCKMODE_ENABLED)
828 {
829 // Find the blocks, and then continue the conversion
830 sourcePicture.FindBlocks(m_block_data);
831 //std::cout << "-b1 (block mode) not supported on this machine";
832 //return false;
833 }
834
835 if ( ( (m_format==OricPictureConverter::FORMAT_COLORED) || (m_format==OricPictureConverter::FORMAT_SAM_HOCEVAR) ) &&
836 ((sourcePicture.GetWidth()%6)==0) &&
837 (sourcePicture.GetWidth()>240))
838 {
839 printf("\r\n Colored/SamHocevar pictures should be at most 240 pixels wide, and multiple of 6 pixel wide.");
840 return false;
841 }
842
843 m_Buffer.SetBufferSize(sourcePicture.GetWidth(),sourcePicture.GetHeight());
844 m_Buffer.ClearBuffer(m_flag_setbit6);
845
846 switch (m_format)
847 {
848 case FORMAT_MONOCHROM:
849 convert_monochrom(sourcePicture);
850 break;
851
852 case FORMAT_COLORED:
853 convert_colored(sourcePicture);
854 break;
855
856 case FORMAT_RGB:
857 convert_rgb(sourcePicture);
858 break;
859
860 case FORMAT_RB:
861 convert_rb(sourcePicture);
862 break;
863
864 case FORMAT_TWILIGHTE_MASK:
865 convert_twilighte_mask(sourcePicture);
866 break;
867
868 case FORMAT_CHARMAP:
869 convert_charmap(sourcePicture);
870 break;
871
872 case FORMAT_SAM_HOCEVAR:
873 convert_sam_hocevar(sourcePicture);
874 break;
875
876 case FORMAT_AIC:
877 convert_aic(sourcePicture);
878 break;
879
880 default:
881 // Oops
882 return false;
883 break;
884 }
885 return true;
886 }
887
888
889
890 bool OricPictureConverter::TakeSnapShot(ImageContainer& sourcePicture)
891 {
892 if (!sourcePicture.Allocate(m_Buffer.m_buffer_width,m_Buffer.m_buffer_height,32))
893 {
894 return false;
895 }
896
897 unsigned char *ptr_hires=m_Buffer.m_buffer;
898 for (unsigned int y=0;y<m_Buffer.m_buffer_height;y++)
899 {
900 ORIC_COLOR paper,ink;
901
902 if (m_format==FORMAT_AIC)
903 {
904 paper=m_PaletteAIC[y&1][0];
905 ink =m_PaletteAIC[y&1][1];
906 }
907 else
908 {
909 paper=ORIC_COLOR_BLACK;
910 ink =ORIC_COLOR_WHITE;
911 }
912
913 int x=0;
914 for (int col=0;col<m_Buffer.m_buffer_cols;col++)
915 {
916 int val=*ptr_hires++;
917 int val2=val&127;
918
919 ORIC_COLOR cpaper=paper;
920 ORIC_COLOR cink =ink;
921 if (val2<8)
922 {
923 ink=(ORIC_COLOR)val2;
924 val2=0;
925 cpaper =paper;
926 cink =ink;
927 }
928 else
929 if ((val2>=16) && (val2<(16+8)))
930 {
931 paper=(ORIC_COLOR)(val2-16);
932 val2=0;
933 cpaper =paper;
934 cink =ink;
935 }
936
937 if (val&128)
938 {
939 cpaper=(ORIC_COLOR)(7-cpaper);
940 cink=(ORIC_COLOR)(7-cink);
941 }
942
943 for (int bit=0;bit<6;bit++)
944 {
945 OricRgbColor rgb;
946 if (val2 & (1<<(5-bit)))
947 {
948 rgb.SetOricColor(cink);
949 }
950 else
951 {
952 rgb.SetOricColor(cpaper);
953 }
954 sourcePicture.WriteColor(rgb,x,y);
955 x++;
956 }
957 }
958 }
959 return true;
960 }
961
962
963
964 //
965 // Contains an hexa dump of the following
966 // auto-loadable BASIC program:
967 //
968 // 10 HIRES
969 // 20 CLOAD""
970 //
971 unsigned char BasicLoader[]=
972 {
973 0x16,0x16,0x16,0x24,0x00,0xff,0x00,0xc7,0x05,0x11,0x05,0x01,0x00,0x48,0x49,0x52,
974 0x4c,0x4f,0x41,0x44,0x00,0x07,0x05,0x0a,0x00,0xa2,0x00,0x0f,0x05,0x14,0x00,0xb6,
975 0x22,0x22,0x00,0x00,0x00,0x55
976 };
977
978
979
980
981 void OricPictureConverter::save_header(long handle,int adress_begin)
982 {
983 unsigned char Header[]=
984 {
985 // 0
986 0x16,0x16,0x16,
987 // 3
988 0x24,
989 // 4
990 0x00,0x00,
991 // 6
992 0x80,0x00,
993 // 8
994 0xbf,0xdf,
995 // 10
996 0xa0,0x00,
997 // 12
998 0x00
999 };
1000
1001 int adress_end=adress_begin+m_Buffer.m_buffer_size;
1002 Header[ 8]=(unsigned char)((adress_end>>8)&255);
1003 Header[ 9]=(unsigned char)( adress_end&255);
1004 Header[10]=(unsigned char)((adress_begin>>8)&255);
1005 Header[11]=(unsigned char)( adress_begin&255);
1006 write(handle,Header,13);
1007 }
1008
1009 void OricPictureConverter::SaveToFile(long handle,int output_format)
1010 {
1011 switch (output_format)
1012 {
1013 case DEVICE_FORMAT_RAWBUFFER_WITH_XYHEADER:
1014 {
1015 unsigned char x=static_cast<unsigned char>(get_buffer_width());
1016 unsigned char y=static_cast<unsigned char>(get_buffer_height());
1017
1018 write(handle,&x,1);
1019 write(handle,&y,1);
1020 }
1021 break;
1022
1023 case DEVICE_FORMAT_RAWBUFFER_WITH_PALETTE:
1024 break;
1025
1026 case DEVICE_FORMAT_RAWBUFFER:
1027 // No header for raw
1028 break;
1029
1030 case DEVICE_FORMAT_BASIC_TAPE:
1031 write(handle,BasicLoader,sizeof(BasicLoader));
1032 default: // Fall trough
1033 bool flag_header=true;
1034 if (flag_header)
1035 {
1036 save_header(handle,0xa000);
1037 //write(handle,Header,13);
1038 write(handle,"",1); //write(handle,name,strlen(name)+1);
1039 }
1040 break;
1041 }
1042 write(handle,(unsigned char*)m_Buffer.m_buffer,GetBufferSize());
1043 }
1044

  ViewVC Help
Powered by ViewVC 1.1.26