diff --git a/.gitignore b/.gitignore
index eba8f54..466178a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,9 @@
./x64
./x86
+./RgbToHiRes.vcxproj.user
+*.sln
+*.bin
+*.asm
+**/.vs
**/Debug
**/Release
diff --git a/RgbToHiRes.vcxproj.user b/RgbToHiRes.vcxproj.user
deleted file mode 100644
index 26ab88e..0000000
--- a/RgbToHiRes.vcxproj.user
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- -i D:\Chris.ARES\Dropbox\_Partages\_Macbook\Green.png
- WindowsLocalDebugger
-
-
- -i D:\Chris.ARES\Dropbox\_Partages\_Macbook\Green.png
- WindowsLocalDebugger
-
-
\ No newline at end of file
diff --git a/src/HiRes.cpp b/src/HiRes.cpp
index 0392e37..c0a52eb 100644
--- a/src/HiRes.cpp
+++ b/src/HiRes.cpp
@@ -9,6 +9,8 @@ using namespace std;
namespace RgbToHires {
+ /************************* CLASS BlockHr **********************/
+
BlockHr::BlockHr()
{
_data[0] = 0;
@@ -37,9 +39,9 @@ namespace RgbToHires {
}
- std::pair BlockHr::getGroup(const BlockPixel& block) const
+ pair BlockHr::getGroup(const BlockPixel& block) const
{
- std::pair groups{ GROUP_1, GROUP_1 };
+ pair groups{ GROUP_1, GROUP_1 };
//1st block group, including the last semi-pixel
for (auto i = 0u; i < 4u; ++i) {
if (block[i] == GREEN || block[i] == VIOLET) {
@@ -86,25 +88,78 @@ namespace RgbToHires {
}
+
+ /************************* CLASS HiRes **********************/
+
+
+
+
HiRes::HiRes(const ImageQuantized& source)
{
auto pixel_src = source.getConstPixels(0u, 0u, WIDTH, HEIGHT);
-
+ //Filling the storage with BlockHrs
for (auto& line : _blob) {
- for (auto& block : line) {
+ line.reserve(NB_BLOCK_PER_LINES);
+ //Useful data
+ for (auto blockNr = 0u; blockNr < NB_BLOCK_PER_LINES; ++blockNr ) {
BlockPixel blockPxRgb;
for (auto& pxRgb : blockPxRgb) {
pxRgb = *pixel_src++;
}
- block = BlockHr{ blockPxRgb };
+ line.emplace_back(BlockHr{ blockPxRgb });
+ }
+ }
+ //Constructing the map used to interleave the lines
+ auto i = 0u;
+ for (const auto& line : _blob) {
+ auto addr_interleaved = _lineAdresses[i / 8] + _lineOffsets[i % 8];
+ _hrOrderedLines.insert(pair(addr_interleaved, &line));
+ ++i;
+ }
+ //Adding the 8 byte "memory holes"
+ for (auto line : _hrOrderedLines) {
+ if ((line.first & 0xFF) == 0x50 || (line.first & 0xFF) == 0xD0) {
+ for (auto i = 0u; i < 4u; ++i) {
+ const_cast(line.second)->emplace_back(BlockHr{});
+ }
}
}
-
}
+ unique_ptr> HiRes::getBlob() const
+ {
+ auto blob = unique_ptr>{ new array};
+ auto byte_blob = begin(*blob);
+ for (const auto& line : _hrOrderedLines) {
+ for (const auto& block : *(line.second)) {
+ for (const auto byte_block : block) {
+ *byte_blob++ = byte_block;
+ }
+ }
+ }
+ return blob;
+ }
+ string HiRes::getAsm() const
+ {
+ string assembly{ "Picture:\n" };
+ for (const auto& line : _hrOrderedLines) {
+ assembly += "\t.byte\t";
+ for (const auto& block : *(line.second)) {
+ for (const auto byte : block) {
+ assembly += to_string(byte) + ", ";
+ }
+ }
+ assembly.pop_back(); //removing the last coma
+ assembly.pop_back();
+ assembly += "\n";
+ }
+ return assembly;
+ }
+
+
}
\ No newline at end of file
diff --git a/src/HiRes.h b/src/HiRes.h
index 403aaf9..849c13d 100644
--- a/src/HiRes.h
+++ b/src/HiRes.h
@@ -3,6 +3,8 @@
#include
#include
+#include
+#include
#include "Common.h"
@@ -18,14 +20,21 @@ namespace RgbToHires {
BlockHr();
/// \brief Construction from 7 pixels
BlockHr(const BlockPixel& );
+ /// \brief returns the position of the first element
+ inline std::array::const_iterator begin() const {
+ return _data.begin();
+ }
+ /// \brief returns the position after the last element
+ inline std::array::const_iterator end() const {
+ return _data.end();
+ }
private:
/// \brief color group as defined in Apple's documentation
enum eColorGroup {
GROUP_1,
GROUP_2
};
- /// \brief Returns the color group of these two pixel blocks
- /// Works on double blocks instead of single blocks
+ /// \brief Returns the color group of these two 3.5 pixel blocks
std::pair getGroup(const BlockPixel&) const;
/// \brief Returns the bit pait corresponding to the given color
uint8_t getDibit(const Magick::Color&) const;
@@ -33,18 +42,38 @@ namespace RgbToHires {
std::array _data;
};
- using LineHr = std::array;
- using Blob = std::array;
+
+ static constexpr unsigned NB_BLOCK_PER_LINES = 20u;
+ static constexpr unsigned NB_LINES_PER_SCREEN = 192u;
+ using LineHr = std::vector;
+ using Blob = std::array;
+
+
class HiRes
{
public:
+ static constexpr unsigned FRAME_SIZE = 192 * 40 + 512; ///< Frame size in byte
+
HiRes(const ImageQuantized&);
~HiRes() = default;
+ /// \brief Returns the binary hires picture
+ std::unique_ptr > getBlob() const;
+ /// \brief Returns asm code corresponding to the image in memory (CA65 format)
+ std::string getAsm() const;
private:
- Blob _blob; ///< A frame ordered buffer of hires data
+ Blob _blob; ///< A frame ordered buffer of hires data
+ static constexpr std::array _lineAdresses = {
+ 0x2000, 0x2080, 0x2100, 0x2180, 0x2200, 0x2280, 0x2300, 0x2380,
+ 0x2028, 0x20a8, 0x2128, 0x21a8, 0x2228, 0x22a8, 0x2328, 0x23a8,
+ 0x2050, 0x20d0, 0x2150, 0x21d0, 0x2250, 0x22d0, 0x2350, 0x23d0
+ };
+ static constexpr std::array _lineOffsets = {
+ 0x0, 0x400, 0x800, 0xc00, 0x1000, 0x1400, 0x1800, 0x1c00
+ };
+ std::map _hrOrderedLines; ///< map
};
diff --git a/src/Main.cpp b/src/Main.cpp
index 547b662..e7cb647 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -1,6 +1,7 @@
#include
#include
+#include
#include
#include
@@ -19,16 +20,25 @@ inline bool exists(const std::string& path)
return (stat(path.c_str(), &buffer) == 0);
}
+/// \brief Program entry point
int main( int argc, char *argv[] )
{
Magick::InitializeMagick(*argv);
//Parsing command line
TCLAP::CmdLine cmd("rgbtohires", ' ', "0");
- TCLAP::ValueArg imagePath("i", "image", "Image path", true, "", "path_to_image");
+ TCLAP::ValueArg imagePath("i", "image", "Source image path", true, "", "path_to_image");
+ TCLAP::ValueArg outputPath("o", "output", "Output path", true, "", "path_to_output");
+ TCLAP::SwitchArg assembly("a", "asm", "Output asm format");
cmd.add(imagePath);
+ cmd.add(outputPath);
+ cmd.add(assembly);
cmd.parse(argc, argv);
+ if (imagePath.getValue().size() == 0 || outputPath.getValue().size() == 0) {
+ return -1;
+ }
+
try {
const auto filepath = imagePath.getValue();
if (!exists(filepath)) {
@@ -36,7 +46,16 @@ int main( int argc, char *argv[] )
}
const auto imageRgb = Magick::Image{ filepath };
auto imageQuantized = ImageQuantized{ imageRgb };
- const auto imageHiRes = HiRes{ imageQuantized };
+ const auto imageHiRes = HiRes{ imageQuantized };
+ if (assembly.getValue() == true) { //Ouput in ASM
+ ofstream output(outputPath.getValue());
+ output << imageHiRes.getAsm();
+ }
+ else { //Binary output
+ ofstream output(outputPath.getValue(), ios::binary);
+ const auto bytes = imageHiRes.getBlob();
+ output.write(reinterpret_cast(bytes.get()), bytes->size());
+ }
}
//Fatal error