Jump to content
IGNORED

Printing using Altirra?


Mclaneinc

Recommended Posts

What would be the use of that? Is there any software, which doesn't account for an 850 for printing?

E.g. Print Shop just print 7 graphic lines, then advances the paper accordingly to circumvent the EOL conversion.

 

Altirra's (or whatever emulator's) ability to output raw data sent to P: device could be very beneficial. Imagine a standalone printer emulator (1029, 1027 or whatever) program that would take the raw data stream and generate a PDF. That would also keep the printer emulation outside Altirra. With libraries like cairo (free and relatively simple rendering to PDF) and pango (rendering of text), it could result in a portable (Win/Mac/Lin) solution. And if someone creates a ttf version of the 1029 and 1027's font, here we are. Such standalone printer emulator would also allow convenient localization.

 

Of course, there are few EPSON printer emulators already that print to PDF too. So if Altirra could output the raw datastream from an application that supports EPSON standard, you can have your PDF.

 

Edit:

When thinking about it, If the Atari application uses CIO to print, who prevents us from printing to D1:FILE.PRN or H1:FILE.PRN and feed the printer emulator....

Edited by baktra
  • Like 3
Link to comment
Share on other sites

 

Altirra's (or whatever emulator's) ability to output raw data sent to P: device could be very beneficial. Imagine a standalone printer emulator (1029, 1027 or whatever) program that would take the raw data stream and generate a PDF. That would also keep the printer emulation outside Altirra. With libraries like cairo (free and relatively simple rendering to PDF) and pango (rendering of text), it could result in a portable (Win/Mac/Lin) solution. And if someone creates a ttf version of the 1029 and 1027's font, here we are. Such standalone printer emulator would also allow convenient localization.

Ok, I thought we are talking ESC/P. For most of the Atari Printer, only raw output makes sense. I already implemented Atari 1020 and 1027 emulation in RespeQt like this.

But for ESC/P, you have to assume there is a 850 inbetween. And that's how I also implemented the Centronics connected printers (of which I actually implemented none ;-) ).

Edited by JoSch
  • Like 1
Link to comment
Share on other sites

  • 7 years later...
On 5/28/2017 at 1:55 PM, toddtmw said:

Bump.

 

Is this posible? Can I print from printshop to something that I could then print on a modern printer connected to my Windows computer?

 

Thanks.

The super Bump 😷

 

I've been messing with printers lately and this is just a quick Altirra TCP printer hack I managed to implement for my upcoming printer emulator which I am actually writing for Atari ST platform. 

Hopefully to be release soon but for now if you need raw file data dump using this method all you need is correctly set up Altirra emulator and Processing language installed on your system.

This connects to the Altirra using Network TCP printer.atdevice .... which is included with the emulator in  \extras\sampledevices folder at least on MS Windows installation.

 

Just a quick Altirra set up guide here:

For Processing language here: https://processing.org/

 

in System tab select Devices

image.thumb.jpeg.29819794b93583ac0851b02a241336dd.jpeg

Other devices

image.thumb.jpeg.255392cfd12cfa8168aa6812a9bcc762.jpeg

You need to click on config path ....  as you can see mine is already selected here.

image.jpeg.78ac68f245c590ba58663ff3aa0a1e25.jpeg

select  printer.atdavice

image.thumb.jpeg.6599fd55087263b88a314511961d9681.jpeg

 if I didn't miss anything here next time you start Altirra you should see this text in bottom left corner.

image.thumb.jpeg.1599b7ef65c74a488853efd1163ddcf8.jpeg

Now if you have your Processing language installed just copy this and run it.

Use your favorite application for printing in the emulator and then point to the green processing window and click on it.

image.jpeg.986f7085a71e11be851bf0a15eec79a4.jpeg

This will open file selector choose the name and save the raw file that's it

(Note: only tested on MS Windows 10)

(Processing is open source and is available for macOS, Windows, Linux and Raspberry Pi +)

 

/** Altirra atdavice TCP Protocol RAW file dump example.
 MIT License
 Chris O. 2024
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */

import processing.net.*;
Server myServer;

boolean IsClientUP = false;
boolean thisClientbool = false;
int netstart = 0;
int[] data = new int[131073]; // 128Kb buffer
int[] dataheader = new int[50];
int dataIn;
int timer;
long timer2;
int countheader;
int count;
int D2count;
boolean headerbool = false;
boolean databool = false;

String path ="";

// --- setup() ---
void setup() {
  size(400, 200);
  // Starts a myServer on port 6502
  myServer = new Server(this, 6502);
}

// --- draw() ---
void draw() {

  Client thisClient = myServer.available();
  // If the client is not null, and says something, display what it said
  if (thisClient !=null) {
    thisClientbool = true;
    dataIn = thisClient.read();
    //
    if (countheader == 0 && (dataIn == 4 || dataIn == 7)  ) { // DO THIS ONLY IF DATA 7 OR 4
      println("headerbool " + headerbool);
      if ((countheader >= 0) && (countheader < 17)) { // 17 bytes header ~ 0 indexed
        dataheader[countheader] = dataIn; // save in header array
        println("HEX: " +hex(dataheader[countheader], 2) + /** " , show chr: " + (char)dataIn + */ " , countheader: " + countheader);
        countheader++;
        //
        while (countheader < 17) {
          dataheader[countheader] = thisClient.read();
          println("HEX: " +hex(dataheader[countheader], 2) + /** " , show chr: " + (char)dataIn + */ " , countheader: " + countheader);
          if (countheader == 16) {
            timer = 0;
            timer = ((dataheader[8] & 0xFF) << 0); // / & 0xff
            timer = ((dataheader[9] & 0xFF) << 8);
            timer = ((dataheader[10] & 0xFF) << 16);
            timer = ((dataheader[11] & 0xFF) << 24);
            //timer = ((dataheader[13] & 0xFF) << 32);
            //timer = ((dataheader[14] & 0xFF) << 40);

            timer2 = timer & 0xffffffffL;

            int mm = millis();
            int s = second();  // Values from 0 - 59
            int m = minute();  // Values from 0 - 59
            int h = hour();    // Values from 0 - 23
            println("System time: " + h + ":" + m + ":" + s + "." + mm);

            headerbool = true;
            println("headerbool " + headerbool + " timer: " + timer2);
          }
          countheader++;
        }
      }
    }

    if (headerbool == true) {
      dataIn = thisClient.read();
      data[count] = dataIn;
      //
      countheader = 0;
      // we got the header now ask for data
      // println(" we got the header now ask for data ");
      if (dataheader[0] == 4) {
        //
        // println(" skip id4 ");
        // println("databool " + databool);
        //
        /*
        myServer.write(0x06); //1
         myServer.write(0x00); //2
         myServer.write(0x00); //3
         myServer.write(0x00); //4
         myServer.write(0x00); //5
         myServer.write(0x00); //6
         myServer.write(0x28); //7, print_width 40
         myServer.write(0x00); //8
         myServer.write(0x00); //9
         myServer.write(0x00); //10
         myServer.write(0x01); //11
         myServer.write(0x00); //12
         myServer.write(0x00); //13
         myServer.write(0x00); //14
         myServer.write(0x00); //15
         */
        delay(50);
      }
      if (dataheader[0] == 7) {
        // ASK ONLY IF DATA AVAL, need 2 ask or emulator frozen ?
        println(" Ask for data id7 ");
        println("databool " + databool);
        myServer.write(0x06); //1
        myServer.write(0x00); //2
        myServer.write(0x00); //3
        myServer.write(0x00); //4
        myServer.write(0x00); //5
        myServer.write(0x00); //6
        myServer.write(0x28); //7, print_width 40
        myServer.write(0x00); //8
        myServer.write(0x00); //9
        myServer.write(0x00); //10
        myServer.write(0x01); //11
        myServer.write(0x00); //12
        myServer.write(0x00); //13
        myServer.write(0x00); //14
        myServer.write(0x00); //15
        databool = true;
        delay(50); // if you see FFFFFFFF count #n~ dataheader[1] size 40 - change this to *2 --- exp: 100
      }
    }

    if (databool == true) {
      //
      println("databool " + databool);
      //
      if (dataheader[0] == 7) {
        int i = dataheader[1] + count;
        background(0, 100, 255); // RGB
        while (i > count) {
          dataIn = thisClient.read();
          data[count] = dataIn;
          println(hex(dataIn, 2) + " " + (char)dataIn + " count " + count + " dataheader[1] size " + dataheader[1]);
          count++;
        }
        //
        headerbool = false;
      }
    } //- if (databool == true)
  } else { // if (thisClient !=null)
    // Client aval. but data == null
    if (thisClientbool == true) {
      background(0, 255, 0); // RGB
      println("thisClientbool " + thisClientbool);
      thisClientbool = false;
      if (IsClientUP == true) {
        println("IsClientUP " + IsClientUP);

        println("data, size:" + count);
        D2count = count;
        int x = 0;
        for (int i = 0; i < count; i++)
        {
          x++;
          print("[" + i + "] " + hex(data[i], 2) + "  ");
          if (x == 11) {
            x = 0;
            println();
          }
        }
        count = 0; // DATA COUNT RESET
      }
    }
  }

  if (netstart == 0) {
    if (IsClientUP == true) {
      println("netstart restart " + IsClientUP);
      netstart = 1;
      // why i need to send this twice?
      netstart(); // reint... connection
      netstart(); // reint... connection
    }
  }
} //- draw loop end

// --- ServerEvent message is generated when a new client connects ---
// --- to an existing server.                                      ---
void serverEvent(Server someServer, Client someClient) {
  println("We have a new client: " + someClient.ip());
  IsClientUP = true;
  background(0, 0, 255); // RGB
}

// --- ClientEvent message is generated when a client disconnects. ---
void disconnectEvent(Client someClient) {
  IsClientUP = false;
  netstart = 0;
  print("Server Says: client disconnected,  IsClientUP: " + IsClientUP);
  background(255, 0, 0); // RGB
}

// --- netstart                                                    ---
void netstart() {

  // HELLO START
  println("SetUP - ask for heder ");
  myServer.write(0x0C);
  myServer.write(0x02);
  myServer.write(0x0A);
  myServer.write(0x0B);
  myServer.write(0x01);
  myServer.write(0x00);
  myServer.write(0x00);
  myServer.write(0x00);
  myServer.write(0x00);
  delay(100);

  // Ask or Altirra will be frozen ?
  println("SetUP - ask for data ");
  myServer.write(0x06); //1
  myServer.write(0x00); //2
  myServer.write(0x00); //3
  myServer.write(0x00); //4
  myServer.write(0x00); //5
  myServer.write(0x00); //6
  myServer.write(0x28); //7, print_width 40
  myServer.write(0x00); //8
  myServer.write(0x00); //9
  myServer.write(0x00); //10
  myServer.write(0x01); //11
  myServer.write(0x00); //12
  myServer.write(0x00); //13
  myServer.write(0x00); //14
  myServer.write(0x00); //15
  delay(100);
}

void keyPressed() {
  if (key == ' ') {
    println();
    if (D2count > 0) {
      selectOutput("Select a file to write to:", "fileSelected");
    } else {
      println("Sorry but you are trying to save empty file, DATA SIZE:" + D2count);
      println("Try printing something in Altirra emulator!!! noob ):");
      background(255, 0, 0); // RGB
      fill(255);
      textAlign(CENTER);
      text("Sorry but you are trying to save empty file, DATA SIZE:" + D2count, width / 2, height / 2 - 20);
      text("Try printing something in Altirra emulator first !!! noob ):", width / 2, height / 2 + 20);
    }
  }
}

void mousePressed() {
  println();
  if (D2count > 0) {
    selectOutput("Select a file to write to:", "fileSelected");
  } else {

    println("Sorry but you are trying to save empty file, DATA SIZE:" + D2count);
    println("Try printing something in Altirra emulator!!! noob ):");
    background(255, 0, 0); // RGB
    fill(255);
    textAlign(CENTER);
    text("Sorry but you are trying to save empty file, DATA SIZE:" + D2count, width / 2, height / 2 - 20);
    text("Try printing something in Altirra emulator first !!! noob ):", width / 2, height / 2 + 20);
  }
}

void fileSelected(File selection) {
  if (selection == null) {
    println();
    println("Window was closed or the user hit cancel.");
    fill(255);
    textAlign(CENTER);
    text("Window was closed or the user hit cancel.", width / 2, height / 2 - 20);
  } else {
    println();
    println("User selected " + selection.getAbsolutePath());
    path = selection.getAbsolutePath();
    println("User selected path  " + path);
    byte[] nums = new byte[D2count];
    // copy byte array
    for (int i = 0; i < D2count; i++) {
      nums[i] = byte(data[i]);
    }
    // Writes the bytes to a file
    saveBytes(path, nums);
    println("Saved file, SIZE:" + D2count);
  }
}

 

  • Like 3
Link to comment
Share on other sites

Just a quick bug correction..

edit setup () from this:

// --- setup() ---
void setup() {
  size(400, 200);
  // Starts a myServer on port 6502
  myServer = new Server(this, 6502);
}

to this:

// --- setup() ---
void setup() {
  size(400, 200);
  // Starts a myServer on port 6502
  println("Altirra atdavice TCP Protocol RAW file dump example");
  myServer = new Server(this, 6502);
  netstart = 0;
}

This will fix APP shut down and restart when Altirra is up and running.

Link to comment
Share on other sites

Did you 'home roll' your own Epson emulation? Or are you using something already existing.  (I played around with PrinterToPDF, which was a pain to compile but did work, and got it running on Apple IIGS emulators, but not Altirra/Atari yet.)

Link to comment
Share on other sites

Currently supported :

Epson ESC/P and Hewlett-Packard PCL 5 Printer Language (HP_LaserJet_series_II & HP_LaserJet_series_ 500) the minimum required for graphics.

Almost forgot + Canon Bubble jet bit image commands.

Link to comment
Share on other sites

I figured out the work around for the max 7bit printing issue however I did run into issues with my Altirra TCP raw dump utility.

 

The bug and the fix 😷 for now...

This happens when you actually try printing full page and the data is being built in the memory what appears to be sending buffered chunks with about +- 5 seconds apart.

Find and replace:

  } else { // if (thisClient !=null)
    // Client aval. but data == null
    if (thisClientbool == true) {
      background(0, 255, 0); // RGB
      println("thisClientbool " + thisClientbool);
      thisClientbool = false;
      if (IsClientUP == true) {
        println("IsClientUP " + IsClientUP);

        println("data, size:" + count);
        D2count = count;
        int x = 0;
        for (int i = 0; i < count; i++)
        {
          x++;
          print("[" + i + "] " + hex(data[i], 2) + "  ");
          if (x == 11) {
            x = 0;
            println();
          }
        }
        count = 0; // DATA COUNT RESET
      }
    }
  }

With:

  } else { // if (thisClient !=null)
    // Client aval. but data == null
    if (thisClientbool == true) {
      background(0, 255, 0); // RGB
      println("thisClientbool " + thisClientbool);
      thisClientbool = false;
      if (IsClientUP == true) {
        println("IsClientUP " + IsClientUP);

        println("data, size:" + count);
        D2count = count;
        int x = 0;
        for (int i = 0; i < count; i++)
        {
          x++;
          print("[" + i + "] " + hex(data[i], 2) + "  ");
          if (x == 11) {
            x = 0;
            println();
          }
        }
        // FIX
        // RESET in void mousePressed() or void keyPressed() ?
        //count = 0; // DATA COUNT RESET
      }
    }
  }

Now move the --> DATA COUNT RESET to:

void keyPressed() {
  if (key == ' ') { // SPACE KEY
    println();
    if (D2count > 0) {
      selectOutput("Select a file to write to:", "fileSelected");
      count = 0; // DATA COUNT RESET
    } else {
      println("Sorry but you are trying to save empty file, DATA SIZE:" + D2count);
      println("Try printing something in Altirra emulator!!! noob ):");
      background(255, 0, 0); // RGB
      fill(255);
      textAlign(CENTER);
      text("Sorry but you are trying to save empty file, DATA SIZE:" + D2count, width / 2, height / 2 - 20);
      text("Try printing something in Altirra emulator first !!! noob ):", width / 2, height / 2 + 20);
    }
  }
}

void mousePressed() {
  println();
  if (D2count > 0) {
    selectOutput("Select a file to write to:", "fileSelected");
    count = 0; // DATA COUNT RESET
  } else {

    println("Sorry but you are trying to save empty file, DATA SIZE:" + D2count);
    println("Try printing something in Altirra emulator!!! noob ):");
    background(255, 0, 0); // RGB
    fill(255);
    textAlign(CENTER);
    text("Sorry but you are trying to save empty file, DATA SIZE:" + D2count, width / 2, height / 2 - 20);
    text("Try printing something in Altirra emulator first !!! noob ):", width / 2, height / 2 + 20);
  }
}

 

And while editing the code I suggest replacing the data array buffer size.

 

from:

 int[] data = new int[131073]; // 128Kb buffer 

to:

 int kb = 1024;

 int[] data = new int[kb * 4000]; // 4MB

 

This way you can print multiple pages just don't press on the Green window till you absolutely sure you finish printing all the pages.

 

 

 

Link to comment
Share on other sites

  • 2 weeks later...

Okay just a quick update.

I modify my MSD2SIO Drive now accepting printer protocol sending all the data to USB and my new processing file dumping utility APP so I can analyze the data from real hardware (130 XE )

Guess what be careful which Print Shop version you use on interwebs.

They seem to be mostly buggy not sure if it's the software version or some type of copy protection.

Link to comment
Share on other sites

Altirra atdavice TCP Protocol RAW file dump example VER 0.02

ADD: Altirra Cold / Warm Reset command handling.

 

Spoiler

/** Altirra atdavice TCP Protocol RAW file dump example.
 MIT License
 Chris O. 6/13/2024
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */
String Ver = "0.02";

import processing.net.*;
Server myServer;

boolean IsClientUP = false;
boolean thisClientbool = false;
int netstart = 0;
int kb = 1024;
int[] data = new int[kb * 10000]; // 10MB buffer

int[] dataheader = new int[50];
int dataIn;
int timer;
long timer2;
int countheader;
int count;
int skipcount; // error data over (0x7F) 127 >
int D2count;
boolean headerbool = false;
boolean databool = false;

String path ="";

// --- setup() ---
void setup() {
  size(600, 200);
  // create a font with the third font available to the system:
  PFont myFont = createFont(PFont.list()[2], 18);
  textFont(myFont);
  background(50, 50, 50); // RGB
  fill(255);
  textAlign(CENTER);
  text("Altirra atdavice TCP Protocol RAW file dump example ", width / 2, height / 2 - 20);
  text(" - Version " + Ver, width / 2, height / 2 + 20);

  // Starts a myServer on port 6502
  print("Altirra atdavice TCP Protocol RAW file dump example");
  println(" - Version " + Ver);
  myServer = new Server(this, 6502);

  if (IsClientUP == false) {
    text("Server Says: client disconnected ", width / 2, height / 2 + 50);
    text("Try Warm/Cold Reset in Altirra or RUN Altirra emulator first !!!!!!", width / 2, height / 2 + 80);
  } else {
    text("Server Says: We have a new client ", width / 2, height / 2 + 50);
  }

  //netstart = 0;
  // HELLO START
  println("SetUP - Ask Altirra for heder ");
  myServer.write(0x0C);
  myServer.write(0x02);
  myServer.write(0x0A);
  myServer.write(0x0B);
  myServer.write(0x01);
  myServer.write(0x00);
  myServer.write(0x00);
  myServer.write(0x00);
  myServer.write(0x00);
  delay(250);
}

// --- draw() ---
void draw() {
  AltirraLOOP();
} //- draw loop end

void AltirraLOOP() {
  Client thisClient = myServer.available();

  // If the client is not null, and says something, display what it said
  if (thisClient !=null) {
    thisClientbool = true;
    dataIn = thisClient.read();
    if (countheader == 0 && (dataIn > 0 || dataIn < 9)  ) { // DO THIS ONLY IF DATA 7 OR 4
      //println("headerbool " + headerbool);
      if ((countheader >= 0) && (countheader < 17)) { // 17 bytes header ~ 0 indexed
        dataheader[countheader] = dataIn; // save in header array
        //println("HEX: " +hex(dataheader[countheader], 2) + /** " , show chr: " + (char)dataIn + */ " , countheader: " + countheader);
        countheader++;
        while (countheader < 17) {
          //delay(1);
          dataheader[countheader] = thisClient.read();
          //println("HEX: " +hex(dataheader[countheader], 2) + /** " , show chr: " + (char)dataIn + */ " , countheader: " + countheader);
          if (countheader == 16) {
            // todo fix 64bit ?
            timer = 0;
            timer = ((dataheader[8] & 0xFF) << 0); // / & 0xff
            timer = ((dataheader[9] & 0xFF) << 8);
            timer = ((dataheader[10] & 0xFF) << 16);
            timer = ((dataheader[11] & 0xFF) << 24);
            //timer = ((dataheader[13] & 0xFF) << 32);
            //timer = ((dataheader[14] & 0xFF) << 40);

            timer2 = timer & 0xffffffffL;

            int mm = millis();
            int s = second();  // Values from 0 - 59
            int m = minute();  // Values from 0 - 59
            int h = hour();    // Values from 0 - 23
            print("System time: " + h + ":" + m + ":" + s + "." + mm);

            headerbool = true;
            println(" , Header timestamp: " + timer2); // TODO fix 64bit ?
          }
          countheader++;
        }
      }
    }

    if (headerbool == true) {
      dataIn = thisClient.read();
      data[count] = dataIn;
      //
      countheader = 0;
      // we got the header now ask for data
      // println(" we got the header now ask for data ");
      // self.handlers[0] = ("None", self.handle_none)
      //  self.handlers[1] = ("Debug read byte", self.wrap_debugreadbyte)
      //  self.handlers[2] = ("Read byte", self.wrap_readbyte)
      //  self.handlers[3] = ("Write byte", self.wrap_writebyte)
      //  self.handlers[4] = ("Cold reset", self.wrap_coldreset)
      //  self.handlers[5] = ("Warm reset", self.wrap_warmreset)
      //  self.handlers[6] = ("Error", self.handle_error)
      //  self.handlers[7] = ("Script event", self.wrap_script_event)
      //  self.handlers[8] = ("Script post", self.handle_script_post)

      if (dataheader[0] == 6) {
        //
        println(" ID 6 ERROR  ");
        background(255, 0, 0); // RGB
        fill(0);
        textAlign(CENTER);
        text("ID 6, self.handle_error ", width / 2, height / 2 - 20);
        text(" - Version " + Ver, width / 2, height / 2 + 20);
        /*
         myServer.write(0x06); //1
         myServer.write(0x00); //2
         myServer.write(0x00); //3
         myServer.write(0x00); //4
         myServer.write(0x00); //5
         myServer.write(0x00); //6
         myServer.write(0x28); //7, print_width 40
         myServer.write(0x00); //8
         myServer.write(0x00); //9
         myServer.write(0x00); //10
         myServer.write(0x01); //11
         myServer.write(0x00); //12
         myServer.write(0x00); //13
         myServer.write(0x00); //14
         myServer.write(0x00); //15
         */
        delay(1500);
      }
      if (dataheader[0] == 2) {
        // println(" skip id2 ");
        //  not in use
        /*
         myServer.write(0x06); //1
         myServer.write(0x00); //2
         myServer.write(0x00); //3
         myServer.write(0x00); //4
         myServer.write(0x00); //5
         myServer.write(0x00); //6
         myServer.write(0x28); //7, print_width 40
         myServer.write(0x00); //8
         myServer.write(0x00); //9
         myServer.write(0x00); //10
         myServer.write(0x01); //11
         myServer.write(0x00); //12
         myServer.write(0x00); //13
         myServer.write(0x00); //14
         myServer.write(0x00); //15
         */
        delay(200);
      }
      if (dataheader[0] == 4) {
        //
        println(" COLD RESET id4 ");
        background(0, 0, 255); // RGB
        fill(255);
        textAlign(CENTER);
        text("Server Says: COLD RESET id4, client disconnected: ", width / 2, height / 2 - 20);
        if (netstart == 1) {
          println(thisClient.ip() + "\t has been disconnected COLD RESET ");
          text(thisClient.ip(), width / 2, height / 2 + 40);
          //myServer.disconnect(thisClient);
          netstart = 0;
        }
      }
      if (dataheader[0] == 5) {
        println(" WARM RESET id5 ");
        if (netstart == 1) {
          netstart = 0;
          println(thisClient.ip() + "\t has been disconnected");
          background(150, 150, 255); // RGB
          fill(250, 255, 0);
          textAlign(CENTER);
          text("Server Says: WARM RESET id5, client disconnected: ", width / 2, height / 2 - 20);
          text(thisClient.ip(), width / 2, height / 2 + 40);
          //myServer.disconnect(thisClient);
        }
      }
      if (dataheader[0] == 7) {
        // ASK ONLY IF DATA AVAL, need 2 ask or emulator frozen ?
        println(" Ask for data id7 ");
        //println("databool " + databool);
        myServer.write(0x06); //1
        delay(1);
        myServer.write(0x00); //2
        delay(1);
        myServer.write(0x00); //3
        delay(1);
        myServer.write(0x00); //4
        delay(1);
        myServer.write(0x00); //5
        delay(1);
        myServer.write(0x00); //6
        delay(1);
        myServer.write(0x28); //7, print_width 40
        delay(1);
        myServer.write(0x00); //8
        delay(1);
        myServer.write(0x00); //9
        delay(1);
        myServer.write(0x00); //10
        delay(1);
        myServer.write(0x01); //11
        delay(1);
        myServer.write(0x00); //12
        delay(1);
        myServer.write(0x00); //13
        delay(1);
        myServer.write(0x00); //14
        delay(1);
        myServer.write(0x00); //15
        delay(1);
        databool = true;
        // delay(60);
      }
    }

    if (databool == true) {
      if (dataheader[0] == 7) {
        int i = dataheader[1] + count;
        background(0, 100, 255); // RGB
        while (i > count) {
          dataIn = thisClient.read();
          data[count] = dataIn;
          // println(hex(dataIn, 2) + " " + (char)dataIn + " count " + count + " dataheader[1] size " + dataheader[1]);
          // delay(1);
          count++;
        }
        //println(" count " + (count - 1) + " skipcount " + (skipcount - 1));
        //
        headerbool = false;
      }
    } // - if (databool == true)
  } else { // if (thisClient !=null)
    // Client aval. but data == null
    if (thisClientbool == true) {
      background(0, 255, 0); // RGB
      fill(0);
      textAlign(CENTER);
      //text(thisClient.ip(), width / 2, height / 2 + 40);
      text("Ready ", width / 2, height / 2 - 50);
      //println("thisClientbool " + thisClientbool);
      thisClientbool = false;
      if (IsClientUP == true) {
        //println("IsClientUP " + IsClientUP);
        println(" Data size: " + count);
        //println(" count " + (count - 1) + " skipcount " + (skipcount - 1));
        D2count = count;
        text("Data size: " + D2count, width / 2, height / 2 - 20);
        if (D2count > 0) {
          text("If printing finish Click Me - Save file", width / 2, height / 2 + 20);
        }

        //int x = 0;
        //for (int i = 0; i < count; i++)
        //{
        //  x++;
        //  print("[" + i + "] " + hex(data[i], 2) + "  ");
        //  if (x == 11) {
        //    x = 0;
        //    println();
        //  }
        //}
      }
    }
  }

  if (netstart == 0) {
    if (IsClientUP == true) {
      println("netstart restart " + IsClientUP);
      netstart = 1;
      // why i need to send this twice?
      netstart(); // reint... connection
      netstart(); // reint... connection
    }
  }
}

// --- ServerEvent message is generated when a new client connects ---
// --- to an existing server.                                      ---
void serverEvent(Server someServer, Client someClient) {
  println("We have a new client: " + someClient.ip() + "  Server: "+ someServer);
  IsClientUP = true;
  background(0, 0, 255); // RGB

  fill(0);
  textAlign(CENTER);
  text("We have a new client: " + someClient.ip(), width / 2, height / 2 - 20);
}

// --- ClientEvent message is generated when a client disconnects. ---
void disconnectEvent(Client someClient) {
  IsClientUP = false;
  netstart = 0;
  print("Server Says: client disconnected,  IsClientUP: " + IsClientUP + "  " + someClient);
  background(255, 0, 0); // RGB
  fill(0);
  textAlign(CENTER);
  text("Server Says: client disconnected: " + IsClientUP, width / 2, height / 2 - 20);
}

// --- netstart                                                    ---
void netstart() {

  // HELLO START
  println("SetUP - ask for heder ");
  myServer.write(0x0C);
  myServer.write(0x02);
  myServer.write(0x0A);
  myServer.write(0x0B);
  myServer.write(0x01);
  myServer.write(0x00);
  myServer.write(0x00);
  myServer.write(0x00);
  myServer.write(0x00);
  delay(250);

  // Ask or Altirra will be frozen ?
  println("SetUP - ask for data ");
  myServer.write(0x06); //1
  myServer.write(0x00); //2
  myServer.write(0x00); //3
  myServer.write(0x00); //4
  myServer.write(0x00); //5
  myServer.write(0x00); //6
  myServer.write(0x28); //7, print_width 40
  myServer.write(0x00); //8
  myServer.write(0x00); //9
  myServer.write(0x00); //10
  myServer.write(0x01); //11
  myServer.write(0x00); //12
  myServer.write(0x00); //13
  myServer.write(0x00); //14
  myServer.write(0x00); //15
  delay(250);
}

void keyPressed() {
  if (key == ' ') { // SPACE KEY
    println();
    if (D2count > 0) {
      selectOutput("Select a file to write to:", "fileSelected");
      count = 0; // DATA COUNT RESET
    } else {
      println("Sorry but you are trying to save empty file, DATA SIZE:" + D2count);
      println("Try printing something in Altirra emulator!!!):");
      background(255, 0, 0); // RGB
      fill(255);
      textAlign(CENTER);
      text("Sorry but you are trying to save empty file, DATA SIZE:" + D2count, width / 2, height / 2 - 20);
      text("Try printing something in Altirra emulator first !!!", width / 2, height / 2 + 20);
    }
  }
}

void mousePressed() {
  println();
  if (D2count > 0) {
    selectOutput("Select a file to write to:", "fileSelected");
    count = 0; // DATA COUNT RESET
  } else {
    if (IsClientUP == false) {
      background(255, 0, 0); // RGB
      text("Try Warm/Cold Reset in Altirra or RUN Altirra emulator first !!!!!!", width / 2, height / 2 + 20);
      text("Server Says: client disconnected ", width / 2, height / 2 + 50);
    } else {
      println("Sorry but you are trying to save empty file, DATA SIZE:" + D2count);
      println("Try printing something in Altirra emulator!!!");
      background(255, 0, 0); // RGB
      fill(255);
      textAlign(CENTER);
      text("Sorry but you are trying to save empty file, DATA SIZE:" + D2count, width / 2, height / 2 - 20);
      text("Try printing something in Altirra emulator first !!!", width / 2, height / 2 + 20);
    }
  }
}

void fileSelected(File selection) {
  if (selection == null) {
    println();
    println("Window was closed or the user hit cancel.");
    fill(255);
    textAlign(CENTER);
    text("Window was closed or the user hit cancel.", width / 2, height / 2 - 20);
  } else {
    println();
    println("User selected " + selection.getAbsolutePath());
    path = selection.getAbsolutePath();
    println("User selected path  " + path);
    byte[] nums = new byte[D2count];
    // copy byte array
    for (int i = 0; i < D2count; i++) {
      nums[i] = byte(data[i]);
    }
    // Writes the bytes to a file
    saveBytes(path, nums);
    println("Saved file, SIZE:" + D2count);
  }
}

 

image.thumb.png.f1fd8e2aaf444afdbe628c4f3c0eecca.png

image.thumb.png.172e66b5506aac203fc3bea5c4de49fd.png

image.thumb.png.04ab732374098d69ecf39d9c82894ba1.png

Ready to run executable files for Linux - Windows - Raspberry Pi

Altirra_Printer_Server_test.zip

 

Edited by Chri O.
  • Like 2
Link to comment
Share on other sites

  • 1 month later...

Altirra atdavice TCP Protocol RAW file dump  VER 0.04

// VER. INFO.
// New for ver 0.03 Console

// New for ver 0.04, 8/2/2024
// Altirra atdavice 0x9B Hbit_ESC issue fix. (line 335)

image.thumb.jpeg.4d17b637a9cd165452ab05bb105fbfa2.jpeg

Ready to run executable files for Linux - Windows - Raspberry Pi - Macosx

+ source code.

Special notes:

This supposed to be run on the same PC that Altirra is running (localhost IP) so I'm not sure if this is useful for platforms other then windows ?

PROCESSING V3 Altirra Printer Server macosx + 0.04.zip

PROCESSING V4 Altirra Printer Server 0.04.zip

Link to comment
Share on other sites

Extremely buggy not supposed to be released today but to be able to See or Print any of the pictures dump from Altirra TCP server ~ this may be useful.

Alpha release --- Ready to run executable files for Linux - Windows - Raspberry Pi (Mac OS coming soon).

 

Select 120 DPI.

image.thumb.jpeg.95eede90ff67e28560d9d253bfda955d.jpeg

Scaled down and up with  +   -  KEY , click right Mouse button and move things around.

image.thumb.jpeg.cbf16b331adf881e0705b2cb17ac382a.jpeg

image.thumb.jpeg.abc55389d15556fc1422b9301cd11338.jpeg

image.thumb.jpeg.6c3d0897d3f3a411ddad5bc486f7cab4.jpeg

If you want to print on your local printer just press P Key on your keyboard.

NOTE: Only print one page at a time.

 

Key J ~ save as Jpeg.

key F ~ save as PDF.

 

PLC5-ESC-P Parser_4k V0.01 alpha.zip

 

Happy printing 😷...

 

 

 

Link to comment
Share on other sites

By the way the monochrome pictures I was able to print with app. Drukarz v1.4a (released by AtariFan) with centronics HP PCL5 on Altirra to my knowledge this is the only software for Atari 8-bit that was capable of HP PCL5 printer command language.

Drukarz only exist in Polish language version I did however translate to English about 90% with hex editor I wish I could release it but I'm waiting for approval from AtariFan.

image.thumb.jpeg.6977fd42c8869cbb61a7430747d1a44d.jpeg

image.thumb.jpeg.45aa148c4b910d5d7d9bde1eefa00396.jpeg

Here is the download link to the Polish language version: Drukarz v1.4a

 

  • Like 1
Link to comment
Share on other sites

MAC OS Alpha release PCL5_ESC_P_Parser_4k --- Ready to run executable for Intel MAC OS. I don't have access to newer Mac let me know if this works on Apple Silicon!!!!

 

PLC5-ESC-P Parser_4k V0.01 alpha.zip

-

Note: APP needs two button mouse with scroll wheel !!!
Scaled down and up pic. with  +   -  KEY , click right Mouse button and move pic. around.
If you want to print on your local network printer just press P Key on your keyboard.
NOTE: Only print one page at a time.
Key J ~ save as Jpeg PIC.
Key F ~ save as PDF.
This will create exported folder with either the PIC. or PDF 
 located in path that application is running from.
Change fonts and pages with mouse wheel.

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...